summaryrefslogtreecommitdiff
path: root/cloudinit/distros
diff options
context:
space:
mode:
authorDaniel Watkins <oddbloke@ubuntu.com>2020-11-17 16:37:29 -0500
committerGitHub <noreply@github.com>2020-11-17 16:37:29 -0500
commit4f2da1cc1d24cbc47025cc8613c0d3ec287a20f9 (patch)
tree00db3d5efc4a83e7fd4251d88943075e56b165a9 /cloudinit/distros
parenta925b5a0ca4aa3e63b084c0f6664fe815c2c9db0 (diff)
downloadvyos-cloud-init-4f2da1cc1d24cbc47025cc8613c0d3ec287a20f9.tar.gz
vyos-cloud-init-4f2da1cc1d24cbc47025cc8613c0d3ec287a20f9.zip
introduce an upgrade framework and related testing (#659)
This commit does the following: * introduces the `cloudinit.persistence` module, containing `CloudInitPickleMixin` which provides lightweight versioning of objects' pickled representations (and associated testing) * introduces a basic upgrade testing framework (in `cloudinit.tests.test_upgrade`) which unpickles pickles from previous versions of cloud-init (stored in `tests/data/old_pickles`) and tests invariants that the current cloud-init codebase expects * uses the versioning framework to address an upgrade issue where `Distro.networking` could get into an unexpected state, and uses the upgrade testing framework to confirm that the issue is addressed
Diffstat (limited to 'cloudinit/distros')
-rwxr-xr-xcloudinit/distros/__init__.py17
1 files changed, 16 insertions, 1 deletions
diff --git a/cloudinit/distros/__init__.py b/cloudinit/distros/__init__.py
index fac8cf67..1e118472 100755
--- a/cloudinit/distros/__init__.py
+++ b/cloudinit/distros/__init__.py
@@ -23,6 +23,7 @@ from cloudinit import net
from cloudinit.net import eni
from cloudinit.net import network_state
from cloudinit.net import renderers
+from cloudinit import persistence
from cloudinit import ssh_util
from cloudinit import type_utils
from cloudinit import subp
@@ -62,7 +63,7 @@ PREFERRED_NTP_CLIENTS = ['chrony', 'systemd-timesyncd', 'ntp', 'ntpdate']
LDH_ASCII_CHARS = string.ascii_letters + string.digits + "-"
-class Distro(metaclass=abc.ABCMeta):
+class Distro(persistence.CloudInitPickleMixin, metaclass=abc.ABCMeta):
usr_lib_exec = "/usr/lib"
hosts_fn = "/etc/hosts"
@@ -77,12 +78,26 @@ class Distro(metaclass=abc.ABCMeta):
# subclasses
shutdown_options_map = {'halt': '-H', 'poweroff': '-P', 'reboot': '-r'}
+ _ci_pkl_version = 1
+
def __init__(self, name, cfg, paths):
self._paths = paths
self._cfg = cfg
self.name = name
self.networking = self.networking_cls()
+ def _unpickle(self, ci_pkl_version: int) -> None:
+ """Perform deserialization fixes for Distro."""
+ if "networking" not in self.__dict__ or not self.networking.__dict__:
+ # This is either a Distro pickle with no networking attribute OR
+ # this is a Distro pickle with a networking attribute but from
+ # before ``Networking`` had any state (meaning that
+ # Networking.__setstate__ will not be called). In either case, we
+ # want to ensure that `self.networking` is freshly-instantiated:
+ # either because it isn't present at all, or because it will be
+ # missing expected instance state otherwise.
+ self.networking = self.networking_cls()
+
@abc.abstractmethod
def install_packages(self, pkglist):
raise NotImplementedError()