Prepare version numbers for 2.10 release cycle
[ganeti-local] / tools / cfgupgrade
index 6bcf773..1135103 100755 (executable)
@@ -44,6 +44,8 @@ from ganeti import config
 from ganeti import netutils
 from ganeti import pathutils
 
+from ganeti.utils import version
+
 
 options = None
 args = None
@@ -58,6 +60,12 @@ DOWNGRADE_MAJOR = 2
 #: Target minor version for downgrade
 DOWNGRADE_MINOR = 9
 
+# map of legacy device types
+# (mapping differing old LD_* constants to new DT_* constants)
+DEV_TYPE_OLD_NEW = {"lvm": constants.DT_PLAIN, "drbd8": constants.DT_DRBD8}
+# (mapping differing new DT_* constants to old LD_* constants)
+DEV_TYPE_NEW_OLD = dict((v, k) for k, v in DEV_TYPE_OLD_NEW.items())
+
 
 class Error(Exception):
   """Generic exception"""
@@ -173,7 +181,34 @@ def GetExclusiveStorageValue(config_data):
   return ret
 
 
+def RemovePhysicalId(disk):
+  if "children" in disk:
+    for d in disk["children"]:
+      RemovePhysicalId(d)
+  if "physical_id" in disk:
+    del disk["physical_id"]
+
+
+def ChangeDiskDevType(disk, dev_type_map):
+  """Replaces disk's dev_type attributes according to the given map.
+
+  This can be used for both, up or downgrading the disks.
+  """
+  if disk["dev_type"] in dev_type_map:
+    disk["dev_type"] = dev_type_map[disk["dev_type"]]
+  if "children" in disk:
+    for child in disk["children"]:
+      ChangeDiskDevType(child, dev_type_map)
+
+
+def UpgradeDiskDevType(disk):
+  """Upgrades the disks' device type."""
+  ChangeDiskDevType(disk, DEV_TYPE_OLD_NEW)
+
+
 def UpgradeInstances(config_data):
+  """Upgrades the instances' configuration."""
+
   network2uuid = dict((n["name"], n["uuid"])
                       for n in config_data["networks"].values())
   if "instances" not in config_data:
@@ -194,6 +229,8 @@ def UpgradeInstances(config_data):
       raise Error("Instance '%s' doesn't have a disks entry?!" % instance)
     disks = iobj["disks"]
     for idx, dobj in enumerate(disks):
+      RemovePhysicalId(dobj)
+
       expected = "disk/%s" % idx
       current = dobj.get("iv_name", "")
       if current != expected:
@@ -201,6 +238,10 @@ def UpgradeInstances(config_data):
                         " from '%s' to '%s'",
                         instance, idx, current, expected)
         dobj["iv_name"] = expected
+
+      if "dev_type" in dobj:
+        UpgradeDiskDevType(dobj)
+
       if not "spindles" in dobj:
         missing_spindles = True
 
@@ -288,7 +329,11 @@ def GetNewNodeIndex(nodes_by_old_key, old_key, new_key_field):
 
 def ChangeNodeIndices(config_data, old_key_field, new_key_field):
   def ChangeDiskNodeIndices(disk):
-    if disk["dev_type"] in constants.LDS_DRBD:
+    # Note: 'drbd8' is a legacy device type from pre 2.9 and needs to be
+    # considered when up/downgrading from/to any versions touching 2.9 on the
+    # way.
+    drbd_disk_types = set(["drbd8"]) | constants.DTS_DRBD
+    if disk["dev_type"] in drbd_disk_types:
       for i in range(0, 2):
         disk["logical_id"][i] = GetNewNodeIndex(nodes_by_old_key,
                                                 disk["logical_id"][i],
@@ -337,8 +382,7 @@ def UpgradeInstanceIndices(config_data):
 
 
 def UpgradeAll(config_data):
-  config_data["version"] = constants.BuildVersion(TARGET_MAJOR,
-                                                  TARGET_MINOR, 0)
+  config_data["version"] = version.BuildVersion(TARGET_MAJOR, TARGET_MINOR, 0)
   UpgradeRapiUsers()
   UpgradeWatcher()
   UpgradeFileStoragePaths(config_data)
@@ -350,11 +394,28 @@ def UpgradeAll(config_data):
   UpgradeInstanceIndices(config_data)
 
 
+def DowngradeInstances(config_data):
+  if "instances" not in config_data:
+    raise Error("Cannot find the 'instances' key in the configuration!")
+  for (iname, iobj) in config_data["instances"].items():
+    DowngradeNicParamsVLAN(iobj["nics"], iname)
+
+
+def DowngradeNicParamsVLAN(nics, owner):
+  for nic in nics:
+    vlan = nic["nicparams"].get("vlan", None)
+    if vlan:
+      logging.warning("Instance with name %s found. Removing VLAN information"
+                      " %s.", owner, vlan)
+      del nic["nicparams"]["vlan"]
+
+
 def DowngradeAll(config_data):
   # Any code specific to a particular version should be labeled that way, so
   # it can be removed when updating to the next version.
-  config_data["version"] = constants.BuildVersion(DOWNGRADE_MAJOR,
-                                                  DOWNGRADE_MINOR, 0)
+  config_data["version"] = version.BuildVersion(DOWNGRADE_MAJOR,
+                                                DOWNGRADE_MINOR, 0)
+  DowngradeInstances(config_data)
 
 
 def main():
@@ -455,7 +516,7 @@ def main():
     raise Error("Unable to determine configuration version")
 
   (config_major, config_minor, config_revision) = \
-    constants.SplitVersion(config_version)
+    version.SplitVersion(config_version)
 
   logging.info("Found configuration version %s (%d.%d.%d)",
                config_version, config_major, config_minor, config_revision)
@@ -475,7 +536,7 @@ def main():
                    config_minor, config_revision))
     DowngradeAll(config_data)
 
-  # Upgrade from 2.{0..7} to 2.9
+  # Upgrade from 2.{0..9} to 2.10
   elif config_major == 2 and config_minor in range(0, 10):
     if config_revision != 0:
       logging.warning("Config revision is %s, not 0", config_revision)