]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Connect cfn utils to the remote server
authorTomas Sedovic <tomas@sedovic.cz>
Thu, 3 May 2012 14:19:17 +0000 (16:19 +0200)
committerTomas Sedovic <tomas@sedovic.cz>
Thu, 3 May 2012 14:55:02 +0000 (16:55 +0200)
The cfn_helper's `Metadata` class can now connect to the metadata server
prodived it's URL is known and available.

Engine will pass metadata server's URL via the User Data to the following file:

    /var/lib/cloud/data/cfn-metadata-server

If the file doesn't exist or the server is unreachable, cfntools will read
metadata from the `/var/lib/cloud/data/cfn-init-data` file as they did so far.

Note that Engine dosen't currently know the metadata server's URL so it's not
passing it to the instance yet.

heat/cfntools/cfn_helper.py
heat/engine/instance.py
heat/engine/parser.py

index 24bfbb9d4f1ee3e0245904b4c92e003bf99ff76e..b35287adef3fe03581caf9655d79a459e679e7cc 100644 (file)
@@ -41,7 +41,8 @@ import rpmUtils.updates as rpmupdates
 import rpmUtils.miscutils as rpmutils
 import subprocess
 import sys
-
+from urllib2 import urlopen
+from urlparse import urlparse, urlunparse
 
 def to_boolean(b):
     val = b.lower().strip() if isinstance(b, basestring) else b
@@ -731,6 +732,8 @@ class ServicesHandler(object):
             else:
                 self._monitor_services(handler, service_entries)
 
+class MetadataServerConnectionError(Exception):
+    pass
 
 class Metadata(object):
     _metadata = None
@@ -750,6 +753,35 @@ class Metadata(object):
         self._is_local_metadata = True
         self._metadata = None
 
+
+    def metadata_server_url(self):
+        """
+        Return the url to the metadata server.
+        """
+        try:
+            f = open("/var/lib/cloud/data/cfn-metadata-server")
+            server_url = f.read()
+            f.close()
+        except IOError:
+            return None
+
+        url_parts = list(urlparse(server_url))
+        url_parts[2] = '/stacks/%s/resources/%s' % (self.stack, self.resource)
+        return urlunparse(url_parts)
+
+    def remote_metadata(self):
+        """
+        Connect to the metadata server and retreive the metadata from there.
+        """
+        server_url = self.metadata_server_url()
+        if not server_url:
+            raise MetadataServerConnectionError()
+
+        try:
+            return urlopen(server_url).read()
+        except:
+            raise MetadataServerConnectionError()
+
     def retrieve(self, meta_str=None):
         """
         Read the metadata from the given filename
@@ -757,9 +789,12 @@ class Metadata(object):
         if meta_str:
             self._data = meta_str
         else:
-            f = open("/var/lib/cloud/data/cfn-init-data")
-            self._data = f.read()
-            f.close()
+            try:
+                self._data = self.remote_metadata()
+            except MetadataServerConnectionError:
+                f = open("/var/lib/cloud/data/cfn-init-data")
+                self._data = f.read()
+                f.close()
 
         if isinstance(self._data, str):
             self._metadata = json.loads(self._data)
index bd3fc8db444d896da1a0bc7c53bd95f4b29840ae..951a38edfb182e2d6894feddf3e4f57cf74d6b0f 100644 (file)
@@ -108,13 +108,19 @@ class Instance(Resource):
                            filename='cfn-init-data')
             mime_blob.attach(msg)
 
+            if self.stack.metadata_server:
+                msg = MIMEText(self.stack.metadata_server,
+                               _subtype='x-cfninitdata')
+                msg.add_header('Content-Disposition', 'attachment',
+                               filename='cfn-metadata-server')
+                mime_blob.attach(msg)
+
             msg = MIMEText(userdata, _subtype='x-shellscript')
             msg.add_header('Content-Disposition', 'attachment', filename='startup')
             mime_blob.attach(msg)
             self.mime_string = mime_blob.as_string()
-        
-        return self.mime_string
 
+        return self.mime_string
 
     def create(self):
         def _null_callback(p, n, out):
index 4f30c6c2639af0e7ae7ef368f04858ae40c90bf5..a137031769f9be63c186b814b66a10f43f32ab25 100644 (file)
@@ -48,7 +48,8 @@ class Stack(object):
         self.doc = None
         self.name = stack_name
         self.parsed_template_id = 0
-        self.metadata_server = 'http://10.0.0.1'
+        # TODO(shadower) load this from a config file
+        #self.metadata_server = 'http://10.0.0.1'
 
         self.parms['AWS::StackName'] = {"Description": "AWS StackName",
             "Type": "String",