From 1e2e810f3f7cb6a163a0229ac37037e8c6744d72 Mon Sep 17 00:00:00 2001 From: Dominic Schlegel Date: Thu, 8 Mar 2018 12:13:38 +0100 Subject: Make salt minion module work on FreeBSD. Previously the module was not working under FreeBSD due to a different package name and some different paths. The module now has OS specific default values which can even be customized via corresponding cloud config variables. LP: #1721503 --- cloudinit/config/cc_salt_minion.py | 82 ++++++++++++++++------ config/cloud.cfg.tmpl | 2 +- tests/cloud_tests/testcases/modules/salt_minion.py | 5 ++ .../cloud_tests/testcases/modules/salt_minion.yaml | 5 +- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/cloudinit/config/cc_salt_minion.py b/cloudinit/config/cc_salt_minion.py index 5112a347..d6a21d72 100644 --- a/cloudinit/config/cc_salt_minion.py +++ b/cloudinit/config/cc_salt_minion.py @@ -12,7 +12,9 @@ key is present in the config parts, then salt minion will be installed and started. Configuration for salt minion can be specified in the ``conf`` key under ``salt_minion``. Any conf values present there will be assigned in ``/etc/salt/minion``. The public and private keys to use for salt minion can be -specified with ``public_key`` and ``private_key`` respectively. +specified with ``public_key`` and ``private_key`` respectively. Optionally if +you have a custom package name, service name or config directory you can +specify them with ``pkg_name``, ``service_name`` and ``config_dir``. **Internal name:** ``cc_salt_minion`` @@ -23,6 +25,9 @@ specified with ``public_key`` and ``private_key`` respectively. **Config keys**:: salt_minion: + pkg_name: 'salt-minion' + service_name: 'salt-minion' + config_dir: '/etc/salt' conf: master: salt.example.com grains: @@ -42,7 +47,34 @@ import os from cloudinit import util -# Note: see http://saltstack.org/topics/installation/ +# Note: see https://docs.saltstack.com/en/latest/topics/installation/ +# Note: see https://docs.saltstack.com/en/latest/ref/configuration/ + + +class SaltConstants(object): + """ + defines default distribution specific salt variables + """ + def __init__(self, cfg): + + # constants tailored for FreeBSD + if util.is_FreeBSD(): + self.pkg_name = 'py27-salt' + self.srv_name = 'salt_minion' + self.conf_dir = '/usr/local/etc/salt' + # constants for any other OS + else: + self.pkg_name = 'salt-minion' + self.srv_name = 'salt-minion' + self.conf_dir = '/etc/salt' + + # if there are constants given in cloud config use those + self.pkg_name = util.get_cfg_option_str(cfg, 'pkg_name', + self.pkg_name) + self.conf_dir = util.get_cfg_option_str(cfg, 'config_dir', + self.conf_dir) + self.srv_name = util.get_cfg_option_str(cfg, 'service_name', + self.srv_name) def handle(name, cfg, cloud, log, _args): @@ -52,45 +84,49 @@ def handle(name, cfg, cloud, log, _args): " no 'salt_minion' key in configuration"), name) return - salt_cfg = cfg['salt_minion'] + s_cfg = cfg['salt_minion'] + const = SaltConstants(cfg=s_cfg) # Start by installing the salt package ... - cloud.distro.install_packages(('salt-minion',)) + cloud.distro.install_packages(const.pkg_name) # Ensure we can configure files at the right dir - config_dir = salt_cfg.get("config_dir", '/etc/salt') - util.ensure_dir(config_dir) + util.ensure_dir(const.conf_dir) # ... and then update the salt configuration - if 'conf' in salt_cfg: - # Add all sections from the conf object to /etc/salt/minion - minion_config = os.path.join(config_dir, 'minion') - minion_data = util.yaml_dumps(salt_cfg.get('conf')) + if 'conf' in s_cfg: + # Add all sections from the conf object to minion config file + minion_config = os.path.join(const.conf_dir, 'minion') + minion_data = util.yaml_dumps(s_cfg.get('conf')) util.write_file(minion_config, minion_data) - if 'grains' in salt_cfg: + if 'grains' in s_cfg: # add grains to /etc/salt/grains - grains_config = os.path.join(config_dir, 'grains') - grains_data = util.yaml_dumps(salt_cfg.get('grains')) + grains_config = os.path.join(const.conf_dir, 'grains') + grains_data = util.yaml_dumps(s_cfg.get('grains')) util.write_file(grains_config, grains_data) # ... copy the key pair if specified - if 'public_key' in salt_cfg and 'private_key' in salt_cfg: - if os.path.isdir("/etc/salt/pki/minion"): - pki_dir_default = "/etc/salt/pki/minion" - else: - pki_dir_default = "/etc/salt/pki" + if 'public_key' in s_cfg and 'private_key' in s_cfg: + pki_dir_default = os.path.join(const.conf_dir, "pki/minion") + if not os.path.isdir(pki_dir_default): + pki_dir_default = os.path.join(const.conf_dir, "pki") - pki_dir = salt_cfg.get('pki_dir', pki_dir_default) + pki_dir = s_cfg.get('pki_dir', pki_dir_default) with util.umask(0o77): util.ensure_dir(pki_dir) pub_name = os.path.join(pki_dir, 'minion.pub') pem_name = os.path.join(pki_dir, 'minion.pem') - util.write_file(pub_name, salt_cfg['public_key']) - util.write_file(pem_name, salt_cfg['private_key']) + util.write_file(pub_name, s_cfg['public_key']) + util.write_file(pem_name, s_cfg['private_key']) + + # we need to have the salt minion service enabled in rc in order to be + # able to start the service. this does only apply on FreeBSD servers. + if cloud.distro.osfamily == 'freebsd': + cloud.distro.updatercconf('salt_minion_enable', 'YES') - # restart salt-minion. 'service' will start even if not started. if it + # restart salt-minion. 'service' will start even if not started. if it # was started, it needs to be restarted for config change. - util.subp(['service', 'salt-minion', 'restart'], capture=False) + util.subp(['service', const.srv_name, 'restart'], capture=False) # vi: ts=4 expandtab diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl index fad11847..cf2e2409 100644 --- a/config/cloud.cfg.tmpl +++ b/config/cloud.cfg.tmpl @@ -113,9 +113,9 @@ cloud_final_modules: {% if variant not in ["freebsd"] %} - puppet - chef - - salt-minion - mcollective {% endif %} + - salt-minion - rightscale_userdata - scripts-vendor - scripts-per-once diff --git a/tests/cloud_tests/testcases/modules/salt_minion.py b/tests/cloud_tests/testcases/modules/salt_minion.py index f13b48a0..70917a4c 100644 --- a/tests/cloud_tests/testcases/modules/salt_minion.py +++ b/tests/cloud_tests/testcases/modules/salt_minion.py @@ -31,4 +31,9 @@ class Test(base.CloudTestCase): out = self.get_data_file('grains') self.assertIn('role: web', out) + def test_minion_installed(self): + """Test if the salt-minion package is installed""" + out = self.get_data_file('minion_installed') + self.assertEqual(1, int(out)) + # vi: ts=4 expandtab diff --git a/tests/cloud_tests/testcases/modules/salt_minion.yaml b/tests/cloud_tests/testcases/modules/salt_minion.yaml index ab0e05bb..f20b9765 100644 --- a/tests/cloud_tests/testcases/modules/salt_minion.yaml +++ b/tests/cloud_tests/testcases/modules/salt_minion.yaml @@ -3,7 +3,7 @@ # # 2016-11-17: Currently takes >60 seconds results in test failure # -enabled: False +enabled: True cloud_config: | #cloud-config salt_minion: @@ -35,5 +35,8 @@ collect_scripts: grains: | #!/bin/bash cat /etc/salt/grains + minion_installed: | + #!/bin/bash + dpkg -l | grep salt-minion | grep ii | wc -l # vi: ts=4 expandtab -- cgit v1.2.3