diff options
author | Daniel Watkins <oddbloke@ubuntu.com> | 2020-11-17 16:37:29 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-17 16:37:29 -0500 |
commit | 4f2da1cc1d24cbc47025cc8613c0d3ec287a20f9 (patch) | |
tree | 00db3d5efc4a83e7fd4251d88943075e56b165a9 /cloudinit/distros | |
parent | a925b5a0ca4aa3e63b084c0f6664fe815c2c9db0 (diff) | |
download | vyos-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-x | cloudinit/distros/__init__.py | 17 |
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() |