From 78e89b03ecb29e7df3181b1219a0b5f44b9d7532 Mon Sep 17 00:00:00 2001 From: Robert Schweikert Date: Thu, 1 Jul 2021 12:35:40 -0400 Subject: - Detect a Python version change and clear the cache (#857) summary: Clear cache when a Python version change is detected When a distribution gets updated it is possible that the Python version changes. Python makes no guarantee that pickle is consistent across versions as such we need to purge the cache and start over. Co-authored-by: James Falcon --- cloudinit/cmd/main.py | 30 ++++++++++++++++++++++++++++++ cloudinit/cmd/tests/test_main.py | 2 ++ 2 files changed, 32 insertions(+) (limited to 'cloudinit/cmd') diff --git a/cloudinit/cmd/main.py b/cloudinit/cmd/main.py index baf1381f..21213a4a 100644 --- a/cloudinit/cmd/main.py +++ b/cloudinit/cmd/main.py @@ -210,6 +210,35 @@ def attempt_cmdline_url(path, network=True, cmdline=None): (cmdline_name, url, path)) +def purge_cache_on_python_version_change(init): + """Purge the cache if python version changed on us. + + There could be changes not represented in our cache (obj.pkl) after we + upgrade to a new version of python, so at that point clear the cache + """ + current_python_version = '%d.%d' % ( + sys.version_info.major, sys.version_info.minor + ) + python_version_path = os.path.join( + init.paths.get_cpath('data'), 'python-version' + ) + if os.path.exists(python_version_path): + cached_python_version = open(python_version_path).read() + # The Python version has changed out from under us, anything that was + # pickled previously is likely useless due to API changes. + if cached_python_version != current_python_version: + LOG.debug('Python version change detected. Purging cache') + init.purge_cache(True) + util.write_file(python_version_path, current_python_version) + else: + if os.path.exists(init.paths.get_ipath_cur('obj_pkl')): + LOG.info( + 'Writing python-version file. ' + 'Cache compatibility status is currently unknown.' + ) + util.write_file(python_version_path, current_python_version) + + def main_init(name, args): deps = [sources.DEP_FILESYSTEM, sources.DEP_NETWORK] if args.local: @@ -276,6 +305,7 @@ def main_init(name, args): util.logexc(LOG, "Failed to initialize, likely bad things to come!") # Stage 4 path_helper = init.paths + purge_cache_on_python_version_change(init) mode = sources.DSMODE_LOCAL if args.local else sources.DSMODE_NETWORK if mode == sources.DSMODE_NETWORK: diff --git a/cloudinit/cmd/tests/test_main.py b/cloudinit/cmd/tests/test_main.py index 78b27441..1f5975b0 100644 --- a/cloudinit/cmd/tests/test_main.py +++ b/cloudinit/cmd/tests/test_main.py @@ -17,6 +17,8 @@ myargs = namedtuple('MyArgs', 'debug files force local reporter subcommand') class TestMain(FilesystemMockingTestCase): + with_logs = True + allowed_subp = False def setUp(self): super(TestMain, self).setUp() -- cgit v1.2.3