Merge lp:~enolfc/cloud-init/opennebula-b64-userdata into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Enol Fernández
Status: Merged
Merged at revision: 971
Proposed branch: lp:~enolfc/cloud-init/opennebula-b64-userdata
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 88 lines (+37/-4)
2 files modified
cloudinit/sources/DataSourceOpenNebula.py (+12/-0)
tests/unittests/test_datasource/test_opennebula.py (+25/-4)
To merge this branch: bzr merge lp:~enolfc/cloud-init/opennebula-b64-userdata
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+212646@code.launchpad.net

Description of the change

This change adds the possibility to have base64 encoded userdata in OpenNebula source.

OpenNebula uses a text file with shell variables for storing the configuration variables (including user provided data). Some user data may not be renderable into this format, so using base64 encoding alleviates the problem. This change considers that, by default, USERDATA variable contains a base64 encoded string with the user provided data. This behavior can be deactivated by defining the USERDATA_ENCODING variable to anything different to "base64" (similarly to the Azure data source).

This feature is of special interest for resource providers with rOCCI-server front-end as the ones in EGI's Federated Cloud (https://wiki.egi.eu/wiki/Fedcloud-tf:Main)

Unit tests for the change are included.

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cloudinit/sources/DataSourceOpenNebula.py'
2--- cloudinit/sources/DataSourceOpenNebula.py 2014-01-17 01:11:27 +0000
3+++ cloudinit/sources/DataSourceOpenNebula.py 2014-03-25 15:42:10 +0000
4@@ -4,11 +4,13 @@
5 # Copyright (C) 2012 Yahoo! Inc.
6 # Copyright (C) 2012-2013 CERIT Scientific Cloud
7 # Copyright (C) 2012-2013 OpenNebula.org
8+# Copyright (C) 2014 Consejo Superior de Investigaciones Cientificas
9 #
10 # Author: Scott Moser <scott.moser@canonical.com>
11 # Author: Joshua Harlow <harlowja@yahoo-inc.com>
12 # Author: Vlastimil Holer <xholer@mail.muni.cz>
13 # Author: Javier Fontan <jfontan@opennebula.org>
14+# Author: Enol Fernandez <enolfc@ifca.unican.es>
15 #
16 # This program is free software: you can redistribute it and/or modify
17 # it under the terms of the GNU General Public License version 3, as
18@@ -22,6 +24,7 @@
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
21
22+import base64
23 import os
24 import pwd
25 import re
26@@ -417,6 +420,15 @@
27 elif "USERDATA" in context:
28 results['userdata'] = context["USERDATA"]
29
30+ # b64decode user data if necessary (default)
31+ if 'userdata' in results:
32+ userdata_encoding = context.get('USERDATA_ENCODING', None)
33+ if userdata_encoding in (None, "base64"):
34+ try:
35+ results['userdata'] = base64.b64decode(results['userdata'])
36+ except TypeError:
37+ LOG.warn("Failed base64 decoding of userdata")
38+
39 # generate static /etc/network/interfaces
40 # only if there are any required context variables
41 # http://opennebula.org/documentation:rel3.8:cong#network_configuration
42
43=== modified file 'tests/unittests/test_datasource/test_opennebula.py'
44--- tests/unittests/test_datasource/test_opennebula.py 2014-01-17 16:09:15 +0000
45+++ tests/unittests/test_datasource/test_opennebula.py 2014-03-25 15:42:10 +0000
46@@ -4,6 +4,7 @@
47 from mocker import MockerTestCase
48 from tests.unittests.helpers import populate_dir
49
50+from base64 import b64encode
51 import os
52 import pwd
53
54@@ -164,10 +165,30 @@
55
56 public_keys.append(SSH_KEY % (c + 1,))
57
58- def test_user_data(self):
59- for k in ('USER_DATA', 'USERDATA'):
60- my_d = os.path.join(self.tmp, k)
61- populate_context_dir(my_d, {k: USER_DATA})
62+ def test_user_data_plain(self):
63+ for k in ('USER_DATA', 'USERDATA'):
64+ my_d = os.path.join(self.tmp, k)
65+ populate_context_dir(my_d, {k: USER_DATA,
66+ 'USERDATA_ENCODING': ''})
67+ results = ds.read_context_disk_dir(my_d)
68+
69+ self.assertTrue('userdata' in results)
70+ self.assertEqual(USER_DATA, results['userdata'])
71+
72+ def test_user_data_default_encoding(self):
73+ for k in ('USER_DATA', 'USERDATA'):
74+ my_d = os.path.join(self.tmp, k)
75+ populate_context_dir(my_d, {k: b64encode(USER_DATA)})
76+ results = ds.read_context_disk_dir(my_d)
77+
78+ self.assertTrue('userdata' in results)
79+ self.assertEqual(USER_DATA, results['userdata'])
80+
81+ def test_user_data_base64_encoding(self):
82+ for k in ('USER_DATA', 'USERDATA'):
83+ my_d = os.path.join(self.tmp, k)
84+ populate_context_dir(my_d, {k: b64encode(USER_DATA),
85+ 'USERDATA_ENCODING': 'base64'})
86 results = ds.read_context_disk_dir(my_d)
87
88 self.assertTrue('userdata' in results)