Move to subparsers

Move argument parsing to subparsers, rather than positional arguments.
This better reflects the tool's role as a driver and allows
sub-commands to deal with arguments in a natural way.

Change-Id: Iae8c368e0f3fe47abfddb9e0a1558bd5b3423aee
This commit is contained in:
Ian Wienand 2017-05-02 13:29:34 +10:00
parent b39b5cb5a5
commit c74ba2fe74
4 changed files with 80 additions and 55 deletions

View File

@ -40,7 +40,7 @@ class BlockDevice(object):
A typical call sequence: A typical call sequence:
cmd_init: initialized the block device level config. After this cmd_init: initialize the block device level config. After this
call it is possible to e.g. query information from the (partially call it is possible to e.g. query information from the (partially
automatic generated) internal state like root-label. automatic generated) internal state like root-label.
@ -74,19 +74,19 @@ class BlockDevice(object):
In a script this should be called in the following way: In a script this should be called in the following way:
dib-block-device --phase=init ... dib-block-device init ...
# From that point the database can be queried, like # From that point the database can be queried, like
ROOT_LABEL=$(dib-block-device --phase=getval --symbol=root-label ...) ROOT_LABEL=$(dib-block-device getval root-label)
Please note that currently the dib-block-device executable can Please note that currently the dib-block-device executable can
only be used outside the chroot. only be used outside the chroot.
dib-block-device --phase=create ... dib-block-device create ...
trap "dib-block-device --phase=delete ..." EXIT trap "dib-block-device delete ..." EXIT
# copy / install files # copy / install files
dib-block-device --phase=umount ... dib-block-device umount ...
# convert image(s) # convert image(s)
dib-block-device --phase=cleanup ... dib-block-device cleanup ...
trap - EXIT trap - EXIT
""" """

View File

@ -26,67 +26,93 @@ logger = logging.getLogger(__name__)
class BlockDeviceCmd(object): class BlockDeviceCmd(object):
def generate_phase_doc(self): def cmd_init(self):
phase_doc = "" self.bd.cmd_init()
bdattrs = dir(BlockDevice)
for attr in bdattrs: def cmd_getval(self):
if attr.startswith("cmd_"): self.bd.cmd_getval()
phase_doc += " '" + attr[4:] + "'\n"
method = getattr(BlockDevice, attr, None) def cmd_create(self):
# The first line is the line that is used self.bd.cmd_create()
phase_doc += " " + method.__doc__.split("\n")[0] + "\n"
return phase_doc def cmd_umount(self):
self.bd.cmd_umount()
def cmd_cleanup(self):
self.bd.cmd_cleanup()
def cmd_delete(self):
self.bd.cmd_delete()
def cmd_writefstab(self):
self.bd.cmd_writefstab()
def main(self): def main(self):
logging_config.setup() logging_config.setup()
phase_doc = self.generate_phase_doc()
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(description="DIB Block Device helper")
formatter_class=argparse.RawDescriptionHelpFormatter,
description="Create block device layer",
epilog="Available phases:\n" + phase_doc)
parser.add_argument('--phase', required=True,
help="phase to execute")
parser.add_argument('--params', required=False, parser.add_argument('--params', required=False,
help="YAML file containing parameters for" help="YAML file containing parameters for"
"block-device handling. Default is " "block-device handling. Default is "
"DIB_BLOCK_DEVICE_PARAMS_YAML") "DIB_BLOCK_DEVICE_PARAMS_YAML")
parser.add_argument('--symbol', required=False,
help="symbol to query for getval") subparsers = parser.add_subparsers(title='commands',
args = parser.parse_args() description='valid commands',
dest='command',
help='additional help')
cmd_init = subparsers.add_parser('init',
help='Initialize configuration')
cmd_init.set_defaults(func=self.cmd_init)
cmd_getval = subparsers.add_parser('getval',
help='Retrieve information about'
'internal state')
cmd_getval.set_defaults(func=self.cmd_getval)
cmd_getval.add_argument('symbol', help='symbol to print')
cmd_create = subparsers.add_parser('create',
help='Create the block device')
cmd_create.set_defaults(func=self.cmd_create)
cmd_umount = subparsers.add_parser('umount',
help='Unmount blockdevice and'
'cleanup resources')
cmd_umount.set_defaults(func=self.cmd_umount)
cmd_cleanup = subparsers.add_parser('cleanup', help='Final cleanup')
cmd_cleanup.set_defaults(func=self.cmd_cleanup)
cmd_delete = subparsers.add_parser('delete', help='Error cleanup')
cmd_delete.set_defaults(func=self.cmd_delete)
cmd_writefstab = subparsers.add_parser('writefstab',
help='Create fstab for system')
cmd_writefstab.set_defaults(func=self.cmd_writefstab)
self.args = parser.parse_args()
# Find, open and parse the parameters file # Find, open and parse the parameters file
if not args.params: if not self.args.params:
if 'DIB_BLOCK_DEVICE_PARAMS_YAML' in os.environ: if 'DIB_BLOCK_DEVICE_PARAMS_YAML' in os.environ:
param_file = os.environ['DIB_BLOCK_DEVICE_PARAMS_YAML'] param_file = os.environ['DIB_BLOCK_DEVICE_PARAMS_YAML']
else: else:
parser.error( parser.error(
"DIB_BLOCK_DEVICE_PARAMS_YAML or --params not set") "DIB_BLOCK_DEVICE_PARAMS_YAML or --params not set")
else: else:
param_file = args.params param_file = self.args.params
logger.info("params [%s]" % param_file) logger.info("params [%s]" % param_file)
try: try:
with open(param_file) as f: with open(param_file) as f:
params = yaml.safe_load(f) self.params = yaml.safe_load(f)
except Exception: except Exception:
logger.exception("Failed to open parameter YAML") logger.exception("Failed to open parameter YAML")
sys.exit(1) sys.exit(1)
logger.info("phase [%s]" % args.phase) # Setup main BlockDevice object from args
self.bd = BlockDevice(self.params, self.args)
if args.symbol: self.args.func()
logger.info("symbol [%s]" % args.symbol)
bd = BlockDevice(params, args)
# Check if the method is available
method = getattr(bd, "cmd_" + args.phase, None)
if callable(method):
# If so: call it.
return method()
else:
logger.error("phase [%s] does not exists" % args.phase)
return 1
def main(): def main():

View File

@ -299,7 +299,7 @@ mount-base: ${TMP_BUILD_DIR}/mnt
build-dir: ${TMP_BUILD_DIR} build-dir: ${TMP_BUILD_DIR}
EOF EOF
dib-block-device --phase=init dib-block-device init
create_base create_base
# This variable needs to be propagated into the chroot # This variable needs to be propagated into the chroot
@ -424,14 +424,13 @@ if [ -z ${IMAGE_BLOCK_DEVICE} ] ; then
# After changeing the parameters, there is the need to # After changeing the parameters, there is the need to
# re-run dib-block-device init because some value might # re-run dib-block-device init because some value might
# change based on the new set parameters. # change based on the new set parameters.
dib-block-device --phase=init dib-block-device init
# values to dib-block-device: using the YAML config and # values to dib-block-device: using the YAML config and
dib-block-device --phase=create dib-block-device create
# It's called 'DEVICE' but it's the partition. # It's called 'DEVICE' but it's the partition.
IMAGE_BLOCK_DEVICE=$(dib-block-device \ IMAGE_BLOCK_DEVICE=$(dib-block-device getval image-block-partition)
--phase=getval --symbol=image-block-partition)
fi fi
export IMAGE_BLOCK_DEVICE export IMAGE_BLOCK_DEVICE
LOOPDEV=${IMAGE_BLOCK_DEVICE} LOOPDEV=${IMAGE_BLOCK_DEVICE}
@ -441,7 +440,7 @@ IMAGE_BLOCK_DEVICE_WITHOUT_PART=$(echo ${IMAGE_BLOCK_DEVICE} \
export IMAGE_BLOCK_DEVICE_WITHOUT_PART export IMAGE_BLOCK_DEVICE_WITHOUT_PART
export EXTRA_DETACH="detach_loopback ${IMAGE_BLOCK_DEVICE_WITHOUT_PART}" export EXTRA_DETACH="detach_loopback ${IMAGE_BLOCK_DEVICE_WITHOUT_PART}"
export EXTRA_UNMOUNT="dib-block-device --phase=cleanup" export EXTRA_UNMOUNT="dib-block-device cleanup"
sudo mkfs -t $FS_TYPE $MKFS_OPTS -L ${DIB_ROOT_LABEL} ${IMAGE_BLOCK_DEVICE} sudo mkfs -t $FS_TYPE $MKFS_OPTS -L ${DIB_ROOT_LABEL} ${IMAGE_BLOCK_DEVICE}
# Tuning the rootfs uuid works only for ext filesystems. # Tuning the rootfs uuid works only for ext filesystems.
@ -505,12 +504,12 @@ fi
export EXTRA_UNMOUNT="" export EXTRA_UNMOUNT=""
unmount_image unmount_image
TMP_IMAGE_PATH=$(dib-block-device --phase=getval --symbol=image-path) TMP_IMAGE_PATH=$(dib-block-device getval image-path)
export TMP_IMAGE_PATH export TMP_IMAGE_PATH
dib-block-device --phase=umount dib-block-device umount
dib-block-device --phase=cleanup dib-block-device cleanup
cleanup_build_dir cleanup_build_dir

View File

@ -50,7 +50,7 @@ function trap_cleanup() {
} }
function cleanup () { function cleanup () {
dib-block-device --phase=umount dib-block-device umount
unmount_image unmount_image
cleanup_build_dir cleanup_build_dir
cleanup_image_dir cleanup_image_dir