Merge ~d-info-e/cloud-init:salt-freebsd-patch into cloud-init:master

Proposed by do3meli
Status: Merged
Approved by: Chad Smith
Approved revision: 42aacc0fcc3c91f3931204445058b9bfc330db27
Merge reported by: Chad Smith
Merged at revision: 1e2e810f3f7cb6a163a0229ac37037e8c6744d72
Proposed branch: ~d-info-e/cloud-init:salt-freebsd-patch
Merge into: cloud-init:master
Diff against target: 183 lines (+69/-25)
4 files modified
cloudinit/config/cc_salt_minion.py (+59/-23)
config/cloud.cfg.tmpl (+1/-1)
tests/cloud_tests/testcases/modules/salt_minion.py (+5/-0)
tests/cloud_tests/testcases/modules/salt_minion.yaml (+4/-1)
Reviewer Review Type Date Requested Status
Chad Smith Approve
Server Team CI bot continuous-integration Approve
Scott Moser Approve
Review via email: mp+340112@code.launchpad.net

Commit message

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

Description of the change

the salt minion module was not really usable on FreeBSD so far. I have adjusted/extended the module with some more config variables that can be set based on the distro for better flexibility and compatibility between different distributions. In particular on FreeBSD system paths, package names and service names are different than on other operating systems. This fixes LP: #1721503

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/796/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    FAILED: Ubuntu LTS: Integration

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/796/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
do3meli (d-info-e) wrote :

can anyone of the jenkins team please have a look at the failed integration test. the error is:

2018-02-28 15:17:37,740 - tests.cloud_tests - ERROR - stage part: setup func for --deb, install deb encountered error: install deb version "17.1-46-g7acc9e68-0ubuntu1~16.04.1" does not match expected "17.1-28-gbee5b162-1~bddeb"

that looks to me like a jenkins setup error instead of a code issue. thanks

Revision history for this message
Scott Moser (smoser) wrote :

This is an interesting set of changes.
In order to configure salt, you have to know details of 2 things
a.) the distribution
b.) salt software

Generally knowledge of the distribution has been in the distribution class and the software in the 'config module' (cc_salt).

You've mostly maintained that here.

It seems to me that information about how to install software X on distribution Y is actually more closely coupled to the software X than the distribution.

So it feels to me that its better to just keep distro specific knowledge of a given package in the config module rather than putting it into the distro.

Does that make sense?

Thoughts?

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/801/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/801/rebuild

review: Approve (continuous-integration)
Revision history for this message
do3meli (d-info-e) wrote :

hi scott,

from a theoretical point of view i totally agree with you. the reason why i added those 3 cfg variables to the distro module was that it is currently not maintained like this everywhere. for example the variable cfg['ssh_svcname'] is also configured in the distro classes instead of the corresponding cc_ssh*.py classes. one may say ssh is such a basic service which is used in many different places in the code so it makes sense to have it in the distro...?

never the less i think in the case of cc_salt_minion it really makes sense to have these params not defined in the distro. i have created an implementation idea that follows the mentioned standard but to be honest the new version doesn't look as neat to me as the previous version. what are your thoughts? check out the patch here: https://git.launchpad.net/~d-info-e/cloud-init/commit/?id=c7c9f90714dcd127faf861e63e465a65d79277fa

i haven't tested it yet but if you think that is nice and good i will merge it to this branch here.

cheers
dom

Revision history for this message
Scott Moser (smoser) wrote :

Dom,
Yeah, we have knowledge of ssh in the distro module. It more qualifies as a "basic service". Similarly, recent work is being done to do ntp configuration. ntp also seems "basic".

So yeah, I like your suggestion in the link you provided.

Some thing like the PuppetConstants might be helpful.

class SaltConstants(object):
   def init(self):
       if util.is_FreeBSD():
           self.package_name = 'salt_minion'
           self.config_dir = '/usr/local/etc/salt'
...

Revision history for this message
do3meli (d-info-e) wrote :

hi scott,

i have just updated this branch with what i think looks much better than before. as an additional feature users can now configure those 3 variables if they have their own service names / packages / config paths.

i haven't tested this yet. will do so on Monday and give feedback again here.

cheers
dom

Revision history for this message
Scott Moser (smoser) wrote :

Please let me know if you don't like hte suggestions.

review: Needs Fixing
Revision history for this message
do3meli (d-info-e) wrote :

hi scott, your suggestion makes sense. i have implemented it accordingly. please review it again. thanks. dom

Revision history for this message
Scott Moser (smoser) wrote :

http://paste.ubuntu.com/p/q8X4WRWH4s/

thats my suggestion, then thats all I have.

Revision history for this message
Scott Moser (smoser) wrote :

I started a jenkins c-i run.
https://jenkins.ubuntu.com/server/job/cloud-init-ci/814/

assuming that goes well, i'm ok with this.

review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/814/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/814/rebuild

review: Approve (continuous-integration)
Revision history for this message
do3meli (d-info-e) wrote :

folks,

i have added another commit that includes an additional integration test and enables the salt minion integration tests again. unfortunately this additional commit https://git.launchpad.net/~d-info-e/cloud-init/commit/?id=48f21de68a38085ce342278a17c98bb16ab6246d is not visible in the MR here. maybe because the status of the MR was "merged" when i pushed and i set it back to WIP after the push. what do we have to do to have it visible here in the MR?

once it is visible you guys can trigger another ci run, approve it and merge it finally.

cheers,
dom

Revision history for this message
do3meli (d-info-e) wrote :

above problem solved by - pushing again. please review/approve/merge

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:42aacc0fcc3c91f3931204445058b9bfc330db27
https://jenkins.ubuntu.com/server/job/cloud-init-ci/827/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/827/rebuild

review: Approve (continuous-integration)
Revision history for this message
Chad Smith (chad.smith) wrote :

Thank you for this integration test update Dominic. We like the approach you've taken here. +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/config/cc_salt_minion.py b/cloudinit/config/cc_salt_minion.py
2index 5112a34..d6a21d7 100644
3--- a/cloudinit/config/cc_salt_minion.py
4+++ b/cloudinit/config/cc_salt_minion.py
5@@ -12,7 +12,9 @@ key is present in the config parts, then salt minion will be installed and
6 started. Configuration for salt minion can be specified in the ``conf`` key
7 under ``salt_minion``. Any conf values present there will be assigned in
8 ``/etc/salt/minion``. The public and private keys to use for salt minion can be
9-specified with ``public_key`` and ``private_key`` respectively.
10+specified with ``public_key`` and ``private_key`` respectively. Optionally if
11+you have a custom package name, service name or config directory you can
12+specify them with ``pkg_name``, ``service_name`` and ``config_dir``.
13
14 **Internal name:** ``cc_salt_minion``
15
16@@ -23,6 +25,9 @@ specified with ``public_key`` and ``private_key`` respectively.
17 **Config keys**::
18
19 salt_minion:
20+ pkg_name: 'salt-minion'
21+ service_name: 'salt-minion'
22+ config_dir: '/etc/salt'
23 conf:
24 master: salt.example.com
25 grains:
26@@ -42,7 +47,34 @@ import os
27
28 from cloudinit import util
29
30-# Note: see http://saltstack.org/topics/installation/
31+# Note: see https://docs.saltstack.com/en/latest/topics/installation/
32+# Note: see https://docs.saltstack.com/en/latest/ref/configuration/
33+
34+
35+class SaltConstants(object):
36+ """
37+ defines default distribution specific salt variables
38+ """
39+ def __init__(self, cfg):
40+
41+ # constants tailored for FreeBSD
42+ if util.is_FreeBSD():
43+ self.pkg_name = 'py27-salt'
44+ self.srv_name = 'salt_minion'
45+ self.conf_dir = '/usr/local/etc/salt'
46+ # constants for any other OS
47+ else:
48+ self.pkg_name = 'salt-minion'
49+ self.srv_name = 'salt-minion'
50+ self.conf_dir = '/etc/salt'
51+
52+ # if there are constants given in cloud config use those
53+ self.pkg_name = util.get_cfg_option_str(cfg, 'pkg_name',
54+ self.pkg_name)
55+ self.conf_dir = util.get_cfg_option_str(cfg, 'config_dir',
56+ self.conf_dir)
57+ self.srv_name = util.get_cfg_option_str(cfg, 'service_name',
58+ self.srv_name)
59
60
61 def handle(name, cfg, cloud, log, _args):
62@@ -52,45 +84,49 @@ def handle(name, cfg, cloud, log, _args):
63 " no 'salt_minion' key in configuration"), name)
64 return
65
66- salt_cfg = cfg['salt_minion']
67+ s_cfg = cfg['salt_minion']
68+ const = SaltConstants(cfg=s_cfg)
69
70 # Start by installing the salt package ...
71- cloud.distro.install_packages(('salt-minion',))
72+ cloud.distro.install_packages(const.pkg_name)
73
74 # Ensure we can configure files at the right dir
75- config_dir = salt_cfg.get("config_dir", '/etc/salt')
76- util.ensure_dir(config_dir)
77+ util.ensure_dir(const.conf_dir)
78
79 # ... and then update the salt configuration
80- if 'conf' in salt_cfg:
81- # Add all sections from the conf object to /etc/salt/minion
82- minion_config = os.path.join(config_dir, 'minion')
83- minion_data = util.yaml_dumps(salt_cfg.get('conf'))
84+ if 'conf' in s_cfg:
85+ # Add all sections from the conf object to minion config file
86+ minion_config = os.path.join(const.conf_dir, 'minion')
87+ minion_data = util.yaml_dumps(s_cfg.get('conf'))
88 util.write_file(minion_config, minion_data)
89
90- if 'grains' in salt_cfg:
91+ if 'grains' in s_cfg:
92 # add grains to /etc/salt/grains
93- grains_config = os.path.join(config_dir, 'grains')
94- grains_data = util.yaml_dumps(salt_cfg.get('grains'))
95+ grains_config = os.path.join(const.conf_dir, 'grains')
96+ grains_data = util.yaml_dumps(s_cfg.get('grains'))
97 util.write_file(grains_config, grains_data)
98
99 # ... copy the key pair if specified
100- if 'public_key' in salt_cfg and 'private_key' in salt_cfg:
101- if os.path.isdir("/etc/salt/pki/minion"):
102- pki_dir_default = "/etc/salt/pki/minion"
103- else:
104- pki_dir_default = "/etc/salt/pki"
105+ if 'public_key' in s_cfg and 'private_key' in s_cfg:
106+ pki_dir_default = os.path.join(const.conf_dir, "pki/minion")
107+ if not os.path.isdir(pki_dir_default):
108+ pki_dir_default = os.path.join(const.conf_dir, "pki")
109
110- pki_dir = salt_cfg.get('pki_dir', pki_dir_default)
111+ pki_dir = s_cfg.get('pki_dir', pki_dir_default)
112 with util.umask(0o77):
113 util.ensure_dir(pki_dir)
114 pub_name = os.path.join(pki_dir, 'minion.pub')
115 pem_name = os.path.join(pki_dir, 'minion.pem')
116- util.write_file(pub_name, salt_cfg['public_key'])
117- util.write_file(pem_name, salt_cfg['private_key'])
118+ util.write_file(pub_name, s_cfg['public_key'])
119+ util.write_file(pem_name, s_cfg['private_key'])
120+
121+ # we need to have the salt minion service enabled in rc in order to be
122+ # able to start the service. this does only apply on FreeBSD servers.
123+ if cloud.distro.osfamily == 'freebsd':
124+ cloud.distro.updatercconf('salt_minion_enable', 'YES')
125
126- # restart salt-minion. 'service' will start even if not started. if it
127+ # restart salt-minion. 'service' will start even if not started. if it
128 # was started, it needs to be restarted for config change.
129- util.subp(['service', 'salt-minion', 'restart'], capture=False)
130+ util.subp(['service', const.srv_name, 'restart'], capture=False)
131
132 # vi: ts=4 expandtab
133diff --git a/config/cloud.cfg.tmpl b/config/cloud.cfg.tmpl
134index fad1184..cf2e240 100644
135--- a/config/cloud.cfg.tmpl
136+++ b/config/cloud.cfg.tmpl
137@@ -113,9 +113,9 @@ cloud_final_modules:
138 {% if variant not in ["freebsd"] %}
139 - puppet
140 - chef
141- - salt-minion
142 - mcollective
143 {% endif %}
144+ - salt-minion
145 - rightscale_userdata
146 - scripts-vendor
147 - scripts-per-once
148diff --git a/tests/cloud_tests/testcases/modules/salt_minion.py b/tests/cloud_tests/testcases/modules/salt_minion.py
149index f13b48a..70917a4 100644
150--- a/tests/cloud_tests/testcases/modules/salt_minion.py
151+++ b/tests/cloud_tests/testcases/modules/salt_minion.py
152@@ -31,4 +31,9 @@ class Test(base.CloudTestCase):
153 out = self.get_data_file('grains')
154 self.assertIn('role: web', out)
155
156+ def test_minion_installed(self):
157+ """Test if the salt-minion package is installed"""
158+ out = self.get_data_file('minion_installed')
159+ self.assertEqual(1, int(out))
160+
161 # vi: ts=4 expandtab
162diff --git a/tests/cloud_tests/testcases/modules/salt_minion.yaml b/tests/cloud_tests/testcases/modules/salt_minion.yaml
163index ab0e05b..f20b976 100644
164--- a/tests/cloud_tests/testcases/modules/salt_minion.yaml
165+++ b/tests/cloud_tests/testcases/modules/salt_minion.yaml
166@@ -3,7 +3,7 @@
167 #
168 # 2016-11-17: Currently takes >60 seconds results in test failure
169 #
170-enabled: False
171+enabled: True
172 cloud_config: |
173 #cloud-config
174 salt_minion:
175@@ -35,5 +35,8 @@ collect_scripts:
176 grains: |
177 #!/bin/bash
178 cat /etc/salt/grains
179+ minion_installed: |
180+ #!/bin/bash
181+ dpkg -l | grep salt-minion | grep ii | wc -l
182
183 # vi: ts=4 expandtab

Subscribers

People subscribed via source and target branches