diff options
author | Joshua Harlow <harlowja@yahoo-inc.com> | 2012-06-15 17:48:09 -0700 |
---|---|---|
committer | Joshua Harlow <harlowja@yahoo-inc.com> | 2012-06-15 17:48:09 -0700 |
commit | 37c0976f5d94c5abf47a848d92acd76feaf150a7 (patch) | |
tree | 2028fb49dbcd278edc345d7a3239ff6ba91fa7e5 /cloudinit | |
parent | 419b9451684f2c1bc5bef73b26ae8fca1a17383d (diff) | |
download | vyos-cloud-init-37c0976f5d94c5abf47a848d92acd76feaf150a7.tar.gz vyos-cloud-init-37c0976f5d94c5abf47a848d92acd76feaf150a7.zip |
Continued adding distro specific functionality to this new parent distro class as needed.
Diffstat (limited to 'cloudinit')
-rw-r--r-- | cloudinit/distros/__init__.py | 133 |
1 files changed, 123 insertions, 10 deletions
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py index f7f48d1f..90607668 100644 --- a/cloudinit/distros/__init__.py +++ b/cloudinit/distros/__init__.py @@ -20,26 +20,139 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import contextlib +import abc +import copy from cloudinit import importer +from cloudinit import util + +from StringIO import StringIO + +# TODO: Make this via config?? +IFACE_ACTIONS = { + 'up': ['ifup', '--all'], + 'down': ['ifdown', '--all'], +} class Distro(object): - def __init__(self, cloud): - self.cloud = cloud + __metaclass__ = abc.ABCMeta + + def __init__(self, cfg, runner): + self._runner = runner + self._cfg = util.get_cfg_by_path(cfg, ('system_info', ), {}) + self.name = self._cfg.pop("distro", 'generic') + + @abc.abstractmethod def install_packages(self, pkglist): raise NotImplementedError() - def apply_network(self, settings): + @abc.abstractmethod + def _write_network(self, settings): + # In the future use the python-netcf + # to write this blob out in a distro format + raise NotImplementedError() + + def get_option(self, opt_name, default=None): + return self._cfg.get(opt_name, default) + + @abc.abstractmethod + def set_hostname(self, hostname): raise NotImplementedError() + @abc.abstractmethod + def update_hostname(self, hostname, prev_hostname_fn): + raise NotImplementedError() + + @abc.abstractmethod + def package_command(self, cmd, args=None): + raise NotImplementedError() + + def get_package_mirror(self): + return self.get_option('package_mirror') + + def get_paths(self): + paths = self.get_option("paths") or {} + return copy.deepcopy(paths) + + def apply_network(self, settings, bring_up=True): + # Write it out + self._write_network(settings) + # Now try to bring them up + if bring_up: + self._interface_action('up') + + @abc.abstractmethod + def set_timezone(self, tz): + raise NotImplementedError() + + def _get_localhost_ip(self): + return "127.0.0.1" + + def update_etc_hosts(self, hostname, fqdn): + # Format defined at + # http://unixhelp.ed.ac.uk/CGI/man-cgi?hosts + header = "# Added by cloud-init" + real_header = "%s on %s" % (header, util.time_rfc2822()) + local_ip = self._get_localhost_ip() + hosts_line = "%s\t%s %s" % (local_ip, fqdn, hostname) + new_etchosts = StringIO() + need_write = False + need_change = True + for line in util.load_file("/etc/hosts").splitlines(): + if line.strip().startswith(header): + continue + if not line.strip() or line.strip().startswith("#"): + new_etchosts.write("%s\n" % (line)) + continue + split_line = [s.strip() for s in line.split()] + if len(split_line) < 2: + new_etchosts.write("%s\n" % (line)) + continue + (ip, hosts) = split_line[0], split_line[1:] + if ip == local_ip: + if sorted([hostname, fqdn]) == sorted(hosts): + need_change = False + if need_change: + line = "%s\n%s" % (real_header, hosts_line) + need_change = False + need_write = True + new_etchosts.write("%s\n" % (line)) + if need_change: + new_etchosts.write("%s\n%s\n" % (real_header, hosts_line)) + need_write = True + if need_write: + contents = new_etchosts.getvalue() + util.write_file("/etc/hosts", contents) + + def _interface_action(self, action): + if action not in IFACE_ACTIONS: + raise NotImplementedError("Unknown interface action %s" % (action)) + cmd = IFACE_ACTIONS[action] + try: + LOG.info("Attempting to run %s interface action using command %s", + action, cmd) + (_out, err) = util.subp(cmd) + if len(err): + LOG.warn("Running %s resulted in stderr output: %s", + IF_UP_CMD, err) + return True + except util.ProcessExecutionError as exc: + util.logexc(LOG, "Running %s failed", cmd) + return False + -def fetch(cfg, cloud): - sys_info = cfg.get('system_info', {}) - distro = sys_info.get('distro', 'ubuntu') - mod_name = "%s.%s" % (__name__, distro) - mod = importer.import_module(mod_name) +def fetch(distro_name, mods=(__name__, )): + mod = None + for m in mods: + try: + mod_name = "%s.%s" % (m, distro_name) + mod = importer.import_module(mod_name) + except RuntimeError: + pass + if not mod: + raise RuntimeError("No distribution found for distro %s" % (distro_name)) distro_cls = getattr(mod, 'Distro') - return distro_cls(cloud)
\ No newline at end of file + return distro_cls + |