def parseargs(argv=None): parser = argparse.ArgumentParser( prog=PROGRAM, description=_('Generate a bootable disk image.'), ) parser.add_argument('--version', action='version', version='{} {}'.format(PROGRAM, __version__)) parser.add_argument('-d', '--debug', default=False, action='store_true', help=_('Enable debugging output')) args = parser.parse_args(argv) if args.debug: logging.basicConfig(level=logging.DEBUG) return args
def invoked(self, ctx): print(_('Enter your Ubuntu One SSO credentials.')) try: email = ctx.args.email if not email: email = input(_('Email: ')) password = getpass.getpass(_('Password: '******'' while True: _logger.info('Authenticating against Ubuntu One SSO.') response = storeapi.login( email, password, token_name='ubuntu-image', otp=otp) success = response.get('success', False) if success: _logger.info('Login successful.') break body = response.get('body') if body is None: raise Exception('Server response does not contain body') code = body.get('code') _logger.info('Login failed %s: (%s)', code, body.get('message')) if code == 'INVALID_CREDENTIALS': print(_('Invalid email or password, please try again')) password = getpass.getpass(_('Password: '******'TWOFACTOR_REQUIRED': print(_('Two-factor authentication required')) otp = input(_('One-time password: '******'Unexpected code in server response: %s', code) break with suppress(auth.UnsuccessfulAuthenticationError): auth.Credentials().remember_sso_response(response)
def parseargs(argv=None): parser = argparse.ArgumentParser( prog=PROGRAM, description=_('Generate a bootable disk image.'), ) parser.add_argument('--version', action='version', version='{} {}'.format(PROGRAM, __version__)) # Common options. common_group = parser.add_argument_group(_('Common options')) common_group.add_argument( 'model_assertion', nargs='?', help=_("""Path to the model assertion file. This argument must be given unless the state machine is being resumed, in which case it cannot be given.""")) common_group.add_argument('-d', '--debug', default=False, action='store_true', help=_('Enable debugging output')) common_group.add_argument( '-i', '--image-size', default=None, action=SizeAction, metavar='SIZE', help=_("""The suggested size of the generated disk image file. If this size is smaller than the minimum calculated size of the image a warning will be issued and --image-size will be ignored. The value is the size in bytes, with allowable suffixes 'M' for MiB and 'G' for GiB. Use an extended syntax to define the suggested size for the disk images generated by a multi-volume gadget.yaml spec. See the ubuntu-image(1) manpage for details.""")) common_group.add_argument( '--image-file-list', default=None, metavar='FILENAME', help=_("""Print to this file, a list of the file system paths to all the disk images created by the command, if any.""")) output_group = common_group.add_mutually_exclusive_group() output_group.add_argument( '-O', '--output-dir', default=None, metavar='DIRECTORY', help=_("""The directory in which to put generated disk image files. The disk image files themselves will be named <volume>.img inside this directory, where <volume> is the volume name taken from the gadget.yaml file. Use this option instead of the deprecated -o/--output option.""")) output_group.add_argument( '-o', '--output', default=None, metavar='FILENAME', help=_("""DEPRECATED (use -O/--output-dir instead). The generated disk image file. If not given, the image will be put in a file called disk.img in the working directory (in which case, you probably want to specify -w).""")) # Snap-based image options. snap_group = parser.add_argument_group( _('Image contents options'), _("""Additional options for defining the contents of snap-based images.""")) snap_group.add_argument( '--extra-snaps', default=None, action='append', help=_("""Extra snaps to install. This is passed through to `snap prepare-image`.""")) snap_group.add_argument( '--cloud-init', default=None, metavar='USER-DATA-FILE', help=_('cloud-config data to be copied to the image')) snap_group.add_argument('-c', '--channel', default=None, help=_('The snap channel to use')) # State machine options. inclusive_state_group = parser.add_argument_group( _('State machine options'), _("""Options for controlling the internal state machine. Other than -w, these options are mutually exclusive. When -u or -t is given, the state machine can be resumed later with -r, but -w must be given in that case since the state is saved in a .ubuntu-image.pck file in the working directory.""")) inclusive_state_group.add_argument( '-w', '--workdir', default=None, metavar='DIRECTORY', help=_("""The working directory in which to download and unpack all the source files for the image. This directory can exist or not, and it is not removed after this program exits. If not given, a temporary working directory is used instead, which *is* deleted after this program exits. Use -w if you want to be able to resume a partial state machine run.""")) state_group = inclusive_state_group.add_mutually_exclusive_group() state_group.add_argument( '-u', '--until', default=None, metavar='STEP', help=_("""Run the state machine until the given STEP, non-inclusively. STEP can be a name or number.""")) state_group.add_argument( '-t', '--thru', default=None, metavar='STEP', help=_("""Run the state machine through the given STEP, inclusively. STEP can be a name or number.""")) state_group.add_argument( '-r', '--resume', default=False, action='store_true', help=_("""Continue the state machine from the previously saved state. It is an error if there is no previous state.""")) args = parser.parse_args(argv) if args.debug: logging.basicConfig(level=logging.DEBUG) # The model assertion argument is required unless --resume is given, in # which case it cannot be given. if args.resume and args.model_assertion: parser.error('model assertion is not allowed with --resume') if not args.resume and args.model_assertion is None: parser.error('model assertion is required') if args.resume and args.workdir is None: parser.error('--resume requires --workdir') # --until and --thru can take an int. with suppress(ValueError, TypeError): args.thru = int(args.thru) with suppress(ValueError, TypeError): args.until = int(args.until) # -o/--output is deprecated and mutually exclusive with -O/--output-dir if args.output is not None: print('-o/--output is deprecated; use -O/--output-dir instead', file=sys.stderr) return args
def parseargs(argv=None): parser = argparse.ArgumentParser( prog=PROGRAM, description=_('Generate a bootable disk image.'), formatter_class=SimpleHelpFormatter) parser.add_argument('--version', action='version', version='{} {}'.format(PROGRAM, __version__)) # create two subcommands, "snap" and "classic" subparser = parser.add_subparsers(title=_('Command'), dest='cmd') snap_cmd = subparser.add_parser( 'snap', help=_("""Create snap-based Ubuntu Core image.""")) classic_cmd = subparser.add_parser( 'classic', help=_("""Create debian-based Ubuntu Classic image.""")) argv = get_modified_args(subparser, 'snap', argv) snap_cmd = add_common_args(snap_cmd) classic_cmd = add_common_args(classic_cmd) # Snap-based image options. snap_cmd.add_argument( 'model_assertion', nargs='?', help=_("""Path to the model assertion file. This argument must be given unless the state machine is being resumed, in which case it cannot be given.""")) snap_cmd.add_argument( '--extra-snaps', default=None, action='append', help=_("""Extra snaps to install. This is passed through to `snap prepare-image`.""")) snap_cmd.add_argument('-c', '--channel', default=None, help=_('The snap channel to use')) # Classic-based image options. classic_cmd.add_argument( 'gadget_tree', nargs='?', help=_("""Gadget tree. This is a tree equivalent to an unpacked and primed gadget snap at core image build time.""")) classic_cmd.add_argument( '-p', '--project', default=None, metavar='PROJECT', help=_("""Project name to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '-s', '--suite', default=get_host_distro(), metavar='SUITE', help=_("""Distribution name to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '-a', '--arch', default=get_host_arch(), metavar='CPU-ARCHITECTURE', help=_("""CPU architecture to be specified to livecd-rootfs. default value is builder arch.""")) classic_cmd.add_argument( '--subproject', default=None, metavar='SUBPROJECT', help=_("""Sub project name to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '--subarch', default=None, metavar='SUBARCH', help=_("""Sub architecture to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '--with-proposed', default=False, action='store_true', help=_("""Proposed repo to install, This is passed through to livecd-rootfs.""")) classic_cmd.add_argument( '--extra-ppas', default=None, action='append', help=_("""Extra ppas to install. This is passed through to livecd-rootfs.""")) # Perform the actual argument parsing. args = parser.parse_args(argv) if args.debug: logging.basicConfig(level=logging.DEBUG) # The model assertion argument is required unless --resume is given, in # which case it cannot be given. if args.cmd == 'snap': if args.resume and args.model_assertion: parser.error('model assertion is not allowed with --resume') if not args.resume and args.model_assertion is None: parser.error('model assertion is required') else: if args.resume and args.gadget_tree: parser.error('gadget tree is not allowed with --resume') if not args.resume: # pragma: no branch if args.gadget_tree is None: parser.error('gadget tree is required') elif args.project is None: parser.error('project is required') if args.resume and args.workdir is None: parser.error('--resume requires --workdir') # --until and --thru can take an int. with suppress(ValueError, TypeError): args.thru = int(args.thru) with suppress(ValueError, TypeError): args.until = int(args.until) # --hooks-directory can be a comma-separated list of directories if args.hooks_directory: args.hooks_directory = args.hooks_directory.split(',') # -o/--output is deprecated and mutually exclusive with -O/--output-dir if args.output is not None: print('-o/--output is deprecated; use -O/--output-dir instead', file=sys.stderr) return args
def add_common_args(subcommand): common_group = subcommand.add_argument_group(_('Common options')) common_group.add_argument('-d', '--debug', default=False, action='store_true', help=_('Enable debugging output')) common_group.add_argument( '-i', '--image-size', default=None, action=SizeAction, metavar='SIZE', help=_("""The suggested size of the generated disk image file. If this size is smaller than the minimum calculated size of the image a warning will be issued and --image-size will be ignored. The value is the size in bytes, with allowable suffixes 'M' for MiB and 'G' for GiB. Use an extended syntax to define the suggested size for the disk images generated by a multi-volume gadget.yaml spec. See the ubuntu-image(1) manpage for details.""")) common_group.add_argument( '--image-file-list', default=None, metavar='FILENAME', help=_("""Print to this file, a list of the file system paths to all the disk images created by the command, if any.""")) common_group.add_argument( '--cloud-init', default=None, metavar='USER-DATA-FILE', help=_('cloud-config data to be copied to the image')) common_group.add_argument( '--hooks-directory', default=[], metavar='DIRECTORY', help=_("""Path or comma-separated list of paths of directories in which scripts for build-time hooks will be located.""")) output_group = common_group.add_mutually_exclusive_group() output_group.add_argument( '-O', '--output-dir', default=None, metavar='DIRECTORY', help=_("""The directory in which to put generated disk image files. The disk image files themselves will be named <volume>.img inside this directory, where <volume> is the volume name taken from the gadget.yaml file. Use this option instead of the deprecated -o/--output option.""")) output_group.add_argument( '-o', '--output', default=None, metavar='FILENAME', help=_("""DEPRECATED (use -O/--output-dir instead). The generated disk image file. If not given, the image will be put in a file called disk.img in the working directory (in which case, you probably want to specify -w).""")) # State machine options. inclusive_state_group = subcommand.add_argument_group( _('State machine options'), _("""Options for controlling the internal state machine. Other than -w, these options are mutually exclusive. When -u or -t is given, the state machine can be resumed later with -r, but -w must be given in that case since the state is saved in a .ubuntu-image.pck file in the working directory.""")) inclusive_state_group.add_argument( '-w', '--workdir', default=None, metavar='DIRECTORY', help=_("""The working directory in which to download and unpack all the source files for the image. This directory can exist or not, and it is not removed after this program exits. If not given, a temporary working directory is used instead, which *is* deleted after this program exits. Use -w if you want to be able to resume a partial state machine run.""")) state_group = inclusive_state_group.add_mutually_exclusive_group() state_group.add_argument( '-u', '--until', default=None, metavar='STEP', help=_("""Run the state machine until the given STEP, non-inclusively. STEP can be a name or number.""")) state_group.add_argument( '-t', '--thru', default=None, metavar='STEP', help=_("""Run the state machine through the given STEP, inclusively. STEP can be a name or number.""")) state_group.add_argument( '-r', '--resume', default=False, action='store_true', help=_("""Continue the state machine from the previously saved state. It is an error if there is no previous state.""")) return subcommand
def parseargs(argv=None): parser = argparse.ArgumentParser( prog=PROGRAM, description=_('Generate a bootable disk image.'), formatter_class=SimpleHelpFormatter) parser.add_argument('--version', action='version', version='{} {}'.format(PROGRAM, __version__)) # create two subcommands, "snap" and "classic" subparser = parser.add_subparsers(title=_('Command'), dest='cmd') snap_cmd = subparser.add_parser( 'snap', help=_("""Create snap-based Ubuntu Core image.""")) classic_cmd = subparser.add_parser( 'classic', help=_("""Create debian-based Ubuntu Classic image.""")) argv = get_modified_args(subparser, 'snap', argv) snap_cmd = add_common_args(snap_cmd) classic_cmd = add_common_args(classic_cmd) # Snap-based image options. snap_cmd.add_argument( 'model_assertion', nargs='?', help=_("""Path to the model assertion file. This argument must be given unless the state machine is being resumed, in which case it cannot be given.""")) snap_cmd.add_argument( '--snap', default=None, action='append', help=_("""Install an extra snap. This is passed through to `snap prepare-image`. The snap argument can include additional information about the channel and/or risk with the following syntax: <snap>=<channel|risk>""")) snap_cmd.add_argument( '--extra-snaps', default=None, action='append', help=_("""DEPRECATED (use --snap instead). Extra snap to install. This is passed through to `snap prepare-image`.""")) snap_cmd.add_argument('-c', '--channel', default=None, help=_('The default snap channel to use')) snap_cmd.add_argument( '--disable-console-conf', default=False, action='store_true', help=_("""Disable console-conf on the resulting image.""")) # Classic-based image options. classic_cmd.add_argument( 'gadget_tree', nargs='?', help=_("""Gadget tree. This is a tree equivalent to an unpacked and primed gadget snap at core image build time.""")) classic_cmd.add_argument( '-p', '--project', default=None, metavar='PROJECT', help=_("""Project name to be specified to livecd-rootfs. Mutually exclusive with --filesystem.""")) classic_cmd.add_argument( '-f', '--filesystem', default=None, metavar='FILESYSTEM', help=_("""Unpacked Ubuntu filesystem to be copied to the system partition. Mutually exclusive with --project.""")) classic_cmd.add_argument( '-s', '--suite', default=get_host_distro(), metavar='SUITE', help=_("""Distribution name to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '-a', '--arch', default=None, metavar='CPU-ARCHITECTURE', help=_("""CPU architecture to be specified to livecd-rootfs. default value is builder arch.""")) classic_cmd.add_argument( '--subproject', default=None, metavar='SUBPROJECT', help=_("""Sub project name to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '--subarch', default=None, metavar='SUBARCH', help=_("""Sub architecture to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '--with-proposed', default=False, action='store_true', help=_("""Proposed repo to install, This is passed through to livecd-rootfs.""")) classic_cmd.add_argument( '--extra-ppas', default=None, action='append', help=_("""Extra ppas to install. This is passed through to livecd-rootfs.""")) # Perform the actual argument parsing. args = parser.parse_args(argv) if args.debug: logging.basicConfig(level=logging.DEBUG) # The model assertion argument is required unless --resume is given, in # which case it cannot be given. if args.cmd == 'snap': if args.resume and args.model_assertion: parser.error('model assertion is not allowed with --resume') if not args.resume and args.model_assertion is None: parser.error('model assertion is required') # --extra-snaps is deprecated if args.extra_snaps is not None: print('--extra-snaps is deprecated; use --snap instead', file=sys.stderr) # XXX: This is temporary # Some features are currently unsupported for UC20 images. # Error out early when those are requested. if args.model_assertion and os.path.exists(args.model_assertion): # Try to guess if we're building an UC20 image. # Normally we don't want to do this, but if we want to give # the user feedback early, we need to do this here. # Otherwise we'd have to wait for u-i to pull in all the snaps, # which can take a while. with open(args.model_assertion) as fd: if 'base: core20' in fd.read(): unsupported = [] if args.disable_console_conf: unsupported.append('--disable-console-conf') if args.cloud_init: unsupported.append('--cloud-init') if unsupported: # pragma: no branch parser.error( 'base: core20 model assertion detected, the ' 'following features are unsupported: {}'.format( ' '.join(unsupported))) else: if args.resume and args.gadget_tree: parser.error('gadget tree is not allowed with --resume') if not args.resume: # pragma: no branch if args.gadget_tree is None: parser.error('gadget tree is required') elif args.project is None and args.filesystem is None: parser.error('project or filesystem is required') elif args.project and args.filesystem: parser.error('project and filesystem are mutually exclusive') # And classic doesn't use console-conf args.disable_console_conf = False if args.resume and args.workdir is None: parser.error('--resume requires --workdir') # --until and --thru can take an int. with suppress(ValueError, TypeError): args.thru = int(args.thru) with suppress(ValueError, TypeError): args.until = int(args.until) # --hooks-directory can be a comma-separated list of directories if args.hooks_directory: args.hooks_directory = args.hooks_directory.split(',') # -o/--output is deprecated and mutually exclusive with -O/--output-dir if args.output is not None: print('-o/--output is deprecated; use -O/--output-dir instead', file=sys.stderr) return args
def parseargs(argv=None): parser = argparse.ArgumentParser( prog=PROGRAM, description=_('Generate a bootable disk image.'), ) parser.add_argument('--version', action='version', version='{} {}'.format(PROGRAM, __version__)) parser.add_argument('-d', '--debug', default=False, action='store_true', help=_('Enable debugging output')) parser.add_argument('-c', '--channel', default=None, help=_('For snap-based images, the channel to use')) parser.add_argument('--extra-snaps', default=None, action='append', help=_("""For snap-based images, the extra snaps to install""")) parser.add_argument('-w', '--workdir', default=None, help=_("""The working directory in which to download and unpack all the source files for the image. This directory can exist or not, and it is not removed after this program exits. If not given, a temporary working directory is used instead, which *is* deleted after this program exits.""")) parser.add_argument('--cloud-init', default=None, help=_("cloud-config data to be copied in the image")) parser.add_argument('-o', '--output', default=None, help=_('The output file for the disk image')) parser.add_argument('-r', '--resume', default=False, action='store_true', help=_("""Continue the state machine from the previously saved state. It is an error if there is no previous state.""")) parser.add_argument('model_assertion', nargs='?', help=_('Path to the model assertion')) group = parser.add_mutually_exclusive_group() group.add_argument('-u', '--until', default=None, metavar='STEP', help=_("""Run the state machine until the given STEP, non-inclusively. STEP can be a name or number. The state will be saved in a .ubuntu-image.pck file in the working directory, and can be resumed with -r. Use -w if you want to resume the process later.""")) group.add_argument('-t', '--thru', default=None, metavar='STEP', help=_("""Run the state machine through the given STEP, inclusively. STEP can be a name or number. The state will be saved in a .ubuntu-image.pck file in the working directory and can be resumed with -r. Use -w if you want to resume the process later.""")) args = parser.parse_args(argv) if args.debug: logging.basicConfig(level=logging.DEBUG) # The model assertion argument is required unless --resume is given, in # which case it cannot be given. if args.resume and args.model_assertion: parser.error('model assertion is not allowed with --resume') if not args.resume and args.model_assertion is None: parser.error('model assertion is required') if args.resume and args.workdir is None: parser.error('--resume requires --workdir') # --until and --thru can take an int. with suppress(ValueError, TypeError): args.thru = int(args.thru) with suppress(ValueError, TypeError): args.until = int(args.until) return args
def parseargs(argv=None): parser = argparse.ArgumentParser( prog=PROGRAM, description=_('Generate a bootable disk image.'), formatter_class=SimpleHelpFormatter) parser.add_argument( '--version', action='version', version='{} {}'.format(PROGRAM, __version__)) # create two subcommands, "snap" and "classic" subparser = parser.add_subparsers(title=_('Command'), dest='cmd') snap_cmd = subparser.add_parser( 'snap', help=_("""Create snap-based Ubuntu Core image.""")) classic_cmd = subparser.add_parser( 'classic', help=_("""Create debian-based Ubuntu Classic image.""")) argv = get_modified_args(subparser, 'snap', argv) snap_cmd = add_common_args(snap_cmd) classic_cmd = add_common_args(classic_cmd) # Snap-based image options. snap_cmd.add_argument( 'model_assertion', nargs='?', help=_("""Path to the model assertion file. This argument must be given unless the state machine is being resumed, in which case it cannot be given.""")) snap_cmd.add_argument( '--snap', default=None, action='append', help=_("""Install an extra snap. This is passed through to `snap prepare-image`. The snap argument can include additional information about the channel and/or risk with the following syntax: <snap>=<channel|risk>""")) snap_cmd.add_argument( '--extra-snaps', default=None, action='append', help=_("""DEPRECATED (use --snap instead). Extra snap to install. This is passed through to `snap prepare-image`.""")) snap_cmd.add_argument( '-c', '--channel', default=None, help=_('The default snap channel to use')) # Classic-based image options. classic_cmd.add_argument( 'gadget_tree', nargs='?', help=_("""Gadget tree. This is a tree equivalent to an unpacked and primed gadget snap at core image build time.""")) classic_cmd.add_argument( '-p', '--project', default=None, metavar='PROJECT', help=_("""Project name to be specified to livecd-rootfs. Mutually exclusive with --filesystem.""")) classic_cmd.add_argument( '-f', '--filesystem', default=None, metavar='FILESYSTEM', help=_("""Unpacked Ubuntu filesystem to be copied to the system partition. Mutually exclusive with --project.""")) classic_cmd.add_argument( '-s', '--suite', default=get_host_distro(), metavar='SUITE', help=_("""Distribution name to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '-a', '--arch', default=None, metavar='CPU-ARCHITECTURE', help=_("""CPU architecture to be specified to livecd-rootfs. default value is builder arch.""")) classic_cmd.add_argument( '--subproject', default=None, metavar='SUBPROJECT', help=_("""Sub project name to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '--subarch', default=None, metavar='SUBARCH', help=_("""Sub architecture to be specified to livecd-rootfs.""")) classic_cmd.add_argument( '--with-proposed', default=False, action='store_true', help=_("""Proposed repo to install, This is passed through to livecd-rootfs.""")) classic_cmd.add_argument( '--extra-ppas', default=None, action='append', help=_("""Extra ppas to install. This is passed through to livecd-rootfs.""")) # Perform the actual argument parsing. args = parser.parse_args(argv) if args.debug: logging.basicConfig(level=logging.DEBUG) # The model assertion argument is required unless --resume is given, in # which case it cannot be given. if args.cmd == 'snap': if args.resume and args.model_assertion: parser.error('model assertion is not allowed with --resume') if not args.resume and args.model_assertion is None: parser.error('model assertion is required') # --extra-snaps is deprecated if args.extra_snaps is not None: print('--extra-snaps is deprecated; use --snap instead', file=sys.stderr) else: if args.resume and args.gadget_tree: parser.error('gadget tree is not allowed with --resume') if not args.resume: # pragma: no branch if args.gadget_tree is None: parser.error('gadget tree is required') elif args.project is None and args.filesystem is None: parser.error('project or filesystem is required') elif args.project and args.filesystem: parser.error('project and filesystem are mutually exclusive') if args.resume and args.workdir is None: parser.error('--resume requires --workdir') # --until and --thru can take an int. with suppress(ValueError, TypeError): args.thru = int(args.thru) with suppress(ValueError, TypeError): args.until = int(args.until) # --hooks-directory can be a comma-separated list of directories if args.hooks_directory: args.hooks_directory = args.hooks_directory.split(',') # -o/--output is deprecated and mutually exclusive with -O/--output-dir if args.output is not None: print('-o/--output is deprecated; use -O/--output-dir instead', file=sys.stderr) return args
def add_common_args(subcommand): common_group = subcommand.add_argument_group(_('Common options')) common_group.add_argument( '-d', '--debug', default=False, action='store_true', help=_('Enable debugging output')) common_group.add_argument( '-i', '--image-size', default=None, action=SizeAction, metavar='SIZE', help=_("""The suggested size of the generated disk image file. If this size is smaller than the minimum calculated size of the image a warning will be issued and --image-size will be ignored. The value is the size in bytes, with allowable suffixes 'M' for MiB and 'G' for GiB. Use an extended syntax to define the suggested size for the disk images generated by a multi-volume gadget.yaml spec. See the ubuntu-image(1) manpage for details.""")) common_group.add_argument( '--image-file-list', default=None, metavar='FILENAME', help=_("""Print to this file, a list of the file system paths to all the disk images created by the command, if any.""")) common_group.add_argument( '--cloud-init', default=None, metavar='USER-DATA-FILE', help=_('cloud-config data to be copied to the image')) common_group.add_argument( '--hooks-directory', default=[], metavar='DIRECTORY', help=_("""Path or comma-separated list of paths of directories in which scripts for build-time hooks will be located.""")) output_group = common_group.add_mutually_exclusive_group() output_group.add_argument( '-O', '--output-dir', default=None, metavar='DIRECTORY', help=_("""The directory in which to put generated disk image files. The disk image files themselves will be named <volume>.img inside this directory, where <volume> is the volume name taken from the gadget.yaml file. Use this option instead of the deprecated -o/--output option.""")) output_group.add_argument( '-o', '--output', default=None, metavar='FILENAME', help=_("""DEPRECATED (use -O/--output-dir instead). The generated disk image file. If not given, the image will be put in a file called disk.img in the working directory (in which case, you probably want to specify -w).""")) # State machine options. inclusive_state_group = subcommand.add_argument_group( _('State machine options'), _("""Options for controlling the internal state machine. Other than -w, these options are mutually exclusive. When -u or -t is given, the state machine can be resumed later with -r, but -w must be given in that case since the state is saved in a .ubuntu-image.pck file in the working directory.""")) inclusive_state_group.add_argument( '-w', '--workdir', default=None, metavar='DIRECTORY', help=_("""The working directory in which to download and unpack all the source files for the image. This directory can exist or not, and it is not removed after this program exits. If not given, a temporary working directory is used instead, which *is* deleted after this program exits. Use -w if you want to be able to resume a partial state machine run.""")) state_group = inclusive_state_group.add_mutually_exclusive_group() state_group.add_argument( '-u', '--until', default=None, metavar='STEP', help=_("""Run the state machine until the given STEP, non-inclusively. STEP can be a name or number.""")) state_group.add_argument( '-t', '--thru', default=None, metavar='STEP', help=_("""Run the state machine through the given STEP, inclusively. STEP can be a name or number.""")) state_group.add_argument( '-r', '--resume', default=False, action='store_true', help=_("""Continue the state machine from the previously saved state. It is an error if there is no previous state.""")) return subcommand
def register_arguments(cls, parser): parser.add_argument( '--debug', help=_("Enable debugging output"), action='store_true', default=False)
def invoked(self, ctx): with suppress(FileNotFoundError): auth.Credentials().forget() print(_('You have been logged out'))
def register_arguments(cls, parser): parser.add_argument( 'email', metavar=_('EMAIL-ADDRESS'), help=_('Email address on Ubuntu SSO'), nargs='?')