summaryrefslogtreecommitdiff
path: root/cloudinit/util.py
diff options
context:
space:
mode:
authorBen Howard <ben.howard@canonical.com>2014-01-24 12:29:04 -0700
committerBen Howard <ben.howard@canonical.com>2014-01-24 12:29:04 -0700
commitfb55c1079375454d2a2a2f82c6c1812759eeb1f1 (patch)
tree38dea394d0ecd7a0969291fbf4a6d63778be1f5d /cloudinit/util.py
parent5aa7d4ccf984ac296f58fa355bdce17d175dcc7d (diff)
downloadvyos-cloud-init-fb55c1079375454d2a2a2f82c6c1812759eeb1f1.tar.gz
vyos-cloud-init-fb55c1079375454d2a2a2f82c6c1812759eeb1f1.zip
Fixes for SmartOS datasource (LP: #1272115):
1. fixed conflation of user-data and cloud-init user-data. Cloud-init user-data is now namespaced as 'cloud-init:user-data'. 2. user-scripts are now fetched from the meta-data service each boot and executed as in the scripts directory 3. datacenter name is now namespaced as sdc:datacenter 4. user-scripts should be shebanged if there is no file magic
Diffstat (limited to 'cloudinit/util.py')
-rw-r--r--cloudinit/util.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/cloudinit/util.py b/cloudinit/util.py
index 77f9ab36..5f64cb69 100644
--- a/cloudinit/util.py
+++ b/cloudinit/util.py
@@ -1904,3 +1904,75 @@ def expand_dotted_devname(dotted):
return toks
else:
return (dotted, None)
+
+
+def write_executable_content(script, script_f):
+ """
+ This writes executable content and ensures that the shebang
+ exists.
+ """
+ write_file(script_f, script, mode=0700)
+ try:
+ cmd = ["file", "--brief", "--mime-type", script_f]
+ (f_type, _err) = subp(cmd)
+
+ LOG.debug("script %s mime type is %s" % (script_f, f_type))
+
+ # if the magic is text/plain, re-write with the shebang
+ if f_type.strip() == "text/plain":
+ with open(script_f, 'w') as f:
+ f.write("#!/bin/bash\n")
+ f.write(script)
+ LOG.debug("added shebang to file %s" % script_f)
+
+ except ProcessExecutionError as e:
+ logexc(LOG, "Failed to identify script type for %s" % script_f, e)
+ return False
+
+ except IOError as e:
+ logexc(LOG, "Failed to add shebang to file %s" % script_f, e)
+ return False
+
+ return True
+
+
+def write_content(content, content_f, link=None,
+ executable=False):
+ """
+ Write the content to content_f. Under the following rules:
+ 1. Backup previous content_f
+ 2. Write the contente
+ 3. If no content, remove the file
+ 4. If there is a link, create it
+
+ @param content: what to write
+ @param content_f: the file name
+ @param backup_d: the directory to save the backup at
+ @param link: if defined, location to create a symlink to
+ @param executable: is the file executable
+ """
+
+ if content:
+ if not executable:
+ write_file(content_f, content, mode=0400)
+ else:
+ w = write_executable_content(content, content_f)
+ if not w:
+ LOG.debug("failed to write file to %s" % content_f)
+ return False
+
+ if not content and os.path.exists(content_f):
+ os.unlink(content_f)
+
+ if link:
+ try:
+ if os.path.islink(link):
+ os.unlink(link)
+ if content and os.path.exists(content_f):
+ ensure_dir(os.path.dirname(link))
+ os.symlink(content_f, link)
+ except IOError as e:
+ logexc(LOG, "failed establishing content link", e)
+ return False
+
+ return True