summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorLucendio <github+dev@lucendio.com>2021-10-25 21:31:07 +0200
committerGitHub <noreply@github.com>2021-10-25 14:31:07 -0500
commita4236c375ddf78258a8f9252c1d79c665aa4f88b (patch)
treea092882639d27965c2fe6fd7d3faa232c37f5d22 /cloudinit
parent81f6aa1653936e324bba69e51439aa8894aaf170 (diff)
downloadvyos-cloud-init-a4236c375ddf78258a8f9252c1d79c665aa4f88b.tar.gz
vyos-cloud-init-a4236c375ddf78258a8f9252c1d79c665aa4f88b.zip
Add module 'write-files-deferred' executed in stage 'final' (#916)
The main idea is to introduce a second module that takes care of writing files, but in the 'final' stage. While the introduction of a second module would allow for choosing the appropriate place withing the order of modules (and stages), there is no addition top-level directive being added to the cloud configuration schema. Instead, 'write-files' schema is being extended to include a 'defer' attribute used only by the 'write-deffered-files' modules. The new module 'write-deferred-files' reuses as much as possible of the 'write-files' functionality.
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/config/cc_write_files.py41
-rw-r--r--cloudinit/config/cc_write_files_deferred.py55
2 files changed, 92 insertions, 4 deletions
diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py
index 8601e707..41c75fa2 100644
--- a/cloudinit/config/cc_write_files.py
+++ b/cloudinit/config/cc_write_files.py
@@ -21,6 +21,7 @@ frequency = PER_INSTANCE
DEFAULT_OWNER = "root:root"
DEFAULT_PERMS = 0o644
+DEFAULT_DEFER = False
UNKNOWN_ENC = 'text/plain'
LOG = logging.getLogger(__name__)
@@ -90,6 +91,24 @@ schema = {
# Create an empty file on the system
write_files:
- path: /root/CLOUD_INIT_WAS_HERE
+ """),
+ dedent("""\
+ # Defer writing the file until after the package (Nginx) is
+ # installed and its user is created alongside
+ write_files:
+ - path: /etc/nginx/conf.d/example.com.conf
+ content: |
+ server {
+ server_name example.com;
+ listen 80;
+ root /var/www;
+ location / {
+ try_files $uri $uri/ $uri.html =404;
+ }
+ }
+ owner: 'nginx:nginx'
+ permissions: '0640'
+ defer: true
""")],
'frequency': frequency,
'type': 'object',
@@ -151,6 +170,15 @@ schema = {
``path`` exists. Default: **false**.
"""),
},
+ 'defer': {
+ 'type': 'boolean',
+ 'default': DEFAULT_DEFER,
+ 'description': dedent("""\
+ Defer writing the file until 'final' stage, after
+ users were created, and packages were installed.
+ Default: **{defer}**.
+ """.format(defer=DEFAULT_DEFER)),
+ },
},
'required': ['path'],
'additionalProperties': False
@@ -163,13 +191,18 @@ __doc__ = get_schema_doc(schema) # Supplement python help()
def handle(name, cfg, _cloud, log, _args):
- files = cfg.get('write_files')
- if not files:
+ validate_cloudconfig_schema(cfg, schema)
+ file_list = cfg.get('write_files', [])
+ filtered_files = [
+ f for f in file_list if not util.get_cfg_option_bool(f,
+ 'defer',
+ DEFAULT_DEFER)
+ ]
+ if not filtered_files:
log.debug(("Skipping module named %s,"
" no/empty 'write_files' key in configuration"), name)
return
- validate_cloudconfig_schema(cfg, schema)
- write_files(name, files)
+ write_files(name, filtered_files)
def canonicalize_extraction(encoding_type):
diff --git a/cloudinit/config/cc_write_files_deferred.py b/cloudinit/config/cc_write_files_deferred.py
new file mode 100644
index 00000000..0c75aa22
--- /dev/null
+++ b/cloudinit/config/cc_write_files_deferred.py
@@ -0,0 +1,55 @@
+# Copyright (C) 2021 Canonical Ltd.
+#
+# This file is part of cloud-init. See LICENSE file for license information.
+
+"""Defer writing certain files"""
+
+from textwrap import dedent
+
+from cloudinit.config.schema import validate_cloudconfig_schema
+from cloudinit import util
+from cloudinit.config.cc_write_files import (
+ schema as write_files_schema, write_files, DEFAULT_DEFER)
+
+
+schema = util.mergemanydict([
+ {
+ 'id': 'cc_write_files_deferred',
+ 'name': 'Write Deferred Files',
+ 'title': dedent("""\
+ write certain files, whose creation as been deferred, during
+ final stage
+ """),
+ 'description': dedent("""\
+ This module is based on `'Write Files' <write-files>`__, and
+ will handle all files from the write_files list, that have been
+ marked as deferred and thus are not being processed by the
+ write-files module.
+
+ *Please note that his module is not exposed to the user through
+ its own dedicated top-level directive.*
+ """)
+ },
+ write_files_schema
+])
+
+# Not exposed, because related modules should document this behaviour
+__doc__ = None
+
+
+def handle(name, cfg, _cloud, log, _args):
+ validate_cloudconfig_schema(cfg, schema)
+ file_list = cfg.get('write_files', [])
+ filtered_files = [
+ f for f in file_list if util.get_cfg_option_bool(f,
+ 'defer',
+ DEFAULT_DEFER)
+ ]
+ if not filtered_files:
+ log.debug(("Skipping module named %s,"
+ " no deferred file defined in configuration"), name)
+ return
+ write_files(name, filtered_files)
+
+
+# vi: ts=4 expandtab