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