예제 #1
0
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
예제 #2
0
 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)
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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
예제 #10
0
 def register_arguments(cls, parser):
     parser.add_argument(
         '--debug',
         help=_("Enable debugging output"),
         action='store_true',
         default=False)
예제 #11
0
 def invoked(self, ctx):
     with suppress(FileNotFoundError):
         auth.Credentials().forget()
         print(_('You have been logged out'))
예제 #12
0
 def register_arguments(cls, parser):
     parser.add_argument(
         'email', metavar=_('EMAIL-ADDRESS'),
         help=_('Email address on Ubuntu SSO'), nargs='?')