summaryrefslogtreecommitdiff
path: root/cloudinit/cmd
diff options
context:
space:
mode:
authorJames Falcon <james.falcon@canonical.com>2022-09-14 10:03:31 -0500
committerGitHub <noreply@github.com>2022-09-14 09:03:31 -0600
commit197cc8ccb9d2b9856456ed2e2a5cb4748df5ec0f (patch)
tree294adaec5129c6823bfff099e7172c5c1167fbeb /cloudinit/cmd
parentb861ea8a5e1fd0eb33096f60f54eeff42d80d3bd (diff)
downloadcloud-init-git-197cc8ccb9d2b9856456ed2e2a5cb4748df5ec0f.tar.gz
Allow jinja templating in /etc/cloud (SC-1170) (#1722)
There have been multiple requests to allow jinja templating in /etc/cloud configs the same way we allow jinja templating in vendordata and userdata. This commit allows for templating both /etc/cloud/cloud.cfg and any file in /etc/cloud/cloud.cfg.d. The same instance data used for substitution in vendordata and userdata will be used here. Note that these configs get loaded multiple times during the lifetime of cloud-init, and during cloud-init's earlier loads, instance data is not yet available. LP: #1913461
Diffstat (limited to 'cloudinit/cmd')
-rwxr-xr-xcloudinit/cmd/devel/render.py37
1 files changed, 21 insertions, 16 deletions
diff --git a/cloudinit/cmd/devel/render.py b/cloudinit/cmd/devel/render.py
index e28cc0af..97193ea1 100755
--- a/cloudinit/cmd/devel/render.py
+++ b/cloudinit/cmd/devel/render.py
@@ -9,7 +9,11 @@ import os
import sys
from cloudinit import log
-from cloudinit.handlers.jinja_template import render_jinja_payload_from_file
+from cloudinit.handlers.jinja_template import (
+ JinjaLoadError,
+ NotJinjaError,
+ render_jinja_payload_from_file,
+)
from . import addLogHandlerCLI, read_cfg_paths
@@ -50,7 +54,7 @@ def get_parser(parser=None):
return parser
-def handle_args(name, args):
+def render_template(user_data_path, instance_data_path=None, debug=False):
"""Render the provided user-data template file using instance-data values.
Also setup CLI log handlers to report to stderr since this is a development
@@ -58,9 +62,9 @@ def handle_args(name, args):
@return 0 on success, 1 on failure.
"""
- addLogHandlerCLI(LOG, log.DEBUG if args.debug else log.WARNING)
- if args.instance_data:
- instance_data_fn = args.instance_data
+ addLogHandlerCLI(LOG, log.DEBUG if debug else log.WARNING)
+ if instance_data_path:
+ instance_data_fn = instance_data_path
else:
paths = read_cfg_paths()
uid = os.getuid()
@@ -80,32 +84,33 @@ def handle_args(name, args):
LOG.error("Missing instance-data.json file: %s", instance_data_fn)
return 1
try:
- with open(args.user_data) as stream:
+ with open(user_data_path) as stream:
user_data = stream.read()
except IOError:
- LOG.error("Missing user-data file: %s", args.user_data)
+ LOG.error("Missing user-data file: %s", user_data_path)
return 1
try:
rendered_payload = render_jinja_payload_from_file(
payload=user_data,
- payload_fn=args.user_data,
+ payload_fn=user_data_path,
instance_data_file=instance_data_fn,
- debug=True if args.debug else False,
+ debug=True if debug else False,
+ )
+ except (JinjaLoadError, NotJinjaError) as e:
+ LOG.error(
+ "Cannot render from instance data due to exception: %s", repr(e)
)
- except RuntimeError as e:
- LOG.error("Cannot render from instance data: %s", str(e))
return 1
if not rendered_payload:
- LOG.error("Unable to render user-data file: %s", args.user_data)
+ LOG.error("Unable to render user-data file: %s", user_data_path)
return 1
sys.stdout.write(rendered_payload)
return 0
-def main():
- args = get_parser().parse_args()
- return handle_args(NAME, args)
+def handle_args(_name, args):
+ return render_template(args.user_data, args.instance_data, args.debug)
if __name__ == "__main__":
- sys.exit(main())
+ sys.exit(handle_args(NAME, get_parser().parse_args()))