Merge ~smoser/cloud-init:fix/1849640-adjust-yaml-usage into cloud-init:master

Proposed by Scott Moser on 2019-10-24
Status: Merged
Approved by: Ryan Harper on 2019-10-24
Approved revision: e69df5dce264f9f329dd0630aad3954b32999153
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~smoser/cloud-init:fix/1849640-adjust-yaml-usage
Merge into: cloud-init:master
Diff against target: 395 lines (+53/-46)
13 files modified
cloudinit/cmd/devel/net_convert.py (+5/-8)
cloudinit/cmd/tests/test_main.py (+4/-3)
cloudinit/config/cc_debug.py (+2/-1)
cloudinit/config/cc_salt_minion.py (+3/-3)
cloudinit/config/cc_snappy.py (+2/-1)
cloudinit/handlers/cloud_config.py (+2/-1)
cloudinit/net/netplan.py (+8/-7)
cloudinit/net/network_state.py (+3/-2)
cloudinit/safeyaml.py (+15/-0)
cloudinit/util.py (+1/-15)
tests/unittests/test_data.py (+2/-1)
tests/unittests/test_runs/test_merge_run.py (+2/-1)
tests/unittests/test_runs/test_simple_run.py (+4/-3)
Reviewer Review Type Date Requested Status
Ryan Harper 2019-10-24 Approve on 2019-10-24
Server Team CI bot continuous-integration Approve on 2019-10-24
Review via email: mp+374679@code.launchpad.net

Commit message

Fix usages of yaml, and move yaml_dump to safeyaml.dumps.

Here we replace uses of the pyyaml module directly with functions
provided by cloudinit.safeyaml. Also, change/move
  cloudinit.util.yaml_dumps
to
  cloudinit.safeyaml.dumps

LP: #1849640

Description of the change

see commit message

To post a comment you must log in.
Ryan Harper (raharper) wrote :

Is there an advantage to moving dumps into safeyaml? I didn't think dump had any concerns. Could we just have replaced the yaml.load() calls with util.load_yaml() ?

Scott Moser (smoser) wrote :

not a real advantage other than getting closer to getting all yaml
usage into a single place.

On Thu, Oct 24, 2019 at 12:56 PM Ryan Harper <email address hidden> wrote:
>
> Is there an advantage to moving dumps into safeyaml? I didn't think dump had any concerns. Could we just have replaced the yaml.load() calls with util.load_yaml() ?
> --
> https://code.launchpad.net/~smoser/cloud-init/+git/cloud-init/+merge/374679
> You are the owner of ~smoser/cloud-init:fix/1849640-adjust-yaml-usage.

Scott Moser (smoser) wrote :

just in better use of modules... putting yaml things into their own module rather than having them all in util.

I'm willing to move load_yaml also if you'd like. which would mean util would have no yaml code in it.

PASSED: Continuous integration, rev:e7c84bfdc42bc533a8f737ecd6b9557b466e1ebd
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1232/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1232//rebuild

review: Approve (continuous-integration)
e69df5d... by Scott Moser on 2019-10-24

remove 'import yaml' from cloudinit.util

Ryan Harper (raharper) wrote :

OK. I just wanted to make sure that I wasn't missing something on the dump path.

For relocating; there are quite a few yaml users inside util.py so we'd still need to import
safeyaml into util; so module load wise, we're still pulling it in on any import of util. additionally, moving the load_yaml into safeyaml would mean inter-module deps; load_yaml uses decode_binary(), so we'd need to duplicate that.

I'm fine with this as it is, but would also review moving all yaml operations into safeyaml.

FAILED: Continuous integration, rev:e69df5dce264f9f329dd0630aad3954b32999153
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1233/
Executed test runs:
    FAILED: Checkout

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1233//rebuild

review: Needs Fixing (continuous-integration)

PASSED: Continuous integration, rev:e69df5dce264f9f329dd0630aad3954b32999153
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1234/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/1234//rebuild

review: Approve (continuous-integration)
Scott Moser (smoser) wrote :

I'm happy with the way it is here... we got rid of all 'import yaml' from cloudinit.util at least.
and down to a signle place that 'yaml.load' is called.

Ryan Harper (raharper) wrote :

Sounds good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/cloudinit/cmd/devel/net_convert.py b/cloudinit/cmd/devel/net_convert.py
index 1ad7e0b..9b76830 100755
--- a/cloudinit/cmd/devel/net_convert.py
+++ b/cloudinit/cmd/devel/net_convert.py
@@ -5,13 +5,12 @@ import argparse
5import json5import json
6import os6import os
7import sys7import sys
8import yaml
98
10from cloudinit.sources.helpers import openstack9from cloudinit.sources.helpers import openstack
11from cloudinit.sources import DataSourceAzure as azure10from cloudinit.sources import DataSourceAzure as azure
12from cloudinit.sources import DataSourceOVF as ovf11from cloudinit.sources import DataSourceOVF as ovf
1312
14from cloudinit import distros13from cloudinit import distros, safeyaml
15from cloudinit.net import eni, netplan, network_state, sysconfig14from cloudinit.net import eni, netplan, network_state, sysconfig
16from cloudinit import log15from cloudinit import log
1716
@@ -78,13 +77,12 @@ def handle_args(name, args):
78 if args.kind == "eni":77 if args.kind == "eni":
79 pre_ns = eni.convert_eni_data(net_data)78 pre_ns = eni.convert_eni_data(net_data)
80 elif args.kind == "yaml":79 elif args.kind == "yaml":
81 pre_ns = yaml.load(net_data)80 pre_ns = safeyaml.load(net_data)
82 if 'network' in pre_ns:81 if 'network' in pre_ns:
83 pre_ns = pre_ns.get('network')82 pre_ns = pre_ns.get('network')
84 if args.debug:83 if args.debug:
85 sys.stderr.write('\n'.join(84 sys.stderr.write('\n'.join(
86 ["Input YAML",85 ["Input YAML", safeyaml.dumps(pre_ns), ""]))
87 yaml.dump(pre_ns, default_flow_style=False, indent=4), ""]))
88 elif args.kind == 'network_data.json':86 elif args.kind == 'network_data.json':
89 pre_ns = openstack.convert_net_json(87 pre_ns = openstack.convert_net_json(
90 json.loads(net_data), known_macs=known_macs)88 json.loads(net_data), known_macs=known_macs)
@@ -100,9 +98,8 @@ def handle_args(name, args):
100 "input data")98 "input data")
10199
102 if args.debug:100 if args.debug:
103 sys.stderr.write('\n'.join([101 sys.stderr.write('\n'.join(
104 "", "Internal State",102 ["", "Internal State", safeyaml.dumps(ns), ""]))
105 yaml.dump(ns, default_flow_style=False, indent=4), ""]))
106 distro_cls = distros.fetch(args.distro)103 distro_cls = distros.fetch(args.distro)
107 distro = distro_cls(args.distro, {}, None)104 distro = distro_cls(args.distro, {}, None)
108 config = {}105 config = {}
diff --git a/cloudinit/cmd/tests/test_main.py b/cloudinit/cmd/tests/test_main.py
index a1e534f..57b8fdf 100644
--- a/cloudinit/cmd/tests/test_main.py
+++ b/cloudinit/cmd/tests/test_main.py
@@ -6,8 +6,9 @@ import os
6from six import StringIO6from six import StringIO
77
8from cloudinit.cmd import main8from cloudinit.cmd import main
9from cloudinit import safeyaml
9from cloudinit.util import (10from cloudinit.util import (
10 ensure_dir, load_file, write_file, yaml_dumps)11 ensure_dir, load_file, write_file)
11from cloudinit.tests.helpers import (12from cloudinit.tests.helpers import (
12 FilesystemMockingTestCase, wrap_and_call)13 FilesystemMockingTestCase, wrap_and_call)
1314
@@ -39,7 +40,7 @@ class TestMain(FilesystemMockingTestCase):
39 ],40 ],
40 'cloud_init_modules': ['write-files', 'runcmd'],41 'cloud_init_modules': ['write-files', 'runcmd'],
41 }42 }
42 cloud_cfg = yaml_dumps(self.cfg)43 cloud_cfg = safeyaml.dumps(self.cfg)
43 ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))44 ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))
44 self.cloud_cfg_file = os.path.join(45 self.cloud_cfg_file = os.path.join(
45 self.new_root, 'etc', 'cloud', 'cloud.cfg')46 self.new_root, 'etc', 'cloud', 'cloud.cfg')
@@ -113,7 +114,7 @@ class TestMain(FilesystemMockingTestCase):
113 """When local-hostname metadata is present, call cc_set_hostname."""114 """When local-hostname metadata is present, call cc_set_hostname."""
114 self.cfg['datasource'] = {115 self.cfg['datasource'] = {
115 'None': {'metadata': {'local-hostname': 'md-hostname'}}}116 'None': {'metadata': {'local-hostname': 'md-hostname'}}}
116 cloud_cfg = yaml_dumps(self.cfg)117 cloud_cfg = safeyaml.dumps(self.cfg)
117 write_file(self.cloud_cfg_file, cloud_cfg)118 write_file(self.cloud_cfg_file, cloud_cfg)
118 cmdargs = myargs(119 cmdargs = myargs(
119 debug=False, files=None, force=False, local=False, reporter=None,120 debug=False, files=None, force=False, local=False, reporter=None,
diff --git a/cloudinit/config/cc_debug.py b/cloudinit/config/cc_debug.py
index 0a039eb..610dbc8 100644
--- a/cloudinit/config/cc_debug.py
+++ b/cloudinit/config/cc_debug.py
@@ -33,6 +33,7 @@ from six import StringIO
3333
34from cloudinit import type_utils34from cloudinit import type_utils
35from cloudinit import util35from cloudinit import util
36from cloudinit import safeyaml
3637
37SKIP_KEYS = frozenset(['log_cfgs'])38SKIP_KEYS = frozenset(['log_cfgs'])
3839
@@ -49,7 +50,7 @@ def _make_header(text):
4950
5051
51def _dumps(obj):52def _dumps(obj):
52 text = util.yaml_dumps(obj, explicit_start=False, explicit_end=False)53 text = safeyaml.dumps(obj, explicit_start=False, explicit_end=False)
53 return text.rstrip()54 return text.rstrip()
5455
5556
diff --git a/cloudinit/config/cc_salt_minion.py b/cloudinit/config/cc_salt_minion.py
index d6a21d7..cd9cb0b 100644
--- a/cloudinit/config/cc_salt_minion.py
+++ b/cloudinit/config/cc_salt_minion.py
@@ -45,7 +45,7 @@ specify them with ``pkg_name``, ``service_name`` and ``config_dir``.
4545
46import os46import os
4747
48from cloudinit import util48from cloudinit import safeyaml, util
4949
50# Note: see https://docs.saltstack.com/en/latest/topics/installation/50# Note: see https://docs.saltstack.com/en/latest/topics/installation/
51# Note: see https://docs.saltstack.com/en/latest/ref/configuration/51# Note: see https://docs.saltstack.com/en/latest/ref/configuration/
@@ -97,13 +97,13 @@ def handle(name, cfg, cloud, log, _args):
97 if 'conf' in s_cfg:97 if 'conf' in s_cfg:
98 # Add all sections from the conf object to minion config file98 # Add all sections from the conf object to minion config file
99 minion_config = os.path.join(const.conf_dir, 'minion')99 minion_config = os.path.join(const.conf_dir, 'minion')
100 minion_data = util.yaml_dumps(s_cfg.get('conf'))100 minion_data = safeyaml.dumps(s_cfg.get('conf'))
101 util.write_file(minion_config, minion_data)101 util.write_file(minion_config, minion_data)
102102
103 if 'grains' in s_cfg:103 if 'grains' in s_cfg:
104 # add grains to /etc/salt/grains104 # add grains to /etc/salt/grains
105 grains_config = os.path.join(const.conf_dir, 'grains')105 grains_config = os.path.join(const.conf_dir, 'grains')
106 grains_data = util.yaml_dumps(s_cfg.get('grains'))106 grains_data = safeyaml.dumps(s_cfg.get('grains'))
107 util.write_file(grains_config, grains_data)107 util.write_file(grains_config, grains_data)
108108
109 # ... copy the key pair if specified109 # ... copy the key pair if specified
diff --git a/cloudinit/config/cc_snappy.py b/cloudinit/config/cc_snappy.py
index 15bee2d..b94cd04 100644
--- a/cloudinit/config/cc_snappy.py
+++ b/cloudinit/config/cc_snappy.py
@@ -68,6 +68,7 @@ is ``auto``. Options are:
68from cloudinit import log as logging68from cloudinit import log as logging
69from cloudinit.settings import PER_INSTANCE69from cloudinit.settings import PER_INSTANCE
70from cloudinit import temp_utils70from cloudinit import temp_utils
71from cloudinit import safeyaml
71from cloudinit import util72from cloudinit import util
7273
73import glob74import glob
@@ -188,7 +189,7 @@ def render_snap_op(op, name, path=None, cfgfile=None, config=None):
188 # Note, however, we do not touch config files on disk.189 # Note, however, we do not touch config files on disk.
189 nested_cfg = {'config': {shortname: config}}190 nested_cfg = {'config': {shortname: config}}
190 (fd, cfg_tmpf) = temp_utils.mkstemp()191 (fd, cfg_tmpf) = temp_utils.mkstemp()
191 os.write(fd, util.yaml_dumps(nested_cfg).encode())192 os.write(fd, safeyaml.dumps(nested_cfg).encode())
192 os.close(fd)193 os.close(fd)
193 cfgfile = cfg_tmpf194 cfgfile = cfg_tmpf
194195
diff --git a/cloudinit/handlers/cloud_config.py b/cloudinit/handlers/cloud_config.py
index 99bf0e6..2a30736 100644
--- a/cloudinit/handlers/cloud_config.py
+++ b/cloudinit/handlers/cloud_config.py
@@ -14,6 +14,7 @@ from cloudinit import handlers
14from cloudinit import log as logging14from cloudinit import log as logging
15from cloudinit import mergers15from cloudinit import mergers
16from cloudinit import util16from cloudinit import util
17from cloudinit import safeyaml
1718
18from cloudinit.settings import (PER_ALWAYS)19from cloudinit.settings import (PER_ALWAYS)
1920
@@ -75,7 +76,7 @@ class CloudConfigPartHandler(handlers.Handler):
75 '',76 '',
76 ]77 ]
77 lines.extend(file_lines)78 lines.extend(file_lines)
78 lines.append(util.yaml_dumps(self.cloud_buf))79 lines.append(safeyaml.dumps(self.cloud_buf))
79 else:80 else:
80 lines = []81 lines = []
81 util.write_file(self.cloud_fn, "\n".join(lines), 0o600)82 util.write_file(self.cloud_fn, "\n".join(lines), 0o600)
diff --git a/cloudinit/net/netplan.py b/cloudinit/net/netplan.py
index e54a34e..54be122 100644
--- a/cloudinit/net/netplan.py
+++ b/cloudinit/net/netplan.py
@@ -8,6 +8,7 @@ from .network_state import subnet_is_ipv6, NET_CONFIG_TO_V2
88
9from cloudinit import log as logging9from cloudinit import log as logging
10from cloudinit import util10from cloudinit import util
11from cloudinit import safeyaml
11from cloudinit.net import SYS_CLASS_NET, get_devicelist12from cloudinit.net import SYS_CLASS_NET, get_devicelist
1213
13KNOWN_SNAPD_CONFIG = b"""\14KNOWN_SNAPD_CONFIG = b"""\
@@ -235,9 +236,9 @@ class Renderer(renderer.Renderer):
235 # if content already in netplan format, pass it back236 # if content already in netplan format, pass it back
236 if network_state.version == 2:237 if network_state.version == 2:
237 LOG.debug('V2 to V2 passthrough')238 LOG.debug('V2 to V2 passthrough')
238 return util.yaml_dumps({'network': network_state.config},239 return safeyaml.dumps({'network': network_state.config},
239 explicit_start=False,240 explicit_start=False,
240 explicit_end=False)241 explicit_end=False)
241242
242 ethernets = {}243 ethernets = {}
243 wifis = {}244 wifis = {}
@@ -359,10 +360,10 @@ class Renderer(renderer.Renderer):
359 # workaround yaml dictionary key sorting when dumping360 # workaround yaml dictionary key sorting when dumping
360 def _render_section(name, section):361 def _render_section(name, section):
361 if section:362 if section:
362 dump = util.yaml_dumps({name: section},363 dump = safeyaml.dumps({name: section},
363 explicit_start=False,364 explicit_start=False,
364 explicit_end=False,365 explicit_end=False,
365 noalias=True)366 noalias=True)
366 txt = util.indent(dump, ' ' * 4)367 txt = util.indent(dump, ' ' * 4)
367 return [txt]368 return [txt]
368 return []369 return []
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index c0c415d..b485f3d 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -12,6 +12,7 @@ import struct
1212
13import six13import six
1414
15from cloudinit import safeyaml
15from cloudinit import util16from cloudinit import util
1617
17LOG = logging.getLogger(__name__)18LOG = logging.getLogger(__name__)
@@ -253,7 +254,7 @@ class NetworkStateInterpreter(object):
253 'config': self._config,254 'config': self._config,
254 'network_state': self._network_state,255 'network_state': self._network_state,
255 }256 }
256 return util.yaml_dumps(state)257 return safeyaml.dumps(state)
257258
258 def load(self, state):259 def load(self, state):
259 if 'version' not in state:260 if 'version' not in state:
@@ -272,7 +273,7 @@ class NetworkStateInterpreter(object):
272 setattr(self, key, state[key])273 setattr(self, key, state[key])
273274
274 def dump_network_state(self):275 def dump_network_state(self):
275 return util.yaml_dumps(self._network_state)276 return safeyaml.dumps(self._network_state)
276277
277 def as_dict(self):278 def as_dict(self):
278 return {'version': self._version, 'config': self._config}279 return {'version': self._version, 'config': self._config}
diff --git a/cloudinit/safeyaml.py b/cloudinit/safeyaml.py
index 3bd5e03..d6f5f95 100644
--- a/cloudinit/safeyaml.py
+++ b/cloudinit/safeyaml.py
@@ -6,6 +6,8 @@
66
7import yaml7import yaml
88
9YAMLError = yaml.YAMLError
10
911
10class _CustomSafeLoader(yaml.SafeLoader):12class _CustomSafeLoader(yaml.SafeLoader):
11 def construct_python_unicode(self, node):13 def construct_python_unicode(self, node):
@@ -27,4 +29,17 @@ class NoAliasSafeDumper(yaml.dumper.SafeDumper):
27def load(blob):29def load(blob):
28 return(yaml.load(blob, Loader=_CustomSafeLoader))30 return(yaml.load(blob, Loader=_CustomSafeLoader))
2931
32
33def dumps(obj, explicit_start=True, explicit_end=True, noalias=False):
34 """Return data in nicely formatted yaml."""
35
36 return yaml.dump(obj,
37 line_break="\n",
38 indent=4,
39 explicit_start=explicit_start,
40 explicit_end=explicit_end,
41 default_flow_style=False,
42 Dumper=(NoAliasSafeDumper
43 if noalias else yaml.dumper.Dumper))
44
30# vi: ts=4 expandtab45# vi: ts=4 expandtab
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 0d338ca..1f600df 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -38,7 +38,6 @@ from base64 import b64decode, b64encode
38from six.moves.urllib import parse as urlparse38from six.moves.urllib import parse as urlparse
3939
40import six40import six
41import yaml
4241
43from cloudinit import importer42from cloudinit import importer
44from cloudinit import log as logging43from cloudinit import log as logging
@@ -958,7 +957,7 @@ def load_yaml(blob, default=None, allowed=(dict,)):
958 " but got %s instead") %957 " but got %s instead") %
959 (allowed, type_utils.obj_name(converted)))958 (allowed, type_utils.obj_name(converted)))
960 loaded = converted959 loaded = converted
961 except (yaml.YAMLError, TypeError, ValueError) as e:960 except (safeyaml.YAMLError, TypeError, ValueError) as e:
962 msg = 'Failed loading yaml blob'961 msg = 'Failed loading yaml blob'
963 mark = None962 mark = None
964 if hasattr(e, 'context_mark') and getattr(e, 'context_mark'):963 if hasattr(e, 'context_mark') and getattr(e, 'context_mark'):
@@ -1629,19 +1628,6 @@ def json_dumps(data):
1629 raise1628 raise
16301629
16311630
1632def yaml_dumps(obj, explicit_start=True, explicit_end=True, noalias=False):
1633 """Return data in nicely formatted yaml."""
1634
1635 return yaml.dump(obj,
1636 line_break="\n",
1637 indent=4,
1638 explicit_start=explicit_start,
1639 explicit_end=explicit_end,
1640 default_flow_style=False,
1641 Dumper=(safeyaml.NoAliasSafeDumper
1642 if noalias else yaml.dumper.Dumper))
1643
1644
1645def ensure_dir(path, mode=None):1631def ensure_dir(path, mode=None):
1646 if not os.path.isdir(path):1632 if not os.path.isdir(path):
1647 # Make the dir and adjust the mode1633 # Make the dir and adjust the mode
diff --git a/tests/unittests/test_data.py b/tests/unittests/test_data.py
index 3efe7ad..22cf8f2 100644
--- a/tests/unittests/test_data.py
+++ b/tests/unittests/test_data.py
@@ -27,6 +27,7 @@ from cloudinit.settings import (PER_INSTANCE)
27from cloudinit import sources27from cloudinit import sources
28from cloudinit import stages28from cloudinit import stages
29from cloudinit import user_data as ud29from cloudinit import user_data as ud
30from cloudinit import safeyaml
30from cloudinit import util31from cloudinit import util
3132
32from cloudinit.tests import helpers33from cloudinit.tests import helpers
@@ -502,7 +503,7 @@ c: 4
502 data = [{'content': '#cloud-config\npassword: gocubs\n'},503 data = [{'content': '#cloud-config\npassword: gocubs\n'},
503 {'content': '#cloud-config\nlocale: chicago\n'},504 {'content': '#cloud-config\nlocale: chicago\n'},
504 {'content': non_decodable}]505 {'content': non_decodable}]
505 message = b'#cloud-config-archive\n' + util.yaml_dumps(data).encode()506 message = b'#cloud-config-archive\n' + safeyaml.dumps(data).encode()
506507
507 self.reRoot()508 self.reRoot()
508 ci = stages.Init()509 ci = stages.Init()
diff --git a/tests/unittests/test_runs/test_merge_run.py b/tests/unittests/test_runs/test_merge_run.py
index d1ac494..ff27a28 100644
--- a/tests/unittests/test_runs/test_merge_run.py
+++ b/tests/unittests/test_runs/test_merge_run.py
@@ -7,6 +7,7 @@ import tempfile
7from cloudinit.tests import helpers7from cloudinit.tests import helpers
88
9from cloudinit.settings import PER_INSTANCE9from cloudinit.settings import PER_INSTANCE
10from cloudinit import safeyaml
10from cloudinit import stages11from cloudinit import stages
11from cloudinit import util12from cloudinit import util
1213
@@ -26,7 +27,7 @@ class TestMergeRun(helpers.FilesystemMockingTestCase):
26 'system_info': {'paths': {'run_dir': new_root}}27 'system_info': {'paths': {'run_dir': new_root}}
27 }28 }
28 ud = helpers.readResource('user_data.1.txt')29 ud = helpers.readResource('user_data.1.txt')
29 cloud_cfg = util.yaml_dumps(cfg)30 cloud_cfg = safeyaml.dumps(cfg)
30 util.ensure_dir(os.path.join(new_root, 'etc', 'cloud'))31 util.ensure_dir(os.path.join(new_root, 'etc', 'cloud'))
31 util.write_file(os.path.join(new_root, 'etc',32 util.write_file(os.path.join(new_root, 'etc',
32 'cloud', 'cloud.cfg'), cloud_cfg)33 'cloud', 'cloud.cfg'), cloud_cfg)
diff --git a/tests/unittests/test_runs/test_simple_run.py b/tests/unittests/test_runs/test_simple_run.py
index d67c422..cb3aae6 100644
--- a/tests/unittests/test_runs/test_simple_run.py
+++ b/tests/unittests/test_runs/test_simple_run.py
@@ -5,6 +5,7 @@ import os
55
66
7from cloudinit.settings import PER_INSTANCE7from cloudinit.settings import PER_INSTANCE
8from cloudinit import safeyaml
8from cloudinit import stages9from cloudinit import stages
9from cloudinit.tests import helpers10from cloudinit.tests import helpers
10from cloudinit import util11from cloudinit import util
@@ -34,7 +35,7 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase):
34 ],35 ],
35 'cloud_init_modules': ['write-files', 'spacewalk', 'runcmd'],36 'cloud_init_modules': ['write-files', 'spacewalk', 'runcmd'],
36 }37 }
37 cloud_cfg = util.yaml_dumps(self.cfg)38 cloud_cfg = safeyaml.dumps(self.cfg)
38 util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))39 util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))
39 util.write_file(os.path.join(self.new_root, 'etc',40 util.write_file(os.path.join(self.new_root, 'etc',
40 'cloud', 'cloud.cfg'), cloud_cfg)41 'cloud', 'cloud.cfg'), cloud_cfg)
@@ -130,7 +131,7 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase):
130 # re-write cloud.cfg with unverified_modules override131 # re-write cloud.cfg with unverified_modules override
131 cfg = copy.deepcopy(self.cfg)132 cfg = copy.deepcopy(self.cfg)
132 cfg['unverified_modules'] = ['spacewalk'] # Would have skipped133 cfg['unverified_modules'] = ['spacewalk'] # Would have skipped
133 cloud_cfg = util.yaml_dumps(cfg)134 cloud_cfg = safeyaml.dumps(cfg)
134 util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))135 util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))
135 util.write_file(os.path.join(self.new_root, 'etc',136 util.write_file(os.path.join(self.new_root, 'etc',
136 'cloud', 'cloud.cfg'), cloud_cfg)137 'cloud', 'cloud.cfg'), cloud_cfg)
@@ -159,7 +160,7 @@ class TestSimpleRun(helpers.FilesystemMockingTestCase):
159 cfg = copy.deepcopy(self.cfg)160 cfg = copy.deepcopy(self.cfg)
160 # Represent empty configuration in /etc/cloud/cloud.cfg161 # Represent empty configuration in /etc/cloud/cloud.cfg
161 cfg['cloud_init_modules'] = None162 cfg['cloud_init_modules'] = None
162 cloud_cfg = util.yaml_dumps(cfg)163 cloud_cfg = safeyaml.dumps(cfg)
163 util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))164 util.ensure_dir(os.path.join(self.new_root, 'etc', 'cloud'))
164 util.write_file(os.path.join(self.new_root, 'etc',165 util.write_file(os.path.join(self.new_root, 'etc',
165 'cloud', 'cloud.cfg'), cloud_cfg)166 'cloud', 'cloud.cfg'), cloud_cfg)

Subscribers

People subscribed via source and target branches