]> git-server-git.apps.pok.os.sepia.ceph.com Git - teuthology.git/commitdiff
Check os-type and os-version for vps 297/head
authorWarren Usui <warren.usui@inktank.com>
Tue, 9 Sep 2014 03:12:24 +0000 (20:12 -0700)
committerWarren Usui <warren.usui@inktank.com>
Wed, 10 Sep 2014 18:00:09 +0000 (11:00 -0700)
Fixes: 8712
Signed-off-by: Warren Usui warren.usui@inktank.com
teuthology/lock.py
teuthology/task/internal.py
teuthology/test/test_vps_os_vers_parameter_checking.py [new file with mode: 0644]

index 16272e337e106aaa25db2f2ac35644660428765d..a4119610f856da6305c9a6cdaaea53a3a453d490 100644 (file)
@@ -9,6 +9,7 @@ import os
 import time
 import requests
 import urllib
+from distutils.spawn import find_executable
 
 import teuthology
 from . import misc
@@ -23,6 +24,80 @@ logging.getLogger("requests.packages.urllib3.connectionpool").setLevel(
 
 is_vpm = lambda name: 'vpm' in name
 
+def get_distro_from_downburst():
+    """
+    Return a table of valid distros.
+
+    If downburst is in path use it.  If either downburst is unavailable,
+    or if downburst is unable to produce a json list, then use a default
+    table.
+    """
+    default_table = {u'rhel_minimal': [u'6.4', u'6.5'],
+                     u'fedora': [u'17', u'18', u'19', u'20'],
+                     u'centos': [u'6.3', u'6.4', u'6.5', u'7.0'],
+                     u'opensuse': [u'12.2'],
+                     u'rhel': [u'6.3', u'6.4', u'6.5', u'7.0', u'7beta'],
+                     u'centos_minimal': [u'6.4', u'6.5'],
+                     u'ubuntu': [u'8.04(hardy)', u'9.10(karmic)',
+                                 u'10.04(lucid)', u'10.10(maverick)',
+                                 u'11.04(natty)', u'11.10(oneiric)',
+                                 u'12.04(precise)', u'12.10(quantal)',
+                                 u'13.04(raring)', u'13.10(saucy)',
+                                 u'14.04(trusty)', u'utopic(utopic)'],
+                     u'sles': [u'11-sp2'],
+                     u'debian': [u'6.0', u'7.0']}
+    executable_cmd = find_executable('downburst')
+    if not executable_cmd:
+        log.info('Using default values for supported os_type/os_version')
+        return default_table
+    try:
+        p = subprocess.Popen([executable_cmd, 'list-json'],
+                             stdout=subprocess.PIPE, stderr=subprocess.PIPE,)
+        output, err = p.communicate()
+        downburst_data = json.loads(output)
+        return downburst_data
+    except OSError:
+        log.info('Using default values for supported os_type/os_version')
+        return default_table
+
+    
+def vps_version_or_type_valid(machine_type, os_type, os_version):
+    """
+    Check os-type and os-version parameters when locking a vps.
+    Os-type will always be set (defaults to ubuntu).
+   
+    In the case where downburst does not handle list-json (an older version
+    of downburst, for instance), a message is printed and this checking
+    is skipped (so that this code should behave as it did before this
+    check was added).
+    """
+    if not machine_type == 'vps':
+        return True
+    valid_os_and_version = get_distro_from_downburst()
+    if os_type not in valid_os_and_version:
+        log.error('os-type is invalid')
+        return False
+    if not validate_distro_version(os_version,
+                                   valid_os_and_version[os_type]):
+        log.error('os-version is invalid')
+        return False
+    return True
+
+def validate_distro_version(version, supported_versions):
+    """
+    Return True if the version is valid.  For Ubuntu, possible
+    supported version values are of the form '12.04 (precise)' where
+    either the number of the version name is acceptable.
+    """
+    if version in supported_versions:
+        return True
+    for parts in supported_versions:
+        part = parts.split('(') 
+        if len(part) == 2:
+            if version == part[0]:
+                return True
+            if version == part[1][0:len(part[1])-1]:
+                return True
 
 def main(ctx):
     if ctx.verbose:
@@ -158,6 +233,10 @@ def main(ctx):
         return 0
 
     elif ctx.lock:
+        if not vps_version_or_type_valid(ctx.machine_type, ctx.os_type,
+                                         ctx.os_version):
+            log.error('Invalid os-type or version detected -- lock failed')
+            return 1
         for machine in machines:
             if not lock_one(machine, user, ctx.desc):
                 ret = 1
@@ -224,6 +303,10 @@ def main(ctx):
 
 
 def lock_many(ctx, num, machinetype, user=None, description=None):
+    if not vps_version_or_type_valid(ctx.machine_type, ctx.os_type,
+                                     ctx.os_version):
+        log.error('Invalid os-type or version detected -- lock failed')
+        return
     machinetypes = misc.get_multi_machine_types(machinetype)
     if user is None:
         user = misc.get_user()
index cb0b41ce0d67b6ea5441a50759b28cfc09c22fb1..b4430e0ffadcff35c73f7c21c77aa5cb063b18a7 100644 (file)
@@ -96,6 +96,8 @@ def lock_machines(ctx, config):
 
         newly_locked = lock.lock_many(ctx, how_many, machine_type, ctx.owner,
                                       ctx.archive)
+        if not newly_locked and not isinstance(newly_locked, list):
+            raise RuntimeError('Invalid parameters specified')
         if len(newly_locked) == how_many:
             vmlist = []
             for lmach in newly_locked:
diff --git a/teuthology/test/test_vps_os_vers_parameter_checking.py b/teuthology/test/test_vps_os_vers_parameter_checking.py
new file mode 100644 (file)
index 0000000..d3b5fe9
--- /dev/null
@@ -0,0 +1,67 @@
+from .. import lock
+
+class Mock: pass
+
+class TestVpsOsVersionParamCheck(object):
+
+    def setup(self):
+        self.fake_ctx = Mock()
+        self.fake_ctx.machine_type = 'vps'
+        self.fake_ctx.num_to_lock = 1
+        self.fake_ctx.lock = False
+
+    def test_ubuntu_precise(self):
+        self.fake_ctx.os_type = 'ubuntu'
+        self.fake_ctx.os_version = 'precise'
+        check_value = lock.vps_version_or_type_valid(
+                      self.fake_ctx.machine_type,
+                      self.fake_ctx.os_type,
+                      self.fake_ctx.os_version)
+                            
+        assert check_value
+
+    def test_ubuntu_number(self):
+        self.fake_ctx.os_type = 'ubuntu'
+        self.fake_ctx.os_version = '12.04'
+        check_value = lock.vps_version_or_type_valid(
+                      self.fake_ctx.machine_type,
+                      self.fake_ctx.os_type,
+                      self.fake_ctx.os_version)
+        assert check_value
+
+    def test_rhel(self):
+        self.fake_ctx.os_type = 'rhel'
+        self.fake_ctx.os_version = '6.5'
+        check_value = lock.vps_version_or_type_valid(
+                      self.fake_ctx.machine_type,
+                      self.fake_ctx.os_type,
+                      self.fake_ctx.os_version)
+        assert check_value
+
+    def test_mixup(self):
+        self.fake_ctx.os_type = '6.5'
+        self.fake_ctx.os_version = 'rhel'
+        check_value = lock.vps_version_or_type_valid(
+                      self.fake_ctx.machine_type,
+                      self.fake_ctx.os_type,
+                      self.fake_ctx.os_version)
+        assert not check_value
+
+    def test_bad_type(self):
+        self.fake_ctx.os_type = 'aardvark'
+        self.fake_ctx.os_version = '6.5'
+        check_value = lock.vps_version_or_type_valid(
+                      self.fake_ctx.machine_type,
+                      self.fake_ctx.os_type,
+                      self.fake_ctx.os_version)
+        assert not check_value
+
+    def test_bad_version(self):
+        self.fake_ctx.os_type = 'rhel'
+        self.fake_ctx.os_version = 'vampire_bat'
+        check_value = lock.vps_version_or_type_valid(
+                      self.fake_ctx.machine_type,
+                      self.fake_ctx.os_type,
+                      self.fake_ctx.os_version)
+        assert not check_value
+