Joshua Harlow 5f586faf98 Updated so that the locale that is being written out currently in 'cc_locale'
now will be done by the distro classes (since its not the same for rhel and ubuntu).

Remove the template also since it will just be created by the ubuntu distro class (its just one line).
2012-06-21 19:46:16 -07:00

160 lines
5.3 KiB
Python

# vi: ts=4 expandtab
#
# Copyright (C) 2012 Canonical Ltd.
# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
# Copyright (C) 2012 Yahoo! Inc.
#
# Author: Scott Moser <scott.moser@canonical.com>
# Author: Juerg Haefliger <juerg.haefliger@hp.com>
# Author: Joshua Harlow <harlowja@yahoo-inc.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from StringIO import StringIO
import abc
from cloudinit import importer
from cloudinit import log as logging
from cloudinit import util
# TODO: Make this via config??
IFACE_ACTIONS = {
'up': ['ifup', '--all'],
'down': ['ifdown', '--all'],
}
LOG = logging.getLogger(__name__)
class Distro(object):
__metaclass__ = abc.ABCMeta
def __init__(self, name, cfg, paths):
self._paths = paths
self._cfg = cfg
self.name = name
@abc.abstractmethod
def install_packages(self, pkglist):
raise NotImplementedError()
@abc.abstractmethod
def _write_network(self, settings):
# In the future use the http://fedorahosted.org/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 apply_network(self, settings, bring_up=True):
# Write it out
self._write_network(settings)
# Now try to bring them up
if bring_up:
return self._interface_action('up')
return False
@abc.abstractmethod
def apply_locale(self, locale, out_fn=None):
raise NotImplementedError()
@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
hosts_ro_fn = self._paths.join(True, "/etc/hosts")
for line in util.load_file(hosts_ro_fn).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(self._paths.join(False, "/etc/hosts"),
contents, mode=0644)
def _interface_action(self, action):
if action not in IFACE_ACTIONS:
raise NotImplementedError("Unknown interface action %s" % (action))
cmd = IFACE_ACTIONS[action]
try:
LOG.debug("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", cmd, err)
return True
except util.ProcessExecutionError:
util.logexc(LOG, "Running interface command %s failed", cmd)
return False
def fetch(name):
locs = importer.find_module(name,
['', __name__],
['Distro'])
if not locs:
raise ImportError("No distribution found for distro %s"
% (name))
mod = importer.import_module(locs[0])
cls = getattr(mod, 'Distro')
return cls