Merge lp:~smoser/ubuntu/trusty/cloud-init/trusty-1461242 into lp:ubuntu/trusty/cloud-init
- Trusty (14.04)
- trusty-1461242
- Merge into trusty
Proposed by
Scott Moser
Status: | Merged |
---|---|
Merged at revision: | 351 |
Proposed branch: | lp:~smoser/ubuntu/trusty/cloud-init/trusty-1461242 |
Merge into: | lp:ubuntu/trusty/cloud-init |
Diff against target: |
411 lines (+294/-31) 6 files modified
.pc/applied-patches (+1/-0) .pc/lp-1461242-generate-ed25519-host-keys.patch/cloudinit/config/cc_ssh.py (+138/-0) cloudinit/config/cc_ssh.py (+33/-30) debian/changelog (+6/-1) debian/patches/lp-1461242-generate-ed25519-host-keys.patch (+115/-0) debian/patches/series (+1/-0) |
To merge this branch: | bzr merge lp:~smoser/ubuntu/trusty/cloud-init/trusty-1461242 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ben Howard (community) | Approve | ||
Dan Watkins | Pending | ||
Review via email: mp+270711@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 352. By Scott Moser
-
remove use of 'decode_binary'
there is no 'decode_binary' here.
the return values from subp in python2 are strings.
Revision history for this message
Ben Howard (darkmuggle-deactivatedaccount) wrote : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.pc/applied-patches' |
2 | --- .pc/applied-patches 2015-09-10 16:24:44 +0000 |
3 | +++ .pc/applied-patches 2015-09-10 16:50:23 +0000 |
4 | @@ -14,3 +14,4 @@ |
5 | lp-1470890-include-regions-in-dynamic-mirror-discovery.patch |
6 | lp-1490796-azure-fix-mount_cb-for-symlinks.patch |
7 | lp-1469260-fix-consumption-of-vendor-data.patch |
8 | +lp-1461242-generate-ed25519-host-keys.patch |
9 | |
10 | === added directory '.pc/lp-1461242-generate-ed25519-host-keys.patch' |
11 | === added directory '.pc/lp-1461242-generate-ed25519-host-keys.patch/cloudinit' |
12 | === added directory '.pc/lp-1461242-generate-ed25519-host-keys.patch/cloudinit/config' |
13 | === added file '.pc/lp-1461242-generate-ed25519-host-keys.patch/cloudinit/config/cc_ssh.py' |
14 | --- .pc/lp-1461242-generate-ed25519-host-keys.patch/cloudinit/config/cc_ssh.py 1970-01-01 00:00:00 +0000 |
15 | +++ .pc/lp-1461242-generate-ed25519-host-keys.patch/cloudinit/config/cc_ssh.py 2015-09-10 16:50:23 +0000 |
16 | @@ -0,0 +1,138 @@ |
17 | +# vi: ts=4 expandtab |
18 | +# |
19 | +# Copyright (C) 2009-2010 Canonical Ltd. |
20 | +# Copyright (C) 2012, 2013 Hewlett-Packard Development Company, L.P. |
21 | +# |
22 | +# Author: Scott Moser <scott.moser@canonical.com> |
23 | +# Author: Juerg Haefliger <juerg.haefliger@hp.com> |
24 | +# |
25 | +# This program is free software: you can redistribute it and/or modify |
26 | +# it under the terms of the GNU General Public License version 3, as |
27 | +# published by the Free Software Foundation. |
28 | +# |
29 | +# This program is distributed in the hope that it will be useful, |
30 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
31 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
32 | +# GNU General Public License for more details. |
33 | +# |
34 | +# You should have received a copy of the GNU General Public License |
35 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
36 | + |
37 | +import glob |
38 | +import os |
39 | + |
40 | +# Ensure this is aliased to a name not 'distros' |
41 | +# since the module attribute 'distros' |
42 | +# is a list of distros that are supported, not a sub-module |
43 | +from cloudinit import distros as ds |
44 | + |
45 | +from cloudinit import ssh_util |
46 | +from cloudinit import util |
47 | + |
48 | +DISABLE_ROOT_OPTS = ("no-port-forwarding,no-agent-forwarding," |
49 | +"no-X11-forwarding,command=\"echo \'Please login as the user \\\"$USER\\\" " |
50 | +"rather than the user \\\"root\\\".\';echo;sleep 10\"") |
51 | + |
52 | +KEY_2_FILE = { |
53 | + "rsa_private": ("/etc/ssh/ssh_host_rsa_key", 0600), |
54 | + "rsa_public": ("/etc/ssh/ssh_host_rsa_key.pub", 0644), |
55 | + "dsa_private": ("/etc/ssh/ssh_host_dsa_key", 0600), |
56 | + "dsa_public": ("/etc/ssh/ssh_host_dsa_key.pub", 0644), |
57 | + "ecdsa_private": ("/etc/ssh/ssh_host_ecdsa_key", 0600), |
58 | + "ecdsa_public": ("/etc/ssh/ssh_host_ecdsa_key.pub", 0644), |
59 | +} |
60 | + |
61 | +PRIV_2_PUB = { |
62 | + 'rsa_private': 'rsa_public', |
63 | + 'dsa_private': 'dsa_public', |
64 | + 'ecdsa_private': 'ecdsa_public', |
65 | +} |
66 | + |
67 | +KEY_GEN_TPL = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"' |
68 | + |
69 | +GENERATE_KEY_NAMES = ['rsa', 'dsa', 'ecdsa'] |
70 | + |
71 | +KEY_FILE_TPL = '/etc/ssh/ssh_host_%s_key' |
72 | + |
73 | + |
74 | +def handle(_name, cfg, cloud, log, _args): |
75 | + |
76 | + # remove the static keys from the pristine image |
77 | + if cfg.get("ssh_deletekeys", True): |
78 | + key_pth = os.path.join("/etc/ssh/", "ssh_host_*key*") |
79 | + for f in glob.glob(key_pth): |
80 | + try: |
81 | + util.del_file(f) |
82 | + except: |
83 | + util.logexc(log, "Failed deleting key file %s", f) |
84 | + |
85 | + if "ssh_keys" in cfg: |
86 | + # if there are keys in cloud-config, use them |
87 | + for (key, val) in cfg["ssh_keys"].iteritems(): |
88 | + if key in KEY_2_FILE: |
89 | + tgt_fn = KEY_2_FILE[key][0] |
90 | + tgt_perms = KEY_2_FILE[key][1] |
91 | + util.write_file(tgt_fn, val, tgt_perms) |
92 | + |
93 | + for (priv, pub) in PRIV_2_PUB.iteritems(): |
94 | + if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']: |
95 | + continue |
96 | + pair = (KEY_2_FILE[priv][0], KEY_2_FILE[pub][0]) |
97 | + cmd = ['sh', '-xc', KEY_GEN_TPL % pair] |
98 | + try: |
99 | + # TODO(harlowja): Is this guard needed? |
100 | + with util.SeLinuxGuard("/etc/ssh", recursive=True): |
101 | + util.subp(cmd, capture=False) |
102 | + log.debug("Generated a key for %s from %s", pair[0], pair[1]) |
103 | + except: |
104 | + util.logexc(log, "Failed generated a key for %s from %s", |
105 | + pair[0], pair[1]) |
106 | + else: |
107 | + # if not, generate them |
108 | + genkeys = util.get_cfg_option_list(cfg, |
109 | + 'ssh_genkeytypes', |
110 | + GENERATE_KEY_NAMES) |
111 | + for keytype in genkeys: |
112 | + keyfile = KEY_FILE_TPL % (keytype) |
113 | + util.ensure_dir(os.path.dirname(keyfile)) |
114 | + if not os.path.exists(keyfile): |
115 | + cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] |
116 | + try: |
117 | + # TODO(harlowja): Is this guard needed? |
118 | + with util.SeLinuxGuard("/etc/ssh", recursive=True): |
119 | + util.subp(cmd, capture=False) |
120 | + except: |
121 | + util.logexc(log, "Failed generating key type %s to " |
122 | + "file %s", keytype, keyfile) |
123 | + |
124 | + try: |
125 | + (users, _groups) = ds.normalize_users_groups(cfg, cloud.distro) |
126 | + (user, _user_config) = ds.extract_default(users) |
127 | + disable_root = util.get_cfg_option_bool(cfg, "disable_root", True) |
128 | + disable_root_opts = util.get_cfg_option_str(cfg, "disable_root_opts", |
129 | + DISABLE_ROOT_OPTS) |
130 | + |
131 | + keys = cloud.get_public_ssh_keys() or [] |
132 | + if "ssh_authorized_keys" in cfg: |
133 | + cfgkeys = cfg["ssh_authorized_keys"] |
134 | + keys.extend(cfgkeys) |
135 | + |
136 | + apply_credentials(keys, user, disable_root, disable_root_opts) |
137 | + except: |
138 | + util.logexc(log, "Applying ssh credentials failed!") |
139 | + |
140 | + |
141 | +def apply_credentials(keys, user, disable_root, disable_root_opts): |
142 | + |
143 | + keys = set(keys) |
144 | + if user: |
145 | + ssh_util.setup_user_keys(keys, user) |
146 | + |
147 | + if disable_root: |
148 | + if not user: |
149 | + user = "NONE" |
150 | + key_prefix = disable_root_opts.replace('$USER', user) |
151 | + else: |
152 | + key_prefix = '' |
153 | + |
154 | + ssh_util.setup_user_keys(keys, 'root', options=key_prefix) |
155 | |
156 | === modified file 'cloudinit/config/cc_ssh.py' |
157 | --- cloudinit/config/cc_ssh.py 2013-07-10 13:35:59 +0000 |
158 | +++ cloudinit/config/cc_ssh.py 2015-09-10 16:50:23 +0000 |
159 | @@ -20,6 +20,7 @@ |
160 | |
161 | import glob |
162 | import os |
163 | +import sys |
164 | |
165 | # Ensure this is aliased to a name not 'distros' |
166 | # since the module attribute 'distros' |
167 | @@ -33,27 +34,19 @@ |
168 | "no-X11-forwarding,command=\"echo \'Please login as the user \\\"$USER\\\" " |
169 | "rather than the user \\\"root\\\".\';echo;sleep 10\"") |
170 | |
171 | -KEY_2_FILE = { |
172 | - "rsa_private": ("/etc/ssh/ssh_host_rsa_key", 0600), |
173 | - "rsa_public": ("/etc/ssh/ssh_host_rsa_key.pub", 0644), |
174 | - "dsa_private": ("/etc/ssh/ssh_host_dsa_key", 0600), |
175 | - "dsa_public": ("/etc/ssh/ssh_host_dsa_key.pub", 0644), |
176 | - "ecdsa_private": ("/etc/ssh/ssh_host_ecdsa_key", 0600), |
177 | - "ecdsa_public": ("/etc/ssh/ssh_host_ecdsa_key.pub", 0644), |
178 | -} |
179 | +GENERATE_KEY_NAMES = ['rsa', 'dsa', 'ecdsa', 'ed25519'] |
180 | +KEY_FILE_TPL = '/etc/ssh/ssh_host_%s_key' |
181 | |
182 | -PRIV_2_PUB = { |
183 | - 'rsa_private': 'rsa_public', |
184 | - 'dsa_private': 'dsa_public', |
185 | - 'ecdsa_private': 'ecdsa_public', |
186 | -} |
187 | +CONFIG_KEY_TO_FILE = {} |
188 | +PRIV_TO_PUB = {} |
189 | +for k in GENERATE_KEY_NAMES: |
190 | + CONFIG_KEY_TO_FILE.update({"%s_private" % k: (KEY_FILE_TPL % k, 0o600)}) |
191 | + CONFIG_KEY_TO_FILE.update( |
192 | + {"%s_public" % k: (KEY_FILE_TPL % k + ".pub", 0o600)}) |
193 | + PRIV_TO_PUB["%s_private" % k] = "%s_public" % k |
194 | |
195 | KEY_GEN_TPL = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"' |
196 | |
197 | -GENERATE_KEY_NAMES = ['rsa', 'dsa', 'ecdsa'] |
198 | - |
199 | -KEY_FILE_TPL = '/etc/ssh/ssh_host_%s_key' |
200 | - |
201 | |
202 | def handle(_name, cfg, cloud, log, _args): |
203 | |
204 | @@ -69,15 +62,15 @@ |
205 | if "ssh_keys" in cfg: |
206 | # if there are keys in cloud-config, use them |
207 | for (key, val) in cfg["ssh_keys"].iteritems(): |
208 | - if key in KEY_2_FILE: |
209 | - tgt_fn = KEY_2_FILE[key][0] |
210 | - tgt_perms = KEY_2_FILE[key][1] |
211 | + if key in CONFIG_KEY_TO_FILE: |
212 | + tgt_fn = CONFIG_KEY_TO_FILE[key][0] |
213 | + tgt_perms = CONFIG_KEY_TO_FILE[key][1] |
214 | util.write_file(tgt_fn, val, tgt_perms) |
215 | |
216 | - for (priv, pub) in PRIV_2_PUB.iteritems(): |
217 | + for (priv, pub) in PRIV_TO_PUB.items(): |
218 | if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']: |
219 | continue |
220 | - pair = (KEY_2_FILE[priv][0], KEY_2_FILE[pub][0]) |
221 | + pair = (CONFIG_KEY_TO_FILE[priv][0], CONFIG_KEY_TO_FILE[pub][0]) |
222 | cmd = ['sh', '-xc', KEY_GEN_TPL % pair] |
223 | try: |
224 | # TODO(harlowja): Is this guard needed? |
225 | @@ -92,18 +85,28 @@ |
226 | genkeys = util.get_cfg_option_list(cfg, |
227 | 'ssh_genkeytypes', |
228 | GENERATE_KEY_NAMES) |
229 | + lang_c = os.environ.copy() |
230 | + lang_c['LANG'] = 'C' |
231 | for keytype in genkeys: |
232 | keyfile = KEY_FILE_TPL % (keytype) |
233 | + if os.path.exists(keyfile): |
234 | + continue |
235 | util.ensure_dir(os.path.dirname(keyfile)) |
236 | - if not os.path.exists(keyfile): |
237 | - cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] |
238 | + cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] |
239 | + |
240 | + # TODO(harlowja): Is this guard needed? |
241 | + with util.SeLinuxGuard("/etc/ssh", recursive=True): |
242 | try: |
243 | - # TODO(harlowja): Is this guard needed? |
244 | - with util.SeLinuxGuard("/etc/ssh", recursive=True): |
245 | - util.subp(cmd, capture=False) |
246 | - except: |
247 | - util.logexc(log, "Failed generating key type %s to " |
248 | - "file %s", keytype, keyfile) |
249 | + out, err = util.subp(cmd, capture=True, env=lang_c) |
250 | + sys.stdout.write(out) |
251 | + except util.ProcessExecutionError as e: |
252 | + err = e.stderr.lower() |
253 | + if (e.exit_code == 1 and |
254 | + err.lower().startswith("unknown key")): |
255 | + log.debug("ssh-keygen: unknown key type '%s'", keytype) |
256 | + else: |
257 | + util.logexc(log, "Failed generating key type %s to " |
258 | + "file %s", keytype, keyfile) |
259 | |
260 | try: |
261 | (users, _groups) = ds.normalize_users_groups(cfg, cloud.distro) |
262 | |
263 | === modified file 'debian/changelog' |
264 | --- debian/changelog 2015-09-10 16:24:44 +0000 |
265 | +++ debian/changelog 2015-09-10 16:50:23 +0000 |
266 | @@ -1,10 +1,15 @@ |
267 | cloud-init (0.7.5-0ubuntu1.11) UNRELEASED; urgency=medium |
268 | |
269 | + [ Felipe Reyes ] |
270 | * d/patches/fix-consumption-of-vendor-data.patch: |
271 | - Fix consumption of vendor-data in OpenStack to allow namespacing |
272 | (LP: #1469260). |
273 | |
274 | - -- Felipe Reyes <felipe.reyes@canonical.com> Thu, 10 Sep 2015 12:50:32 -0300 |
275 | + [ Scott Moser ] |
276 | + * d/patches/lp-1461242-generate-ed25519-host-keys.patch: |
277 | + - ssh: generate ed25519 host keys if supported (LP: #1461242) |
278 | + |
279 | + -- Scott Moser <smoser@ubuntu.com> Thu, 10 Sep 2015 12:36:14 -0400 |
280 | |
281 | cloud-init (0.7.5-0ubuntu1.10) trusty; urgency=medium |
282 | |
283 | |
284 | === added file 'debian/patches/lp-1461242-generate-ed25519-host-keys.patch' |
285 | --- debian/patches/lp-1461242-generate-ed25519-host-keys.patch 1970-01-01 00:00:00 +0000 |
286 | +++ debian/patches/lp-1461242-generate-ed25519-host-keys.patch 2015-09-10 16:50:23 +0000 |
287 | @@ -0,0 +1,115 @@ |
288 | +Author: Scott Moser <smoser@ubuntu.com> |
289 | +Bug: https://launchpad.net/bugs/1461242 |
290 | +Applied-Upstream: yes |
291 | +Origin: http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/revision/1125 |
292 | +Description: ssh: generate ed25519 host keys if supported |
293 | + . |
294 | + now we attempt to generate ed25519 host keys. |
295 | + If ssh-keygen does not support it, a debug log message will be written. |
296 | + |
297 | +=== modified file 'cloudinit/config/cc_ssh.py' |
298 | +--- a/cloudinit/config/cc_ssh.py |
299 | ++++ b/cloudinit/config/cc_ssh.py |
300 | +@@ -20,6 +20,7 @@ |
301 | + |
302 | + import glob |
303 | + import os |
304 | ++import sys |
305 | + |
306 | + # Ensure this is aliased to a name not 'distros' |
307 | + # since the module attribute 'distros' |
308 | +@@ -33,26 +34,18 @@ DISABLE_ROOT_OPTS = ("no-port-forwarding |
309 | + "no-X11-forwarding,command=\"echo \'Please login as the user \\\"$USER\\\" " |
310 | + "rather than the user \\\"root\\\".\';echo;sleep 10\"") |
311 | + |
312 | +-KEY_2_FILE = { |
313 | +- "rsa_private": ("/etc/ssh/ssh_host_rsa_key", 0600), |
314 | +- "rsa_public": ("/etc/ssh/ssh_host_rsa_key.pub", 0644), |
315 | +- "dsa_private": ("/etc/ssh/ssh_host_dsa_key", 0600), |
316 | +- "dsa_public": ("/etc/ssh/ssh_host_dsa_key.pub", 0644), |
317 | +- "ecdsa_private": ("/etc/ssh/ssh_host_ecdsa_key", 0600), |
318 | +- "ecdsa_public": ("/etc/ssh/ssh_host_ecdsa_key.pub", 0644), |
319 | +-} |
320 | +- |
321 | +-PRIV_2_PUB = { |
322 | +- 'rsa_private': 'rsa_public', |
323 | +- 'dsa_private': 'dsa_public', |
324 | +- 'ecdsa_private': 'ecdsa_public', |
325 | +-} |
326 | +- |
327 | +-KEY_GEN_TPL = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"' |
328 | ++GENERATE_KEY_NAMES = ['rsa', 'dsa', 'ecdsa', 'ed25519'] |
329 | ++KEY_FILE_TPL = '/etc/ssh/ssh_host_%s_key' |
330 | + |
331 | +-GENERATE_KEY_NAMES = ['rsa', 'dsa', 'ecdsa'] |
332 | ++CONFIG_KEY_TO_FILE = {} |
333 | ++PRIV_TO_PUB = {} |
334 | ++for k in GENERATE_KEY_NAMES: |
335 | ++ CONFIG_KEY_TO_FILE.update({"%s_private" % k: (KEY_FILE_TPL % k, 0o600)}) |
336 | ++ CONFIG_KEY_TO_FILE.update( |
337 | ++ {"%s_public" % k: (KEY_FILE_TPL % k + ".pub", 0o600)}) |
338 | ++ PRIV_TO_PUB["%s_private" % k] = "%s_public" % k |
339 | + |
340 | +-KEY_FILE_TPL = '/etc/ssh/ssh_host_%s_key' |
341 | ++KEY_GEN_TPL = 'o=$(ssh-keygen -yf "%s") && echo "$o" root@localhost > "%s"' |
342 | + |
343 | + |
344 | + def handle(_name, cfg, cloud, log, _args): |
345 | +@@ -69,15 +62,15 @@ def handle(_name, cfg, cloud, log, _args |
346 | + if "ssh_keys" in cfg: |
347 | + # if there are keys in cloud-config, use them |
348 | + for (key, val) in cfg["ssh_keys"].iteritems(): |
349 | +- if key in KEY_2_FILE: |
350 | +- tgt_fn = KEY_2_FILE[key][0] |
351 | +- tgt_perms = KEY_2_FILE[key][1] |
352 | ++ if key in CONFIG_KEY_TO_FILE: |
353 | ++ tgt_fn = CONFIG_KEY_TO_FILE[key][0] |
354 | ++ tgt_perms = CONFIG_KEY_TO_FILE[key][1] |
355 | + util.write_file(tgt_fn, val, tgt_perms) |
356 | + |
357 | +- for (priv, pub) in PRIV_2_PUB.iteritems(): |
358 | ++ for (priv, pub) in PRIV_TO_PUB.items(): |
359 | + if pub in cfg['ssh_keys'] or not priv in cfg['ssh_keys']: |
360 | + continue |
361 | +- pair = (KEY_2_FILE[priv][0], KEY_2_FILE[pub][0]) |
362 | ++ pair = (CONFIG_KEY_TO_FILE[priv][0], CONFIG_KEY_TO_FILE[pub][0]) |
363 | + cmd = ['sh', '-xc', KEY_GEN_TPL % pair] |
364 | + try: |
365 | + # TODO(harlowja): Is this guard needed? |
366 | +@@ -92,18 +85,28 @@ def handle(_name, cfg, cloud, log, _args |
367 | + genkeys = util.get_cfg_option_list(cfg, |
368 | + 'ssh_genkeytypes', |
369 | + GENERATE_KEY_NAMES) |
370 | ++ lang_c = os.environ.copy() |
371 | ++ lang_c['LANG'] = 'C' |
372 | + for keytype in genkeys: |
373 | + keyfile = KEY_FILE_TPL % (keytype) |
374 | ++ if os.path.exists(keyfile): |
375 | ++ continue |
376 | + util.ensure_dir(os.path.dirname(keyfile)) |
377 | +- if not os.path.exists(keyfile): |
378 | +- cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] |
379 | ++ cmd = ['ssh-keygen', '-t', keytype, '-N', '', '-f', keyfile] |
380 | ++ |
381 | ++ # TODO(harlowja): Is this guard needed? |
382 | ++ with util.SeLinuxGuard("/etc/ssh", recursive=True): |
383 | + try: |
384 | +- # TODO(harlowja): Is this guard needed? |
385 | +- with util.SeLinuxGuard("/etc/ssh", recursive=True): |
386 | +- util.subp(cmd, capture=False) |
387 | +- except: |
388 | +- util.logexc(log, "Failed generating key type %s to " |
389 | +- "file %s", keytype, keyfile) |
390 | ++ out, err = util.subp(cmd, capture=True, env=lang_c) |
391 | ++ sys.stdout.write(out) |
392 | ++ except util.ProcessExecutionError as e: |
393 | ++ err = e.stderr.lower() |
394 | ++ if (e.exit_code == 1 and |
395 | ++ err.lower().startswith("unknown key")): |
396 | ++ log.debug("ssh-keygen: unknown key type '%s'", keytype) |
397 | ++ else: |
398 | ++ util.logexc(log, "Failed generating key type %s to " |
399 | ++ "file %s", keytype, keyfile) |
400 | + |
401 | + try: |
402 | + (users, _groups) = ds.normalize_users_groups(cfg, cloud.distro) |
403 | |
404 | === modified file 'debian/patches/series' |
405 | --- debian/patches/series 2015-09-10 16:24:44 +0000 |
406 | +++ debian/patches/series 2015-09-10 16:50:23 +0000 |
407 | @@ -14,3 +14,4 @@ |
408 | lp-1470890-include-regions-in-dynamic-mirror-discovery.patch |
409 | lp-1490796-azure-fix-mount_cb-for-symlinks.patch |
410 | lp-1469260-fix-consumption-of-vendor-data.patch |
411 | +lp-1461242-generate-ed25519-host-keys.patch |
Tested and okay for merger. It works as expected by creating ed25519 keys in /etc/ssh.
I would merge it, but bzr is complaining of a "readonly transport."