persisting OpenStack metadata fails
| Affects | Status | Importance | Assigned to | Milestone | |
|---|---|---|---|---|---|
| cloud-init |
Fix Released
|
Undecided
|
Unassigned | ||
Bug Description
Persistsing OpenStack metadata may fail.
OpenStack has an entry named "random_seed" in the metadata [1]. This entry is treaded specially in the openstack.py helper when the metadat is read [2]. The attempt to decode the read data my result in a string that is not utf-8 compliant which eventually results in an error when we attempt to persist the metadata as follows:
2018年11月02日 12:14:13,755 - __init_
[1] https:/
[2] https:/
Related branches
- Robert Schweikert (community): Approve
- Server Team CI bot: Approve (continuous-integration)
- cloud-init Commiters: Pending requested
-
Diff: 108 lines (+50/-9) 3 files modifiedapicloudinit/sources/tests/test_init.py (+5/-7)
cloudinit/tests/test_util.py (+20/-0)
cloudinit/util.py (+25/-2)
- Server Team CI bot: Needs Fixing (continuous-integration)
- Ryan Harper: Approve
-
Diff: 2904 lines (+1300/-449) 34 files modifiedapicloudinit/cmd/main.py (+5/-4)
cloudinit/config/cc_ubuntu_advantage.py (+116/-109)
cloudinit/config/cc_ubuntu_drivers.py (+112/-0)
cloudinit/config/tests/test_ubuntu_advantage.py (+191/-156)
cloudinit/config/tests/test_ubuntu_drivers.py (+174/-0)
cloudinit/net/eni.py (+11/-5)
cloudinit/net/network_state.py (+33/-8)
cloudinit/net/sysconfig.py (+25/-9)
cloudinit/sources/DataSourceAzure.py (+168/-89)
cloudinit/sources/DataSourceEc2.py (+6/-2)
cloudinit/sources/DataSourceNoCloud.py (+3/-1)
cloudinit/sources/DataSourceScaleway.py (+2/-1)
cloudinit/sources/__init__.py (+3/-3)
cloudinit/sources/helpers/azure.py (+31/-0)
cloudinit/sources/tests/test_init.py (+15/-0)
cloudinit/util.py (+15/-0)
config/cloud.cfg.tmpl (+3/-0)
debian/changelog (+29/-0)
doc/rtd/topics/datasources/azure.rst (+35/-22)
doc/rtd/topics/datasources/nocloud.rst (+1/-1)
doc/rtd/topics/modules.rst (+1/-0)
tests/cloud_tests/testcases/modules/apt_pipelining_disable.yaml (+1/-2)
tests/cloud_tests/testcases/modules/apt_pipelining_os.py (+3/-3)
tests/cloud_tests/testcases/modules/apt_pipelining_os.yaml (+4/-5)
tests/data/azure/non_unicode_random_string (+1/-0)
tests/unittests/test_datasource/test_azure.py (+22/-2)
tests/unittests/test_datasource/test_nocloud.py (+42/-0)
tests/unittests/test_datasource/test_scaleway.py (+7/-0)
tests/unittests/test_distros/test_netconfig.py (+2/-0)
tests/unittests/test_ds_identify.py (+17/-0)
tests/unittests/test_handler/test_schema.py (+1/-0)
tests/unittests/test_net.py (+209/-15)
tools/ds-identify (+4/-3)
tox.ini (+8/-9)
Example data for the case that triggered this issue:
From debug output inserted into util.load_json, which is called from read_v2() in openstack.py
"random_seed": "Cr7LysUKbg/
After processing this turned into:
u'random_seed': '\xb8!\
per debug output inserted into _crawl_metadata(). With this data in the metadata dictionary persisting the data via persist_
The question is whether "random_seed" should be persisted in the first place. The value for "random_seed" is different every time the metadata server is accessed. Thus the value is not useful for comparison. However I do not know for what other reasons the persisted data would be used.
- cloud-init-ostack-metadat-dencode.patch Edit (749 bytes, text/plain)
The patch is one possible implementation of avoiding the utf-8 error when persisting the metadata.
Depending on whether random_seed is actually useful to persist it may also be possible to simply drop the data in openstack.py
if 'random_seed' in metadata:
del metadata[
+ persisting OpenStack metadata fails
Robert,
Can you please attach logs?
cloud-init collect-logs
The 'persist_
it uses util.json_dumps which uses json_serialize_
Here is an example:
$ python3 -c 'from cloudinit import util; print(util.
{
"bin": "ci-b64:
}
Notice that the dump adds 'ci-b64' in front of the value.
I'm guessing that there is a differnce in python versions that is causing a problem.
Please attach logs.
thanks.
Yes, sorry, this is Python version dependent, fails with Python 2.7, works with Python 3.
- cloud-init.log Edit (81.3 KiB, text/plain)
Log file that shows the failure.
Note in this case we ran with cloud-init 18.2 but issue reproduces the same way in 18.4, to which the attached patch applies.
As stated in previous comment this happens with Python 2.7, Python 3.6 works with no modification.
- Test that shows the failure in python2.7 Edit (1.5 KiB, text/plain)
I'm attaching a test case that shows the failure on python2.7.
The issue is in the way that we're serializing binary data into
json. The implementation we have (using default=
just does not work in python2.7.
I recall that I had seen a stackexchange question basically covering
this and the dsubmitter eventually just throwing up their hands.
This adds the test case to show the problem, but does not do anything to fix it.
If someone fixes this correctly/
There is good discussion on the general dumps/JsonEncoder issue at https:/
Just to be clear, our python 3 implementation works as designed.
The patch in https:/
This bug is fixed with commit 067516d7 to cloud-init on branch master.
To view that commit see the following URL:
https:/
I'm trying to understand how this bug is considered fixed by the following commit; https:/
We have resolved the issue by just not base64 decoding;
- if 'random_seed' in metadata:
- random_seed = metadata[
- try:
- metadata[
- except (ValueError, TypeError) as e:
- raise BrokenMetadata(
- " random_seed entry: %s" % e)
Could somebody help me with some information about why we try to get the random_seed and interpret it?
I can't figure it out; the commit where this was added was the same as the initial Openstack. Openstack documentation doesn't say if we should be injecting this somewhere either.
On 12/10/19 8:22 AM, Eric Lafontaine wrote:
> I'm trying to understand how this bug is considered fixed by the
> following commit; https:/
> init/commit/
>
> We have resolved the issue by just not base64 decoding;
> - if 'random_seed' in metadata:
> - random_seed = metadata[
> - try:
> - metadata[
> - except (ValueError, TypeError) as e:
> - raise BrokenMetadata(
> - " random_seed entry: %s" % e)
>
> Could somebody help me with some information about why we try to get the
> random_seed and interpret it?
We had discussions at the last summit about not persisting the
random_seed to cache, which would avoid this problem. But I am not
certain we reached an actionable conclusion. Then again the topic
becomes somewhat academic at this point as Python 2 support will be
dropped at the end of this year with the release of 19.4
@Eric,
It should be fixed in that it will no longer stack trace as it did.
The path to failure was:
a.) openstack has 'random_seed' which (not surprisingly) had non-utf8 data in it
b.) cloud-init tries to persist data from the metadata service by storing json
c.) json can only serialize/store utf-8 data.
d.) stack trace on attempt to do so.
cloud-init needs to be able to persist non-utf8 data and then re-load that data correctly.
The change we made was to fix cloud-init to catch the unicodedecodeerror that is raised in c, and then to "pre-serialize" the content so that it *can* be fed to json.dumps.
Do you still see the problem?
> I can't figure it out; the commit where this was added was the same as the initial Openstack. Openstack documentation doesn't say if we should be injecting this somewhere either.
When a platform provides a random_seed, cloud-init will add this to the host entry pool. See
https:/
Alright, thanks folks.
I'm on Centos7 with cloudinit 19.3. I'll confirm this afternoon if I still have the issue and if I do, I'll go and suggest a possible fix for it. (might be a colleague that will do it :) ).
Thanks again, the cc_seed_random module is enlightening.
Just did a test and it does seem to persist with the latest commits on the master branch :).
All *my* tests passed for the image I generated, not that it means anything.
So, what would be needed to consider this bug closed?
> Just did a test and it *does* seem to persist with the latest commits
> on the master branch :).
... (emphasis added)
> So, what would be needed to consider this bug closed?
I'm confused. did you mean "does not" ?
> So, what would be needed to consider this bug closed?
The bug is fix-committed. It goes to "fix released", when it is present in a release.
This bug is believed to be fixed in cloud-init in version 19.2-53. If this is still a problem for you, please make a comment and set the state back to New
Thank you.
Tracked in Github Issues as https:/