sailesh1993 / rpms / cloud-init

Forked from rpms/cloud-init a year ago
Clone
44fd36
From 83f3d481c5f0d962bff5bacfd2c323529754869e Mon Sep 17 00:00:00 2001
44fd36
From: Amy Chen <xiachen@redhat.com>
44fd36
Date: Thu, 2 Dec 2021 18:11:08 +0800
44fd36
Subject: [PATCH] fix error on upgrade caused by new vendordata2 attributes
44fd36
44fd36
RH-Author: xiachen <None>
44fd36
RH-MergeRequest: 14: fix error on upgrade caused by new vendordata2 attributes
44fd36
RH-Commit: [1/1] ef14db399cd1fe6e4ba847d98acee15fef8021de (xiachen/cloud-init-centos)
44fd36
RH-Bugzilla: 2028381
44fd36
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
44fd36
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
44fd36
RH-Acked-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
44fd36
44fd36
commit d132356cc361abef2d90d4073438f3ab759d5964
44fd36
Author: James Falcon <TheRealFalcon@users.noreply.github.com>
44fd36
Date:   Mon Apr 19 11:31:28 2021 -0500
44fd36
44fd36
    fix error on upgrade caused by new vendordata2 attributes (#869)
44fd36
44fd36
    In #777, we added 'vendordata2' and 'vendordata2_raw' attributes to
44fd36
    the DataSource class, but didn't use the upgrade framework to deal
44fd36
    with an unpickle after upgrade. This commit adds the necessary
44fd36
    upgrade code.
44fd36
44fd36
    Additionally, added a smaller-scope upgrade test to our integration
44fd36
    tests that will be run on every CI run so we catch these issues
44fd36
    immediately in the future.
44fd36
44fd36
    LP: #1922739
44fd36
44fd36
Signed-off-by: Amy Chen <xiachen@redhat.com>
44fd36
---
44fd36
 cloudinit/sources/__init__.py           | 12 +++++++++++-
44fd36
 cloudinit/tests/test_upgrade.py         |  4 ++++
44fd36
 tests/integration_tests/clouds.py       |  4 ++--
44fd36
 tests/integration_tests/test_upgrade.py | 25 ++++++++++++++++++++++++-
44fd36
 4 files changed, 41 insertions(+), 4 deletions(-)
44fd36
44fd36
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
44fd36
index 1ad1880d..7d74f8d9 100644
44fd36
--- a/cloudinit/sources/__init__.py
44fd36
+++ b/cloudinit/sources/__init__.py
44fd36
@@ -24,6 +24,7 @@ from cloudinit import util
44fd36
 from cloudinit.atomic_helper import write_json
44fd36
 from cloudinit.event import EventType
44fd36
 from cloudinit.filters import launch_index
44fd36
+from cloudinit.persistence import CloudInitPickleMixin
44fd36
 from cloudinit.reporting import events
44fd36
 
44fd36
 DSMODE_DISABLED = "disabled"
44fd36
@@ -134,7 +135,7 @@ URLParams = namedtuple(
44fd36
     'URLParms', ['max_wait_seconds', 'timeout_seconds', 'num_retries'])
44fd36
 
44fd36
 
44fd36
-class DataSource(metaclass=abc.ABCMeta):
44fd36
+class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
44fd36
 
44fd36
     dsmode = DSMODE_NETWORK
44fd36
     default_locale = 'en_US.UTF-8'
44fd36
@@ -196,6 +197,8 @@ class DataSource(metaclass=abc.ABCMeta):
44fd36
     # non-root users
44fd36
     sensitive_metadata_keys = ('merged_cfg', 'security-credentials',)
44fd36
 
44fd36
+    _ci_pkl_version = 1
44fd36
+
44fd36
     def __init__(self, sys_cfg, distro, paths, ud_proc=None):
44fd36
         self.sys_cfg = sys_cfg
44fd36
         self.distro = distro
44fd36
@@ -218,6 +221,13 @@ class DataSource(metaclass=abc.ABCMeta):
44fd36
         else:
44fd36
             self.ud_proc = ud_proc
44fd36
 
44fd36
+    def _unpickle(self, ci_pkl_version: int) -> None:
44fd36
+        """Perform deserialization fixes for Paths."""
44fd36
+        if not hasattr(self, 'vendordata2'):
44fd36
+            self.vendordata2 = None
44fd36
+        if not hasattr(self, 'vendordata2_raw'):
44fd36
+            self.vendordata2_raw = None
44fd36
+
44fd36
     def __str__(self):
44fd36
         return type_utils.obj_name(self)
44fd36
 
44fd36
diff --git a/cloudinit/tests/test_upgrade.py b/cloudinit/tests/test_upgrade.py
44fd36
index f79a2536..71cea616 100644
44fd36
--- a/cloudinit/tests/test_upgrade.py
44fd36
+++ b/cloudinit/tests/test_upgrade.py
44fd36
@@ -43,3 +43,7 @@ class TestUpgrade:
44fd36
     def test_blacklist_drivers_set_on_networking(self, previous_obj_pkl):
44fd36
         """We always expect Networking.blacklist_drivers to be initialised."""
44fd36
         assert previous_obj_pkl.distro.networking.blacklist_drivers is None
44fd36
+
44fd36
+    def test_vendordata_exists(self, previous_obj_pkl):
44fd36
+        assert previous_obj_pkl.vendordata2 is None
44fd36
+        assert previous_obj_pkl.vendordata2_raw is None
44fd36
\ No newline at end of file
44fd36
diff --git a/tests/integration_tests/clouds.py b/tests/integration_tests/clouds.py
44fd36
index 9527a413..1d0b9d83 100644
44fd36
--- a/tests/integration_tests/clouds.py
44fd36
+++ b/tests/integration_tests/clouds.py
44fd36
@@ -100,14 +100,14 @@ class IntegrationCloud(ABC):
44fd36
             # Even if we're using the default key, it may still have a
44fd36
             # different name in the clouds, so we need to set it separately.
44fd36
             self.cloud_instance.key_pair.name = settings.KEYPAIR_NAME
44fd36
-        self._released_image_id = self._get_initial_image()
44fd36
+        self.released_image_id = self._get_initial_image()
44fd36
         self.snapshot_id = None
44fd36
 
44fd36
     @property
44fd36
     def image_id(self):
44fd36
         if self.snapshot_id:
44fd36
             return self.snapshot_id
44fd36
-        return self._released_image_id
44fd36
+        return self.released_image_id
44fd36
 
44fd36
     def emit_settings_to_log(self) -> None:
44fd36
         log.info(
44fd36
diff --git a/tests/integration_tests/test_upgrade.py b/tests/integration_tests/test_upgrade.py
44fd36
index c20cb3c1..48e0691b 100644
44fd36
--- a/tests/integration_tests/test_upgrade.py
44fd36
+++ b/tests/integration_tests/test_upgrade.py
44fd36
@@ -1,4 +1,5 @@
44fd36
 import logging
44fd36
+import os
44fd36
 import pytest
44fd36
 import time
44fd36
 from pathlib import Path
44fd36
@@ -8,6 +9,8 @@ from tests.integration_tests.conftest import (
44fd36
     get_validated_source,
44fd36
     session_start_time,
44fd36
 )
44fd36
+from tests.integration_tests.instances import CloudInitSource
44fd36
+
44fd36
 
44fd36
 log = logging.getLogger('integration_testing')
44fd36
 
44fd36
@@ -63,7 +66,7 @@ def test_upgrade(session_cloud: IntegrationCloud):
44fd36
         return  # type checking doesn't understand that skip raises
44fd36
 
44fd36
     launch_kwargs = {
44fd36
-        'image_id': session_cloud._get_initial_image(),
44fd36
+        'image_id': session_cloud.released_image_id,
44fd36
     }
44fd36
 
44fd36
     image = ImageSpecification.from_os_image()
44fd36
@@ -93,6 +96,26 @@ def test_upgrade(session_cloud: IntegrationCloud):
44fd36
         instance.install_new_cloud_init(source, take_snapshot=False)
44fd36
         instance.execute('hostname something-else')
44fd36
         _restart(instance)
44fd36
+        assert instance.execute('cloud-init status --wait --long').ok
44fd36
         _output_to_compare(instance, after_path, netcfg_path)
44fd36
 
44fd36
     log.info('Wrote upgrade test logs to %s and %s', before_path, after_path)
44fd36
+
44fd36
+
44fd36
+@pytest.mark.ci
44fd36
+@pytest.mark.ubuntu
44fd36
+def test_upgrade_package(session_cloud: IntegrationCloud):
44fd36
+    if get_validated_source(session_cloud) != CloudInitSource.DEB_PACKAGE:
44fd36
+        not_run_message = 'Test only supports upgrading to build deb'
44fd36
+        if os.environ.get('TRAVIS'):
44fd36
+            # If this isn't running on CI, we should know
44fd36
+            pytest.fail(not_run_message)
44fd36
+        else:
44fd36
+            pytest.skip(not_run_message)
44fd36
+
44fd36
+    launch_kwargs = {'image_id': session_cloud.released_image_id}
44fd36
+
44fd36
+    with session_cloud.launch(launch_kwargs=launch_kwargs) as instance:
44fd36
+        instance.install_deb()
44fd36
+        instance.restart()
44fd36
+        assert instance.execute('cloud-init status --wait --long').ok
44fd36
-- 
44fd36
2.27.0
44fd36