6732b3
From 04a4cc7b8da04ba4103118cf9d975d8e9548e0dc Mon Sep 17 00:00:00 2001
6732b3
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6732b3
Date: Fri, 4 Mar 2022 11:23:22 +0100
6732b3
Subject: [PATCH 2/2] Fix MIME policy failure on python version upgrade (#934)
6732b3
6732b3
RH-Author: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6732b3
RH-MergeRequest: 54: - Detect a Python version change and clear the cache (#857)
6732b3
RH-Commit: [2/2] 05fc8c52a39b5ad464ad146488703467e39d73b1
6732b3
RH-Bugzilla: 1935826
6732b3
RH-Acked-by: Eduardo Otubo <otubo@redhat.com>
6732b3
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
6732b3
RH-Acked-by: Mohamed Gamal Morsy <mmorsy@redhat.com>
6732b3
6732b3
commit eacb0353803263934aa2ac827c37e461c87cb107
6732b3
Author: James Falcon <therealfalcon@gmail.com>
6732b3
Date:   Thu Jul 15 17:52:21 2021 -0500
6732b3
6732b3
    Fix MIME policy failure on python version upgrade (#934)
6732b3
6732b3
    Python 3.6 added a new `policy` attribute to `MIMEMultipart`.
6732b3
    MIMEMultipart may be part of the cached object pickle of a datasource.
6732b3
    Upgrading from an old version of python to 3.6+ will cause the
6732b3
    datasource to be invalid after pickle load.
6732b3
6732b3
    This commit uses the upgrade framework to attempt to access the mime
6732b3
    message and fail early (thus discarding the cache) if we cannot.
6732b3
    Commit 78e89b03 should fix this issue more generally.
6732b3
6732b3
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
6732b3
---
6732b3
 cloudinit/sources/__init__.py                 |  18 +
6732b3
 cloudinit/stages.py                           |   2 +
6732b3
 .../assets/trusty_with_mime.pkl               | 572 ++++++++++++++++++
6732b3
 .../modules/test_persistence.py               |  30 +
6732b3
 4 files changed, 622 insertions(+)
6732b3
 create mode 100644 tests/integration_tests/assets/trusty_with_mime.pkl
6732b3
 create mode 100644 tests/integration_tests/modules/test_persistence.py
6732b3
6732b3
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
6732b3
index 7d74f8d9..338861e6 100644
6732b3
--- a/cloudinit/sources/__init__.py
6732b3
+++ b/cloudinit/sources/__init__.py
6732b3
@@ -74,6 +74,10 @@ NetworkConfigSource = namedtuple('NetworkConfigSource',
6732b3
                                  _NETCFG_SOURCE_NAMES)(*_NETCFG_SOURCE_NAMES)
6732b3
 
6732b3
 
6732b3
+class DatasourceUnpickleUserDataError(Exception):
6732b3
+    """Raised when userdata is unable to be unpickled due to python upgrades"""
6732b3
+
6732b3
+
6732b3
 class DataSourceNotFoundException(Exception):
6732b3
     pass
6732b3
 
6732b3
@@ -227,6 +231,20 @@ class DataSource(CloudInitPickleMixin, metaclass=abc.ABCMeta):
6732b3
             self.vendordata2 = None
6732b3
         if not hasattr(self, 'vendordata2_raw'):
6732b3
             self.vendordata2_raw = None
6732b3
+        if hasattr(self, 'userdata') and self.userdata is not None:
6732b3
+            # If userdata stores MIME data, on < python3.6 it will be
6732b3
+            # missing the 'policy' attribute that exists on >=python3.6.
6732b3
+            # Calling str() on the userdata will attempt to access this
6732b3
+            # policy attribute. This will raise an exception, causing
6732b3
+            # the pickle load to fail, so cloud-init will discard the cache
6732b3
+            try:
6732b3
+                str(self.userdata)
6732b3
+            except AttributeError as e:
6732b3
+                LOG.debug(
6732b3
+                    "Unable to unpickle datasource: %s."
6732b3
+                    " Ignoring current cache.", e
6732b3
+                )
6732b3
+                raise DatasourceUnpickleUserDataError() from e
6732b3
 
6732b3
     def __str__(self):
6732b3
         return type_utils.obj_name(self)
6732b3
diff --git a/cloudinit/stages.py b/cloudinit/stages.py
6732b3
index 83e25dd1..e709a5cf 100644
6732b3
--- a/cloudinit/stages.py
6732b3
+++ b/cloudinit/stages.py
6732b3
@@ -980,6 +980,8 @@ def _pkl_load(fname):
6732b3
         return None
6732b3
     try:
6732b3
         return pickle.loads(pickle_contents)
6732b3
+    except sources.DatasourceUnpickleUserDataError:
6732b3
+        return None
6732b3
     except Exception:
6732b3
         util.logexc(LOG, "Failed loading pickled blob from %s", fname)
6732b3
         return None
6732b3
diff --git a/tests/integration_tests/assets/trusty_with_mime.pkl b/tests/integration_tests/assets/trusty_with_mime.pkl
6732b3
new file mode 100644
6732b3
index 00000000..a4089ecf
6732b3
--- /dev/null
6732b3
+++ b/tests/integration_tests/assets/trusty_with_mime.pkl
6732b3
@@ -0,0 +1,572 @@
6732b3
+ccopy_reg
6732b3
+_reconstructor
6732b3
+p1
6732b3
+(ccloudinit.sources.DataSourceNoCloud
6732b3
+DataSourceNoCloudNet
6732b3
+p2
6732b3
+c__builtin__
6732b3
+object
6732b3
+p3
6732b3
+NtRp4
6732b3
+(dp5
6732b3
+S'paths'
6732b3
+p6
6732b3
+g1
6732b3
+(ccloudinit.helpers
6732b3
+Paths
6732b3
+p7
6732b3
+g3
6732b3
+NtRp8
6732b3
+(dp9
6732b3
+S'lookups'
6732b3
+p10
6732b3
+(dp11
6732b3
+S'cloud_config'
6732b3
+p12
6732b3
+S'cloud-config.txt'
6732b3
+p13
6732b3
+sS'userdata'
6732b3
+p14
6732b3
+S'user-data.txt.i'
6732b3
+p15
6732b3
+sS'vendordata'
6732b3
+p16
6732b3
+S'vendor-data.txt.i'
6732b3
+p17
6732b3
+sS'userdata_raw'
6732b3
+p18
6732b3
+S'user-data.txt'
6732b3
+p19
6732b3
+sS'boothooks'
6732b3
+p20
6732b3
+g20
6732b3
+sS'scripts'
6732b3
+p21
6732b3
+g21
6732b3
+sS'sem'
6732b3
+p22
6732b3
+g22
6732b3
+sS'data'
6732b3
+p23
6732b3
+g23
6732b3
+sS'vendor_scripts'
6732b3
+p24
6732b3
+S'scripts/vendor'
6732b3
+p25
6732b3
+sS'handlers'
6732b3
+p26
6732b3
+g26
6732b3
+sS'obj_pkl'
6732b3
+p27
6732b3
+S'obj.pkl'
6732b3
+p28
6732b3
+sS'vendordata_raw'
6732b3
+p29
6732b3
+S'vendor-data.txt'
6732b3
+p30
6732b3
+sS'vendor_cloud_config'
6732b3
+p31
6732b3
+S'vendor-cloud-config.txt'
6732b3
+p32
6732b3
+ssS'template_tpl'
6732b3
+p33
6732b3
+S'/etc/cloud/templates/%s.tmpl'
6732b3
+p34
6732b3
+sS'cfgs'
6732b3
+p35
6732b3
+(dp36
6732b3
+S'cloud_dir'
6732b3
+p37
6732b3
+S'/var/lib/cloud/'
6732b3
+p38
6732b3
+sS'templates_dir'
6732b3
+p39
6732b3
+S'/etc/cloud/templates/'
6732b3
+p40
6732b3
+sS'upstart_dir'
6732b3
+p41
6732b3
+S'/etc/init/'
6732b3
+p42
6732b3
+ssS'cloud_dir'
6732b3
+p43
6732b3
+g38
6732b3
+sS'datasource'
6732b3
+p44
6732b3
+NsS'upstart_conf_d'
6732b3
+p45
6732b3
+g42
6732b3
+sS'boot_finished'
6732b3
+p46
6732b3
+S'/var/lib/cloud/instance/boot-finished'
6732b3
+p47
6732b3
+sS'instance_link'
6732b3
+p48
6732b3
+S'/var/lib/cloud/instance'
6732b3
+p49
6732b3
+sS'seed_dir'
6732b3
+p50
6732b3
+S'/var/lib/cloud/seed'
6732b3
+p51
6732b3
+sbsS'supported_seed_starts'
6732b3
+p52
6732b3
+(S'http://'
6732b3
+p53
6732b3
+S'https://'
6732b3
+p54
6732b3
+S'ftp://'
6732b3
+p55
6732b3
+tp56
6732b3
+sS'sys_cfg'
6732b3
+p57
6732b3
+(dp58
6732b3
+S'output'
6732b3
+p59
6732b3
+(dp60
6732b3
+S'all'
6732b3
+p61
6732b3
+S'| tee -a /var/log/cloud-init-output.log'
6732b3
+p62
6732b3
+ssS'users'
6732b3
+p63
6732b3
+(lp64
6732b3
+S'default'
6732b3
+p65
6732b3
+asS'def_log_file'
6732b3
+p66
6732b3
+S'/var/log/cloud-init.log'
6732b3
+p67
6732b3
+sS'cloud_final_modules'
6732b3
+p68
6732b3
+(lp69
6732b3
+S'rightscale_userdata'
6732b3
+p70
6732b3
+aS'scripts-vendor'
6732b3
+p71
6732b3
+aS'scripts-per-once'
6732b3
+p72
6732b3
+aS'scripts-per-boot'
6732b3
+p73
6732b3
+aS'scripts-per-instance'
6732b3
+p74
6732b3
+aS'scripts-user'
6732b3
+p75
6732b3
+aS'ssh-authkey-fingerprints'
6732b3
+p76
6732b3
+aS'keys-to-console'
6732b3
+p77
6732b3
+aS'phone-home'
6732b3
+p78
6732b3
+aS'final-message'
6732b3
+p79
6732b3
+aS'power-state-change'
6732b3
+p80
6732b3
+asS'disable_root'
6732b3
+p81
6732b3
+I01
6732b3
+sS'syslog_fix_perms'
6732b3
+p82
6732b3
+S'syslog:adm'
6732b3
+p83
6732b3
+sS'log_cfgs'
6732b3
+p84
6732b3
+(lp85
6732b3
+(lp86
6732b3
+S'[loggers]\nkeys=root,cloudinit\n\n[handlers]\nkeys=consoleHandler,cloudLogHandler\n\n[formatters]\nkeys=simpleFormatter,arg0Formatter\n\n[logger_root]\nlevel=DEBUG\nhandlers=consoleHandler,cloudLogHandler\n\n[logger_cloudinit]\nlevel=DEBUG\nqualname=cloudinit\nhandlers=\npropagate=1\n\n[handler_consoleHandler]\nclass=StreamHandler\nlevel=WARNING\nformatter=arg0Formatter\nargs=(sys.stderr,)\n\n[formatter_arg0Formatter]\nformat=%(asctime)s - %(filename)s[%(levelname)s]: %(message)s\n\n[formatter_simpleFormatter]\nformat=[CLOUDINIT] %(filename)s[%(levelname)s]: %(message)s\n'
6732b3
+p87
6732b3
+aS'[handler_cloudLogHandler]\nclass=handlers.SysLogHandler\nlevel=DEBUG\nformatter=simpleFormatter\nargs=("/dev/log", handlers.SysLogHandler.LOG_USER)\n'
6732b3
+p88
6732b3
+aa(lp89
6732b3
+g87
6732b3
+aS"[handler_cloudLogHandler]\nclass=FileHandler\nlevel=DEBUG\nformatter=arg0Formatter\nargs=('/var/log/cloud-init.log',)\n"
6732b3
+p90
6732b3
+aasS'cloud_init_modules'
6732b3
+p91
6732b3
+(lp92
6732b3
+S'migrator'
6732b3
+p93
6732b3
+aS'seed_random'
6732b3
+p94
6732b3
+aS'bootcmd'
6732b3
+p95
6732b3
+aS'write-files'
6732b3
+p96
6732b3
+aS'growpart'
6732b3
+p97
6732b3
+aS'resizefs'
6732b3
+p98
6732b3
+aS'set_hostname'
6732b3
+p99
6732b3
+aS'update_hostname'
6732b3
+p100
6732b3
+aS'update_etc_hosts'
6732b3
+p101
6732b3
+aS'ca-certs'
6732b3
+p102
6732b3
+aS'rsyslog'
6732b3
+p103
6732b3
+aS'users-groups'
6732b3
+p104
6732b3
+aS'ssh'
6732b3
+p105
6732b3
+asS'preserve_hostname'
6732b3
+p106
6732b3
+I00
6732b3
+sS'_log'
6732b3
+p107
6732b3
+(lp108
6732b3
+g87
6732b3
+ag90
6732b3
+ag88
6732b3
+asS'datasource_list'
6732b3
+p109
6732b3
+(lp110
6732b3
+S'NoCloud'
6732b3
+p111
6732b3
+aS'ConfigDrive'
6732b3
+p112
6732b3
+aS'OpenNebula'
6732b3
+p113
6732b3
+aS'Azure'
6732b3
+p114
6732b3
+aS'AltCloud'
6732b3
+p115
6732b3
+aS'OVF'
6732b3
+p116
6732b3
+aS'MAAS'
6732b3
+p117
6732b3
+aS'GCE'
6732b3
+p118
6732b3
+aS'OpenStack'
6732b3
+p119
6732b3
+aS'CloudSigma'
6732b3
+p120
6732b3
+aS'Ec2'
6732b3
+p121
6732b3
+aS'CloudStack'
6732b3
+p122
6732b3
+aS'SmartOS'
6732b3
+p123
6732b3
+aS'None'
6732b3
+p124
6732b3
+asS'vendor_data'
6732b3
+p125
6732b3
+(dp126
6732b3
+S'prefix'
6732b3
+p127
6732b3
+(lp128
6732b3
+sS'enabled'
6732b3
+p129
6732b3
+I01
6732b3
+ssS'cloud_config_modules'
6732b3
+p130
6732b3
+(lp131
6732b3
+S'emit_upstart'
6732b3
+p132
6732b3
+aS'disk_setup'
6732b3
+p133
6732b3
+aS'mounts'
6732b3
+p134
6732b3
+aS'ssh-import-id'
6732b3
+p135
6732b3
+aS'locale'
6732b3
+p136
6732b3
+aS'set-passwords'
6732b3
+p137
6732b3
+aS'grub-dpkg'
6732b3
+p138
6732b3
+aS'apt-pipelining'
6732b3
+p139
6732b3
+aS'apt-configure'
6732b3
+p140
6732b3
+aS'package-update-upgrade-install'
6732b3
+p141
6732b3
+aS'landscape'
6732b3
+p142
6732b3
+aS'timezone'
6732b3
+p143
6732b3
+aS'puppet'
6732b3
+p144
6732b3
+aS'chef'
6732b3
+p145
6732b3
+aS'salt-minion'
6732b3
+p146
6732b3
+aS'mcollective'
6732b3
+p147
6732b3
+aS'disable-ec2-metadata'
6732b3
+p148
6732b3
+aS'runcmd'
6732b3
+p149
6732b3
+aS'byobu'
6732b3
+p150
6732b3
+assg14
6732b3
+(iemail.mime.multipart
6732b3
+MIMEMultipart
6732b3
+p151
6732b3
+(dp152
6732b3
+S'_headers'
6732b3
+p153
6732b3
+(lp154
6732b3
+(S'Content-Type'
6732b3
+p155
6732b3
+S'multipart/mixed; boundary="===============4291038100093149247=="'
6732b3
+tp156
6732b3
+a(S'MIME-Version'
6732b3
+p157
6732b3
+S'1.0'
6732b3
+p158
6732b3
+tp159
6732b3
+a(S'Number-Attachments'
6732b3
+p160
6732b3
+S'1'
6732b3
+tp161
6732b3
+asS'_payload'
6732b3
+p162
6732b3
+(lp163
6732b3
+(iemail.mime.base
6732b3
+MIMEBase
6732b3
+p164
6732b3
+(dp165
6732b3
+g153
6732b3
+(lp166
6732b3
+(g157
6732b3
+g158
6732b3
+tp167
6732b3
+a(S'Content-Type'
6732b3
+p168
6732b3
+S'text/x-not-multipart'
6732b3
+tp169
6732b3
+a(S'Content-Disposition'
6732b3
+p170
6732b3
+S'attachment; filename="part-001"'
6732b3
+tp171
6732b3
+asg162
6732b3
+S''
6732b3
+sS'_charset'
6732b3
+p172
6732b3
+NsS'_default_type'
6732b3
+p173
6732b3
+S'text/plain'
6732b3
+p174
6732b3
+sS'preamble'
6732b3
+p175
6732b3
+NsS'defects'
6732b3
+p176
6732b3
+(lp177
6732b3
+sS'_unixfrom'
6732b3
+p178
6732b3
+NsS'epilogue'
6732b3
+p179
6732b3
+Nsbasg172
6732b3
+Nsg173
6732b3
+g174
6732b3
+sg175
6732b3
+Nsg176
6732b3
+(lp180
6732b3
+sg178
6732b3
+Nsg179
6732b3
+Nsbsg16
6732b3
+S'#cloud-config\n{}\n\n'
6732b3
+p181
6732b3
+sg18
6732b3
+S'Content-Type: multipart/mixed; boundary="===============1378281702283945349=="\nMIME-Version: 1.0\n\n--===============1378281702283945349==\nContent-Type: text/x-shellscript; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment; filename="script1.sh"\n\nIyEvYmluL3NoCgplY2hvICdoaScgPiAvdmFyL3RtcC9oaQo=\n\n--===============1378281702283945349==\nContent-Type: text/x-shellscript; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment; filename="script2.sh"\n\nIyEvYmluL2Jhc2gKCmVjaG8gJ2hpMicgPiAvdmFyL3RtcC9oaTIK\n\n--===============1378281702283945349==--\n\n#cloud-config\n# final_message: |\n#   This is my final message!\n#   $version\n#   $timestamp\n#   $datasource\n#   $uptime\n# updates:\n#   network:\n#     when: [\'hotplug\']\n'
6732b3
+p182
6732b3
+sg29
6732b3
+NsS'dsmode'
6732b3
+p183
6732b3
+S'net'
6732b3
+p184
6732b3
+sS'seed'
6732b3
+p185
6732b3
+S'/var/lib/cloud/seed/nocloud-net'
6732b3
+p186
6732b3
+sS'cmdline_id'
6732b3
+p187
6732b3
+S'ds=nocloud-net'
6732b3
+p188
6732b3
+sS'ud_proc'
6732b3
+p189
6732b3
+g1
6732b3
+(ccloudinit.user_data
6732b3
+UserDataProcessor
6732b3
+p190
6732b3
+g3
6732b3
+NtRp191
6732b3
+(dp192
6732b3
+g6
6732b3
+g8
6732b3
+sS'ssl_details'
6732b3
+p193
6732b3
+(dp194
6732b3
+sbsg50
6732b3
+g186
6732b3
+sS'ds_cfg'
6732b3
+p195
6732b3
+(dp196
6732b3
+sS'distro'
6732b3
+p197
6732b3
+g1
6732b3
+(ccloudinit.distros.ubuntu
6732b3
+Distro
6732b3
+p198
6732b3
+g3
6732b3
+NtRp199
6732b3
+(dp200
6732b3
+S'osfamily'
6732b3
+p201
6732b3
+S'debian'
6732b3
+p202
6732b3
+sS'_paths'
6732b3
+p203
6732b3
+g8
6732b3
+sS'name'
6732b3
+p204
6732b3
+S'ubuntu'
6732b3
+p205
6732b3
+sS'_runner'
6732b3
+p206
6732b3
+g1
6732b3
+(ccloudinit.helpers
6732b3
+Runners
6732b3
+p207
6732b3
+g3
6732b3
+NtRp208
6732b3
+(dp209
6732b3
+g6
6732b3
+g8
6732b3
+sS'sems'
6732b3
+p210
6732b3
+(dp211
6732b3
+sbsS'_cfg'
6732b3
+p212
6732b3
+(dp213
6732b3
+S'paths'
6732b3
+p214
6732b3
+(dp215
6732b3
+g37
6732b3
+g38
6732b3
+sg39
6732b3
+g40
6732b3
+sg41
6732b3
+g42
6732b3
+ssS'default_user'
6732b3
+p216
6732b3
+(dp217
6732b3
+S'shell'
6732b3
+p218
6732b3
+S'/bin/bash'
6732b3
+p219
6732b3
+sS'name'
6732b3
+p220
6732b3
+S'ubuntu'
6732b3
+p221
6732b3
+sS'sudo'
6732b3
+p222
6732b3
+(lp223
6732b3
+S'ALL=(ALL) NOPASSWD:ALL'
6732b3
+p224
6732b3
+asS'lock_passwd'
6732b3
+p225
6732b3
+I01
6732b3
+sS'gecos'
6732b3
+p226
6732b3
+S'Ubuntu'
6732b3
+p227
6732b3
+sS'groups'
6732b3
+p228
6732b3
+(lp229
6732b3
+S'adm'
6732b3
+p230
6732b3
+aS'audio'
6732b3
+p231
6732b3
+aS'cdrom'
6732b3
+p232
6732b3
+aS'dialout'
6732b3
+p233
6732b3
+aS'dip'
6732b3
+p234
6732b3
+aS'floppy'
6732b3
+p235
6732b3
+aS'netdev'
6732b3
+p236
6732b3
+aS'plugdev'
6732b3
+p237
6732b3
+aS'sudo'
6732b3
+p238
6732b3
+aS'video'
6732b3
+p239
6732b3
+assS'package_mirrors'
6732b3
+p240
6732b3
+(lp241
6732b3
+(dp242
6732b3
+S'arches'
6732b3
+p243
6732b3
+(lp244
6732b3
+S'i386'
6732b3
+p245
6732b3
+aS'amd64'
6732b3
+p246
6732b3
+asS'failsafe'
6732b3
+p247
6732b3
+(dp248
6732b3
+S'security'
6732b3
+p249
6732b3
+S'http://security.ubuntu.com/ubuntu'
6732b3
+p250
6732b3
+sS'primary'
6732b3
+p251
6732b3
+S'http://archive.ubuntu.com/ubuntu'
6732b3
+p252
6732b3
+ssS'search'
6732b3
+p253
6732b3
+(dp254
6732b3
+S'security'
6732b3
+p255
6732b3
+(lp256
6732b3
+sS'primary'
6732b3
+p257
6732b3
+(lp258
6732b3
+S'http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/'
6732b3
+p259
6732b3
+aS'http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/'
6732b3
+p260
6732b3
+aS'http://%(region)s.clouds.archive.ubuntu.com/ubuntu/'
6732b3
+p261
6732b3
+assa(dp262
6732b3
+S'arches'
6732b3
+p263
6732b3
+(lp264
6732b3
+S'armhf'
6732b3
+p265
6732b3
+aS'armel'
6732b3
+p266
6732b3
+aS'default'
6732b3
+p267
6732b3
+asS'failsafe'
6732b3
+p268
6732b3
+(dp269
6732b3
+S'security'
6732b3
+p270
6732b3
+S'http://ports.ubuntu.com/ubuntu-ports'
6732b3
+p271
6732b3
+sS'primary'
6732b3
+p272
6732b3
+S'http://ports.ubuntu.com/ubuntu-ports'
6732b3
+p273
6732b3
+ssasS'ssh_svcname'
6732b3
+p274
6732b3
+S'ssh'
6732b3
+p275
6732b3
+ssbsS'metadata'
6732b3
+p276
6732b3
+(dp277
6732b3
+g183
6732b3
+g184
6732b3
+sS'local-hostname'
6732b3
+p278
6732b3
+S'me'
6732b3
+p279
6732b3
+sS'instance-id'
6732b3
+p280
6732b3
+S'me'
6732b3
+p281
6732b3
+ssb.
6732b3
\ No newline at end of file
6732b3
diff --git a/tests/integration_tests/modules/test_persistence.py b/tests/integration_tests/modules/test_persistence.py
6732b3
new file mode 100644
6732b3
index 00000000..00fdeaea
6732b3
--- /dev/null
6732b3
+++ b/tests/integration_tests/modules/test_persistence.py
6732b3
@@ -0,0 +1,30 @@
6732b3
+# This file is part of cloud-init. See LICENSE file for license information.
6732b3
+"""Test the behavior of loading/discarding pickle data"""
6732b3
+from pathlib import Path
6732b3
+
6732b3
+import pytest
6732b3
+
6732b3
+from tests.integration_tests.instances import IntegrationInstance
6732b3
+from tests.integration_tests.util import (
6732b3
+    ASSETS_DIR,
6732b3
+    verify_ordered_items_in_text,
6732b3
+)
6732b3
+
6732b3
+
6732b3
+PICKLE_PATH = Path('/var/lib/cloud/instance/obj.pkl')
6732b3
+TEST_PICKLE = ASSETS_DIR / 'trusty_with_mime.pkl'
6732b3
+
6732b3
+
6732b3
+@pytest.mark.lxd_container
6732b3
+def test_log_message_on_missing_version_file(client: IntegrationInstance):
6732b3
+    client.push_file(TEST_PICKLE, PICKLE_PATH)
6732b3
+    client.restart()
6732b3
+    assert client.execute('cloud-init status --wait').ok
6732b3
+    log = client.read_from_file('/var/log/cloud-init.log')
6732b3
+    verify_ordered_items_in_text([
6732b3
+        "Unable to unpickle datasource: 'MIMEMultipart' object has no "
6732b3
+        "attribute 'policy'. Ignoring current cache.",
6732b3
+        'no cache found',
6732b3
+        'Searching for local data source',
6732b3
+        'SUCCESS: found local data from DataSourceNoCloud'
6732b3
+    ], log)
6732b3
-- 
6732b3
2.31.1
6732b3