1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
# Copyright (C) 2014 Rackspace, US Inc.
#
# Author: Nate House <nathan.house@rackspace.com>
#
# This file is part of cloud-init. See LICENSE file for license information.
import logging
from cloudinit import distros, helpers, subp, util
from cloudinit.distros import PackageList
from cloudinit.distros.parsers.hostname import HostnameConf
from cloudinit.net.netplan import CLOUDINIT_NETPLAN_FILE
from cloudinit.settings import PER_ALWAYS, PER_INSTANCE
LOG = logging.getLogger(__name__)
class Distro(distros.Distro):
locale_gen_fn = "/etc/locale.gen"
init_cmd = ["systemctl"] # init scripts
renderer_configs = {
"netplan": {
"netplan_path": CLOUDINIT_NETPLAN_FILE,
"netplan_header": "# generated by cloud-init\n",
"postcmds": True,
}
}
def __init__(self, name, cfg, paths):
distros.Distro.__init__(self, name, cfg, paths)
# This will be used to restrict certain
# calls from repeatedly happening (when they
# should only happen say once per instance...)
self._runner = helpers.Runners(paths)
self.osfamily = "arch"
cfg["ssh_svcname"] = "sshd"
def apply_locale(self, locale, out_fn=None):
if out_fn is not None and out_fn != "/etc/locale.conf":
LOG.warning(
"Invalid locale_configfile %s, only supported "
"value is /etc/locale.conf",
out_fn,
)
lines = [
util.make_header(),
# Hard-coding the charset isn't ideal, but there is no other way.
"%s UTF-8" % (locale),
"",
]
util.write_file(self.locale_gen_fn, "\n".join(lines))
subp.subp(["locale-gen"], capture=False)
# In the future systemd can handle locale-gen stuff:
# https://github.com/systemd/systemd/pull/9864
subp.subp(["localectl", "set-locale", locale], capture=False)
def install_packages(self, pkglist: PackageList):
self.update_package_sources()
self.package_command("", pkgs=pkglist)
def _write_hostname(self, hostname, filename):
conf = None
try:
# Try to update the previous one
# so lets see if we can read it first.
conf = self._read_hostname_conf(filename)
except IOError:
create_hostname_file = util.get_cfg_option_bool(
self._cfg, "create_hostname_file", True
)
if create_hostname_file:
pass
else:
LOG.info(
"create_hostname_file is False; hostname file not created"
)
return
if not conf:
conf = HostnameConf("")
conf.set_hostname(hostname)
util.write_file(filename, str(conf), omode="w", mode=0o644)
def _read_system_hostname(self):
sys_hostname = self._read_hostname(self.hostname_conf_fn)
return (self.hostname_conf_fn, sys_hostname)
def _read_hostname_conf(self, filename):
conf = HostnameConf(util.load_text_file(filename))
conf.parse()
return conf
def _read_hostname(self, filename, default=None):
hostname = None
try:
conf = self._read_hostname_conf(filename)
hostname = conf.hostname
except IOError:
pass
if not hostname:
return default
return hostname
# hostname (inetutils) isn't installed per default on arch, so we use
# hostnamectl which is installed per default (systemd).
def _apply_hostname(self, hostname):
LOG.debug(
"Non-persistently setting the system hostname to %s", hostname
)
try:
subp.subp(["hostnamectl", "--transient", "set-hostname", hostname])
except subp.ProcessExecutionError:
util.logexc(
LOG,
"Failed to non-persistently adjust the system hostname to %s",
hostname,
)
def set_timezone(self, tz):
distros.set_etc_timezone(tz=tz, tz_file=self._find_tz_file(tz))
def package_command(self, command, args=None, pkgs=None):
if pkgs is None:
pkgs = []
cmd = ["pacman", "-Sy", "--quiet", "--noconfirm"]
# Redirect output
if args and isinstance(args, str):
cmd.append(args)
elif args and isinstance(args, list):
cmd.extend(args)
if command == "upgrade":
command = "-u"
if command:
cmd.append(command)
pkglist = util.expand_package_list("%s-%s", pkgs)
cmd.extend(pkglist)
# Allow the output of this to flow outwards (ie not be captured)
subp.subp(cmd, capture=False)
def update_package_sources(self, *, force=False):
self._runner.run(
"update-sources",
self.package_command,
["-y"],
freq=PER_ALWAYS if force else PER_INSTANCE,
)
|