Romanos Skiadas has proposed merging ~rski/cloud-init:puppet_4 into cloud-init:master.
Requested reviews: cloud init development team (cloud-init-dev) Related bugs: Bug #1446804 in cloud-init: "Puppet fails with puppet 4" https://bugs.launchpad.net/cloud-init/+bug/1446804 For more details, see: https://code.launchpad.net/~rski/cloud-init/+git/cloud-init/+merge/312284 -- Your team cloud init development team is requested to review the proposed merge of ~rski/cloud-init:puppet_4 into cloud-init:master.
diff --git a/cloudinit/config/cc_puppet.py b/cloudinit/config/cc_puppet.py index bfd630d..d5351f6 100644 --- a/cloudinit/config/cc_puppet.py +++ b/cloudinit/config/cc_puppet.py @@ -33,6 +33,13 @@ under ``version``, and defaults to ``none``, which selects the latest version in the repos. If the ``puppet`` config key exists in the config archive, this module will attempt to start puppet even if no installation was performed. +The module also provides keys for configuring the new puppet 4 paths and +installing the puppet package from the puppetlabs repositories: +https://docs.puppet.com/puppet/4.2/reference/whered_it_go.html +The keys are ``package_name``, ``conf_dir`` and ``ssl_dir``. If unset, their +values will default to ones that work with puppet 3.x and with distributions +that ship modified puppet 4.x that uses the old paths. + Puppet configuration can be specified under the ``conf`` key. The configuration is specified as a dictionary which is converted into ``<key>=<value>`` format and appended to ``puppet.conf`` under the ``[puppetd]`` section. The @@ -54,6 +61,9 @@ yaml notation). puppet: install: <true/false> version: <version> + conf_dir: '/etc/puppet/' + ssl_dir: '/var/lib/puppet/ssl' + package_name: 'puppet' conf: server: "puppetmaster.example.org" certname: "%i.%f" @@ -71,10 +81,23 @@ import socket from cloudinit import helpers from cloudinit import util -PUPPET_CONF_PATH = '/etc/puppet/puppet.conf' -PUPPET_SSL_CERT_DIR = '/var/lib/puppet/ssl/certs/' -PUPPET_SSL_DIR = '/var/lib/puppet/ssl' -PUPPET_SSL_CERT_PATH = '/var/lib/puppet/ssl/certs/ca.pem' +DEFAULT_PACKAGE_NAME = 'puppet' +DEFAULT_SSL_DIR = '/var/lib/puppet/ssl' +DEFAULT_CONF_DIR = '/etc/puppet' + + +class PuppetConstants(object): + + def __init__(self, + puppet_conf_dir, + puppet_ssl_dir, + log): + self.conf_dir = puppet_conf_dir + self.conf_path = os.path.join(puppet_conf_dir, "puppet.conf") + self.ssl_dir = puppet_ssl_dir + self.ssl_cert_dir = os.path.join(puppet_ssl_dir, "certs") + self.ssl_cert_path = os.path.join(self.ssl_cert_dir, + "ca.pem") def _autostart_puppet(log): @@ -101,22 +124,35 @@ def handle(name, cfg, cloud, log, _args): return puppet_cfg = cfg['puppet'] - # Start by installing the puppet package if necessary... install = util.get_cfg_option_bool(puppet_cfg, 'install', True) version = util.get_cfg_option_str(puppet_cfg, 'version', None) + package_name = util.get_cfg_option_str(puppet_cfg, + 'package_name', + DEFAULT_PACKAGE_NAME) + conf_dir = util.get_cfg_option_str(puppet_cfg, + 'conf_dir', + DEFAULT_CONF_DIR) + ssl_dir = util.get_cfg_option_str(puppet_cfg, + 'ssl_dir', + DEFAULT_SSL_DIR) + + p_constants = PuppetConstants(conf_dir, + ssl_dir, + log) if not install and version: log.warn(("Puppet install set false but version supplied," " doing nothing.")) elif install: log.debug(("Attempting to install puppet %s,"), version if version else 'latest') - cloud.distro.install_packages(('puppet', version)) + + cloud.distro.install_packages((package_name, version)) # ... and then update the puppet configuration if 'conf' in puppet_cfg: # Add all sections from the conf object to puppet.conf - contents = util.load_file(PUPPET_CONF_PATH) + contents = util.load_file(p_constants.conf_path) # Create object for reading puppet.conf values puppet_config = helpers.DefaultingConfigParser() # Read puppet.conf values from original file in order to be able to @@ -125,21 +161,21 @@ def handle(name, cfg, cloud, log, _args): cleaned_lines = [i.lstrip() for i in contents.splitlines()] cleaned_contents = '\n'.join(cleaned_lines) puppet_config.readfp(StringIO(cleaned_contents), - filename=PUPPET_CONF_PATH) + filename=p_constants.conf_path) for (cfg_name, cfg) in puppet_cfg['conf'].items(): # Cert configuration is a special case # Dump the puppet master ca certificate in the correct place if cfg_name == 'ca_cert': # Puppet ssl sub-directory isn't created yet # Create it with the proper permissions and ownership - util.ensure_dir(PUPPET_SSL_DIR, 0o771) - util.chownbyname(PUPPET_SSL_DIR, 'puppet', 'root') - util.ensure_dir(PUPPET_SSL_CERT_DIR) - util.chownbyname(PUPPET_SSL_CERT_DIR, 'puppet', 'root') - util.write_file(PUPPET_SSL_CERT_PATH, cfg) - util.chownbyname(PUPPET_SSL_CERT_PATH, 'puppet', 'root') + util.ensure_dir(p_constants.ssl_dir, 0o771) + util.chownbyname(p_constants.ssl_dir, 'puppet', 'root') + util.ensure_dir(p_constants.ssl_cert_dir) + util.chownbyname(p_constants.ssl_cert_dir, 'puppet', 'root') + util.write_file(p_constants.ssl_cert_path, cfg) + util.chownbyname(p_constants.ssl_cert_path, 'puppet', 'root') else: - # Iterate throug the config items, we'll use ConfigParser.set + # Iterate through the config items, we'll use ConfigParser.set # to overwrite or create new items as needed for (o, v) in cfg.items(): if o == 'certname': @@ -153,8 +189,9 @@ def handle(name, cfg, cloud, log, _args): puppet_config.set(cfg_name, o, v) # We got all our config as wanted we'll rename # the previous puppet.conf and create our new one - util.rename(PUPPET_CONF_PATH, "%s.old" % (PUPPET_CONF_PATH)) - util.write_file(PUPPET_CONF_PATH, puppet_config.stringify()) + util.rename(p_constants.conf_path, "%s.old" + % (p_constants.conf_path)) + util.write_file(p_constants.conf_path, puppet_config.stringify()) # Set it up so it autostarts _autostart_puppet(log) diff --git a/cloudinit/util.py b/cloudinit/util.py index cc08471..2b244be 100644 --- a/cloudinit/util.py +++ b/cloudinit/util.py @@ -1742,7 +1742,7 @@ def chmod(path, mode): def write_file(filename, content, mode=0o644, omode="wb"): """ Writes a file with the given content and sets the file mode as specified. - Resotres the SELinux context if possible. + Restores the SELinux context if possible. @param filename: The full path of the file to write. @param content: The content to write to the file.
_______________________________________________ Mailing list: https://launchpad.net/~cloud-init-dev Post to : cloud-init-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~cloud-init-dev More help : https://help.launchpad.net/ListHelp