cloud-init-dev team mailing list archive
-
cloud-init-dev team
-
Mailing list archive
-
Message #01249
[Merge] ~harlowja/cloud-init:tpl-cloud-cfg into cloud-init:master
Joshua Harlow has proposed merging ~harlowja/cloud-init:tpl-cloud-cfg into cloud-init:master.
Requested reviews:
cloud init development team (cloud-init-dev)
For more details, see:
https://code.launchpad.net/~harlowja/cloud-init/+git/cloud-init/+merge/307485
--
Your team cloud init development team is requested to review the proposed merge of ~harlowja/cloud-init:tpl-cloud-cfg into cloud-init:master.
diff --git a/cloudinit/helpers.py b/cloudinit/helpers.py
index fb95bab..12c8ef3 100644
--- a/cloudinit/helpers.py
+++ b/cloudinit/helpers.py
@@ -33,6 +33,7 @@ from cloudinit.settings import (PER_INSTANCE, PER_ALWAYS, PER_ONCE,
CFG_ENV_NAME)
from cloudinit import log as logging
+from cloudinit import templater
from cloudinit import type_utils
from cloudinit import util
@@ -200,18 +201,47 @@ class Runners(object):
return (True, results)
+class ConfigError(Exception):
+ pass
+
+
class ConfigMerger(object):
def __init__(self, paths=None, datasource=None,
additional_fns=None, base_cfg=None,
include_vendor=True):
self._paths = paths
self._ds = datasource
- self._fns = additional_fns
+ self._fns = additional_fns or []
self._base_cfg = base_cfg
self._include_vendor = include_vendor
# Created on first use
self._cfg = None
+ @staticmethod
+ def _read_conf(fn, kind="config", tpl_params=None):
+ try:
+ c = util.load_file(fn, quiet=False)
+ except (IOError, OSError) as e:
+ raise ConfigError("Failed loading of %s from"
+ " %s due to: %s" % (kind, fn, e))
+ else:
+ if fn.endswith(".tpl"):
+ if tpl_params is None:
+ tpl_params = {}
+ tpl_params.setdefault('system', util.system_info())
+ try:
+ c = templater.render_string(c, tpl_params)
+ except Exception as e:
+ raise ConfigError(
+ "Failed rendering %s from %s"
+ " using params %s due to: %s" % (kind, fn,
+ tpl_params, e))
+ try:
+ return util.load_yaml(c, default={})
+ except TypeError as e:
+ raise ConfigError("Failed parsing (into yaml) %s"
+ " from %s due to: %s" % (kind, fn, e))
+
def _get_datasource_configs(self):
d_cfgs = []
if self._ds:
@@ -229,10 +259,9 @@ class ConfigMerger(object):
if CFG_ENV_NAME in os.environ:
e_fn = os.environ[CFG_ENV_NAME]
try:
- e_cfgs.append(util.read_conf(e_fn))
- except Exception:
- util.logexc(LOG, 'Failed loading of env. config from %s',
- e_fn)
+ e_cfgs.append(self._read_conf(e_fn, "environment config"))
+ except ConfigError as e:
+ util.logexc(LOG, str(e))
return e_cfgs
def _get_instance_configs(self):
@@ -241,19 +270,16 @@ class ConfigMerger(object):
# a configuration file to use when running...
if not self._paths:
return i_cfgs
-
- cc_paths = ['cloud_config']
+ cc_paths = [("cloud config", 'cloud_config')]
if self._include_vendor:
- cc_paths.append('vendor_cloud_config')
-
- for cc_p in cc_paths:
+ cc_paths.append(("vendor cloud config", 'vendor_cloud_config'))
+ for cc_kind, cc_p in cc_paths:
cc_fn = self._paths.get_ipath_cur(cc_p)
if cc_fn and os.path.isfile(cc_fn):
try:
- i_cfgs.append(util.read_conf(cc_fn))
- except Exception:
- util.logexc(LOG, 'Failed loading of cloud-config from %s',
- cc_fn)
+ i_cfgs.append(self._read_conf(cc_fn, cc_kind))
+ except ConfigError as e:
+ util.logexc(LOG, str(e))
return i_cfgs
def _read_cfg(self):
@@ -264,14 +290,11 @@ class ConfigMerger(object):
# configs which override
# base configuration
cfgs = []
- if self._fns:
- for c_fn in self._fns:
- try:
- cfgs.append(util.read_conf(c_fn))
- except Exception:
- util.logexc(LOG, "Failed loading of configuration from %s",
- c_fn)
-
+ for c_fn in self._fns:
+ try:
+ cfgs.append(self._read_conf(c_fn, "config"))
+ except ConfigError as e:
+ util.logexc(LOG, str(e))
cfgs.extend(self._get_env_configs())
cfgs.extend(self._get_instance_configs())
cfgs.extend(self._get_datasource_configs())
diff --git a/cloudinit/settings.py b/cloudinit/settings.py
index 8c258ea..3796262 100644
--- a/cloudinit/settings.py
+++ b/cloudinit/settings.py
@@ -23,8 +23,12 @@
# Set and read for determining the cloud config file location
CFG_ENV_NAME = "CLOUD_CFG"
-# This is expected to be a yaml formatted file
-CLOUD_CONFIG = '/etc/cloud/cloud.cfg'
+# This is expected to be a yaml (or yaml formatted template) file.
+CLOUD_CONFIG = '/etc/cloud/cloud.cfg.tpl'
+
+# This is expected to be a directory of yaml formatted file(s)
+# or templates that can/will turn into yaml formatted file(s)
+CLOUD_CONFIG_D = '/etc/cloud/cloud.cfg.d/'
# What u get if no config is provided
CFG_BUILTIN = {
diff --git a/cloudinit/util.py b/cloudinit/util.py
index eb3e589..421a68b 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -579,13 +579,40 @@ def get_cfg_option_int(yobj, key, default=0):
def system_info():
- return {
+ info = {
'platform': platform.platform(),
'release': platform.release(),
'python': platform.python_version(),
'uname': platform.uname(),
'dist': platform.linux_distribution(),
}
+ plat = info['platform'].lower()
+ # Try to get more info about what it actually is, in a format
+ # that we can easily use across linux and variants...
+ if plat.startswith('darwin'):
+ info['variant'] = 'darwin'
+ elif plat.endswith("bsd"):
+ info['variant'] = 'bsd'
+ elif plat.startswith('win'):
+ info['variant'] = 'windows'
+ elif 'linux' in plat:
+ # Try to get a single string out of these...
+ linux_dist, _version, _id = info['dist']
+ linux_dist = linux_dist.lower()
+ if linux_dist in ('ubuntu', 'linuxmint', 'mint'):
+ info['variant'] = 'ubuntu'
+ else:
+ for prefix, variant in [('redhat', 'rhel'),
+ ('centos', 'rhel'),
+ ('fedora', 'fedora'),
+ ('debian', 'debian')]:
+ if linux_dist.startswith(prefix):
+ info['variant'] = variant
+ if 'variant' not in info:
+ info['variant'] = 'linux'
+ if 'variant' not in info:
+ info['variant'] = 'unknown'
+ return info
def get_cfg_option_list(yobj, key, default=None):
diff --git a/config/cloud.cfg b/config/cloud.cfg
deleted file mode 100644
index d608dc8..0000000
--- a/config/cloud.cfg
+++ /dev/null
@@ -1,116 +0,0 @@
-# The top level settings are used as module
-# and system configuration.
-
-# A set of users which may be applied and/or used by various modules
-# when a 'default' entry is found it will reference the 'default_user'
-# from the distro configuration specified below
-users:
- - default
-
-# If this is set, 'root' will not be able to ssh in and they
-# will get a message to login instead as the above $user (ubuntu)
-disable_root: true
-
-# This will cause the set+update hostname module to not operate (if true)
-preserve_hostname: false
-
-# Example datasource config
-# datasource:
-# Ec2:
-# metadata_urls: [ 'blah.com' ]
-# timeout: 5 # (defaults to 50 seconds)
-# max_wait: 10 # (defaults to 120 seconds)
-
-# The modules that run in the 'init' stage
-cloud_init_modules:
- - migrator
- - ubuntu-init-switch
- - seed_random
- - bootcmd
- - write-files
- - growpart
- - resizefs
- - disk_setup
- - mounts
- - set_hostname
- - update_hostname
- - update_etc_hosts
- - ca-certs
- - rsyslog
- - users-groups
- - ssh
-
-# The modules that run in the 'config' stage
-cloud_config_modules:
-# Emit the cloud config ready event
-# this can be used by upstart jobs for 'start on cloud-config'.
- - emit_upstart
- - ssh-import-id
- - locale
- - set-passwords
- - grub-dpkg
- - apt-pipelining
- - apt-configure
- - ntp
- - timezone
- - disable-ec2-metadata
- - runcmd
- - byobu
-
-# The modules that run in the 'final' stage
-cloud_final_modules:
- - snappy
- - package-update-upgrade-install
- - fan
- - landscape
- - lxd
- - puppet
- - chef
- - salt-minion
- - mcollective
- - rightscale_userdata
- - scripts-vendor
- - scripts-per-once
- - scripts-per-boot
- - scripts-per-instance
- - scripts-user
- - ssh-authkey-fingerprints
- - keys-to-console
- - phone-home
- - final-message
- - power-state-change
-
-# System and/or distro specific settings
-# (not accessible to handlers/transforms)
-system_info:
- # This will affect which distro class gets used
- distro: ubuntu
- # Default user name + that default users groups (if added/used)
- default_user:
- name: ubuntu
- lock_passwd: True
- gecos: Ubuntu
- groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/bash
- # Other config here will be given to the distro class and/or path classes
- paths:
- cloud_dir: /var/lib/cloud/
- templates_dir: /etc/cloud/templates/
- upstart_dir: /etc/init/
- package_mirrors:
- - arches: [i386, amd64]
- failsafe:
- primary: http://archive.ubuntu.com/ubuntu
- security: http://security.ubuntu.com/ubuntu
- search:
- primary:
- - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
- - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
- - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
- security: []
- - arches: [armhf, armel, default]
- failsafe:
- primary: http://ports.ubuntu.com/ubuntu-ports
- security: http://ports.ubuntu.com/ubuntu-ports
- ssh_svcname: ssh
diff --git a/config/cloud.cfg-freebsd b/config/cloud.cfg-freebsd
deleted file mode 100644
index be664f5..0000000
--- a/config/cloud.cfg-freebsd
+++ /dev/null
@@ -1,88 +0,0 @@
-# The top level settings are used as module
-# and system configuration.
-
-syslog_fix_perms: root:wheel
-
-# This should not be required, but leave it in place until the real cause of
-# not beeing able to find -any- datasources is resolved.
-datasource_list: ['ConfigDrive', 'OpenStack', 'Ec2']
-
-# A set of users which may be applied and/or used by various modules
-# when a 'default' entry is found it will reference the 'default_user'
-# from the distro configuration specified below
-users:
- - default
-
-# If this is set, 'root' will not be able to ssh in and they
-# will get a message to login instead as the above $user (ubuntu)
-disable_root: false
-
-# This will cause the set+update hostname module to not operate (if true)
-preserve_hostname: false
-
-# Example datasource config
-# datasource:
-# Ec2:
-# metadata_urls: [ 'blah.com' ]
-# timeout: 5 # (defaults to 50 seconds)
-# max_wait: 10 # (defaults to 120 seconds)
-
-# The modules that run in the 'init' stage
-cloud_init_modules:
-# - migrator
- - seed_random
- - bootcmd
-# - write-files
- - growpart
- - resizefs
- - set_hostname
- - update_hostname
-# - update_etc_hosts
-# - ca-certs
-# - rsyslog
- - users-groups
- - ssh
-
-# The modules that run in the 'config' stage
-cloud_config_modules:
-# - disk_setup
-# - mounts
- - ssh-import-id
- - locale
- - set-passwords
- - package-update-upgrade-install
-# - landscape
- - timezone
-# - puppet
-# - chef
-# - salt-minion
-# - mcollective
- - disable-ec2-metadata
- - runcmd
-# - byobu
-
-# The modules that run in the 'final' stage
-cloud_final_modules:
- - rightscale_userdata
- - scripts-vendor
- - scripts-per-once
- - scripts-per-boot
- - scripts-per-instance
- - scripts-user
- - ssh-authkey-fingerprints
- - keys-to-console
- - phone-home
- - final-message
- - power-state-change
-
-# System and/or distro specific settings
-# (not accessible to handlers/transforms)
-system_info:
- distro: freebsd
- default_user:
- name: freebsd
- lock_passwd: True
- gecos: FreeBSD
- groups: [wheel]
- sudo: ["ALL=(ALL) NOPASSWD:ALL"]
- shell: /bin/tcsh
diff --git a/config/cloud.cfg.tpl b/config/cloud.cfg.tpl
new file mode 100644
index 0000000..224c564
--- /dev/null
+++ b/config/cloud.cfg.tpl
@@ -0,0 +1,198 @@
+## template:jinja
+
+# The top level settings are used as module
+# and system configuration.
+
+{% if platform.variant in ["bsd"] %}
+syslog_fix_perms: root:wheel
+{% endif %}
+
+# A set of users which may be applied and/or used by various modules
+# when a 'default' entry is found it will reference the 'default_user'
+# from the distro configuration specified below
+users:
+ - default
+
+# If this is set, 'root' will not be able to ssh in and they
+# will get a message to login instead as the default $user
+{% if platform.variant in ["bsd"] %}
+disable_root: false
+{% else %}
+disable_root: true
+{% endif %}
+
+# This will cause the set+update hostname module to not operate (if true)
+preserve_hostname: false
+
+# Example datasource config
+# datasource:
+# Ec2:
+# metadata_urls: [ 'blah.com' ]
+# timeout: 5 # (defaults to 50 seconds)
+# max_wait: 10 # (defaults to 120 seconds)
+
+{% if platform.variant in ["bsd"] %}
+# This should not be required, but leave it in place until the real cause of
+# not beeing able to find -any- datasources is resolved.
+datasource_list: ['ConfigDrive', 'OpenStack', 'Ec2']
+{% endif %}
+
+# The modules that run in the 'init' stage
+cloud_init_modules:
+ - migrator
+{% if platform.variant in ["ubuntu", "unknown", "debian"] %}
+ - ubuntu-init-switch
+{% endif %}
+ - seed_random
+ - bootcmd
+# Setup disks and filesystems ... before we do much else.
+ - growpart
+ - resizefs
+ - disk_setup
+ - mounts
+# (end block of disk/fs modules)
+{% if platform.variant not in ["bsd"] %}
+ - write-files
+{% endif %}
+ - set_hostname
+ - update_hostname
+{% if platform.variant not in ["bsd"] %}
+ - update_etc_hosts
+ - ca-certs
+ - rsyslog
+{% endif %}
+ - users-groups
+ - ssh
+
+# The modules that run in the 'config' stage
+cloud_config_modules:
+{% if platform.variant in ["ubuntu", "unknown", "debian"] %}
+# Emit the cloud config ready event
+# this can be used by upstart jobs for 'start on cloud-config'.
+ - emit_upstart
+{% endif %}
+ - ssh-import-id
+ - locale
+ - set-passwords
+{% if platform.variant in ["rhel", "fedora"] %}
+ - spacewalk
+ - yum-add-repo
+{% endif %}
+{% if platform.variant in ["ubuntu", "unknown", "debian"] %}
+ - grub-dpkg
+ - apt-pipelining
+ - apt-configure
+{% endif %}
+ - ntp
+ - timezone
+ - disable-ec2-metadata
+ - runcmd
+{% if platform.variant in ["ubuntu", "unknown", "debian"] %}
+ - byobu
+{% endif %}
+
+# The modules that run in the 'final' stage
+cloud_final_modules:
+{% if platform.variant in ["ubuntu", "unknown", "debian"] %}
+ - snappy
+{% endif %}
+ - package-update-upgrade-install
+{% if platform.variant in ["ubuntu", "unknown", "debian"] %}
+ - fan
+ - landscape
+ - lxd
+{% endif %}
+{% if platform.variant not in ["bsd"] %}
+ # These are all grouped together (but typically only one of them
+ # actually is doing anything, since most people don't run many of these
+ # package/configuration management systems at the same time).
+ - puppet
+ - chef
+ - salt-minion
+ - mcollective
+ # (end block of configuration management 'like' modules)
+{% endif %}
+ - rightscale_userdata
+ - scripts-vendor
+ - scripts-per-once
+ - scripts-per-boot
+ - scripts-per-instance
+ - scripts-user
+ - ssh-authkey-fingerprints
+ - keys-to-console
+ - phone-home
+ - final-message
+ - power-state-change
+
+# System and/or distro specific settings
+# (not accessible to handlers/transforms)
+system_info:
+ # This will affect which distro class gets used...
+{% if platform.variant in ["ubuntu"] %}
+ distro: ubuntu
+{% elif platform.variant in ["fedora"] %}
+ distro: fedora
+{% elif platform.variant in ["debian"] %}
+ distro: debian
+{% elif platform.variant in ["rhel"] %}
+ distro: rhel
+{% elif platform.variant in ["bsd"] %}
+ distro: freebsd
+{% else %}
+ # Unknown/fallback distro.
+ distro: ubuntu
+{% endif %}
+{% if platform.variant in ["ubuntu", "unknown", "debian"] %}
+ # Default user name + that default users groups (if added/used)
+ default_user:
+ name: ubuntu
+ lock_passwd: True
+ gecos: Ubuntu
+ groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video]
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+ shell: /bin/bash
+ # Other config here will be given to the distro class and/or path classes
+ paths:
+ cloud_dir: /var/lib/cloud/
+ templates_dir: /etc/cloud/templates/
+ upstart_dir: /etc/init/
+ package_mirrors:
+ - arches: [i386, amd64]
+ failsafe:
+ primary: http://archive.ubuntu.com/ubuntu
+ security: http://security.ubuntu.com/ubuntu
+ search:
+ primary:
+ - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/
+ - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/
+ - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/
+ security: []
+ - arches: [armhf, armel, default]
+ failsafe:
+ primary: http://ports.ubuntu.com/ubuntu-ports
+ security: http://ports.ubuntu.com/ubuntu-ports
+ ssh_svcname: ssh
+{% elif platform.variant in ["rhel", "fedora"] %}
+ # Default user name + that default users groups (if added/used)
+ default_user:
+ name: fedora
+ lock_passwd: True
+ gecos: Fedora Cloud User
+ groups: [wheel, adm, systemd-journal]
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+ shell: /bin/bash
+ # Other config here will be given to the distro class and/or path classes
+ paths:
+ cloud_dir: /var/lib/cloud/
+ templates_dir: /etc/cloud/templates/
+ ssh_svcname: sshd
+{% elif platform.variant in ["bsd"] %}
+ # Default user name + that default users groups (if added/used)
+ default_user:
+ name: freebsd
+ lock_passwd: True
+ gecos: FreeBSD
+ groups: [wheel]
+ sudo: ["ALL=(ALL) NOPASSWD:ALL"]
+ shell: /bin/tcsh
+{% endif %}
diff --git a/packages/debian/rules.in b/packages/debian/rules.in
index 9b00435..1d4f829 100755
--- a/packages/debian/rules.in
+++ b/packages/debian/rules.in
@@ -11,6 +11,7 @@ override_dh_install:
dh_install
install -d debian/cloud-init/etc/rsyslog.d
cp tools/21-cloudinit.conf debian/cloud-init/etc/rsyslog.d/21-cloudinit.conf
+ mv debian/cloud-init/etc/cloud.cfg-ubuntu debian/cloud-init/etc/cloud.cfg
override_dh_auto_test:
ifeq (,$(findstring nocheck,$(DEB_BUILD_OPTIONS)))
diff --git a/packages/redhat/cloud-init.spec.in b/packages/redhat/cloud-init.spec.in
index d0ae048..9b8fd33 100644
--- a/packages/redhat/cloud-init.spec.in
+++ b/packages/redhat/cloud-init.spec.in
@@ -95,11 +95,23 @@ rm -rf \$RPM_BUILD_ROOT%{python_sitelib}/tests
mkdir -p \$RPM_BUILD_ROOT/%{_sharedstatedir}/cloud
mkdir -p \$RPM_BUILD_ROOT/%{_libexecdir}/%{name}
+# Remove these for now (not sure if they work)...
+rm \$RPM_BUILD_ROOT/%{_sysconfdir}/NetworkManager/dispatcher.d/hook-network-manager
+rm \$RPM_BUILD_ROOT/%{_sysconfdir}/dhcp/dhclient-exit-hooks.d/hook-dhclient
+
#if $systemd
mkdir -p \$RPM_BUILD_ROOT/%{_unitdir}
cp -p systemd/* \$RPM_BUILD_ROOT/%{_unitdir}
#end if
+# The fedora (and/or rhel) file is what should be working on rhel based
+# systems.
+mv \$RPM_BUILD_ROOT/%{_sysconfdir}/cloud/cloud.cfg-fedora \$RPM_BUILD_ROOT/%{_sysconfdir}/cloud/cloud.cfg
+
+# Remove the other configs (we don't need them anymore)
+rm %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg-ubuntu
+rm %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg-freebsd
+
%clean
rm -rf \$RPM_BUILD_ROOT
diff --git a/packages/suse/cloud-init.spec.in b/packages/suse/cloud-init.spec.in
index f994a0c..5906828 100644
--- a/packages/suse/cloud-init.spec.in
+++ b/packages/suse/cloud-init.spec.in
@@ -77,6 +77,14 @@ ssh keys and to let the user run various scripts.
--record-rpm=INSTALLED_FILES --install-lib=%{python_sitelib} \
--init-system=%{initsys}
+# Unsure what file should work here, so we will copy over the prior
+# default which is the ubuntu one and use that.
+mv \$RPM_BUILD_ROOT/%{_sysconfdir}/cloud/cloud.cfg-ubuntu \$RPM_BUILD_ROOT/%{_sysconfdir}/cloud/cloud.cfg
+
+# Remove the other configs (we don't need them anymore)
+rm %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg-fedora
+rm %{buildroot}/%{_sysconfdir}/cloud/cloud.cfg-freebsd
+
# Remove non-SUSE templates
rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.debian.*
rm %{buildroot}/%{_sysconfdir}/cloud/templates/*.redhat.*
diff --git a/setup.py b/setup.py
index 8ff667d..eab9a16 100755
--- a/setup.py
+++ b/setup.py
@@ -98,12 +98,15 @@ USR = "/usr"
ETC = "/etc"
USR_LIB_EXEC = "/usr/lib"
LIB = "/lib"
+CLOUD_CFG = "config/cloud.cfg-ubuntu"
if os.uname()[0] == 'FreeBSD':
USR = "/usr/local"
USR_LIB_EXEC = "/usr/local/lib"
ETC = "/usr/local/etc"
+ CLOUD_CFG = "config/cloud.cfg-freebsd"
elif os.path.isfile('/etc/redhat-release'):
USR_LIB_EXEC = "/usr/libexec"
+ CLOUD_CFG = "config/cloud.cfg-fedora"
# Avoid having datafiles installed in a virtualenv...
@@ -175,7 +178,7 @@ if in_virtualenv():
cmdclass = {}
else:
data_files = [
- (ETC + '/cloud', glob('config/*.cfg')),
+ (ETC + '/cloud', [CLOUD_CFG]),
(ETC + '/cloud/cloud.cfg.d', glob('config/cloud.cfg.d/*')),
(ETC + '/cloud/templates', glob('templates/*')),
(ETC + '/NetworkManager/dispatcher.d/', ['tools/hook-network-manager']),
diff --git a/tools/render_ud.py b/tools/render_ud.py
new file mode 100644
index 0000000..624403f
--- /dev/null
+++ b/tools/render_ud.py
@@ -0,0 +1,20 @@
+import sys
+
+from cloudinit import templater
+from cloudinit import util
+
+
+def main():
+ fn = sys.argv[1]
+ tpl_params = {
+ 'platform': util.system_info(),
+ }
+ with open(fn, 'rb') as fh:
+ contents = fh.read()
+ contents = (templater.render_string(contents, tpl_params))
+ print(contents)
+ util.load_yaml(contents)
+
+
+if __name__ == '__main__':
+ main()
Follow ups