Fix upgrades of instances with missing creation time
authorHrvoje Ribicic <riba@google.com>
Tue, 27 Oct 2015 18:38:16 +0000 (18:38 +0000)
committerHrvoje Ribicic <riba@google.com>
Wed, 28 Oct 2015 14:41:04 +0000 (14:41 +0000)
Some instances from very old Ganeti versions may not have any creation
time information embedded in the config. The upgrade code does not
expect this, and crashes horribly when trying to populate newly
separate disk objects with the same creation time, and this patch
fixes things by inserting a fake value: 0.

The value was chosen because the serialization and deserialization of
such an instance in Haskell yields a value of 0 for the ctime, making
the time consistent between instance and disk. While showing the epoch
time instead of N/A in gnt-instance info is suboptimal, due to the age
of the Ganeti version in which these instances must have been created,
they are at least still ordered correctly.

Signed-off-by: Gerard Oskamp <gjo@google.com>
Signed-off-by: Hrvoje Ribicic <riba@google.com>
Reviewed-by: Klaus Aehlig <aehlig@google.com>

test/data/cluster_config_2.11.json
test/py/cfgupgrade_unittest.py
tools/cfgupgrade

index d4c5f5b..dc8a4e6 100644 (file)
             "admin_state": "up",
             "admin_state_source": "admin",
             "beparams": {},
-            "ctime": 1355186880.451181,
             "disk_template": "plain",
             "disks": [
                 {
index 8602996..7afda1f 100755 (executable)
@@ -396,6 +396,9 @@ class TestCfgupgrade(unittest.TestCase):
   def testUpgradeFullConfigFrom_2_10(self):
     self._TestUpgradeFromFile("cluster_config_2.10.json", False)
 
+  def testUpgradeFullConfigFrom_2_11(self):
+    self._TestUpgradeFromFile("cluster_config_2.11.json", False)
+
   def testUpgradeCurrent(self):
     self._TestSimpleUpgrade(constants.CONFIG_VERSION, False)
 
index 9131fde..baffe56 100755 (executable)
@@ -445,7 +445,9 @@ def UpgradeTopLevelDisks(config_data):
     for disk in iobj["disks"]:
       duuid = disk["uuid"]
       disk["serial_no"] = 1
-      disk["ctime"] = disk["mtime"] = iobj["ctime"]
+      # Instances may not have the ctime value, and the Haskell serialization
+      # will have set it to zero.
+      disk["ctime"] = disk["mtime"] = iobj.get("ctime", 0)
       config_data["disks"][duuid] = disk
       disk_uuids.append(duuid)
     iobj["disks"] = disk_uuids