Ejemplo n.º 1
0
def apt_command(args):
    """ Main entry point for curtin apt-config standalone command
        This does not read the global config as handled by curthooks, but
        instead one can specify a different "target" and a new cfg via --config
        """
    cfg = config.load_command_config(args, {})

    if args.target is not None:
        target = args.target
    else:
        state = util.load_command_environment()
        target = state['target']

    if target is None:
        sys.stderr.write("Unable to find target.  "
                         "Use --target or set TARGET_MOUNT_POINT\n")
        sys.exit(2)

    apt_cfg = cfg.get("apt")
    # if no apt config section is available, do nothing
    if apt_cfg is not None:
        LOG.debug("Handling apt to target %s with config %s", target, apt_cfg)
        try:
            with util.ChrootableTarget(target, sys_resolvconf=True):
                handle_apt(apt_cfg, target)
        except (RuntimeError, TypeError, ValueError, IOError):
            LOG.exception("Failed to configure apt features '%s'", apt_cfg)
            sys.exit(1)
    else:
        LOG.info("No apt config provided, skipping")

    sys.exit(0)
Ejemplo n.º 2
0
def interfaces_custom(args):
    state = util.load_command_environment()
    cfg = config.load_command_config(args, state)

    network_config = cfg.get('network', [])
    if not network_config:
        raise Exception("network configuration is required by mode '%s' "
                        "but not provided in the config file" % 'custom')

    return {'network': network_config}
Ejemplo n.º 3
0
def install_grub_main(args):
    state = util.load_command_environment()

    if args.target is not None:
        target = args.target
    else:
        target = state['target']

    if target is None:
        sys.stderr.write("Unable to find target.  "
                         "Use --target or set TARGET_MOUNT_POINT\n")
        sys.exit(2)

    cfg = config.load_command_config(args, state)
    stack_prefix = state.get('report_stack_prefix', '')
    uefi = util.is_uefi_bootable()
    grubcfg = cfg.get('grub')
    with events.ReportEventStack(
            name=stack_prefix,
            reporting_enabled=True,
            level="INFO",
            description="Installing grub to target devices"):
        install_grub(args.devices, target, uefi=uefi, grubcfg=grubcfg)
    sys.exit(0)
Ejemplo n.º 4
0
def net_meta(args):
    #    curtin net-meta --devices connected dhcp
    #    curtin net-meta --devices configured dhcp
    #    curtin net-meta --devices netboot dhcp
    #    curtin net-meta --devices connected custom

    # if network-config hook exists in target,
    # we do not run the builtin
    if util.run_hook_if_exists(args.target, 'network-config'):
        sys.exit(0)

    state = util.load_command_environment()
    cfg = config.load_command_config(args, state)
    if cfg.get("network") is not None:
        args.mode = "custom"

    eni = "etc/network/interfaces"
    if args.mode == "auto":
        if not args.devices:
            args.devices = ["connected"]

        t_eni = None
        if args.target:
            t_eni = os.path.sep.join((
                args.target,
                eni,
            ))
            if not os.path.isfile(t_eni):
                t_eni = None

        if t_eni:
            args.mode = "copy"
        else:
            args.mode = "dhcp"

    devices = []
    if args.devices:
        for dev in args.devices:
            if dev in DEVNAME_ALIASES:
                devices += resolve_alias(dev)
            else:
                devices.append(dev)

    LOG.debug("net-meta mode is '%s'.  devices=%s", args.mode, devices)

    output_network_config = os.environ.get("OUTPUT_NETWORK_CONFIG", "")
    if args.mode == "copy":
        if not args.target:
            raise argparse.ArgumentTypeError("mode 'copy' requires --target")

        t_eni = os.path.sep.join((
            args.target,
            "etc/network/interfaces",
        ))
        with open(t_eni, "r") as fp:
            content = fp.read()
        LOG.warn(
            "net-meta mode is 'copy', static network interfaces files"
            "can be brittle.  Copied interfaces: %s", content)
        target = args.output

    elif args.mode == "dhcp":
        target = output_network_config
        content = config.dump_config(interfaces_basic_dhcp(devices))

    elif args.mode == 'custom':
        target = output_network_config
        content = config.dump_config(interfaces_custom(args))

    else:
        raise Exception("Unexpected network config mode '%s'." % args.mode)

    if not target:
        raise Exception(
            "No target given for mode = '%s'.  No where to write content: %s" %
            (args.mode, content))

    LOG.debug("writing to file %s with network config: %s", target, content)
    if target == "-":
        sys.stdout.write(content)
    else:
        with open(target, "w") as fp:
            fp.write(content)

    sys.exit(0)
Ejemplo n.º 5
0
def curthooks(args):
    state = util.load_command_environment()

    if args.target is not None:
        target = args.target
    else:
        target = state['target']

    if target is None:
        sys.stderr.write("Unable to find target.  "
                         "Use --target or set TARGET_MOUNT_POINT\n")
        sys.exit(2)

    cfg = config.load_command_config(args, state)
    stack_prefix = state.get('report_stack_prefix', '')

    # if curtin-hooks hook exists in target we can defer to the in-target hooks
    if util.run_hook_if_exists(target, 'curtin-hooks'):
        # For vmtests to force execute centos_apply_network_config, uncomment
        # the value in examples/tests/centos_defaults.yaml
        if cfg.get('_ammend_centos_curthooks'):
            if cfg.get('cloudconfig'):
                handle_cloudconfig(cfg['cloudconfig'],
                                   base_dir=util.target_path(
                                       target, 'etc/cloud/cloud.cfg.d'))

            if target_is_centos(target) or target_is_rhel(target):
                LOG.info('Detected RHEL/CentOS image, running extra hooks')
                with events.ReportEventStack(
                        name=stack_prefix,
                        reporting_enabled=True,
                        level="INFO",
                        description="Configuring CentOS for first boot"):
                    centos_apply_network_config(cfg.get('network', {}), target)
        sys.exit(0)

    if target_is_ubuntu_core(target):
        LOG.info('Detected Ubuntu-Core image, running hooks')
        with events.ReportEventStack(
                name=stack_prefix,
                reporting_enabled=True,
                level="INFO",
                description="Configuring Ubuntu-Core for first boot"):
            ubuntu_core_curthooks(cfg, target)
        sys.exit(0)

    with events.ReportEventStack(
            name=stack_prefix + '/writing-config',
            reporting_enabled=True,
            level="INFO",
            description="configuring apt configuring apt"):
        do_apt_config(cfg, target)
        disable_overlayroot(cfg, target)

    # LP: #1742560 prevent zfs-dkms from being installed (Xenial)
    if util.lsb_release(target=target)['codename'] == 'xenial':
        util.apt_update(target=target)
        with util.ChrootableTarget(target) as in_chroot:
            in_chroot.subp(['apt-mark', 'hold', 'zfs-dkms'])

    # packages may be needed prior to installing kernel
    with events.ReportEventStack(name=stack_prefix +
                                 '/installing-missing-packages',
                                 reporting_enabled=True,
                                 level="INFO",
                                 description="installing missing packages"):
        install_missing_packages(cfg, target)

    # If a /etc/iscsi/nodes/... file was created by block_meta then it
    # needs to be copied onto the target system
    nodes_location = os.path.join(os.path.split(state['fstab'])[0], "nodes")
    if os.path.exists(nodes_location):
        copy_iscsi_conf(nodes_location, target)
        # do we need to reconfigure open-iscsi?

    # If a mdadm.conf file was created by block_meta than it needs to be copied
    # onto the target system
    mdadm_location = os.path.join(
        os.path.split(state['fstab'])[0], "mdadm.conf")
    if os.path.exists(mdadm_location):
        copy_mdadm_conf(mdadm_location, target)
        # as per https://bugs.launchpad.net/ubuntu/+source/mdadm/+bug/964052
        # reconfigure mdadm
        util.subp(['dpkg-reconfigure', '--frontend=noninteractive', 'mdadm'],
                  data=None,
                  target=target)

    with events.ReportEventStack(name=stack_prefix + '/installing-kernel',
                                 reporting_enabled=True,
                                 level="INFO",
                                 description="installing kernel"):
        setup_zipl(cfg, target)
        install_kernel(cfg, target)
        run_zipl(cfg, target)
        restore_dist_interfaces(cfg, target)

    with events.ReportEventStack(name=stack_prefix + '/setting-up-swap',
                                 reporting_enabled=True,
                                 level="INFO",
                                 description="setting up swap"):
        add_swap(cfg, target, state.get('fstab'))

    with events.ReportEventStack(name=stack_prefix +
                                 '/apply-networking-config',
                                 reporting_enabled=True,
                                 level="INFO",
                                 description="apply networking config"):
        apply_networking(target, state)

    with events.ReportEventStack(name=stack_prefix + '/writing-etc-fstab',
                                 reporting_enabled=True,
                                 level="INFO",
                                 description="writing etc/fstab"):
        copy_fstab(state.get('fstab'), target)

    with events.ReportEventStack(name=stack_prefix + '/configuring-multipath',
                                 reporting_enabled=True,
                                 level="INFO",
                                 description="configuring multipath"):
        detect_and_handle_multipath(cfg, target)

    with events.ReportEventStack(
            name=stack_prefix + '/system-upgrade',
            reporting_enabled=True,
            level="INFO",
            description="updating packages on target system"):
        system_upgrade(cfg, target)

    with events.ReportEventStack(
            name=stack_prefix + '/pollinate-user-agent',
            reporting_enabled=True,
            level="INFO",
            description="configuring pollinate user-agent on target system"):
        handle_pollinate_user_agent(cfg, target)

    # If a crypttab file was created by block_meta than it needs to be copied
    # onto the target system, and update_initramfs() needs to be run, so that
    # the cryptsetup hooks are properly configured on the installed system and
    # it will be able to open encrypted volumes at boot.
    crypttab_location = os.path.join(
        os.path.split(state['fstab'])[0], "crypttab")
    if os.path.exists(crypttab_location):
        copy_crypttab(crypttab_location, target)
        update_initramfs(target)

    # If udev dname rules were created, copy them to target
    udev_rules_d = os.path.join(state['scratch'], "rules.d")
    if os.path.isdir(udev_rules_d):
        copy_dname_rules(udev_rules_d, target)

    # As a rule, ARMv7 systems don't use grub. This may change some
    # day, but for now, assume no. They do require the initramfs
    # to be updated, and this also triggers boot loader setup via
    # flash-kernel.
    machine = platform.machine()
    if (machine.startswith('armv7') or machine.startswith('s390x')
            or machine.startswith('aarch64') and not util.is_uefi_bootable()):
        update_initramfs(target)
    else:
        setup_grub(cfg, target)

    sys.exit(0)