Repository: Azure/WALinuxAgent
Pull request #564 (2017-01-20 21:05:29)

Unhandled errors
Multiple unhandled errors were found in our telemetry. This addresses the following issues:
- ignore missing vmbus file
- correctly handle decoding of custom data
- handle errors in resource disk activation

/cc @jinhyunr @brendandixon 


Patch:
diff --git a/azurelinuxagent/common/osutil/default.py b/azurelinuxagent/common/osutil/default.py
index 5465c5c2..8973025d 100644
--- a/azurelinuxagent/common/osutil/default.py
+++ b/azurelinuxagent/common/osutil/default.py
@@ -728,20 +728,21 @@ class DefaultOSUtil(object):
             port_id = port_id - 2
         device = None
         path = "/sys/bus/vmbus/devices/"
-        for vmbus in os.listdir(path):
-            deviceid = fileutil.read_file(os.path.join(path, vmbus, "device_id"))
-            guid = deviceid.lstrip('{').split('-')
-            if guid[0] == g0 and guid[1] == "000" + ustr(port_id):
-                for root, dirs, files in os.walk(path + vmbus):
-                    if root.endswith("/block"):
-                        device = dirs[0]
-                        break
-                    else : #older distros
-                        for d in dirs:
-                            if ':' in d and "block" == d.split(':')[0]:
-                                device = d.split(':')[1]
-                                break
-                break
+        if os.path.exists(path):
+            for vmbus in os.listdir(path):
+                deviceid = fileutil.read_file(os.path.join(path, vmbus, "device_id"))
+                guid = deviceid.lstrip('{').split('-')
+                if guid[0] == g0 and guid[1] == "000" + ustr(port_id):
+                    for root, dirs, files in os.walk(path + vmbus):
+                        if root.endswith("/block"):
+                            device = dirs[0]
+                            break
+                        else : #older distros
+                            for d in dirs:
+                                if ':' in d and "block" == d.split(':')[0]:
+                                    device = d.split(':')[1]
+                                    break
+                    break
         return device
 
     def set_hostname_record(self, hostname):
@@ -761,7 +762,7 @@ class DefaultOSUtil(object):
         self.conf_sudoer(username, remove=True)
 
     def decode_customdata(self, data):
-        return base64.b64decode(data)
+        return base64.b64decode(data).decode('utf-8')
 
     def get_total_mem(self):
         # Get total memory in bytes and divide by 1024**2 to get the valu in MB.
diff --git a/azurelinuxagent/daemon/resourcedisk/default.py b/azurelinuxagent/daemon/resourcedisk/default.py
index ee79aac2..bfcfee86 100644
--- a/azurelinuxagent/daemon/resourcedisk/default.py
+++ b/azurelinuxagent/daemon/resourcedisk/default.py
@@ -99,7 +99,14 @@ class ResourceDiskHandler(object):
                         existing)
             return existing
 
-        fileutil.mkdir(mount_point, mode=0o755)
+        try:
+            fileutil.mkdir(mount_point, mode=0o755)
+        except OSError as ose:
+            msg = "Failed to create mount point " \
+                  "directory [{0}]: {1}".format(mount_point, ose)
+            logger.error(msg)
+            raise ResourceDiskError(msg=msg, inner=ose)
+
         logger.info("Examining partition table")
         ret = shellutil.run_get_output("parted {0} print".format(device))
         if ret[0]:
@@ -217,7 +224,9 @@ class ResourceDiskHandler(object):
         swapfile = os.path.join(mount_point, 'swapfile')
         swaplist = shellutil.run_get_output("swapon -s")[1]
 
-        if swapfile in swaplist and os.path.getsize(swapfile) == size:
+        if swapfile in swaplist \
+                and os.path.isfile(swapfile) \
+                and os.path.getsize(swapfile) == size:
             logger.info("Swap already enabled")
             return
 


Test patch:
diff --git a/tests/pa/test_provision.py b/tests/pa/test_provision.py
index 6508017c..a98eacd0 100644
--- a/tests/pa/test_provision.py
+++ b/tests/pa/test_provision.py
@@ -15,11 +15,12 @@
 # Requires Python 2.4+ and Openssl 1.0+
 #
 
-from tests.tools import *
-import azurelinuxagent.common.conf as conf
-from azurelinuxagent.common.protocol import OVF_FILE_NAME
 import azurelinuxagent.common.utils.fileutil as fileutil
+from azurelinuxagent.common.osutil.default import DefaultOSUtil
+from azurelinuxagent.common.protocol import OVF_FILE_NAME
 from azurelinuxagent.pa.provision import get_provision_handler
+from tests.tools import *
+
 
 class TestProvision(AgentTestCase):
  
@@ -42,6 +43,12 @@ class TestProvision(AgentTestCase):
          
         provision_handler.run()
 
+    def test_customdata(self):
+        base64data = 'Q3VzdG9tRGF0YQ=='
+        data = DefaultOSUtil().decode_customdata(base64data)
+        fileutil.write_file(tempfile.mktemp(), data)
+
+
 if __name__ == '__main__':
     unittest.main()