Repository: Azure/WALinuxAgent
Pull request #459 (2016-10-07 20:08:12)

Add version hooks for F5 products
F5's products do not use the common /etc/product-release format for
platform version information. A different method is needed via parsing
the /VERSION file.

I was not sure if /VERSION was too broad of a thing to check for (for
instance if it might crop up in other platforms) so instead I check
for the /shared/vadc which is definitely an F5-ism.

This patch adds a small method to parse the relevant content from that
file and put it in a list that is returned for later use by the rest
of the version.py lib.


msftclas: Hi __@caphrim007__, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!
    <span>You've already signed the contribution license agreement. Thanks!</span>
        <p>The agreement was validated by Microsoft and real humans are currently evaluating your PR.</p>

TTYL, MSBOT;

caphrim007: @brendandixon @hglkrijger any comments on this?
brendandixon: @caphrim007 It looks good, but we should have tests. While much of the early code lacks tests, we're trying to ensure rigorous testing of all new code.
caphrim007: @brendandixon absolutely. Lemme go find out where to put those tests. Thanks!

Patch:
diff --git a/azurelinuxagent/common/version.py b/azurelinuxagent/common/version.py
index b2d970b3..b57b8fd2 100644
--- a/azurelinuxagent/common/version.py
+++ b/azurelinuxagent/common/version.py
@@ -39,11 +39,16 @@ def get_distro():
         osinfo = platform.dist()
 
     # The platform.py lib has issue with detecting oracle linux distribution.
-    # Merge the following patch provided by oracle as a temparory fix.
+    # Merge the following patch provided by oracle as a temporary fix.
     if os.path.exists("/etc/oracle-release"):
         osinfo[2] = "oracle"
         osinfo[3] = "Oracle Linux"
 
+    # The platform.py lib has issue with detecting BIG-IP linux distribution.
+    # Merge the following patch provided by F5.
+    if os.path.exists("/shared/vadc"):
+        osinfo = get_f5_platform()
+
     # Remove trailing whitespace and quote in distro name
     osinfo[0] = osinfo[0].strip('"').strip(' ').lower()
     return osinfo
@@ -134,3 +139,33 @@ def is_snappy():
 
 if is_snappy():
     DISTRO_FULL_NAME = "Snappy Ubuntu Core"
+
+"""
+Add this workaround for detecting F5 products because BIG-IP/IQ/etc do not show
+their version info in the /etc/product-version location. Instead, the version
+and product information is contained in the /VERSION file.
+"""
+def get_f5_platform():
+    result = [None,None,None,None]
+    f5_version = re.compile("^Version: (\d+\.\d+\.\d+)")
+    f5_product = re.compile("^Product: ([\w-]+)")
+
+    with open('/VERSION', 'r') as fh:
+        content = fh.readlines()
+        for line in content:
+            version_matches = f5_version.match(line)
+            product_matches = f5_product.match(line)
+            if version_matches:
+                result[1] = version_matches.group(1)
+            elif product_matches:
+                result[3] = product_matches.group(1)
+                if result[3] == "BIG-IP":
+                    result[0] = "bigip"
+                    result[2] = "bigip"
+                elif result[3] == "BIG-IQ":
+                    result[0] = "bigiq"
+                    result[2] = "bigiq"
+                elif result[3] == "iWorkflow":
+                    result[0] = "iworkflow"
+                    result[2] = "iworkflow"
+    return result


Test patch:
diff --git a/tests/common/test_version.py b/tests/common/test_version.py
index 6a4dc387..dbd7adaf 100644
--- a/tests/common/test_version.py
+++ b/tests/common/test_version.py
@@ -20,12 +20,14 @@ from __future__ import print_function
 import copy
 import glob
 import json
+import mock
 import os
 import platform
 import random
 import subprocess
 import sys
 import tempfile
+import textwrap
 import zipfile
 
 from tests.protocol.mockwiredata import *
@@ -34,6 +36,7 @@ from tests.tools import *
 import azurelinuxagent.common.conf as conf
 import azurelinuxagent.common.logger as logger
 import azurelinuxagent.common.utils.fileutil as fileutil
+import azurelinuxagent.common.version as version
 
 from azurelinuxagent.common.utils.flexible_version import FlexibleVersion
 from azurelinuxagent.common.version import *
@@ -63,3 +66,67 @@ class TestCurrentAgentName(AgentTestCase):
         self.assertEqual(agent, current_agent)
         self.assertEqual(version, str(current_version))
         return
+
+class TestGetF5Platforms(AgentTestCase):
+    def test_get_f5_platform_bigip_12_1_1(self):
+        version_file = textwrap.dedent("""
+        Product: BIG-IP
+        Version: 12.1.1
+        Build: 0.0.184
+        Sequence: 12.1.1.0.0.184.0
+        BaseBuild: 0.0.184
+        Edition: Final
+        Date: Thu Aug 11 17:09:01 PDT 2016
+        Built: 160811170901
+        Changelist: 1874858
+        JobID: 705993""")
+
+        mo = mock.mock_open(read_data=version_file)
+        with patch(open_patch(), mo):
+            platform = version.get_f5_platform()
+            self.assertTrue(platform[0] == 'bigip')
+            self.assertTrue(platform[1] == '12.1.1')
+            self.assertTrue(platform[2] == 'bigip')
+            self.assertTrue(platform[3] == 'BIG-IP')
+
+    def test_get_f5_platform_bigip_12_1_0_hf1(self):
+        version_file = textwrap.dedent("""
+        Product: BIG-IP
+        Version: 12.1.0
+        Build: 1.0.1447
+        Sequence: 12.1.0.1.0.1447.0
+        BaseBuild: 0.0.1434
+        Edition: Hotfix HF1
+        Date: Wed Jun  8 13:41:59 PDT 2016
+        Built: 160608134159
+        Changelist: 1773831
+        JobID: 673467""")
+
+        mo = mock.mock_open(read_data=version_file)
+        with patch(open_patch(), mo):
+            platform = version.get_f5_platform()
+            self.assertTrue(platform[0] == 'bigip')
+            self.assertTrue(platform[1] == '12.1.0')
+            self.assertTrue(platform[2] == 'bigip')
+            self.assertTrue(platform[3] == 'BIG-IP')
+
+    def test_get_f5_platform_bigip_12_0_0(self):
+        version_file = textwrap.dedent("""
+        Product: BIG-IP
+        Version: 12.0.0
+        Build: 0.0.606
+        Sequence: 12.0.0.0.0.606.0
+        BaseBuild: 0.0.606
+        Edition: Final
+        Date: Fri Aug 21 13:29:22 PDT 2015
+        Built: 150821132922
+        Changelist: 1486072
+        JobID: 536212""")
+
+        mo = mock.mock_open(read_data=version_file)
+        with patch(open_patch(), mo):
+            platform = version.get_f5_platform()
+            self.assertTrue(platform[0] == 'bigip')
+            self.assertTrue(platform[1] == '12.0.0')
+            self.assertTrue(platform[2] == 'bigip')
+            self.assertTrue(platform[3] == 'BIG-IP')