]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
loguserdata: handle exceptions from running the userdata
authorAngus Salkeld <asalkeld@redhat.com>
Thu, 14 Mar 2013 03:21:55 +0000 (14:21 +1100)
committerAngus Salkeld <asalkeld@redhat.com>
Thu, 14 Mar 2013 03:21:55 +0000 (14:21 +1100)
- log the exceptions so the user can diagnose issues.

bug 1154641
Change-Id: Ic085c9f062255a9fa44b3e31b464c9ebd19a947c
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
heat/cloudinit/loguserdata.py
heat/tests/test_loguserdata.py

index 7e66166f72bd64cef50bd63616bc8b3650ff8858..a33e8b3c57ec138dbe035b40701bc8f1cd61382a 100644 (file)
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 
+import errno
 import datetime
 import pkg_resources
 import os
@@ -25,8 +26,19 @@ def create_log(log_path):
 def call(args, logger):
     logger.write('%s\n' % ' '.join(args))
     logger.flush()
-    p = subprocess.Popen(args, stdout=logger, stderr=logger)
-    p.wait()
+    try:
+        p = subprocess.Popen(args, stdout=logger, stderr=logger)
+        p.wait()
+    except OSError as ex:
+        if ex.errno == errno.ENOEXEC:
+            logger.write('Userdata empty or not executable: %s\n' % str(ex))
+            return os.EX_OK
+        else:
+            logger.write('OS error running userdata: %s\n' % str(ex))
+            return os.EX_OSERR
+    except Exception as ex:
+        logger.write('Unknown error running userdata: %s\n' % str(ex))
+        return os.EX_SOFTWARE
     return p.returncode
 
 
index 0fce0e1519ded0a211cdaeb20ec196a003fe8e36..94c0f2cb36d5b30ab798138269babdcd0946e3b5 100644 (file)
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-
+import errno
 import mox
 import os
 import pkg_resources
@@ -23,7 +23,7 @@ import StringIO
 
 from nose.plugins.attrib import attr
 
-import heat.cloudinit.loguserdata as loguserdata
+from heat.cloudinit import loguserdata
 
 
 class FakeCiVersion():
@@ -118,14 +118,62 @@ class LoguserdataTest(unittest.TestCase):
         loguserdata.main(log)
         self.m.VerifyAll()
 
-    def test_main_fails(self):
+    def test_main_script_empty(self):
 
         log = StringIO.StringIO()
 
+        pkg_resources.get_distribution('cloud-init').AndReturn(
+            FakeCiVersion('0.7.0'))
+
+        os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0700).AndReturn(None)
+        subprocess.Popen(
+            ['/var/lib/heat-cfntools/cfn-userdata'],
+            stderr=log,
+            stdout=log).AndRaise(OSError(errno.ENOEXEC, "empty script"))
+
+        self.m.ReplayAll()
+        self.assertEqual(None, loguserdata.main(log))
+
+        self.m.VerifyAll()
+
+    def test_main_os_error(self):
+
+        log = StringIO.StringIO()
+
+        pkg_resources.get_distribution('cloud-init').AndReturn(
+            FakeCiVersion('0.7.0'))
+
+        os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0700).AndReturn(None)
+        subprocess.Popen(
+            ['/var/lib/heat-cfntools/cfn-userdata'],
+            stderr=log,
+            stdout=log).AndRaise(OSError(errno.ENOENT, "no such file"))
+
+        self.m.ReplayAll()
+        self.assertEqual(os.EX_OSERR, loguserdata.main(log))
+
+        self.m.VerifyAll()
+
+    def test_main_error_other(self):
+        log = StringIO.StringIO()
+        pkg_resources.get_distribution('cloud-init').AndReturn(
+            FakeCiVersion('0.7.0'))
+        os.chmod('/var/lib/heat-cfntools/cfn-userdata', 0700).AndReturn(None)
+        subprocess.Popen(
+            ['/var/lib/heat-cfntools/cfn-userdata'],
+            stderr=log,
+            stdout=log).AndRaise(IOError("read failed"))
+
+        self.m.ReplayAll()
+        self.assertEqual(os.EX_SOFTWARE, loguserdata.main(log))
+        self.m.VerifyAll()
+
+    def test_main_fails(self):
+        log = StringIO.StringIO()
+
         #fail on ci version
         pkg_resources.get_distribution('cloud-init').AndReturn(
             FakeCiVersion('0.5.0'))
-
         #fail on execute cfn-userdata
         pkg_resources.get_distribution('cloud-init').AndReturn(
             FakeCiVersion('0.7.0'))
@@ -139,5 +187,4 @@ class LoguserdataTest(unittest.TestCase):
         self.m.ReplayAll()
         self.assertEqual(-1, loguserdata.main(log))
         self.assertEqual(-2, loguserdata.main(log))
-
         self.m.VerifyAll()