Ejemplo n.º 1
0
def _clean_default(target=None):
    # clean out any known default files and derived files in target
    # LP: #1675576
    tpath = subp.target_path(target, "etc/netplan/00-snapd-config.yaml")
    if not os.path.isfile(tpath):
        return
    content = util.load_file(tpath, decode=False)
    if content != KNOWN_SNAPD_CONFIG:
        return

    derived = [
        subp.target_path(target, f) for f in (
            "run/systemd/network/10-netplan-all-en.network",
            "run/systemd/network/10-netplan-all-eth.network",
            "run/systemd/generator/netplan.stamp",
        )
    ]
    existing = [f for f in derived if os.path.isfile(f)]
    LOG.debug(
        "removing known config '%s' and derived existing files: %s",
        tpath,
        existing,
    )

    for f in [tpath] + existing:
        os.unlink(f)
Ejemplo n.º 2
0
 def test_bunch_of_slashes_in_path(self):
     self.assertEqual(
         "/target/my/path/", subp.target_path("/target/", "//my/path/")
     )
     self.assertEqual(
         "/target/my/path/", subp.target_path("/target/", "///my/path/")
     )
Ejemplo n.º 3
0
    def render_network_state(self, network_state, templates=None, target=None):
        fpeni = subp.target_path(target, self.eni_path)
        util.ensure_dir(os.path.dirname(fpeni))
        header = self.eni_header if self.eni_header else ""
        util.write_file(fpeni, header + self._render_interfaces(network_state))

        if self.netrules_path:
            netrules = subp.target_path(target, self.netrules_path)
            util.ensure_dir(os.path.dirname(netrules))
            util.write_file(netrules,
                            self._render_persistent_net(network_state))
Ejemplo n.º 4
0
 def available(target=None) -> bool:
     """Return true if network manager can be used on this system."""
     config_present = os.path.isfile(
         subp.target_path(target, path=NM_CFG_FILE)
     )
     nmcli_present = subp.which("nmcli", target=target)
     return config_present and bool(nmcli_present)
Ejemplo n.º 5
0
def clean_cloud_init(target):
    """clean out any local cloud-init config"""
    flist = glob.glob(
        subp.target_path(target, "/etc/cloud/cloud.cfg.d/*dpkg*"))

    LOG.debug("cleaning cloud-init config from: %s", flist)
    for dpkg_cfg in flist:
        os.unlink(dpkg_cfg)
Ejemplo n.º 6
0
    def _resolve_conf(self, settings):
        nameservers = settings.dns_nameservers
        searchdomains = settings.dns_searchdomains
        for interface in settings.iter_interfaces():
            for subnet in interface.get("subnets", []):
                if "dns_nameservers" in subnet:
                    nameservers.extend(subnet["dns_nameservers"])
                if "dns_search" in subnet:
                    searchdomains.extend(subnet["dns_search"])
        # Try to read the /etc/resolv.conf or just start from scratch if that
        # fails.
        try:
            resolvconf = ResolvConf(
                util.load_file(
                    subp.target_path(self.target, self.resolv_conf_fn)
                )
            )
            resolvconf.parse()
        except IOError:
            util.logexc(
                LOG,
                "Failed to parse %s, use new empty file",
                subp.target_path(self.target, self.resolv_conf_fn),
            )
            resolvconf = ResolvConf("")
            resolvconf.parse()

        # Add some nameservers
        for server in set(nameservers):
            try:
                resolvconf.add_nameserver(server)
            except ValueError:
                util.logexc(LOG, "Failed to add nameserver %s", server)

        # And add any searchdomains.
        for domain in set(searchdomains):
            try:
                resolvconf.add_search_domain(domain)
            except ValueError:
                util.logexc(LOG, "Failed to add search domain %s", domain)
        util.write_file(
            subp.target_path(self.target, self.resolv_conf_fn),
            str(resolvconf),
            0o644,
        )
Ejemplo n.º 7
0
    def render_network_state(
        self, network_state: NetworkState, templates=None, target=None
    ):
        if not templates:
            templates = self.templates
        file_mode = 0o644
        base_sysconf_dir = subp.target_path(target, self.sysconf_dir)
        for path, data in self._render_sysconfig(
            base_sysconf_dir, network_state, self.flavor, templates=templates
        ).items():
            util.write_file(path, data, file_mode)
        if self.dns_path:
            dns_path = subp.target_path(target, self.dns_path)
            resolv_content = self._render_dns(
                network_state, existing_dns_path=dns_path
            )
            if resolv_content:
                util.write_file(dns_path, resolv_content, file_mode)
        if self.networkmanager_conf_path:
            nm_conf_path = subp.target_path(
                target, self.networkmanager_conf_path
            )
            nm_conf_content = self._render_networkmanager_conf(
                network_state, templates
            )
            if nm_conf_content:
                util.write_file(nm_conf_path, nm_conf_content, file_mode)
        if self.netrules_path:
            netrules_content = self._render_persistent_net(network_state)
            netrules_path = subp.target_path(target, self.netrules_path)
            util.write_file(netrules_path, netrules_content, file_mode)

        sysconfig_path = subp.target_path(target, templates.get("control"))
        # Distros configuring /etc/sysconfig/network as a file e.g. Centos
        if sysconfig_path.endswith("network"):
            util.ensure_dir(os.path.dirname(sysconfig_path))
            netcfg = [_make_header(), "NETWORKING=yes"]
            if network_state.use_ipv6:
                netcfg.append("NETWORKING_IPV6=yes")
                netcfg.append("IPV6_AUTOCONF=no")
            util.write_file(
                sysconfig_path, "\n".join(netcfg) + "\n", file_mode
            )
Ejemplo n.º 8
0
    def render_network_state(self, network_state, templates=None, target=None):
        network_dir = self.network_conf_dir
        if target:
            network_dir = subp.target_path(target) + network_dir

        util.ensure_dir(network_dir)

        ret_dict = self._render_content(network_state)
        for k, v in ret_dict.items():
            self.create_network_file(k, v, network_dir)
Ejemplo n.º 9
0
    def render_network_state(self, network_state, templates=None, target=None):
        fp_nwkd = self.network_conf_dir
        if target:
            fp_nwkd = subp.target_path(target) + fp_nwkd

        util.ensure_dir(os.path.dirname(fp_nwkd))

        ret_dict = self._render_content(network_state)
        for k, v in ret_dict.items():
            self.create_network_file(k, v, fp_nwkd)
Ejemplo n.º 10
0
def available(target=None):
    expected = ["ifquery", "ifup", "ifdown"]
    search = ["/sbin", "/usr/sbin"]
    for p in expected:
        if not subp.which(p, search=search, target=target):
            return False
    eni = subp.target_path(target, "etc/network/interfaces")
    if not os.path.isfile(eni):
        return False

    return True
Ejemplo n.º 11
0
def add_apt_sources(srcdict, cloud, target=None, template_params=None,
                    aa_repo_match=None):
    """
    add entries in /etc/apt/sources.list.d for each abbreviated
    sources.list entry in 'srcdict'.  When rendering template, also
    include the values in dictionary searchList
    """
    if template_params is None:
        template_params = {}

    if aa_repo_match is None:
        raise ValueError('did not get a valid repo matcher')

    if not isinstance(srcdict, dict):
        raise TypeError('unknown apt format: %s' % (srcdict))

    for filename in srcdict:
        ent = srcdict[filename]
        LOG.debug("adding source/key '%s'", ent)
        if 'filename' not in ent:
            ent['filename'] = filename

        add_apt_key(ent, target)

        if 'source' not in ent:
            continue
        source = ent['source']
        source = templater.render_string(source, template_params)

        if not ent['filename'].startswith("/"):
            ent['filename'] = os.path.join("/etc/apt/sources.list.d/",
                                           ent['filename'])
        if not ent['filename'].endswith(".list"):
            ent['filename'] += ".list"

        if aa_repo_match(source):
            try:
                subp.subp(["add-apt-repository", source], target=target)
            except subp.ProcessExecutionError:
                LOG.exception("add-apt-repository failed.")
                raise
            continue

        sourcefn = subp.target_path(target, ent['filename'])
        try:
            contents = "%s\n" % (source)
            util.write_file(sourcefn, contents, omode="a")
        except IOError as detail:
            LOG.exception("failed write to file %s: %s", sourcefn, detail)
            raise

    update_packages(cloud)

    return
Ejemplo n.º 12
0
def available(target=None):
    expected = ['ifquery', 'ifup', 'ifdown']
    search = ['/sbin', '/usr/sbin']
    for p in expected:
        if not subp.which(p, search=search, target=target):
            return False
    eni = subp.target_path(target, 'etc/network/interfaces')
    if not os.path.isfile(eni):
        return False

    return True
Ejemplo n.º 13
0
def _render_network(
    entries,
    target="/",
    conf_dir="etc/netctl",
    resolv_conf="etc/resolv.conf",
    enable_func=None,
):
    """Render the translate_network format into netctl files in target.
    Paths will be rendered under target.
    """

    devs = []
    nameservers = []
    resolv_conf = subp.target_path(target, resolv_conf)
    conf_dir = subp.target_path(target, conf_dir)

    for (dev, info) in entries.items():
        if dev == "lo":
            # no configuration should be rendered for 'lo'
            continue
        devs.append(dev)
        net_fn = os.path.join(conf_dir, dev)
        net_cfg = {
            "Connection": "ethernet",
            "Interface": dev,
            "IP": info.get("bootproto"),
            "Address": "%s/%s" % (info.get("address"), info.get("netmask")),
            "Gateway": info.get("gateway"),
            "DNS": info.get("dns-nameservers", []),
        }
        util.write_file(net_fn, convert_netctl(net_cfg))
        if enable_func and info.get("auto"):
            enable_func(dev)
        if "dns-nameservers" in info:
            nameservers.extend(info["dns-nameservers"])

    if nameservers:
        util.write_file(resolv_conf, convert_resolv_conf(nameservers))
    return devs
Ejemplo n.º 14
0
def available_sysconfig(target=None):
    expected = ['ifup', 'ifdown']
    search = ['/sbin', '/usr/sbin']
    for p in expected:
        if not subp.which(p, search=search, target=target):
            return False

    expected_paths = [
        'etc/sysconfig/network-scripts/network-functions',
        'etc/sysconfig/config']
    for p in expected_paths:
        if os.path.isfile(subp.target_path(target, p)):
            return True
    return False
Ejemplo n.º 15
0
 def write_config(self):
     for device_name, v in self.interface_configurations.items():
         if_file = 'etc/hostname.{}'.format(device_name)
         fn = subp.target_path(self.target, if_file)
         if device_name in self.dhcp_interfaces():
             content = 'dhcp\n'
         elif isinstance(v, dict):
             try:
                 content = "inet {address} {netmask}\n".format(
                     address=v['address'], netmask=v['netmask'])
             except KeyError:
                 LOG.error("Invalid static configuration for %s",
                           device_name)
         util.write_file(fn, content)
Ejemplo n.º 16
0
def _render_network(entries,
                    target="/",
                    conf_dir="etc/netctl",
                    resolv_conf="etc/resolv.conf",
                    enable_func=None):
    """Render the translate_network format into netctl files in target.
    Paths will be rendered under target.
    """

    devs = []
    nameservers = []
    resolv_conf = subp.target_path(target, resolv_conf)
    conf_dir = subp.target_path(target, conf_dir)

    for (dev, info) in entries.items():
        if dev == 'lo':
            # no configuration should be rendered for 'lo'
            continue
        devs.append(dev)
        net_fn = os.path.join(conf_dir, dev)
        net_cfg = {
            'Connection': 'ethernet',
            'Interface': dev,
            'IP': info.get('bootproto'),
            'Address': "%s/%s" % (info.get('address'), info.get('netmask')),
            'Gateway': info.get('gateway'),
            'DNS': info.get('dns-nameservers', []),
        }
        util.write_file(net_fn, convert_netctl(net_cfg))
        if enable_func and info.get('auto'):
            enable_func(dev)
        if 'dns-nameservers' in info:
            nameservers.extend(info['dns-nameservers'])

    if nameservers:
        util.write_file(resolv_conf, convert_resolv_conf(nameservers))
    return devs
Ejemplo n.º 17
0
def available(target=None):
    # TODO: Move `uses_systemd` to a more appropriate location
    # It is imported here to avoid circular import
    from cloudinit.distros import uses_systemd

    config_present = os.path.isfile(subp.target_path(target, path=NM_CFG_FILE))
    nmcli_present = subp.which("nmcli", target=target)
    service_active = True
    if uses_systemd():
        try:
            subp.subp(["systemctl", "is-enabled", "NetworkManager.service"])
        except subp.ProcessExecutionError:
            service_active = False

    return config_present and bool(nmcli_present) and service_active
Ejemplo n.º 18
0
def available_sysconfig(target=None):
    expected = ["ifup", "ifdown"]
    search = ["/sbin", "/usr/sbin"]
    for p in expected:
        if not subp.which(p, search=search, target=target):
            return False

    expected_paths = [
        "etc/sysconfig/network-scripts/network-functions",
        "etc/sysconfig/config",
    ]
    for p in expected_paths:
        if os.path.isfile(subp.target_path(target, p)):
            return True
    return False
Ejemplo n.º 19
0
def available(target=None):
    if not util.system_info()["variant"] in KNOWN_DISTROS:
        return False

    expected = ["ifup", "ifdown"]
    search = ["/sbin", "/usr/sbin"]
    for p in expected:
        if not subp.which(p, search=search, target=target):
            return False

    expected_paths = [
        "etc/sysconfig/network-scripts/network-functions",
        "etc/sysconfig/config",
    ]
    for p in expected_paths:
        if os.path.isfile(subp.target_path(target, p)):
            return True
    return False
Ejemplo n.º 20
0
 def write_config(self):
     for device_name, v in self.interface_configurations.items():
         if_file = "etc/hostname.{}".format(device_name)
         fn = subp.target_path(self.target, if_file)
         if device_name in self.dhcp_interfaces():
             content = "dhcp\n"
         elif isinstance(v, dict):
             try:
                 content = "inet {address} {netmask}".format(
                     address=v["address"], netmask=v["netmask"])
             except KeyError:
                 LOG.error("Invalid static configuration for %s",
                           device_name)
             mtu = v.get("mtu")
             if mtu:
                 content += " mtu %d" % mtu
             content += "\n"
         util.write_file(fn, content)
Ejemplo n.º 21
0
    def render_network_state(self, network_state, templates=None, target=None):
        # check network state for version
        # if v2, then extract network_state.config
        # else render_v2_from_state
        fpnplan = os.path.join(subp.target_path(target), self.netplan_path)

        util.ensure_dir(os.path.dirname(fpnplan))
        header = self.netplan_header if self.netplan_header else ""

        # render from state
        content = self._render_content(network_state)

        if not header.endswith("\n"):
            header += "\n"
        util.write_file(fpnplan, header + content)

        if self.clean_default:
            _clean_default(target=target)
        self._netplan_generate(run=self._postcmds)
        self._net_setup_link(run=self._postcmds)
Ejemplo n.º 22
0
def rename_apt_lists(new_mirrors, target, arch):
    """rename_apt_lists - rename apt lists to preserve old cache data"""
    default_mirrors = get_default_mirrors(arch)

    pre = subp.target_path(target, APT_LISTS)
    for (name, omirror) in default_mirrors.items():
        nmirror = new_mirrors.get(name)
        if not nmirror:
            continue

        oprefix = pre + os.path.sep + mirrorurl_to_apt_fileprefix(omirror)
        nprefix = pre + os.path.sep + mirrorurl_to_apt_fileprefix(nmirror)
        if oprefix == nprefix:
            continue
        olen = len(oprefix)
        for filename in glob.glob("%s_*" % oprefix):
            newname = "%s%s" % (nprefix, filename[olen:])
            LOG.debug("Renaming apt list %s to %s", filename, newname)
            try:
                os.rename(filename, newname)
            except OSError:
                # since this is a best effort task, warn with but don't fail
                LOG.warning("Failed to rename apt list:", exc_info=True)
Ejemplo n.º 23
0
def available_nm(target=None):
    if not os.path.isfile(subp.target_path(target, path=NM_CFG_FILE)):
        return False
    return True
Ejemplo n.º 24
0
 def set_rc_config_value(self, key, value):
     fn = subp.target_path(self.target, self.rc_conf_fn)
     bsd_utils.set_rc_config_value(key, value, fn=fn)
Ejemplo n.º 25
0
 def set_route(self, network, netmask, gateway):
     if network == "0.0.0.0":
         if_file = "etc/mygate"
         fn = subp.target_path(self.target, if_file)
         content = gateway + "\n"
         util.write_file(fn, content)
Ejemplo n.º 26
0
 def available(target=None) -> bool:
     config_present = os.path.isfile(
         subp.target_path(target, path=NM_CFG_FILE))
     nmcli_present = subp.which('nmcli', target=target)
     return config_present and bool(nmcli_present)
Ejemplo n.º 27
0
 def set_route(self, network, netmask, gateway):
     if network == '0.0.0.0':
         if_file = 'etc/mygate'
         fn = subp.target_path(self.target, if_file)
         content = gateway + '\n'
         util.write_file(fn, content)
Ejemplo n.º 28
0
def add_apt_sources(srcdict,
                    cloud,
                    target=None,
                    template_params=None,
                    aa_repo_match=None):
    """
    install keys and repo source .list files defined in 'sources'

    for each 'source' entry in the config:
        1. expand template variables and write source .list file in
                /etc/apt/sources.list.d/
        2. install defined keys
        3. update packages via distro-specific method (i.e. apt-key update)


    @param srcdict: a dict containing elements required
    @param cloud: cloud instance object

    Example srcdict value:
    {
    'rio-grande-repo': {
        'source': 'deb [signed-by=$KEY_FILE] $MIRROR $RELEASE main',
        'keyid': 'B59D 5F15 97A5 04B7 E230  6DCA 0620 BBCF 0368 3F77',
        'keyserver': 'pgp.mit.edu'
        }
    }

    Note: Deb822 format is not supported
    """
    if template_params is None:
        template_params = {}

    if aa_repo_match is None:
        raise ValueError("did not get a valid repo matcher")

    if not isinstance(srcdict, dict):
        raise TypeError("unknown apt format: %s" % (srcdict))

    for filename in srcdict:
        ent = srcdict[filename]
        LOG.debug("adding source/key '%s'", ent)
        if "filename" not in ent:
            ent["filename"] = filename

        if "source" in ent and "$KEY_FILE" in ent["source"]:
            key_file = add_apt_key(ent, target, hardened=True)
            template_params["KEY_FILE"] = key_file
        else:
            key_file = add_apt_key(ent, target)

        if "source" not in ent:
            continue
        source = ent["source"]
        source = templater.render_string(source, template_params)

        if not ent["filename"].startswith("/"):
            ent["filename"] = os.path.join("/etc/apt/sources.list.d/",
                                           ent["filename"])
        if not ent["filename"].endswith(".list"):
            ent["filename"] += ".list"

        if aa_repo_match(source):
            try:
                subp.subp(
                    ["add-apt-repository", "--no-update", source],
                    target=target,
                )
            except subp.ProcessExecutionError:
                LOG.exception("add-apt-repository failed.")
                raise
            continue

        sourcefn = subp.target_path(target, ent["filename"])
        try:
            contents = "%s\n" % (source)
            util.write_file(sourcefn, contents, omode="a")
        except IOError as detail:
            LOG.exception("failed write to file %s: %s", sourcefn, detail)
            raise

    update_packages(cloud)

    return
Ejemplo n.º 29
0
def conn_filename(con_id, target=None):
    target_con_dir = subp.target_path(target, NM_RUN_DIR)
    con_file = f"cloud-init-{con_id}.nmconnection"
    return f"{target_con_dir}/system-connections/{con_file}"
Ejemplo n.º 30
0
def available(target=None):
    target_nm_dir = subp.target_path(target, NM_LIB_DIR)
    return os.path.exists(target_nm_dir)