~ubuntu-branches/ubuntu/saucy/cloud-init/saucy-proposed

« back to all changes in this revision

Viewing changes to debian/patches/lp-1269626-azure_new_instance.patch

  • Committer: Scott Moser
  • Date: 2014-03-21 16:26:05 UTC
  • mfrom: (317.1.2 saucy-proposed.ben)
  • Revision ID: smoser@ubuntu.com-20140321162605-3u4kmqayg5k7agab
* debian/patches/lp-1269626-azure_new_instance.patch:
  fix handling of new instances on Windows Azure (LP: #1269626).
* debian/patches/lp-1292648-azure-format-ephemeral-new.patch:
  re-format ephemeral disk if necessary (LP: #1292648).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Author: Ben Howard <ben.howard@ubuntu.com>
 
2
Bug: https://launchpad.net/bugs/1269626
 
3
Applied-Upstream: revno 936
 
4
Description: Azure: Fix bug where new instances are not detected
 
5
 If a datasource was found other than in /var/lib/waagent, and /var/lib/waagent
 
6
 contained all the files necessary for 'wait_for_files' (most likely
 
7
 'SharedConfig.xml'), then cloud-init would continue on before looking properly.
 
8
 .
 
9
 To address this, if the ovf-env.xml came from somewhere other than
 
10
 /var/lib/waagent, and it differs from the file in /var/lib/waagent, then
 
11
 we clean up some files that we expect to be provided by 'wait_for_files'.
 
12
--- a/cloudinit/sources/DataSourceAzure.py
 
13
+++ b/cloudinit/sources/DataSourceAzure.py
 
14
@@ -34,6 +34,7 @@ DEFAULT_METADATA = {"instance-id": "iid-
 
15
 AGENT_START = ['service', 'walinuxagent', 'start']
 
16
 BOUNCE_COMMAND = ['sh', '-xc',
 
17
     "i=$interface; x=0; ifdown $i || x=$?; ifup $i || x=$?; exit $x"]
 
18
+DATA_DIR_CLEAN_LIST = ['SharedConfig.xml']
 
19
 
 
20
 BUILTIN_DS_CONFIG = {
 
21
     'agent_command': AGENT_START,
 
22
@@ -128,10 +129,26 @@ class DataSourceAzureNet(sources.DataSou
 
23
         user_ds_cfg = util.get_cfg_by_path(self.cfg, DS_CFG_PATH, {})
 
24
         self.ds_cfg = util.mergemanydict([user_ds_cfg, self.ds_cfg])
 
25
         mycfg = self.ds_cfg
 
26
+        ddir = mycfg['data_dir']
 
27
+
 
28
+        if found != ddir:
 
29
+            cached_ovfenv = util.load_file(
 
30
+                os.path.join(ddir, 'ovf-env.xml'), quiet=True)
 
31
+            if cached_ovfenv != files['ovf-env.xml']:
 
32
+                # source was not walinux-agent's datadir, so we have to clean
 
33
+                # up so 'wait_for_files' doesn't return early due to stale data
 
34
+                cleaned = []
 
35
+                for f in [os.path.join(ddir, f) for f in DATA_DIR_CLEAN_LIST]:
 
36
+                    if os.path.exists(f):
 
37
+                        util.del_file(f)
 
38
+                        cleaned.append(f)
 
39
+                if cleaned:
 
40
+                    LOG.info("removed stale file(s) in '%s': %s",
 
41
+                             ddir, str(cleaned))
 
42
 
 
43
         # walinux agent writes files world readable, but expects
 
44
         # the directory to be protected.
 
45
-        write_files(mycfg['data_dir'], files, dirmode=0700)
 
46
+        write_files(ddir, files, dirmode=0700)
 
47
 
 
48
         # handle the hostname 'publishing'
 
49
         try:
 
50
@@ -139,7 +156,7 @@ class DataSourceAzureNet(sources.DataSou
 
51
                                 self.metadata.get('local-hostname'),
 
52
                                 mycfg['hostname_bounce'])
 
53
         except Exception as e:
 
54
-            LOG.warn("Failed publishing hostname: %s" % e)
 
55
+            LOG.warn("Failed publishing hostname: %s", e)
 
56
             util.logexc(LOG, "handling set_hostname failed")
 
57
 
 
58
         try:
 
59
@@ -149,13 +166,13 @@ class DataSourceAzureNet(sources.DataSou
 
60
             util.logexc(LOG, "agent command '%s' failed.",
 
61
                         mycfg['agent_command'])
 
62
 
 
63
-        shcfgxml = os.path.join(mycfg['data_dir'], "SharedConfig.xml")
 
64
+        shcfgxml = os.path.join(ddir, "SharedConfig.xml")
 
65
         wait_for = [shcfgxml]
 
66
 
 
67
         fp_files = []
 
68
         for pk in self.cfg.get('_pubkeys', []):
 
69
-            bname = pk['fingerprint'] + ".crt"
 
70
-            fp_files += [os.path.join(mycfg['data_dir'], bname)]
 
71
+            bname = str(pk['fingerprint'] + ".crt")
 
72
+            fp_files += [os.path.join(ddir, bname)]
 
73
 
 
74
         missing = util.log_time(logfunc=LOG.debug, msg="waiting for files",
 
75
                                 func=wait_for_files,
 
76
@@ -247,10 +264,10 @@ def pubkeys_from_crt_files(flist):
 
77
         try:
 
78
             pubkeys.append(crtfile_to_pubkey(fname))
 
79
         except util.ProcessExecutionError:
 
80
-            errors.extend(fname)
 
81
+            errors.append(fname)
 
82
 
 
83
     if errors:
 
84
-        LOG.warn("failed to convert the crt files to pubkey: %s" % errors)
 
85
+        LOG.warn("failed to convert the crt files to pubkey: %s", errors)
 
86
 
 
87
     return pubkeys
 
88
 
 
89
@@ -281,7 +298,7 @@ def write_files(datadir, files, dirmode=
 
90
 def invoke_agent(cmd):
 
91
     # this is a function itself to simplify patching it for test
 
92
     if cmd:
 
93
-        LOG.debug("invoking agent: %s" % cmd)
 
94
+        LOG.debug("invoking agent: %s", cmd)
 
95
         util.subp(cmd, shell=(not isinstance(cmd, list)))
 
96
     else:
 
97
         LOG.debug("not invoking agent")
 
98
@@ -328,7 +345,7 @@ def load_azure_ovf_pubkeys(sshnode):
 
99
             continue
 
100
         cur = {'fingerprint': "", 'path': ""}
 
101
         for child in pk_node.childNodes:
 
102
-            if (child.nodeType == text_node or not child.localName):
 
103
+            if child.nodeType == text_node or not child.localName:
 
104
                 continue
 
105
 
 
106
             name = child.localName.lower()
 
107
@@ -410,11 +427,11 @@ def read_azure_ovf(contents):
 
108
             simple = True
 
109
             value = child.childNodes[0].wholeText
 
110
 
 
111
-        attrs = {k: v for k, v in child.attributes.items()}
 
112
+        attrs = dict([(k, v) for k, v in child.attributes.items()])
 
113
 
 
114
         # we accept either UserData or CustomData.  If both are present
 
115
         # then behavior is undefined.
 
116
-        if (name == "userdata" or name == "customdata"):
 
117
+        if name == "userdata" or name == "customdata":
 
118
             if attrs.get('encoding') in (None, "base64"):
 
119
                 ud = base64.b64decode(''.join(value.split()))
 
120
             else: