Merge lp:~harlowja/cloud-init/pylint-join-cleanup into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Joshua Harlow
Status: Merged
Merged at revision: 700
Proposed branch: lp:~harlowja/cloud-init/pylint-join-cleanup
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 1143 lines (+180/-261)
28 files modified
Makefile (+4/-4)
cloudinit/config/cc_apt_pipelining.py (+5/-7)
cloudinit/config/cc_apt_update_upgrade.py (+7/-10)
cloudinit/config/cc_ca_certs.py (+13/-15)
cloudinit/config/cc_chef.py (+14/-16)
cloudinit/config/cc_landscape.py (+4/-10)
cloudinit/config/cc_mcollective.py (+9/-13)
cloudinit/config/cc_mounts.py (+4/-5)
cloudinit/config/cc_phone_home.py (+2/-2)
cloudinit/config/cc_puppet.py (+33/-37)
cloudinit/config/cc_resizefs.py (+2/-3)
cloudinit/config/cc_rsyslog.py (+1/-2)
cloudinit/config/cc_runcmd.py (+1/-1)
cloudinit/config/cc_salt_minion.py (+2/-4)
cloudinit/config/cc_set_passwords.py (+2/-4)
cloudinit/config/cc_ssh.py (+7/-9)
cloudinit/config/cc_ssh_authkey_fingerprints.py (+3/-4)
cloudinit/config/cc_update_etc_hosts.py (+1/-2)
cloudinit/distros/__init__.py (+3/-5)
cloudinit/distros/debian.py (+9/-17)
cloudinit/helpers.py (+1/-28)
cloudinit/sources/__init__.py (+0/-2)
cloudinit/ssh_util.py (+15/-19)
pylintrc (+19/-0)
tests/unittests/test_filters/test_launch_index.py (+2/-10)
tests/unittests/test_handler/test_handler_ca_certs.py (+9/-9)
tests/unittests/test_runs/test_simple_run.py (+2/-10)
tools/run-pylint (+6/-13)
To merge this branch: bzr merge lp:~harlowja/cloud-init/pylint-join-cleanup
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+131765@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2012-08-09 17:42:55 +0000
+++ Makefile 2012-10-28 02:29:21 +0000
@@ -1,20 +1,20 @@
1CWD=$(shell pwd)1CWD=$(shell pwd)
2PY_FILES=$(shell find cloudinit bin tests tools -name "*.py")2PY_FILES=$(shell find cloudinit bin tests tools -type f -name "*.py")
3PY_FILES+="bin/cloud-init"3PY_FILES+="bin/cloud-init"
44
5all: test5all: test
66
7pep8:7pep8:
8 $(CWD)/tools/run-pep8 $(PY_FILES)8 @$(CWD)/tools/run-pep8 $(PY_FILES)
99
10pylint:10pylint:
11 $(CWD)/tools/run-pylint $(PY_FILES)11 @$(CWD)/tools/run-pylint $(PY_FILES)
1212
13pyflakes:13pyflakes:
14 pyflakes $(PY_FILES)14 pyflakes $(PY_FILES)
1515
16test:16test:
17 nosetests $(noseopts) tests/unittests/17 @nosetests $(noseopts) tests/
1818
192to3:192to3:
20 2to3 $(PY_FILES)20 2to3 $(PY_FILES)
2121
=== modified file 'cloudinit/config/cc_apt_pipelining.py'
--- cloudinit/config/cc_apt_pipelining.py 2012-08-22 18:12:32 +0000
+++ cloudinit/config/cc_apt_pipelining.py 2012-10-28 02:29:21 +0000
@@ -34,26 +34,24 @@
34# on TCP connections - otherwise data corruption will occur.34# on TCP connections - otherwise data corruption will occur.
3535
3636
37def handle(_name, cfg, cloud, log, _args):37def handle(_name, cfg, _cloud, log, _args):
3838
39 apt_pipe_value = util.get_cfg_option_str(cfg, "apt_pipelining", False)39 apt_pipe_value = util.get_cfg_option_str(cfg, "apt_pipelining", False)
40 apt_pipe_value_s = str(apt_pipe_value).lower().strip()40 apt_pipe_value_s = str(apt_pipe_value).lower().strip()
4141
42 if apt_pipe_value_s == "false":42 if apt_pipe_value_s == "false":
43 write_apt_snippet(cloud, "0", log, DEFAULT_FILE)43 write_apt_snippet("0", log, DEFAULT_FILE)
44 elif apt_pipe_value_s in ("none", "unchanged", "os"):44 elif apt_pipe_value_s in ("none", "unchanged", "os"):
45 return45 return
46 elif apt_pipe_value_s in [str(b) for b in xrange(0, 6)]:46 elif apt_pipe_value_s in [str(b) for b in xrange(0, 6)]:
47 write_apt_snippet(cloud, apt_pipe_value_s, log, DEFAULT_FILE)47 write_apt_snippet(apt_pipe_value_s, log, DEFAULT_FILE)
48 else:48 else:
49 log.warn("Invalid option for apt_pipeling: %s", apt_pipe_value)49 log.warn("Invalid option for apt_pipeling: %s", apt_pipe_value)
5050
5151
52def write_apt_snippet(cloud, setting, log, f_name):52def write_apt_snippet(setting, log, f_name):
53 """Writes f_name with apt pipeline depth 'setting'."""53 """Writes f_name with apt pipeline depth 'setting'."""
5454
55 file_contents = APT_PIPE_TPL % (setting)55 file_contents = APT_PIPE_TPL % (setting)
5656 util.write_file(f_name, file_contents)
57 util.write_file(cloud.paths.join(False, f_name), file_contents)
58
59 log.debug("Wrote %s with apt pipeline depth setting %s", f_name, setting)57 log.debug("Wrote %s with apt pipeline depth setting %s", f_name, setting)
6058
=== modified file 'cloudinit/config/cc_apt_update_upgrade.py'
--- cloudinit/config/cc_apt_update_upgrade.py 2012-08-22 21:02:54 +0000
+++ cloudinit/config/cc_apt_update_upgrade.py 2012-10-28 02:29:21 +0000
@@ -78,8 +78,7 @@
78 try:78 try:
79 # See man 'apt.conf'79 # See man 'apt.conf'
80 contents = PROXY_TPL % (proxy)80 contents = PROXY_TPL % (proxy)
81 util.write_file(cloud.paths.join(False, proxy_filename),81 util.write_file(proxy_filename, contents)
82 contents)
83 except Exception as e:82 except Exception as e:
84 util.logexc(log, "Failed to write proxy to %s", proxy_filename)83 util.logexc(log, "Failed to write proxy to %s", proxy_filename)
85 elif os.path.isfile(proxy_filename):84 elif os.path.isfile(proxy_filename):
@@ -90,7 +89,7 @@
90 params = mirrors89 params = mirrors
91 params['RELEASE'] = release90 params['RELEASE'] = release
92 params['MIRROR'] = mirror91 params['MIRROR'] = mirror
93 errors = add_sources(cloud, cfg['apt_sources'], params)92 errors = add_sources(cfg['apt_sources'], params)
94 for e in errors:93 for e in errors:
95 log.warn("Source Error: %s", ':'.join(e))94 log.warn("Source Error: %s", ':'.join(e))
9695
@@ -196,11 +195,10 @@
196 params = {'codename': codename}195 params = {'codename': codename}
197 for k in mirrors:196 for k in mirrors:
198 params[k] = mirrors[k]197 params[k] = mirrors[k]
199 out_fn = cloud.paths.join(False, '/etc/apt/sources.list')198 templater.render_to_file(template_fn, '/etc/apt/sources.list', params)
200 templater.render_to_file(template_fn, out_fn, params)199
201200
202201def add_sources(srclist, template_params=None):
203def add_sources(cloud, srclist, template_params=None):
204 """202 """
205 add entries in /etc/apt/sources.list.d for each abbreviated203 add entries in /etc/apt/sources.list.d for each abbreviated
206 sources.list entry in 'srclist'. When rendering template, also204 sources.list entry in 'srclist'. When rendering template, also
@@ -250,8 +248,7 @@
250248
251 try:249 try:
252 contents = "%s\n" % (source)250 contents = "%s\n" % (source)
253 util.write_file(cloud.paths.join(False, ent['filename']),251 util.write_file(ent['filename'], contents, omode="ab")
254 contents, omode="ab")
255 except:252 except:
256 errorlist.append([source,253 errorlist.append([source,
257 "failed write to file %s" % ent['filename']])254 "failed write to file %s" % ent['filename']])
258255
=== modified file 'cloudinit/config/cc_ca_certs.py'
--- cloudinit/config/cc_ca_certs.py 2012-06-23 03:59:23 +0000
+++ cloudinit/config/cc_ca_certs.py 2012-10-28 02:29:21 +0000
@@ -22,6 +22,7 @@
22CA_CERT_FILENAME = "cloud-init-ca-certs.crt"22CA_CERT_FILENAME = "cloud-init-ca-certs.crt"
23CA_CERT_CONFIG = "/etc/ca-certificates.conf"23CA_CERT_CONFIG = "/etc/ca-certificates.conf"
24CA_CERT_SYSTEM_PATH = "/etc/ssl/certs/"24CA_CERT_SYSTEM_PATH = "/etc/ssl/certs/"
25CA_CERT_FULL_PATH = os.path.join(CA_CERT_PATH, CA_CERT_FILENAME)
2526
26distros = ['ubuntu', 'debian']27distros = ['ubuntu', 'debian']
2728
@@ -33,7 +34,7 @@
33 util.subp(["update-ca-certificates"], capture=False)34 util.subp(["update-ca-certificates"], capture=False)
3435
3536
36def add_ca_certs(paths, certs):37def add_ca_certs(certs):
37 """38 """
38 Adds certificates to the system. To actually apply the new certificates39 Adds certificates to the system. To actually apply the new certificates
39 you must also call L{update_ca_certs}.40 you must also call L{update_ca_certs}.
@@ -43,27 +44,24 @@
43 if certs:44 if certs:
44 # First ensure they are strings...45 # First ensure they are strings...
45 cert_file_contents = "\n".join([str(c) for c in certs])46 cert_file_contents = "\n".join([str(c) for c in certs])
46 cert_file_fullpath = os.path.join(CA_CERT_PATH, CA_CERT_FILENAME)47 util.write_file(CA_CERT_FULL_PATH, cert_file_contents, mode=0644)
47 cert_file_fullpath = paths.join(False, cert_file_fullpath)
48 util.write_file(cert_file_fullpath, cert_file_contents, mode=0644)
49 # Append cert filename to CA_CERT_CONFIG file.48 # Append cert filename to CA_CERT_CONFIG file.
50 util.write_file(paths.join(False, CA_CERT_CONFIG),49 util.write_file(CA_CERT_CONFIG, "\n%s" % CA_CERT_FILENAME, omode="ab")
51 "\n%s" % CA_CERT_FILENAME, omode="ab")50
5251
5352def remove_default_ca_certs():
54def remove_default_ca_certs(paths):
55 """53 """
56 Removes all default trusted CA certificates from the system. To actually54 Removes all default trusted CA certificates from the system. To actually
57 apply the change you must also call L{update_ca_certs}.55 apply the change you must also call L{update_ca_certs}.
58 """56 """
59 util.delete_dir_contents(paths.join(False, CA_CERT_PATH))57 util.delete_dir_contents(CA_CERT_PATH)
60 util.delete_dir_contents(paths.join(False, CA_CERT_SYSTEM_PATH))58 util.delete_dir_contents(CA_CERT_SYSTEM_PATH)
61 util.write_file(paths.join(False, CA_CERT_CONFIG), "", mode=0644)59 util.write_file(CA_CERT_CONFIG, "", mode=0644)
62 debconf_sel = "ca-certificates ca-certificates/trust_new_crts select no"60 debconf_sel = "ca-certificates ca-certificates/trust_new_crts select no"
63 util.subp(('debconf-set-selections', '-'), debconf_sel)61 util.subp(('debconf-set-selections', '-'), debconf_sel)
6462
6563
66def handle(name, cfg, cloud, log, _args):64def handle(name, cfg, _cloud, log, _args):
67 """65 """
68 Call to handle ca-cert sections in cloud-config file.66 Call to handle ca-cert sections in cloud-config file.
6967
@@ -85,14 +83,14 @@
85 # default trusted CA certs first.83 # default trusted CA certs first.
86 if ca_cert_cfg.get("remove-defaults", False):84 if ca_cert_cfg.get("remove-defaults", False):
87 log.debug("Removing default certificates")85 log.debug("Removing default certificates")
88 remove_default_ca_certs(cloud.paths)86 remove_default_ca_certs()
8987
90 # If we are given any new trusted CA certs to add, add them.88 # If we are given any new trusted CA certs to add, add them.
91 if "trusted" in ca_cert_cfg:89 if "trusted" in ca_cert_cfg:
92 trusted_certs = util.get_cfg_option_list(ca_cert_cfg, "trusted")90 trusted_certs = util.get_cfg_option_list(ca_cert_cfg, "trusted")
93 if trusted_certs:91 if trusted_certs:
94 log.debug("Adding %d certificates" % len(trusted_certs))92 log.debug("Adding %d certificates" % len(trusted_certs))
95 add_ca_certs(cloud.paths, trusted_certs)93 add_ca_certs(trusted_certs)
9694
97 # Update the system with the new cert configuration.95 # Update the system with the new cert configuration.
98 log.debug("Updating certificates")96 log.debug("Updating certificates")
9997
=== modified file 'cloudinit/config/cc_chef.py'
--- cloudinit/config/cc_chef.py 2012-06-23 06:26:50 +0000
+++ cloudinit/config/cc_chef.py 2012-10-28 02:29:21 +0000
@@ -26,6 +26,15 @@
2626
27RUBY_VERSION_DEFAULT = "1.8"27RUBY_VERSION_DEFAULT = "1.8"
2828
29CHEF_DIRS = [
30 '/etc/chef',
31 '/var/log/chef',
32 '/var/lib/chef',
33 '/var/cache/chef',
34 '/var/backups/chef',
35 '/var/run/chef',
36]
37
2938
30def handle(name, cfg, cloud, log, _args):39def handle(name, cfg, cloud, log, _args):
3140
@@ -37,24 +46,15 @@
37 chef_cfg = cfg['chef']46 chef_cfg = cfg['chef']
3847
39 # Ensure the chef directories we use exist48 # Ensure the chef directories we use exist
40 c_dirs = [49 for d in CHEF_DIRS:
41 '/etc/chef',50 util.ensure_dir(d)
42 '/var/log/chef',
43 '/var/lib/chef',
44 '/var/cache/chef',
45 '/var/backups/chef',
46 '/var/run/chef',
47 ]
48 for d in c_dirs:
49 util.ensure_dir(cloud.paths.join(False, d))
5051
51 # Set the validation key based on the presence of either 'validation_key'52 # Set the validation key based on the presence of either 'validation_key'
52 # or 'validation_cert'. In the case where both exist, 'validation_key'53 # or 'validation_cert'. In the case where both exist, 'validation_key'
53 # takes precedence54 # takes precedence
54 for key in ('validation_key', 'validation_cert'):55 for key in ('validation_key', 'validation_cert'):
55 if key in chef_cfg and chef_cfg[key]:56 if key in chef_cfg and chef_cfg[key]:
56 v_fn = cloud.paths.join(False, '/etc/chef/validation.pem')57 util.write_file('/etc/chef/validation.pem', chef_cfg[key])
57 util.write_file(v_fn, chef_cfg[key])
58 break58 break
5959
60 # Create the chef config from template60 # Create the chef config from template
@@ -68,8 +68,7 @@
68 '_default'),68 '_default'),
69 'validation_name': chef_cfg['validation_name']69 'validation_name': chef_cfg['validation_name']
70 }70 }
71 out_fn = cloud.paths.join(False, '/etc/chef/client.rb')71 templater.render_to_file(template_fn, '/etc/chef/client.rb', params)
72 templater.render_to_file(template_fn, out_fn, params)
73 else:72 else:
74 log.warn("No template found, not rendering to /etc/chef/client.rb")73 log.warn("No template found, not rendering to /etc/chef/client.rb")
7574
@@ -81,8 +80,7 @@
81 initial_attributes = chef_cfg['initial_attributes']80 initial_attributes = chef_cfg['initial_attributes']
82 for k in list(initial_attributes.keys()):81 for k in list(initial_attributes.keys()):
83 initial_json[k] = initial_attributes[k]82 initial_json[k] = initial_attributes[k]
84 firstboot_fn = cloud.paths.join(False, '/etc/chef/firstboot.json')83 util.write_file('/etc/chef/firstboot.json', json.dumps(initial_json))
85 util.write_file(firstboot_fn, json.dumps(initial_json))
8684
87 # If chef is not installed, we install chef based on 'install_type'85 # If chef is not installed, we install chef based on 'install_type'
88 if not os.path.isfile('/usr/bin/chef-client'):86 if not os.path.isfile('/usr/bin/chef-client'):
8987
=== modified file 'cloudinit/config/cc_landscape.py'
--- cloudinit/config/cc_landscape.py 2012-10-23 10:57:26 +0000
+++ cloudinit/config/cc_landscape.py 2012-10-28 02:29:21 +0000
@@ -66,22 +66,16 @@
6666
67 merge_data = [67 merge_data = [
68 LSC_BUILTIN_CFG,68 LSC_BUILTIN_CFG,
69 cloud.paths.join(True, LSC_CLIENT_CFG_FILE),69 LSC_CLIENT_CFG_FILE,
70 ls_cloudcfg,70 ls_cloudcfg,
71 ]71 ]
72 merged = merge_together(merge_data)72 merged = merge_together(merge_data)
73
74 lsc_client_fn = cloud.paths.join(False, LSC_CLIENT_CFG_FILE)
75 lsc_dir = cloud.paths.join(False, os.path.dirname(lsc_client_fn))
76 if not os.path.isdir(lsc_dir):
77 util.ensure_dir(lsc_dir)
78
79 contents = StringIO()73 contents = StringIO()
80 merged.write(contents)74 merged.write(contents)
81 contents.flush()
8275
83 util.write_file(lsc_client_fn, contents.getvalue())76 util.ensure_dir(os.path.dirname(LSC_CLIENT_CFG_FILE))
84 log.debug("Wrote landscape config file to %s", lsc_client_fn)77 util.write_file(LSC_CLIENT_CFG_FILE, contents.getvalue())
78 log.debug("Wrote landscape config file to %s", LSC_CLIENT_CFG_FILE)
8579
86 util.write_file(LS_DEFAULT_FILE, "RUN=1\n")80 util.write_file(LS_DEFAULT_FILE, "RUN=1\n")
87 util.subp(["service", "landscape-client", "restart"])81 util.subp(["service", "landscape-client", "restart"])
8882
=== modified file 'cloudinit/config/cc_mcollective.py'
--- cloudinit/config/cc_mcollective.py 2012-06-22 15:48:18 +0000
+++ cloudinit/config/cc_mcollective.py 2012-10-28 02:29:21 +0000
@@ -29,6 +29,7 @@
2929
30PUBCERT_FILE = "/etc/mcollective/ssl/server-public.pem"30PUBCERT_FILE = "/etc/mcollective/ssl/server-public.pem"
31PRICERT_FILE = "/etc/mcollective/ssl/server-private.pem"31PRICERT_FILE = "/etc/mcollective/ssl/server-private.pem"
32SERVER_CFG = '/etc/mcollective/server.cfg'
3233
3334
34def handle(name, cfg, cloud, log, _args):35def handle(name, cfg, cloud, log, _args):
@@ -48,26 +49,23 @@
48 if 'conf' in mcollective_cfg:49 if 'conf' in mcollective_cfg:
49 # Read server.cfg values from the50 # Read server.cfg values from the
50 # original file in order to be able to mix the rest up51 # original file in order to be able to mix the rest up
51 server_cfg_fn = cloud.paths.join(True, '/etc/mcollective/server.cfg')52 mcollective_config = ConfigObj(SERVER_CFG)
52 mcollective_config = ConfigObj(server_cfg_fn)
53 # See: http://tiny.cc/jh9agw53 # See: http://tiny.cc/jh9agw
54 for (cfg_name, cfg) in mcollective_cfg['conf'].iteritems():54 for (cfg_name, cfg) in mcollective_cfg['conf'].iteritems():
55 if cfg_name == 'public-cert':55 if cfg_name == 'public-cert':
56 pubcert_fn = cloud.paths.join(True, PUBCERT_FILE)56 util.write_file(PUBCERT_FILE, cfg, mode=0644)
57 util.write_file(pubcert_fn, cfg, mode=0644)57 mcollective_config['plugin.ssl_server_public'] = PUBCERT_FILE
58 mcollective_config['plugin.ssl_server_public'] = pubcert_fn
59 mcollective_config['securityprovider'] = 'ssl'58 mcollective_config['securityprovider'] = 'ssl'
60 elif cfg_name == 'private-cert':59 elif cfg_name == 'private-cert':
61 pricert_fn = cloud.paths.join(True, PRICERT_FILE)60 util.write_file(PRICERT_FILE, cfg, mode=0600)
62 util.write_file(pricert_fn, cfg, mode=0600)61 mcollective_config['plugin.ssl_server_private'] = PRICERT_FILE
63 mcollective_config['plugin.ssl_server_private'] = pricert_fn
64 mcollective_config['securityprovider'] = 'ssl'62 mcollective_config['securityprovider'] = 'ssl'
65 else:63 else:
66 if isinstance(cfg, (basestring, str)):64 if isinstance(cfg, (basestring, str)):
67 # Just set it in the 'main' section65 # Just set it in the 'main' section
68 mcollective_config[cfg_name] = cfg66 mcollective_config[cfg_name] = cfg
69 elif isinstance(cfg, (dict)):67 elif isinstance(cfg, (dict)):
70 # Iterate throug the config items, create a section68 # Iterate through the config items, create a section
71 # if it is needed and then add/or create items as needed69 # if it is needed and then add/or create items as needed
72 if cfg_name not in mcollective_config.sections:70 if cfg_name not in mcollective_config.sections:
73 mcollective_config[cfg_name] = {}71 mcollective_config[cfg_name] = {}
@@ -78,14 +76,12 @@
78 mcollective_config[cfg_name] = str(cfg)76 mcollective_config[cfg_name] = str(cfg)
79 # We got all our config as wanted we'll rename77 # We got all our config as wanted we'll rename
80 # the previous server.cfg and create our new one78 # the previous server.cfg and create our new one
81 old_fn = cloud.paths.join(False, '/etc/mcollective/server.cfg.old')79 util.rename(SERVER_CFG, "%s.old" % (SERVER_CFG))
82 util.rename(server_cfg_fn, old_fn)
83 # Now we got the whole file, write to disk...80 # Now we got the whole file, write to disk...
84 contents = StringIO()81 contents = StringIO()
85 mcollective_config.write(contents)82 mcollective_config.write(contents)
86 contents = contents.getvalue()83 contents = contents.getvalue()
87 server_cfg_rw = cloud.paths.join(False, '/etc/mcollective/server.cfg')84 util.write_file(SERVER_CFG, contents, mode=0644)
88 util.write_file(server_cfg_rw, contents, mode=0644)
8985
90 # Start mcollective86 # Start mcollective
91 util.subp(['service', 'mcollective', 'start'], capture=False)87 util.subp(['service', 'mcollective', 'start'], capture=False)
9288
=== modified file 'cloudinit/config/cc_mounts.py'
--- cloudinit/config/cc_mounts.py 2012-09-06 18:52:53 +0000
+++ cloudinit/config/cc_mounts.py 2012-10-28 02:29:21 +0000
@@ -28,6 +28,7 @@
28SHORTNAME_FILTER = r"^[x]{0,1}[shv]d[a-z][0-9]*$"28SHORTNAME_FILTER = r"^[x]{0,1}[shv]d[a-z][0-9]*$"
29SHORTNAME = re.compile(SHORTNAME_FILTER)29SHORTNAME = re.compile(SHORTNAME_FILTER)
30WS = re.compile("[%s]+" % (whitespace))30WS = re.compile("[%s]+" % (whitespace))
31FSTAB_PATH = "/etc/fstab"
3132
3233
33def is_mdname(name):34def is_mdname(name):
@@ -167,8 +168,7 @@
167 cc_lines.append('\t'.join(line))168 cc_lines.append('\t'.join(line))
168169
169 fstab_lines = []170 fstab_lines = []
170 fstab = util.load_file(cloud.paths.join(True, "/etc/fstab"))171 for line in util.load_file(FSTAB_PATH).splitlines():
171 for line in fstab.splitlines():
172 try:172 try:
173 toks = WS.split(line)173 toks = WS.split(line)
174 if toks[3].find(comment) != -1:174 if toks[3].find(comment) != -1:
@@ -179,7 +179,7 @@
179179
180 fstab_lines.extend(cc_lines)180 fstab_lines.extend(cc_lines)
181 contents = "%s\n" % ('\n'.join(fstab_lines))181 contents = "%s\n" % ('\n'.join(fstab_lines))
182 util.write_file(cloud.paths.join(False, "/etc/fstab"), contents)182 util.write_file(FSTAB_PATH, contents)
183183
184 if needswap:184 if needswap:
185 try:185 try:
@@ -188,9 +188,8 @@
188 util.logexc(log, "Activating swap via 'swapon -a' failed")188 util.logexc(log, "Activating swap via 'swapon -a' failed")
189189
190 for d in dirs:190 for d in dirs:
191 real_dir = cloud.paths.join(False, d)
192 try:191 try:
193 util.ensure_dir(real_dir)192 util.ensure_dir(d)
194 except:193 except:
195 util.logexc(log, "Failed to make '%s' config-mount", d)194 util.logexc(log, "Failed to make '%s' config-mount", d)
196195
197196
=== modified file 'cloudinit/config/cc_phone_home.py'
--- cloudinit/config/cc_phone_home.py 2012-06-23 05:04:37 +0000
+++ cloudinit/config/cc_phone_home.py 2012-10-28 02:29:21 +0000
@@ -84,10 +84,10 @@
8484
85 for (n, path) in pubkeys.iteritems():85 for (n, path) in pubkeys.iteritems():
86 try:86 try:
87 all_keys[n] = util.load_file(cloud.paths.join(True, path))87 all_keys[n] = util.load_file(path)
88 except:88 except:
89 util.logexc(log, ("%s: failed to open, can not"89 util.logexc(log, ("%s: failed to open, can not"
90 " phone home that data"), path)90 " phone home that data!"), path)
9191
92 submit_keys = {}92 submit_keys = {}
93 for k in post_list:93 for k in post_list:
9494
=== modified file 'cloudinit/config/cc_puppet.py'
--- cloudinit/config/cc_puppet.py 2012-08-22 18:12:32 +0000
+++ cloudinit/config/cc_puppet.py 2012-10-28 02:29:21 +0000
@@ -21,12 +21,32 @@
21from StringIO import StringIO21from StringIO import StringIO
2222
23import os23import os
24import pwd
25import socket24import socket
2625
27from cloudinit import helpers26from cloudinit import helpers
28from cloudinit import util27from cloudinit import util
2928
29PUPPET_CONF_PATH = '/etc/puppet/puppet.conf'
30PUPPET_SSL_CERT_DIR = '/var/lib/puppet/ssl/certs/'
31PUPPET_SSL_DIR = '/var/lib/puppet/ssl'
32PUPPET_SSL_CERT_PATH = '/var/lib/puppet/ssl/certs/ca.pem'
33
34
35def _autostart_puppet(log):
36 # Set puppet to automatically start
37 if os.path.exists('/etc/default/puppet'):
38 util.subp(['sed', '-i',
39 '-e', 's/^START=.*/START=yes/',
40 '/etc/default/puppet'], capture=False)
41 elif os.path.exists('/bin/systemctl'):
42 util.subp(['/bin/systemctl', 'enable', 'puppet.service'],
43 capture=False)
44 elif os.path.exists('/sbin/chkconfig'):
45 util.subp(['/sbin/chkconfig', 'puppet', 'on'], capture=False)
46 else:
47 log.warn(("Sorry we do not know how to enable"
48 " puppet services on this system"))
49
3050
31def handle(name, cfg, cloud, log, _args):51def handle(name, cfg, cloud, log, _args):
32 # If there isn't a puppet key in the configuration don't do anything52 # If there isn't a puppet key in the configuration don't do anything
@@ -43,8 +63,7 @@
43 # ... and then update the puppet configuration63 # ... and then update the puppet configuration
44 if 'conf' in puppet_cfg:64 if 'conf' in puppet_cfg:
45 # Add all sections from the conf object to puppet.conf65 # Add all sections from the conf object to puppet.conf
46 puppet_conf_fn = cloud.paths.join(True, '/etc/puppet/puppet.conf')66 contents = util.load_file(PUPPET_CONF_PATH)
47 contents = util.load_file(puppet_conf_fn)
48 # Create object for reading puppet.conf values67 # Create object for reading puppet.conf values
49 puppet_config = helpers.DefaultingConfigParser()68 puppet_config = helpers.DefaultingConfigParser()
50 # Read puppet.conf values from original file in order to be able to69 # Read puppet.conf values from original file in order to be able to
@@ -53,28 +72,19 @@
53 cleaned_lines = [i.lstrip() for i in contents.splitlines()]72 cleaned_lines = [i.lstrip() for i in contents.splitlines()]
54 cleaned_contents = '\n'.join(cleaned_lines)73 cleaned_contents = '\n'.join(cleaned_lines)
55 puppet_config.readfp(StringIO(cleaned_contents),74 puppet_config.readfp(StringIO(cleaned_contents),
56 filename=puppet_conf_fn)75 filename=PUPPET_CONF_PATH)
57 for (cfg_name, cfg) in puppet_cfg['conf'].iteritems():76 for (cfg_name, cfg) in puppet_cfg['conf'].iteritems():
58 # Cert configuration is a special case77 # Cert configuration is a special case
59 # Dump the puppet master ca certificate in the correct place78 # Dump the puppet master ca certificate in the correct place
60 if cfg_name == 'ca_cert':79 if cfg_name == 'ca_cert':
61 # Puppet ssl sub-directory isn't created yet80 # Puppet ssl sub-directory isn't created yet
62 # Create it with the proper permissions and ownership81 # Create it with the proper permissions and ownership
63 pp_ssl_dir = cloud.paths.join(False, '/var/lib/puppet/ssl')82 util.ensure_dir(PUPPET_SSL_DIR, 0771)
64 util.ensure_dir(pp_ssl_dir, 0771)83 util.chownbyname(PUPPET_SSL_DIR, 'puppet', 'root')
65 util.chownbyid(pp_ssl_dir,84 util.ensure_dir(PUPPET_SSL_CERT_DIR)
66 pwd.getpwnam('puppet').pw_uid, 0)85 util.chownbyname(PUPPET_SSL_CERT_DIR, 'puppet', 'root')
67 pp_ssl_certs = cloud.paths.join(False,86 util.write_file(PUPPET_SSL_CERT_PATH, str(cfg))
68 '/var/lib/puppet/ssl/certs/')87 util.chownbyname(PUPPET_SSL_CERT_PATH, 'puppet', 'root')
69 util.ensure_dir(pp_ssl_certs)
70 util.chownbyid(pp_ssl_certs,
71 pwd.getpwnam('puppet').pw_uid, 0)
72 pp_ssl_ca_certs = cloud.paths.join(False,
73 ('/var/lib/puppet/'
74 'ssl/certs/ca.pem'))
75 util.write_file(pp_ssl_ca_certs, cfg)
76 util.chownbyid(pp_ssl_ca_certs,
77 pwd.getpwnam('puppet').pw_uid, 0)
78 else:88 else:
79 # Iterate throug the config items, we'll use ConfigParser.set89 # Iterate throug the config items, we'll use ConfigParser.set
80 # to overwrite or create new items as needed90 # to overwrite or create new items as needed
@@ -90,25 +100,11 @@
90 puppet_config.set(cfg_name, o, v)100 puppet_config.set(cfg_name, o, v)
91 # We got all our config as wanted we'll rename101 # We got all our config as wanted we'll rename
92 # the previous puppet.conf and create our new one102 # the previous puppet.conf and create our new one
93 conf_old_fn = cloud.paths.join(False,103 util.rename(PUPPET_CONF_PATH, "%s.old" % (PUPPET_CONF_PATH))
94 '/etc/puppet/puppet.conf.old')104 util.write_file(PUPPET_CONF_PATH, puppet_config.stringify())
95 util.rename(puppet_conf_fn, conf_old_fn)
96 puppet_conf_rw = cloud.paths.join(False, '/etc/puppet/puppet.conf')
97 util.write_file(puppet_conf_rw, puppet_config.stringify())
98105
99 # Set puppet to automatically start106 # Set it up so it autostarts
100 if os.path.exists('/etc/default/puppet'):107 _autostart_puppet(log)
101 util.subp(['sed', '-i',
102 '-e', 's/^START=.*/START=yes/',
103 '/etc/default/puppet'], capture=False)
104 elif os.path.exists('/bin/systemctl'):
105 util.subp(['/bin/systemctl', 'enable', 'puppet.service'],
106 capture=False)
107 elif os.path.exists('/sbin/chkconfig'):
108 util.subp(['/sbin/chkconfig', 'puppet', 'on'], capture=False)
109 else:
110 log.warn(("Sorry we do not know how to enable"
111 " puppet services on this system"))
112108
113 # Start puppetd109 # Start puppetd
114 util.subp(['service', 'puppet', 'start'], capture=False)110 util.subp(['service', 'puppet', 'start'], capture=False)
115111
=== modified file 'cloudinit/config/cc_resizefs.py'
--- cloudinit/config/cc_resizefs.py 2012-08-22 18:12:32 +0000
+++ cloudinit/config/cc_resizefs.py 2012-10-28 02:29:21 +0000
@@ -62,7 +62,7 @@
62 raise62 raise
6363
6464
65def handle(name, cfg, cloud, log, args):65def handle(name, cfg, _cloud, log, args):
66 if len(args) != 0:66 if len(args) != 0:
67 resize_root = args[0]67 resize_root = args[0]
68 else:68 else:
@@ -74,11 +74,10 @@
7474
75 # TODO(harlowja) is the directory ok to be used??75 # TODO(harlowja) is the directory ok to be used??
76 resize_root_d = util.get_cfg_option_str(cfg, "resize_rootfs_tmp", "/run")76 resize_root_d = util.get_cfg_option_str(cfg, "resize_rootfs_tmp", "/run")
77 resize_root_d = cloud.paths.join(False, resize_root_d)
78 util.ensure_dir(resize_root_d)77 util.ensure_dir(resize_root_d)
7978
80 # TODO(harlowja): allow what is to be resized to be configurable??79 # TODO(harlowja): allow what is to be resized to be configurable??
81 resize_what = cloud.paths.join(False, "/")80 resize_what = "/"
82 with util.ExtendedTemporaryFile(prefix="cloudinit.resizefs.",81 with util.ExtendedTemporaryFile(prefix="cloudinit.resizefs.",
83 dir=resize_root_d, delete=True) as tfh:82 dir=resize_root_d, delete=True) as tfh:
84 devpth = tfh.name83 devpth = tfh.name
8584
=== modified file 'cloudinit/config/cc_rsyslog.py'
--- cloudinit/config/cc_rsyslog.py 2012-06-21 16:12:16 +0000
+++ cloudinit/config/cc_rsyslog.py 2012-10-28 02:29:21 +0000
@@ -71,8 +71,7 @@
7171
72 try:72 try:
73 contents = "%s\n" % (content)73 contents = "%s\n" % (content)
74 util.write_file(cloud.paths.join(False, filename),74 util.write_file(filename, contents, omode=omode)
75 contents, omode=omode)
76 except Exception:75 except Exception:
77 util.logexc(log, "Failed to write to %s", filename)76 util.logexc(log, "Failed to write to %s", filename)
7877
7978
=== modified file 'cloudinit/config/cc_runcmd.py'
--- cloudinit/config/cc_runcmd.py 2012-06-21 16:12:16 +0000
+++ cloudinit/config/cc_runcmd.py 2012-10-28 02:29:21 +0000
@@ -33,6 +33,6 @@
33 cmd = cfg["runcmd"]33 cmd = cfg["runcmd"]
34 try:34 try:
35 content = util.shellify(cmd)35 content = util.shellify(cmd)
36 util.write_file(cloud.paths.join(False, out_fn), content, 0700)36 util.write_file(out_fn, content, 0700)
37 except:37 except:
38 util.logexc(log, "Failed to shellify %s into file %s", cmd, out_fn)38 util.logexc(log, "Failed to shellify %s into file %s", cmd, out_fn)
3939
=== modified file 'cloudinit/config/cc_salt_minion.py'
--- cloudinit/config/cc_salt_minion.py 2012-09-28 13:03:54 +0000
+++ cloudinit/config/cc_salt_minion.py 2012-10-28 02:29:21 +0000
@@ -34,8 +34,7 @@
34 cloud.distro.install_packages(["salt-minion"])34 cloud.distro.install_packages(["salt-minion"])
3535
36 # Ensure we can configure files at the right dir36 # Ensure we can configure files at the right dir
37 config_dir = cloud.paths.join(False, salt_cfg.get("config_dir",37 config_dir = salt_cfg.get("config_dir", '/etc/salt')
38 '/etc/salt'))
39 util.ensure_dir(config_dir)38 util.ensure_dir(config_dir)
4039
41 # ... and then update the salt configuration40 # ... and then update the salt configuration
@@ -47,8 +46,7 @@
4746
48 # ... copy the key pair if specified47 # ... copy the key pair if specified
49 if 'public_key' in salt_cfg and 'private_key' in salt_cfg:48 if 'public_key' in salt_cfg and 'private_key' in salt_cfg:
50 pki_dir = cloud.paths.join(False, salt_cfg.get('pki_dir',49 pki_dir = salt_cfg.get('pki_dir', '/etc/salt/pki')
51 '/etc/salt/pki'))
52 with util.umask(077):50 with util.umask(077):
53 util.ensure_dir(pki_dir)51 util.ensure_dir(pki_dir)
54 pub_name = os.path.join(pki_dir, 'minion.pub')52 pub_name = os.path.join(pki_dir, 'minion.pub')
5553
=== modified file 'cloudinit/config/cc_set_passwords.py'
--- cloudinit/config/cc_set_passwords.py 2012-09-28 21:06:22 +0000
+++ cloudinit/config/cc_set_passwords.py 2012-10-28 02:29:21 +0000
@@ -114,8 +114,7 @@
114 replaced_auth = False114 replaced_auth = False
115115
116 # See: man sshd_config116 # See: man sshd_config
117 conf_fn = cloud.paths.join(True, ssh_util.DEF_SSHD_CFG)117 old_lines = ssh_util.parse_ssh_config(ssh_util.DEF_SSHD_CFG)
118 old_lines = ssh_util.parse_ssh_config(conf_fn)
119 new_lines = []118 new_lines = []
120 i = 0119 i = 0
121 for (i, line) in enumerate(old_lines):120 for (i, line) in enumerate(old_lines):
@@ -134,8 +133,7 @@
134 pw_auth))133 pw_auth))
135134
136 lines = [str(e) for e in new_lines]135 lines = [str(e) for e in new_lines]
137 ssh_rw_fn = cloud.paths.join(False, ssh_util.DEF_SSHD_CFG)136 util.write_file(ssh_util.DEF_SSHD_CFG, "\n".join(lines))
138 util.write_file(ssh_rw_fn, "\n".join(lines))
139137
140 try:138 try:
141 cmd = ['service']139 cmd = ['service']
142140
=== modified file 'cloudinit/config/cc_ssh.py'
--- cloudinit/config/cc_ssh.py 2012-09-28 21:06:22 +0000
+++ cloudinit/config/cc_ssh.py 2012-10-28 02:29:21 +0000
@@ -59,7 +59,7 @@
5959
60 # remove the static keys from the pristine image60 # remove the static keys from the pristine image
61 if cfg.get("ssh_deletekeys", True):61 if cfg.get("ssh_deletekeys", True):
62 key_pth = cloud.paths.join(False, "/etc/ssh/", "ssh_host_*key*")62 key_pth = os.path.join("/etc/ssh/", "ssh_host_*key*")
63 for f in glob.glob(key_pth):63 for f in glob.glob(key_pth):
64 try:64 try:
65 util.del_file(f)65 util.del_file(f)
@@ -72,8 +72,7 @@
72 if key in KEY_2_FILE:72 if key in KEY_2_FILE:
73 tgt_fn = KEY_2_FILE[key][0]73 tgt_fn = KEY_2_FILE[key][0]
74 tgt_perms = KEY_2_FILE[key][1]74 tgt_perms = KEY_2_FILE[key][1]
75 util.write_file(cloud.paths.join(False, tgt_fn),75 util.write_file(tgt_fn, val, tgt_perms)
76 val, tgt_perms)
7776
78 for (priv, pub) in PRIV_2_PUB.iteritems():77 for (priv, pub) in PRIV_2_PUB.iteritems():
79 if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']:78 if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']:
@@ -94,7 +93,7 @@
94 'ssh_genkeytypes',93 'ssh_genkeytypes',
95 GENERATE_KEY_NAMES)94 GENERATE_KEY_NAMES)
96 for keytype in genkeys:95 for keytype in genkeys:
97 keyfile = cloud.paths.join(False, KEY_FILE_TPL % (keytype))96 keyfile = KEY_FILE_TPL % (keytype)
98 util.ensure_dir(os.path.dirname(keyfile))97 util.ensure_dir(os.path.dirname(keyfile))
99 if not os.path.exists(keyfile):98 if not os.path.exists(keyfile):
100 cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile]99 cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile]
@@ -118,17 +117,16 @@
118 cfgkeys = cfg["ssh_authorized_keys"]117 cfgkeys = cfg["ssh_authorized_keys"]
119 keys.extend(cfgkeys)118 keys.extend(cfgkeys)
120119
121 apply_credentials(keys, user, cloud.paths,120 apply_credentials(keys, user, disable_root, disable_root_opts)
122 disable_root, disable_root_opts)
123 except:121 except:
124 util.logexc(log, "Applying ssh credentials failed!")122 util.logexc(log, "Applying ssh credentials failed!")
125123
126124
127def apply_credentials(keys, user, paths, disable_root, disable_root_opts):125def apply_credentials(keys, user, disable_root, disable_root_opts):
128126
129 keys = set(keys)127 keys = set(keys)
130 if user:128 if user:
131 ssh_util.setup_user_keys(keys, user, '', paths)129 ssh_util.setup_user_keys(keys, user, '')
132130
133 if disable_root:131 if disable_root:
134 if not user:132 if not user:
@@ -137,4 +135,4 @@
137 else:135 else:
138 key_prefix = ''136 key_prefix = ''
139137
140 ssh_util.setup_user_keys(keys, 'root', key_prefix, paths)138 ssh_util.setup_user_keys(keys, 'root', key_prefix)
141139
=== modified file 'cloudinit/config/cc_ssh_authkey_fingerprints.py'
--- cloudinit/config/cc_ssh_authkey_fingerprints.py 2012-09-28 21:21:02 +0000
+++ cloudinit/config/cc_ssh_authkey_fingerprints.py 2012-10-28 02:29:21 +0000
@@ -97,9 +97,8 @@
97 "logging of ssh fingerprints disabled"), name)97 "logging of ssh fingerprints disabled"), name)
9898
99 hash_meth = util.get_cfg_option_str(cfg, "authkey_hash", "md5")99 hash_meth = util.get_cfg_option_str(cfg, "authkey_hash", "md5")
100 extract_func = ssh_util.extract_authorized_keys
101 (users, _groups) = ds.normalize_users_groups(cfg, cloud.distro)100 (users, _groups) = ds.normalize_users_groups(cfg, cloud.distro)
102 for (user_name, _cfg) in users.items():101 for (user_name, _cfg) in users.items():
103 (auth_key_fn, auth_key_entries) = extract_func(user_name, cloud.paths)102 (key_fn, key_entries) = ssh_util.extract_authorized_keys(user_name)
104 _pprint_key_entries(user_name, auth_key_fn,103 _pprint_key_entries(user_name, key_fn,
105 auth_key_entries, hash_meth)104 key_entries, hash_meth)
106105
=== modified file 'cloudinit/config/cc_update_etc_hosts.py'
--- cloudinit/config/cc_update_etc_hosts.py 2012-08-22 18:12:32 +0000
+++ cloudinit/config/cc_update_etc_hosts.py 2012-10-28 02:29:21 +0000
@@ -42,8 +42,7 @@
42 raise RuntimeError(("No hosts template could be"42 raise RuntimeError(("No hosts template could be"
43 " found for distro %s") % (cloud.distro.name))43 " found for distro %s") % (cloud.distro.name))
4444
45 out_fn = cloud.paths.join(False, '/etc/hosts')45 templater.render_to_file(tpl_fn_name, '/etc/hosts',
46 templater.render_to_file(tpl_fn_name, out_fn,
47 {'hostname': hostname, 'fqdn': fqdn})46 {'hostname': hostname, 'fqdn': fqdn})
4847
49 elif manage_hosts == "localhost":48 elif manage_hosts == "localhost":
5049
=== modified file 'cloudinit/distros/__init__.py'
--- cloudinit/distros/__init__.py 2012-10-23 16:58:32 +0000
+++ cloudinit/distros/__init__.py 2012-10-28 02:29:21 +0000
@@ -122,8 +122,7 @@
122 new_etchosts = StringIO()122 new_etchosts = StringIO()
123 need_write = False123 need_write = False
124 need_change = True124 need_change = True
125 hosts_ro_fn = self._paths.join(True, "/etc/hosts")125 for line in util.load_file("/etc/hosts").splitlines():
126 for line in util.load_file(hosts_ro_fn).splitlines():
127 if line.strip().startswith(header):126 if line.strip().startswith(header):
128 continue127 continue
129 if not line.strip() or line.strip().startswith("#"):128 if not line.strip() or line.strip().startswith("#"):
@@ -147,8 +146,7 @@
147 need_write = True146 need_write = True
148 if need_write:147 if need_write:
149 contents = new_etchosts.getvalue()148 contents = new_etchosts.getvalue()
150 util.write_file(self._paths.join(False, "/etc/hosts"),149 util.write_file("/etc/hosts", contents, mode=0644)
151 contents, mode=0644)
152150
153 def _bring_up_interface(self, device_name):151 def _bring_up_interface(self, device_name):
154 cmd = ['ifup', device_name]152 cmd = ['ifup', device_name]
@@ -262,7 +260,7 @@
262 # Import SSH keys260 # Import SSH keys
263 if 'ssh_authorized_keys' in kwargs:261 if 'ssh_authorized_keys' in kwargs:
264 keys = set(kwargs['ssh_authorized_keys']) or []262 keys = set(kwargs['ssh_authorized_keys']) or []
265 ssh_util.setup_user_keys(keys, name, None, self._paths)263 ssh_util.setup_user_keys(keys, name, key_prefix=None)
266264
267 return True265 return True
268266
269267
=== modified file 'cloudinit/distros/debian.py'
--- cloudinit/distros/debian.py 2012-09-20 22:55:52 +0000
+++ cloudinit/distros/debian.py 2012-10-28 02:29:21 +0000
@@ -43,7 +43,7 @@
4343
44 def apply_locale(self, locale, out_fn=None):44 def apply_locale(self, locale, out_fn=None):
45 if not out_fn:45 if not out_fn:
46 out_fn = self._paths.join(False, '/etc/default/locale')46 out_fn = '/etc/default/locale'
47 util.subp(['locale-gen', locale], capture=False)47 util.subp(['locale-gen', locale], capture=False)
48 util.subp(['update-locale', locale], capture=False)48 util.subp(['update-locale', locale], capture=False)
49 lines = ["# Created by cloud-init", 'LANG="%s"' % (locale), ""]49 lines = ["# Created by cloud-init", 'LANG="%s"' % (locale), ""]
@@ -54,8 +54,7 @@
54 self.package_command('install', pkglist)54 self.package_command('install', pkglist)
5555
56 def _write_network(self, settings):56 def _write_network(self, settings):
57 net_fn = self._paths.join(False, "/etc/network/interfaces")57 util.write_file("/etc/network/interfaces", settings)
58 util.write_file(net_fn, settings)
59 return ['all']58 return ['all']
6059
61 def _bring_up_interfaces(self, device_names):60 def _bring_up_interfaces(self, device_names):
@@ -69,12 +68,9 @@
69 return distros.Distro._bring_up_interfaces(self, device_names)68 return distros.Distro._bring_up_interfaces(self, device_names)
7069
71 def set_hostname(self, hostname):70 def set_hostname(self, hostname):
72 out_fn = self._paths.join(False, "/etc/hostname")71 self._write_hostname(hostname, "/etc/hostname")
73 self._write_hostname(hostname, out_fn)72 LOG.debug("Setting hostname to %s", hostname)
74 if out_fn == '/etc/hostname':73 util.subp(['hostname', hostname])
75 # Only do this if we are running in non-adjusted root mode
76 LOG.debug("Setting hostname to %s", hostname)
77 util.subp(['hostname', hostname])
7874
79 def _write_hostname(self, hostname, out_fn):75 def _write_hostname(self, hostname, out_fn):
80 # "" gives trailing newline.76 # "" gives trailing newline.
@@ -82,16 +78,14 @@
8278
83 def update_hostname(self, hostname, prev_fn):79 def update_hostname(self, hostname, prev_fn):
84 hostname_prev = self._read_hostname(prev_fn)80 hostname_prev = self._read_hostname(prev_fn)
85 read_fn = self._paths.join(True, "/etc/hostname")81 hostname_in_etc = self._read_hostname("/etc/hostname")
86 hostname_in_etc = self._read_hostname(read_fn)
87 update_files = []82 update_files = []
88 if not hostname_prev or hostname_prev != hostname:83 if not hostname_prev or hostname_prev != hostname:
89 update_files.append(prev_fn)84 update_files.append(prev_fn)
90 if (not hostname_in_etc or85 if (not hostname_in_etc or
91 (hostname_in_etc == hostname_prev and86 (hostname_in_etc == hostname_prev and
92 hostname_in_etc != hostname)):87 hostname_in_etc != hostname)):
93 write_fn = self._paths.join(False, "/etc/hostname")88 update_files.append("/etc/hostname")
94 update_files.append(write_fn)
95 for fn in update_files:89 for fn in update_files:
96 try:90 try:
97 self._write_hostname(hostname, fn)91 self._write_hostname(hostname, fn)
@@ -103,7 +97,6 @@
103 LOG.debug(("%s differs from /etc/hostname."97 LOG.debug(("%s differs from /etc/hostname."
104 " Assuming user maintained hostname."), prev_fn)98 " Assuming user maintained hostname."), prev_fn)
105 if "/etc/hostname" in update_files:99 if "/etc/hostname" in update_files:
106 # Only do this if we are running in non-adjusted root mode
107 LOG.debug("Setting hostname to %s", hostname)100 LOG.debug("Setting hostname to %s", hostname)
108 util.subp(['hostname', hostname])101 util.subp(['hostname', hostname])
109102
@@ -130,9 +123,8 @@
130 " no file found at %s") % (tz, tz_file))123 " no file found at %s") % (tz, tz_file))
131 # "" provides trailing newline during join124 # "" provides trailing newline during join
132 tz_lines = ["# Created by cloud-init", str(tz), ""]125 tz_lines = ["# Created by cloud-init", str(tz), ""]
133 tz_fn = self._paths.join(False, "/etc/timezone")126 util.write_file("/etc/timezone", "\n".join(tz_lines))
134 util.write_file(tz_fn, "\n".join(tz_lines))127 util.copy(tz_file, "/etc/localtime")
135 util.copy(tz_file, self._paths.join(False, "/etc/localtime"))
136128
137 def package_command(self, command, args=None):129 def package_command(self, command, args=None):
138 e = os.environ.copy()130 e = os.environ.copy()
139131
=== modified file 'cloudinit/helpers.py'
--- cloudinit/helpers.py 2012-07-10 03:34:10 +0000
+++ cloudinit/helpers.py 2012-10-28 02:29:21 +0000
@@ -302,14 +302,10 @@
302 def __init__(self, path_cfgs, ds=None):302 def __init__(self, path_cfgs, ds=None):
303 self.cfgs = path_cfgs303 self.cfgs = path_cfgs
304 # Populate all the initial paths304 # Populate all the initial paths
305 self.cloud_dir = self.join(False,305 self.cloud_dir = path_cfgs.get('cloud_dir', '/var/lib/cloud')
306 path_cfgs.get('cloud_dir',
307 '/var/lib/cloud'))
308 self.instance_link = os.path.join(self.cloud_dir, 'instance')306 self.instance_link = os.path.join(self.cloud_dir, 'instance')
309 self.boot_finished = os.path.join(self.instance_link, "boot-finished")307 self.boot_finished = os.path.join(self.instance_link, "boot-finished")
310 self.upstart_conf_d = path_cfgs.get('upstart_dir')308 self.upstart_conf_d = path_cfgs.get('upstart_dir')
311 if self.upstart_conf_d:
312 self.upstart_conf_d = self.join(False, self.upstart_conf_d)
313 self.seed_dir = os.path.join(self.cloud_dir, 'seed')309 self.seed_dir = os.path.join(self.cloud_dir, 'seed')
314 # This one isn't joined, since it should just be read-only310 # This one isn't joined, since it should just be read-only
315 template_dir = path_cfgs.get('templates_dir', '/etc/cloud/templates/')311 template_dir = path_cfgs.get('templates_dir', '/etc/cloud/templates/')
@@ -328,29 +324,6 @@
328 # Set when a datasource becomes active324 # Set when a datasource becomes active
329 self.datasource = ds325 self.datasource = ds
330326
331 # joins the paths but also appends a read
332 # or write root if available
333 def join(self, read_only, *paths):
334 if read_only:
335 root = self.cfgs.get('read_root')
336 else:
337 root = self.cfgs.get('write_root')
338 if not paths:
339 return root
340 if len(paths) > 1:
341 joined = os.path.join(*paths)
342 else:
343 joined = paths[0]
344 if root:
345 pre_joined = joined
346 # Need to remove any starting '/' since this
347 # will confuse os.path.join
348 joined = joined.lstrip("/")
349 joined = os.path.join(root, joined)
350 LOG.debug("Translated %s to adjusted path %s (read-only=%s)",
351 pre_joined, joined, read_only)
352 return joined
353
354 # get_ipath_cur: get the current instance path for an item327 # get_ipath_cur: get the current instance path for an item
355 def get_ipath_cur(self, name=None):328 def get_ipath_cur(self, name=None):
356 ipath = self.instance_link329 ipath = self.instance_link
357330
=== modified file 'cloudinit/sources/__init__.py'
--- cloudinit/sources/__init__.py 2012-10-05 20:38:54 +0000
+++ cloudinit/sources/__init__.py 2012-10-28 02:29:21 +0000
@@ -20,8 +20,6 @@
20# You should have received a copy of the GNU General Public License20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.21# along with this program. If not, see <http://www.gnu.org/licenses/>.
2222
23from email.mime.multipart import MIMEMultipart
24
25import abc23import abc
26import os24import os
2725
2826
=== modified file 'cloudinit/ssh_util.py'
--- cloudinit/ssh_util.py 2012-08-19 04:15:52 +0000
+++ cloudinit/ssh_util.py 2012-10-28 02:29:21 +0000
@@ -212,17 +212,15 @@
212 return '\n'.join(lines)212 return '\n'.join(lines)
213213
214214
215def users_ssh_info(username, paths):215def users_ssh_info(username):
216 pw_ent = pwd.getpwnam(username)216 pw_ent = pwd.getpwnam(username)
217 if not pw_ent:217 if not pw_ent or not pw_ent.pw_dir:
218 raise RuntimeError("Unable to get ssh info for user %r" % (username))218 raise RuntimeError("Unable to get ssh info for user %r" % (username))
219 ssh_dir = paths.join(False, os.path.join(pw_ent.pw_dir, '.ssh'))219 return (os.path.join(pw_ent.pw_dir, '.ssh'), pw_ent)
220 return (ssh_dir, pw_ent)220
221221
222222def extract_authorized_keys(username):
223def extract_authorized_keys(username, paths):223 (ssh_dir, pw_ent) = users_ssh_info(username)
224 (ssh_dir, pw_ent) = users_ssh_info(username, paths)
225 sshd_conf_fn = paths.join(True, DEF_SSHD_CFG)
226 auth_key_fn = None224 auth_key_fn = None
227 with util.SeLinuxGuard(ssh_dir, recursive=True):225 with util.SeLinuxGuard(ssh_dir, recursive=True):
228 try:226 try:
@@ -231,7 +229,7 @@
231 # The following tokens are defined: %% is replaced by a literal229 # The following tokens are defined: %% is replaced by a literal
232 # '%', %h is replaced by the home directory of the user being230 # '%', %h is replaced by the home directory of the user being
233 # authenticated and %u is replaced by the username of that user.231 # authenticated and %u is replaced by the username of that user.
234 ssh_cfg = parse_ssh_config_map(sshd_conf_fn)232 ssh_cfg = parse_ssh_config_map(DEF_SSHD_CFG)
235 auth_key_fn = ssh_cfg.get("authorizedkeysfile", '').strip()233 auth_key_fn = ssh_cfg.get("authorizedkeysfile", '').strip()
236 if not auth_key_fn:234 if not auth_key_fn:
237 auth_key_fn = "%h/.ssh/authorized_keys"235 auth_key_fn = "%h/.ssh/authorized_keys"
@@ -240,7 +238,6 @@
240 auth_key_fn = auth_key_fn.replace("%%", '%')238 auth_key_fn = auth_key_fn.replace("%%", '%')
241 if not auth_key_fn.startswith('/'):239 if not auth_key_fn.startswith('/'):
242 auth_key_fn = os.path.join(pw_ent.pw_dir, auth_key_fn)240 auth_key_fn = os.path.join(pw_ent.pw_dir, auth_key_fn)
243 auth_key_fn = paths.join(False, auth_key_fn)
244 except (IOError, OSError):241 except (IOError, OSError):
245 # Give up and use a default key filename242 # Give up and use a default key filename
246 auth_key_fn = os.path.join(ssh_dir, 'authorized_keys')243 auth_key_fn = os.path.join(ssh_dir, 'authorized_keys')
@@ -248,14 +245,13 @@
248 " in ssh config"245 " in ssh config"
249 " from %r, using 'AuthorizedKeysFile' file"246 " from %r, using 'AuthorizedKeysFile' file"
250 " %r instead"),247 " %r instead"),
251 sshd_conf_fn, auth_key_fn)248 DEF_SSHD_CFG, auth_key_fn)
252 auth_key_entries = parse_authorized_keys(auth_key_fn)249 return (auth_key_fn, parse_authorized_keys(auth_key_fn))
253 return (auth_key_fn, auth_key_entries)250
254251
255252def setup_user_keys(keys, username, key_prefix):
256def setup_user_keys(keys, username, key_prefix, paths):
257 # Make sure the users .ssh dir is setup accordingly253 # Make sure the users .ssh dir is setup accordingly
258 (ssh_dir, pwent) = users_ssh_info(username, paths)254 (ssh_dir, pwent) = users_ssh_info(username)
259 if not os.path.isdir(ssh_dir):255 if not os.path.isdir(ssh_dir):
260 util.ensure_dir(ssh_dir, mode=0700)256 util.ensure_dir(ssh_dir, mode=0700)
261 util.chownbyid(ssh_dir, pwent.pw_uid, pwent.pw_gid)257 util.chownbyid(ssh_dir, pwent.pw_uid, pwent.pw_gid)
@@ -267,7 +263,7 @@
267 key_entries.append(parser.parse(str(k), def_opt=key_prefix))263 key_entries.append(parser.parse(str(k), def_opt=key_prefix))
268264
269 # Extract the old and make the new265 # Extract the old and make the new
270 (auth_key_fn, auth_key_entries) = extract_authorized_keys(username, paths)266 (auth_key_fn, auth_key_entries) = extract_authorized_keys(username)
271 with util.SeLinuxGuard(ssh_dir, recursive=True):267 with util.SeLinuxGuard(ssh_dir, recursive=True):
272 content = update_authorized_keys(auth_key_entries, key_entries)268 content = update_authorized_keys(auth_key_entries, key_entries)
273 util.ensure_dir(os.path.dirname(auth_key_fn), mode=0700)269 util.ensure_dir(os.path.dirname(auth_key_fn), mode=0700)
274270
=== added file 'pylintrc'
--- pylintrc 1970-01-01 00:00:00 +0000
+++ pylintrc 2012-10-28 02:29:21 +0000
@@ -0,0 +1,19 @@
1[General]
2init-hook='import sys; sys.path.append("tests/")'
3
4[MESSAGES CONTROL]
5# See: http://pylint-messages.wikidot.com/all-codes
6# W0142: *args and **kwargs are fine.
7# W0511: TODOs in code comments are fine.
8# W0702: No exception type(s) specified
9# W0703: Catch "Exception"
10# C0103: Invalid name
11# C0111: Missing docstring
12disable=W0142,W0511,W0702,W0703,C0103,C0111
13
14[REPORTS]
15reports=no
16include-ids=yes
17
18[FORMAT]
19max-line-length=79
020
=== added file 'tests/__init__.py'
=== added file 'tests/unittests/__init__.py'
=== added file 'tests/unittests/test_datasource/__init__.py'
=== added file 'tests/unittests/test_distros/__init__.py'
=== added file 'tests/unittests/test_filters/__init__.py'
=== modified file 'tests/unittests/test_filters/test_launch_index.py'
--- tests/unittests/test_filters/test_launch_index.py 2012-09-26 23:40:07 +0000
+++ tests/unittests/test_filters/test_launch_index.py 2012-10-28 02:29:21 +0000
@@ -1,14 +1,6 @@
1import copy1import copy
2import os2
3import sys3from tests.unittests import helpers
4
5top_dir = os.path.join(os.path.dirname(__file__), os.pardir, "helpers.py")
6top_dir = os.path.abspath(top_dir)
7if os.path.exists(top_dir):
8 sys.path.insert(0, os.path.dirname(top_dir))
9
10
11import helpers
124
13import itertools5import itertools
146
157
=== added file 'tests/unittests/test_handler/__init__.py'
=== modified file 'tests/unittests/test_handler/test_handler_ca_certs.py'
--- tests/unittests/test_handler/test_handler_ca_certs.py 2012-08-22 18:12:32 +0000
+++ tests/unittests/test_handler/test_handler_ca_certs.py 2012-10-28 02:29:21 +0000
@@ -77,7 +77,7 @@
77 """Test that a single cert gets passed to add_ca_certs."""77 """Test that a single cert gets passed to add_ca_certs."""
78 config = {"ca-certs": {"trusted": ["CERT1"]}}78 config = {"ca-certs": {"trusted": ["CERT1"]}}
7979
80 self.mock_add(self.paths, ["CERT1"])80 self.mock_add(["CERT1"])
81 self.mock_update()81 self.mock_update()
82 self.mocker.replay()82 self.mocker.replay()
8383
@@ -87,7 +87,7 @@
87 """Test that multiple certs get passed to add_ca_certs."""87 """Test that multiple certs get passed to add_ca_certs."""
88 config = {"ca-certs": {"trusted": ["CERT1", "CERT2"]}}88 config = {"ca-certs": {"trusted": ["CERT1", "CERT2"]}}
8989
90 self.mock_add(self.paths, ["CERT1", "CERT2"])90 self.mock_add(["CERT1", "CERT2"])
91 self.mock_update()91 self.mock_update()
92 self.mocker.replay()92 self.mocker.replay()
9393
@@ -97,7 +97,7 @@
97 """Test remove_defaults works as expected."""97 """Test remove_defaults works as expected."""
98 config = {"ca-certs": {"remove-defaults": True}}98 config = {"ca-certs": {"remove-defaults": True}}
9999
100 self.mock_remove(self.paths)100 self.mock_remove()
101 self.mock_update()101 self.mock_update()
102 self.mocker.replay()102 self.mocker.replay()
103103
@@ -116,8 +116,8 @@
116 """Test remove_defaults is not called when config value is False."""116 """Test remove_defaults is not called when config value is False."""
117 config = {"ca-certs": {"remove-defaults": True, "trusted": ["CERT1"]}}117 config = {"ca-certs": {"remove-defaults": True, "trusted": ["CERT1"]}}
118118
119 self.mock_remove(self.paths)119 self.mock_remove()
120 self.mock_add(self.paths, ["CERT1"])120 self.mock_add(["CERT1"])
121 self.mock_update()121 self.mock_update()
122 self.mocker.replay()122 self.mocker.replay()
123123
@@ -136,7 +136,7 @@
136 """Test that no certificate are written if not provided."""136 """Test that no certificate are written if not provided."""
137 self.mocker.replace(util.write_file, passthrough=False)137 self.mocker.replace(util.write_file, passthrough=False)
138 self.mocker.replay()138 self.mocker.replay()
139 cc_ca_certs.add_ca_certs(self.paths, [])139 cc_ca_certs.add_ca_certs([])
140140
141 def test_single_cert(self):141 def test_single_cert(self):
142 """Test adding a single certificate to the trusted CAs."""142 """Test adding a single certificate to the trusted CAs."""
@@ -149,7 +149,7 @@
149 "\ncloud-init-ca-certs.crt", omode="ab")149 "\ncloud-init-ca-certs.crt", omode="ab")
150 self.mocker.replay()150 self.mocker.replay()
151151
152 cc_ca_certs.add_ca_certs(self.paths, [cert])152 cc_ca_certs.add_ca_certs([cert])
153153
154 def test_multiple_certs(self):154 def test_multiple_certs(self):
155 """Test adding multiple certificates to the trusted CAs."""155 """Test adding multiple certificates to the trusted CAs."""
@@ -163,7 +163,7 @@
163 "\ncloud-init-ca-certs.crt", omode="ab")163 "\ncloud-init-ca-certs.crt", omode="ab")
164 self.mocker.replay()164 self.mocker.replay()
165165
166 cc_ca_certs.add_ca_certs(self.paths, certs)166 cc_ca_certs.add_ca_certs(certs)
167167
168168
169class TestUpdateCaCerts(MockerTestCase):169class TestUpdateCaCerts(MockerTestCase):
@@ -198,4 +198,4 @@
198 "ca-certificates ca-certificates/trust_new_crts select no")198 "ca-certificates ca-certificates/trust_new_crts select no")
199 self.mocker.replay()199 self.mocker.replay()
200200
201 cc_ca_certs.remove_default_ca_certs(self.paths)201 cc_ca_certs.remove_default_ca_certs()
202202
=== added file 'tests/unittests/test_runs/__init__.py'
=== modified file 'tests/unittests/test_runs/test_simple_run.py'
--- tests/unittests/test_runs/test_simple_run.py 2012-10-23 16:58:32 +0000
+++ tests/unittests/test_runs/test_simple_run.py 2012-10-28 02:29:21 +0000
@@ -1,14 +1,6 @@
1import os1import os
2import sys2
33from tests.unittests import helpers
4# Allow running this test individually
5top_dir = os.path.join(os.path.dirname(__file__), os.pardir, "helpers.py")
6top_dir = os.path.abspath(top_dir)
7if os.path.exists(top_dir):
8 sys.path.insert(0, os.path.dirname(top_dir))
9
10
11import helpers
124
13from cloudinit.settings import (PER_INSTANCE)5from cloudinit.settings import (PER_INSTANCE)
14from cloudinit import stages6from cloudinit import stages
157
=== modified file 'tools/run-pylint'
--- tools/run-pylint 2012-07-09 17:33:26 +0000
+++ tools/run-pylint 2012-10-28 02:29:21 +0000
@@ -6,23 +6,16 @@
6 files=( "$@" );6 files=( "$@" );
7fi 7fi
88
9RC_FILE="pylintrc"
10if [ ! -f $RC_FILE ]; then
11 RC_FILE="../pylintrc"
12fi
13
9cmd=(14cmd=(
10 pylint15 pylint
11 --reports=n16 --rcfile=$RC_FILE
12 --include-ids=y
13 --max-line-length=79
14
15 --disable=R17 --disable=R
16 --disable=I18 --disable=I
17
18 --disable=W0142 # Used * or ** magic
19 --disable=W0511 # TODO/FIXME note
20 --disable=W0702 # No exception type(s) specified
21 --disable=W0703 # Catch "Exception"
22
23 --disable=C0103 # Invalid name
24 --disable=C0111 # Missing docstring
25
26 "${files[@]}"19 "${files[@]}"
27)20)
2821