Merge lp:~avishai-ish-shalom/cloud-init/chef into lp:~cloud-init-dev/cloud-init/trunk
- chef
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 407 | ||||
Proposed branch: | lp:~avishai-ish-shalom/cloud-init/chef | ||||
Merge into: | lp:~cloud-init-dev/cloud-init/trunk | ||||
Diff against target: |
218 lines (+187/-1) 5 files modified
cloudinit/CloudConfig/cc_chef.py (+80/-0) cloudinit/CloudConfig/cc_set_hostname.py (+6/-1) doc/examples/cloud-config-chef.txt (+38/-0) templates/chef_client.rb.tmpl (+12/-0) tools/write-mime-multipart.py (+51/-0) |
||||
To merge this branch: | bzr merge lp:~avishai-ish-shalom/cloud-init/chef | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mike Moulton (community) | Needs Fixing | ||
Avishai Ish-Shalom (community) | Needs Resubmitting | ||
Scott Moser | Needs Information | ||
Review via email: mp+66528@code.launchpad.net |
This proposal supersedes a proposal from 2011-04-29.
Commit message
Description of the change
Added hostname prefix option, custom hostname attribute.
Added chef plugin.
Avishai Ish-Shalom (avishai-ish-shalom) wrote : | # |
A. it's an unrelated feature. being a git man i thought a branch can be
done in the local repo with bazzar, then i got lazy and just left the
first commit. i've since saw the error of my ways and will branch a
different repo in the future (unless you can tell me what's the bazzar
equivalent of feature branch is).
On 18/07/11 18:29, Scott Moser wrote:
> Review: Needs Information
> Avishai,
> Thank you very much for taking the time to put this together. I'd like to merge this for Oneiric.
>
> I have a couple comments
> a.) Why the change to cloudinit/
> You summarized that as "Allow configurable hostname prefix and hostname attribute", but I don't initially see how its related to the rest of the commits. If its valuable, we can merge it, but I'd like that to be done separately if it is not related.
> b.) You added 'tools/
> This file has been moved to cloud-utils (http://
>
> Thanks again, I'm looking forward to hearing back from you. Sorry for the slow reply.
>
Scott Moser (smoser) wrote : | # |
On Mon, 18 Jul 2011, Avishai Ish-Shalom wrote:
> A. it's an unrelated feature.
OK, then I can just drop it in the merge, or you can modify it back.
Mike Moulton (mmoulton) wrote : | # |
I seem to be unable to use the chef feature as included in the Oneiric Beta 1. I have noticed the following errors with this:
- If 'install_type' is undefined, the process fails
- 'firstboot.json' fails to write as it does not yet exist. Assume the missing 'w' param is needed.
- 'validation_cert' writes to '/etc/chef/
- There seems to be a problem with 'subprocess.
I'm not familiar with how to submit patches via launchpad.net, otherwise I would have included fixes for these items.
I would love to get these items fixed for potential inclusion in Oneiric before it goes stable. Let me know what I can do to help.
Avishai Ish-Shalom (avishai-ish-shalom) wrote : | # |
Fixed review rejects in 397.
Mike Moulton (mmoulton) wrote : | # |
Avishai, thank you for the quick turn around. Your changes look like they will address all of my issues.
Scott, is it too late to get this into Oneiric?
Scott Moser (smoser) wrote : | # |
On Thu, 8 Sep 2011, Mike Moulton wrote:
> Review: Approve
>
> Avishai, thank you for the quick turn around. Your changes look like they will address all of my issues.
>
Mike sorry for the run-around, but can you
a.) please actually test the code path. I can make you a cloud-init deb if needed.
The cleanest path to do that is probably to
- launch instance with no user-data
- install new cloud-init
- rm -Rf /var/lib/cloud
- mkdir -p /var/lib/
- populate /var/lib/
with the same user data you would have used
- reboot
- check
b.) open a bug for this? and describe what user-data you gave.
We will get this into oneiric.
Mike Moulton (mmoulton) wrote : | # |
Scott, no problem, I will test this. If you could make a deb, that would help.
Scott Moser (smoser) wrote : | # |
On Thu, 8 Sep 2011, Mike Moulton wrote:
> Scott, no problem, I will test this. If you could make a deb, that would help.
can you please try
http://
Mike Moulton (mmoulton) wrote : | # |
I was able to get this to work with the following patch to cc_chef.py:
root@ip-
35c35
< install_type = cfg.get_
---
> install_type = util.get_
37c37
< if install_type = "gems":
---
> if install_type == "gems":
65,66c65,66
< firstboot_
< firstboot_
---
> firstboot_
> firstboot_
Can either Scott or Avishai apply this?
I will create a bug as requested with the user data I used to get this to work. Please note, the user data will not be testable by others without their own valid chef server and validator key.
Mike Moulton (mmoulton) wrote : | # |
I have submitted the following bug https:/
Preview Diff
1 | === added file 'cloudinit/CloudConfig/cc_chef.py' |
2 | --- cloudinit/CloudConfig/cc_chef.py 1970-01-01 00:00:00 +0000 |
3 | +++ cloudinit/CloudConfig/cc_chef.py 2011-06-30 22:52:32 +0000 |
4 | @@ -0,0 +1,80 @@ |
5 | +# vi: ts=4 expandtab |
6 | +# |
7 | +# Author: Avishai Ish-Shalom <avishai@fewbytes.com> |
8 | +# |
9 | +# This program is free software: you can redistribute it and/or modify |
10 | +# it under the terms of the GNU General Public License version 3, as |
11 | +# published by the Free Software Foundation. |
12 | +# |
13 | +# This program is distributed in the hope that it will be useful, |
14 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | +# GNU General Public License for more details. |
17 | +# |
18 | +# You should have received a copy of the GNU General Public License |
19 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | +import os |
21 | +import pwd |
22 | +import socket |
23 | +import subprocess |
24 | +import StringIO |
25 | +import ConfigParser |
26 | +import cloudinit.CloudConfig as cc |
27 | +import cloudinit.util as util |
28 | + |
29 | +ruby_packages = {'1.8': ('ruby', 'rubygems', 'ruby-dev', 'libopenssl-ruby'), |
30 | + '1.9.1': ('ruby1.9.1', 'ruby1.9.1-dev', 'libruby1.9.1'), |
31 | + '1.9': ('ruby1.9', 'ruby1.9-dev', 'libruby1.9') } |
32 | + |
33 | +def handle(name,cfg,cloud,log,args): |
34 | + # If there isn't a chef key in the configuration don't do anything |
35 | + if not cfg.has_key('chef'): return |
36 | + chef_cfg = cfg['chef'] |
37 | + |
38 | + # Install chef packages from selected source |
39 | + if not os.path.isfile('/usr/bin/chef-client'): |
40 | + if chef_cfg['install_type'] == "gems": |
41 | + if chef_cfg.has_key('version'): |
42 | + chef_version = chef_cfg['version'] |
43 | + else: |
44 | + chef_version = None |
45 | + install_chef_from_gems( |
46 | + util.get_cfg_option_str(chef_cfg, 'ruby_version', '1.8'), |
47 | + chef_version) |
48 | + else: |
49 | + cc.install_packages(('chef',)) |
50 | + |
51 | + # set the validation cert |
52 | + if chef_cfg.has_key('validation_cert'): |
53 | + with open('/etc/chef/validation.cert', 'w') as validation_cert_fh: |
54 | + validation_cert_fh.write(chef_cfg['validation_cert']) |
55 | + |
56 | + # create the chef config from template |
57 | + util.render_to_file('chef_client.rb', '/etc/chef/client.rb', |
58 | + {'server_url': chef_cfg['server_url'], 'validation_name': chef_cfg['validation_name'] || 'chef-validator'}) |
59 | + |
60 | + chef_args = ['-d'] |
61 | + # set the firstboot json |
62 | + if chef_cfg.has_key('run_list'): |
63 | + with open('/etc/chef/firstboot.json') as firstboot_json_fh: |
64 | + firstboot_json_fh.write("{\n\"run_list\":\n[\n") |
65 | + for runlist_item in chef_cfg['run_list']: |
66 | + firstboot_json_fh.write(runlist_item + "\n") |
67 | + firstboot_json_fh.write("]\n\}") |
68 | + chef_args.append('-j /etc/chef/firstboot.json') |
69 | + |
70 | + # and finally, run chef |
71 | + subprocess.check_call(['/usr/bin/chef-client'] + chef_args) |
72 | + |
73 | +def install_chef_from_gems(ruby_version, chef_version = None): |
74 | + cc.install_packages(ruby_packages[ruby_version]) |
75 | + chef_version_arg = "" |
76 | + if chef_version: chef_version_arg = "-v %s" % chef_version |
77 | + subprocess.check_call([gem_bin,'install','chef',chef_version_arg, '--no-ri','--no-rdoc','--no-test','-q']) |
78 | + os.mkdirs('/etc/chef', '/var/log/chef', '/var/lib/chef', '/var/cache/chef', '/var/backups/chef', '/var/run/chef') |
79 | + os.symlink('/var/lib/gem/%s/bin/chef-client' % ruby_version, '/usr/bin/chef-client') |
80 | + # Ohai ruby plugin breaks if there is no ruby or gem binaries at /usr/bin, so |
81 | + try: os.symlink('/usr/bin/gem%s' % ruby_version, '/usr/bin/gem') |
82 | + except: pass |
83 | + try: os.symlink('/usr/bin/ruby%s' % ruby_version, '/usr/bin/ruby') |
84 | + except: pass |
85 | |
86 | === modified file 'cloudinit/CloudConfig/cc_set_hostname.py' |
87 | --- cloudinit/CloudConfig/cc_set_hostname.py 2011-01-26 14:03:46 +0000 |
88 | +++ cloudinit/CloudConfig/cc_set_hostname.py 2011-06-30 22:52:32 +0000 |
89 | @@ -24,7 +24,12 @@ |
90 | return(True) |
91 | |
92 | try: |
93 | - hostname = util.get_cfg_option_str(cfg,"hostname",cloud.get_hostname()) |
94 | + hostname_prefix = util.get_cfg_option_str(cfg, "hostname_prefix", None) |
95 | + hostname_attr = util.get_cfg_option_str(cfg, "hostname_attribute", "hostname") |
96 | + hostname_function = getattr(cloud, 'get_' + hostname_attr, None) |
97 | + if hostname_fucntion is None: hostname_fucntion = cloud.get_hostname |
98 | + hostname = util.get_cfg_option_str(cfg,"hostname", hostname_function) |
99 | + if hostname_prefix: hostname = hostname_prefix + "-" + hostname |
100 | set_hostname(hostname, log) |
101 | except Exception as e: |
102 | util.logexc(log) |
103 | |
104 | === added file 'doc/examples/cloud-config-chef.txt' |
105 | --- doc/examples/cloud-config-chef.txt 1970-01-01 00:00:00 +0000 |
106 | +++ doc/examples/cloud-config-chef.txt 2011-06-30 22:52:32 +0000 |
107 | @@ -0,0 +1,38 @@ |
108 | +#cloud-config |
109 | +# |
110 | +# This is an example file to automatically setup and run puppetd |
111 | +# when the instance boots for the first time. |
112 | +# Make sure that this file is valid yaml before starting instances. |
113 | +# It should be passed as user-data when starting the instance. |
114 | + |
115 | +# The default is to install from packages. If you want the latest packages from Opscode, be sure to add their repo: |
116 | +apt_mirror: http://apt.opscode.com/ |
117 | + |
118 | +chef: |
119 | + # If you want to install from rubygems: |
120 | + install_type: "gems" |
121 | + |
122 | + # Chef settings |
123 | + server_url: "https://chef.yourorg.com:4000" |
124 | + |
125 | + # Default validation name is chef-validator |
126 | + validation_name: "yourorg-validator" |
127 | + validation_cert: | |
128 | + -----BEGIN CERTIFICATE----- |
129 | + MIICCTCCAXKgAwIBAgIBATANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDDAJjYTAe |
130 | + Fw0xMDAyMTUxNzI5MjFaFw0xNTAyMTQxNzI5MjFaMA0xCzAJBgNVBAMMAmNhMIGf |
131 | + MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCu7Q40sm47/E1Pf+r8AYb/V/FWGPgc |
132 | + b014OmNoX7dgCxTDvps/h8Vw555PdAFsW5+QhsGr31IJNI3kSYprFQcYf7A8tNWu |
133 | + 1MASW2CfaEiOEi9F1R3R4Qlz4ix+iNoHiUDTjazw/tZwEdxaQXQVLwgTGRwVa+aA |
134 | + qbutJKi93MILLwIDAQABo3kwdzA4BglghkgBhvhCAQ0EKxYpUHVwcGV0IFJ1Ynkv |
135 | + T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwDwYDVR0TAQH/BAUwAwEB/zAd |
136 | + BgNVHQ4EFgQUu4+jHB+GYE5Vxo+ol1OAhevspjAwCwYDVR0PBAQDAgEGMA0GCSqG |
137 | + SIb3DQEBBQUAA4GBAH/rxlUIjwNb3n7TXJcDJ6MMHUlwjr03BDJXKb34Ulndkpaf |
138 | + +GAlzPXWa7bO908M9I8RnPfvtKnteLbvgTK+h+zX1XCty+S2EQWk29i2AdoqOTxb |
139 | + hppiGMp0tT5Havu4aceCXiy2crVcudj3NFciy8X66SoECemW9UYDCb9T5D0d |
140 | + -----END CERTIFICATE----- |
141 | + |
142 | + # A run list for a first boot json |
143 | + run_list: |
144 | + - "recipe[apache2]" |
145 | + - "role[db]" |
146 | |
147 | === added file 'templates/chef_client.rb.tmpl' |
148 | --- templates/chef_client.rb.tmpl 1970-01-01 00:00:00 +0000 |
149 | +++ templates/chef_client.rb.tmpl 2011-06-30 22:52:32 +0000 |
150 | @@ -0,0 +1,12 @@ |
151 | +log_level :info |
152 | +log_location "/var/log/chef/client.log" |
153 | +ssl_verify_mode :verify_none |
154 | +validation_client_name "$validation_name" |
155 | +validation_key "/etc/chef/validation.pem" |
156 | +client_key "/etc/chef/client.pem" |
157 | +chef_server_url "$server_url" |
158 | +file_cache_path "/var/cache/chef" |
159 | +file_backup_path "/var/backups/chef" |
160 | +pid_file "/var/run/chef/client.pid" |
161 | +Chef::Log::Formatter.show_time = true |
162 | + |
163 | |
164 | === added file 'tools/write-mime-multipart.py' |
165 | --- tools/write-mime-multipart.py 1970-01-01 00:00:00 +0000 |
166 | +++ tools/write-mime-multipart.py 2011-06-30 22:52:32 +0000 |
167 | @@ -0,0 +1,51 @@ |
168 | +#! /usr/bin/env python |
169 | + |
170 | +import sys, os |
171 | +import email |
172 | +import mimetypes |
173 | +import re |
174 | + |
175 | +mimetypes.types_map['.sh'] = 'text/x-shellscript' |
176 | +cloud_config_mark_strings = { '#!': 'text/x-shellscript', '#include': 'text/x-include-url', |
177 | + '#cloud-config': 'text/cloud-config', '#upstart-job': 'text/upstart-job', |
178 | + '#cloud-boothook': 'text/cloud-boothook' |
179 | + } |
180 | +def write_mime_multipart(): |
181 | + multipart_msg = email.mime.Multipart.MIMEMultipart() |
182 | + for arg in sys.argv[1:]: |
183 | + if ',' in arg: |
184 | + (msg_file, msg_type) = arg.split(',') |
185 | + else: |
186 | + msg_file = arg |
187 | + msg_type = None |
188 | + |
189 | + msg_file = os.path.expanduser(msg_file) |
190 | + if not os.path.isfile(msg_file): |
191 | + print >> sys.stderr, "Can't find file %s" % arg |
192 | + exit(1) |
193 | + |
194 | + if not msg_type: msg_type = get_type_from_file(arg) |
195 | + msg = email.mime.base.MIMEBase(*msg_type.split('/')) |
196 | + msg.set_payload(open(msg_file, 'r').read()) |
197 | + multipart_msg.attach(msg) |
198 | + |
199 | + print multipart_msg.as_string() |
200 | + |
201 | +def get_type_from_file(filename): |
202 | + first_line = open(filename).readline() |
203 | + m = re.match('Content-Type: (\w+/\w+)', first_line) |
204 | + if m: |
205 | + return m.groups[1] |
206 | + else: |
207 | + for mark_string, mime_type in cloud_config_mark_strings.items(): |
208 | + if first_line.startswith(mark_string): |
209 | + return mime_type |
210 | + return mimetypes.guess_type(filename)[0] or 'text/plain' |
211 | + |
212 | +if __name__ == '__main__': |
213 | + if len(sys.argv) == 1 or '-h' in sys.argv or '--help' in sys.argv: |
214 | + print "Usage: %s file1,application/cloud-config file2.sh ..." % os.path.basename(sys.argv[0]) |
215 | + print "MIME Multipart message will be written to STDOUT" |
216 | + exit(0) |
217 | + write_mime_multipart() |
218 | + |
Avishai,
Thank you very much for taking the time to put this together. I'd like to merge this for Oneiric.
I have a couple comments CloudConfig/ cc_set_ hostname. py ? write-mime- multipart. py' launchpad. net/cloud- utils) .
a.) Why the change to cloudinit/
You summarized that as "Allow configurable hostname prefix and hostname attribute", but I don't initially see how its related to the rest of the commits. If its valuable, we can merge it, but I'd like that to be done separately if it is not related.
b.) You added 'tools/
This file has been moved to cloud-utils (http://
Thanks again, I'm looking forward to hearing back from you. Sorry for the slow reply.