Create a bash wrapper for EnforcePersonality.py
authorNikos Skalkotos <skalkoto@grnet.gr>
Tue, 8 Nov 2011 13:17:01 +0000 (15:17 +0200)
committerNikos Skalkotos <skalkoto@grnet.gr>
Tue, 8 Nov 2011 13:29:05 +0000 (15:29 +0200)
All tasks should be bash scripts that source common.sh. We have also
fixed BUG #1577

snf-image-helper/Makefile.am
snf-image-helper/inject-files.py [new file with mode: 0755]
snf-image-helper/tasks/40EnforcePersonality [deleted file]
snf-image-helper/tasks/50EnforcePersonality.in [new file with mode: 0644]
snf-image-helper/tasks/Makefile.am

index 1a39462..9d4ccc5 100644 (file)
@@ -7,7 +7,7 @@ SUBDIRS = tasks
 
 dist_doc_DATA = COPYING AUTHORS ChangeLog
 dist_bin_SCRIPTS = snf-image-helper
-dist_scripts_SCRIPTS= snf-passtohash.py
+dist_scripts_SCRIPTS= snf-passtohash.py inject-files.py
 dist_common_DATA = common.sh unattend.xml
 
 edit = sed \
diff --git a/snf-image-helper/inject-files.py b/snf-image-helper/inject-files.py
new file mode 100755 (executable)
index 0000000..87a30e3
--- /dev/null
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+
+"""Inject files into a directory
+
+This program injects files into a target directory.
+The files are passed to the program through a JSON string either read from a
+file or from standard input.
+
+"""
+
+import sys
+import os
+import json
+import datetime
+import base64
+from optparse import OptionParser
+
+
+def timestamp():
+    now = datetime.datetime.now()
+    current_time = now.strftime("%Y%m%d.%H%M%S")
+    return current_time
+
+def parse_arguments(input_args):
+    usage = "Usage: %prog [options] <target>"
+    parser = OptionParser(usage=usage)
+    parser.add_option("-i", "--input",
+                        action="store",type='string', dest="input_file",
+                        help="get input from FILE instead of stdin",
+                        metavar="FILE")
+
+    opts, args = parser.parse_args(input_args)
+
+    if len(args) != 1:
+        parser.error('target is missing')
+   
+    target = args[0]
+    if not os.path.isdir(target):
+        parser.error('target is not a directory')
+
+    input_file = opts.input_file
+    if input_file is None:
+        input_file = sys.stdin
+    else:
+        if not os.path.isfile(input_file):
+            parser.error('input file does not exist')
+        input_file = open(input_file,'r')
+        
+    return (input_file, target)
+
+
+def main():
+    (input_file, target) = parse_arguments(sys.argv[1:])
+
+    files = json.loads(input_file.read())
+    for f in files:
+        real_path = target + '/' + f['path']
+        if os.path.lexists(real_path):
+            backup_file = real_path + '.bak.' + timestamp()
+            os.rename(real_path, backup_file)
+
+        parentdir = os.path.dirname(real_path)
+        if not os.path.exists(parentdir):
+            os.makedirs(parentdir)
+
+        newfile = open(real_path, 'w')
+        newfile.write(base64.b64decode(f['contents']))
+        newfile.close()
+        os.chmod(real_path, 0440)
+    sys.stderr.write('Successful personalization of Image\n')
+
+    input_file.close()
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/snf-image-helper/tasks/40EnforcePersonality b/snf-image-helper/tasks/40EnforcePersonality
deleted file mode 100644 (file)
index 5070b0b..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env python
-
-### BEGIN TASK INFO
-# Provides:            EnforcePersonality
-# RunBefore:           UmountImage
-# RunAfter:            MountImage
-# Short-Description:   Inject files to the instance
-### END TASK INFO
-
-"""Personalize an Image by injecting files
-
-This hook injects files into the filesystem of an Image.
-The files are passed to the hook through the Ganeti
-OS interface and found in the variable OSP_IMG_PERSONALITY.
-
-"""
-
-import sys
-import os
-import json
-import datetime
-import base64
-
-
-def timestamp():
-    now = datetime.datetime.now()
-    current_time = now.strftime("%Y%m%d.%H%M%S")
-    return current_time
-
-
-def main():
-    if not os.environ.has_key('SNF_IMAGE_TARGET'):
-        sys.stderr.write('Error: SNF_IMAGE_TARGET variable is missing\n')
-        return 1
-
-    target = os.environ['SNF_IMAGE_TARGET']
-    if not os.path.isdir(target):
-        sys.stderr.write('Error: Target: `'+target+'\' is not a directory.\n')
-        return 2
-
-    if os.environ.has_key('SNF_IMAGE_PERSONALITY'):
-        osp_img_personality = os.environ['SNF_IMAGE_PERSONALITY']
-        files = json.loads(osp_img_personality)
-        for f in files:
-            real_path = target + '/' + f['path']
-            if os.path.lexists(real_path):
-                backup_file = real_path + '.bak.' + timestamp()
-                os.rename(real_path, backup_file)
-            newfile = open(real_path, 'w')
-            newfile.write(base64.b64decode(f['contents']))
-            newfile.close()
-            os.chmod(real_path, 0440)
-        sys.stderr.write('Successful personalization of Image\n')
-    else:
-        sys.stderr.write('This Image has no personality (0 files to inject)\n')
-    return 0
-
-
-if __name__ == "__main__":
-    sys.exit(main())
-
-# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
diff --git a/snf-image-helper/tasks/50EnforcePersonality.in b/snf-image-helper/tasks/50EnforcePersonality.in
new file mode 100644 (file)
index 0000000..6700c0d
--- /dev/null
@@ -0,0 +1,29 @@
+#! /bin/bash
+
+### BEGIN TASK INFO
+# Provides:            EnforcePersonality
+# RunBefore:           UmountImage
+# RunAfter:            DeleteSSHKeys
+# Short-Description:   Inject files to the instance
+### END TASK INFO
+
+set -e
+set -o pipefail
+
+. "@commondir@/common.sh"
+
+if [ ! -d "$SNF_IMAGE_TARGET" ]; then
+    log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
+fi
+
+if [ -n "$SNF_IMAGE_PERSONALITY" ]; then
+    echo "$SNF_IMAGE_PERSONALITY" |
+        @scriptsdir@/inject-files.py "$SNF_IMAGE_TARGET"
+else
+    warn "This image has no personality (0 files to inject)\n"
+fi
+
+exit 0
+
+# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
+
index 8a36c0c..4c2c19a 100644 (file)
@@ -10,9 +10,9 @@ dist_tasks_SCRIPTS = \
                40FilesystemResizeMounted \
                40SELinuxAutorelabel \
                50AssignHostname \
+               50EnforcePersonality \
                50ChangePassword \
-               80UmountImage \
-               ${srcdir}/40EnforcePersonality
+               80UmountImage
 
 edit = sed \
           -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
@@ -39,6 +39,7 @@ CLEANFILES =  \
                40FilesystemResizeMounted \
                40SELinuxAutorelabel \
                50AssignHostname \
+               50EnforcePersonality \
                50ChangePassword \
                80UmountImage