Exemple #1
0
    def test_netconfig_passthrough_available_no_cloudinit(
            self, mock_which, mock_subp, mock_log):
        mock_which.return_value = None

        available = net.netconfig_passthrough_available(self.target)

        self.assertEqual(False, available,
                         "netconfig passthrough was available")
        self.assertTrue(mock_log.warning.called)
        self.assertFalse(mock_subp.called)
Exemple #2
0
    def test_netconfig_passthrough_available(self, mock_which, mock_subp):
        cloud_init = '/usr/bin/cloud-init'
        mock_which.return_value = cloud_init
        mock_subp.return_value = ("NETWORK_CONFIG_V1\nNETWORK_CONFIG_V2\n", '')

        available = net.netconfig_passthrough_available(self.target)

        self.assertEqual(True, available,
                         "netconfig passthrough was NOT available")
        mock_which.assert_called_with('cloud-init', target=self.target)
        mock_subp.assert_called_with([cloud_init, 'features'],
                                     capture=True,
                                     target=self.target)
Exemple #3
0
    def test_netconfig_passthrough_available_exc(self, mock_which, mock_subp,
                                                 mock_log):
        cloud_init = '/usr/bin/cloud-init'
        mock_which.return_value = cloud_init
        mock_subp.side_effect = util.ProcessExecutionError

        available = net.netconfig_passthrough_available(self.target)

        self.assertEqual(False, available,
                         "netconfig passthrough was available")
        mock_which.assert_called_with('cloud-init', target=self.target)
        mock_subp.assert_called_with([cloud_init, 'features'],
                                     capture=True,
                                     target=self.target)
        self.assertTrue(mock_log.warning.called)
Exemple #4
0
def apply_net(target, network_state=None, network_config=None):
    if network_state is None and network_config is None:
        raise ValueError("Must provide network_config or network_state")

    if target is None:
        raise ValueError("target cannot be None.")

    passthrough = False
    if network_state:
        # NB: we cannot support passthrough until curtin can convert from
        # network_state to network-config yaml
        ns = net.network_state.from_state_file(network_state)
        raise ValueError('Not Supported; curtin lacks a network_state to '
                         'network_config converter.')
    elif network_config:
        netcfg = config.load_config(network_config)

        # curtin will pass-through the netconfig into the target
        # for rendering at runtime unless the target OS does not
        # support NETWORK_CONFIG_V2 feature.
        LOG.info(
            'Checking cloud-init in target [%s] for network '
            'configuration passthrough support.', target)
        try:
            passthrough = net.netconfig_passthrough_available(target)
        except util.ProcessExecutionError:
            LOG.warning('Failed to determine if passthrough is available')

        if passthrough:
            LOG.info('Passing network configuration through to target: %s',
                     target)
            net.render_netconfig_passthrough(target, netconfig=netcfg)
        else:
            ns = net.parse_net_config_data(netcfg.get('network', {}))

            if ns is None:
                return

    if not passthrough:
        LOG.info('Rendering network configuration in target')
        net.render_network_state(target=target, network_state=ns)

    _maybe_remove_legacy_eth0(target)
    _disable_ipv6_privacy_extensions(target)
    _patch_ifupdown_ipv6_mtu_hook(target)
Exemple #5
0
def centos_apply_network_config(netcfg, target=None):
    """ CentOS images execute built-in curthooks which only supports
        simple networking configuration.  This hook enables advanced
        network configuration via config passthrough to the target.
    """
    def cloud_init_repo(version):
        if not version:
            raise ValueError('Missing required version parameter')

        return CLOUD_INIT_YUM_REPO_TEMPLATE % version

    if netcfg:
        LOG.info('Removing embedded network configuration (if present)')
        ifcfgs = glob.glob(
            util.target_path(target, 'etc/sysconfig/network-scripts') +
            '/ifcfg-*')
        # remove ifcfg-* (except ifcfg-lo)
        for ifcfg in ifcfgs:
            if os.path.basename(ifcfg) != "ifcfg-lo":
                util.del_file(ifcfg)

        LOG.info(
            'Checking cloud-init in target [%s] for network '
            'configuration passthrough support.', target)
        passthrough = net.netconfig_passthrough_available(target)
        LOG.debug('passthrough available via in-target: %s', passthrough)

        # if in-target cloud-init is not updated, upgrade via cloud-init repo
        if not passthrough:
            cloud_init_yum_repo = (util.target_path(
                target, 'etc/yum.repos.d/curtin-cloud-init.repo'))
            # Inject cloud-init daily yum repo
            util.write_file(cloud_init_yum_repo,
                            content=cloud_init_repo(rpm_get_dist_id(target)))

            # we separate the installation of repository packages (epel,
            # cloud-init-el-release) as we need a new invocation of yum
            # to read the newly installed repo files.
            YUM_CMD = ['yum', '-y', '--noplugins', 'install']
            retries = [1] * 30
            with util.ChrootableTarget(target) as in_chroot:
                # ensure up-to-date ca-certificates to handle https mirror
                # connections
                in_chroot.subp(YUM_CMD + ['ca-certificates'],
                               capture=True,
                               log_captured=True,
                               retries=retries)
                in_chroot.subp(YUM_CMD + ['epel-release'],
                               capture=True,
                               log_captured=True,
                               retries=retries)
                in_chroot.subp(YUM_CMD + ['cloud-init-el-release'],
                               log_captured=True,
                               capture=True,
                               retries=retries)
                in_chroot.subp(YUM_CMD + ['cloud-init'],
                               capture=True,
                               log_captured=True,
                               retries=retries)

            # remove cloud-init el-stable bootstrap repo config as the
            # cloud-init-el-release package points to the correct repo
            util.del_file(cloud_init_yum_repo)

            # install bridge-utils if needed
            with util.ChrootableTarget(target) as in_chroot:
                try:
                    in_chroot.subp(['rpm', '-q', 'bridge-utils'],
                                   capture=False,
                                   rcs=[0])
                except util.ProcessExecutionError:
                    LOG.debug('Image missing bridge-utils package, installing')
                    in_chroot.subp(YUM_CMD + ['bridge-utils'],
                                   capture=True,
                                   log_captured=True,
                                   retries=retries)

    LOG.info('Passing network configuration through to target')
    net.render_netconfig_passthrough(target, netconfig={'network': netcfg})