Revision 22a2e378

b/snf-image-helper/Makefile.am
7 7

  
8 8
dist_doc_DATA = COPYING AUTHORS ChangeLog
9 9
dist_bin_SCRIPTS = snf-image-helper
10
dist_scripts_SCRIPTS= snf-passtohash.py
10
dist_scripts_SCRIPTS= snf-passtohash.py inject-files.py
11 11
dist_common_DATA = common.sh unattend.xml
12 12

  
13 13
edit = sed \
b/snf-image-helper/inject-files.py
1
#!/usr/bin/env python
2

  
3
"""Inject files into a directory
4

  
5
This program injects files into a target directory.
6
The files are passed to the program through a JSON string either read from a
7
file or from standard input.
8

  
9
"""
10

  
11
import sys
12
import os
13
import json
14
import datetime
15
import base64
16
from optparse import OptionParser
17

  
18

  
19
def timestamp():
20
    now = datetime.datetime.now()
21
    current_time = now.strftime("%Y%m%d.%H%M%S")
22
    return current_time
23

  
24
def parse_arguments(input_args):
25
    usage = "Usage: %prog [options] <target>"
26
    parser = OptionParser(usage=usage)
27
    parser.add_option("-i", "--input",
28
                        action="store",type='string', dest="input_file",
29
                        help="get input from FILE instead of stdin",
30
                        metavar="FILE")
31

  
32
    opts, args = parser.parse_args(input_args)
33

  
34
    if len(args) != 1:
35
        parser.error('target is missing')
36
   
37
    target = args[0]
38
    if not os.path.isdir(target):
39
        parser.error('target is not a directory')
40

  
41
    input_file = opts.input_file
42
    if input_file is None:
43
        input_file = sys.stdin
44
    else:
45
        if not os.path.isfile(input_file):
46
            parser.error('input file does not exist')
47
        input_file = open(input_file,'r')
48
        
49
    return (input_file, target)
50

  
51

  
52
def main():
53
    (input_file, target) = parse_arguments(sys.argv[1:])
54

  
55
    files = json.loads(input_file.read())
56
    for f in files:
57
        real_path = target + '/' + f['path']
58
        if os.path.lexists(real_path):
59
            backup_file = real_path + '.bak.' + timestamp()
60
            os.rename(real_path, backup_file)
61

  
62
        parentdir = os.path.dirname(real_path)
63
        if not os.path.exists(parentdir):
64
            os.makedirs(parentdir)
65

  
66
        newfile = open(real_path, 'w')
67
        newfile.write(base64.b64decode(f['contents']))
68
        newfile.close()
69
        os.chmod(real_path, 0440)
70
    sys.stderr.write('Successful personalization of Image\n')
71

  
72
    input_file.close()
73
    return 0
74

  
75

  
76
if __name__ == "__main__":
77
    sys.exit(main())
78

  
79
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
/dev/null
1
#!/usr/bin/env python
2

  
3
### BEGIN TASK INFO
4
# Provides:		EnforcePersonality
5
# RunBefore:		UmountImage
6
# RunAfter:		MountImage
7
# Short-Description:	Inject files to the instance
8
### END TASK INFO
9

  
10
"""Personalize an Image by injecting files
11

  
12
This hook injects files into the filesystem of an Image.
13
The files are passed to the hook through the Ganeti
14
OS interface and found in the variable OSP_IMG_PERSONALITY.
15

  
16
"""
17

  
18
import sys
19
import os
20
import json
21
import datetime
22
import base64
23

  
24

  
25
def timestamp():
26
    now = datetime.datetime.now()
27
    current_time = now.strftime("%Y%m%d.%H%M%S")
28
    return current_time
29

  
30

  
31
def main():
32
    if not os.environ.has_key('SNF_IMAGE_TARGET'):
33
        sys.stderr.write('Error: SNF_IMAGE_TARGET variable is missing\n')
34
        return 1
35

  
36
    target = os.environ['SNF_IMAGE_TARGET']
37
    if not os.path.isdir(target):
38
        sys.stderr.write('Error: Target: `'+target+'\' is not a directory.\n')
39
        return 2
40

  
41
    if os.environ.has_key('SNF_IMAGE_PERSONALITY'):
42
        osp_img_personality = os.environ['SNF_IMAGE_PERSONALITY']
43
        files = json.loads(osp_img_personality)
44
        for f in files:
45
            real_path = target + '/' + f['path']
46
            if os.path.lexists(real_path):
47
                backup_file = real_path + '.bak.' + timestamp()
48
                os.rename(real_path, backup_file)
49
            newfile = open(real_path, 'w')
50
            newfile.write(base64.b64decode(f['contents']))
51
            newfile.close()
52
            os.chmod(real_path, 0440)
53
        sys.stderr.write('Successful personalization of Image\n')
54
    else:
55
        sys.stderr.write('This Image has no personality (0 files to inject)\n')
56
    return 0
57

  
58

  
59
if __name__ == "__main__":
60
    sys.exit(main())
61

  
62
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
b/snf-image-helper/tasks/50EnforcePersonality.in
1
#! /bin/bash
2

  
3
### BEGIN TASK INFO
4
# Provides:		EnforcePersonality
5
# RunBefore:		UmountImage
6
# RunAfter:		DeleteSSHKeys
7
# Short-Description:	Inject files to the instance
8
### END TASK INFO
9

  
10
set -e
11
set -o pipefail
12

  
13
. "@commondir@/common.sh"
14

  
15
if [ ! -d "$SNF_IMAGE_TARGET" ]; then
16
    log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
17
fi
18

  
19
if [ -n "$SNF_IMAGE_PERSONALITY" ]; then
20
    echo "$SNF_IMAGE_PERSONALITY" |
21
        @scriptsdir@/inject-files.py "$SNF_IMAGE_TARGET"
22
else
23
    warn "This image has no personality (0 files to inject)\n"
24
fi
25

  
26
exit 0
27

  
28
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
29

  
b/snf-image-helper/tasks/Makefile.am
10 10
		40FilesystemResizeMounted \
11 11
		40SELinuxAutorelabel \
12 12
		50AssignHostname \
13
		50EnforcePersonality \
13 14
		50ChangePassword \
14
		80UmountImage \
15
		${srcdir}/40EnforcePersonality
15
		80UmountImage
16 16

  
17 17
edit = sed \
18 18
	   -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
......
39 39
		40FilesystemResizeMounted \
40 40
		40SELinuxAutorelabel \
41 41
		50AssignHostname \
42
		50EnforcePersonality \
42 43
		50ChangePassword \
43 44
		80UmountImage
44 45

  

Also available in: Unified diff