Statistics
| Branch: | Tag: | Revision:

root / snf-image-helper / inject-files.py @ 83d0c566

History | View | Annotate | Download (3.3 kB)

1
#!/usr/bin/env python
2
#
3
# Copyright (C) 2011 GRNET S.A.
4
#
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
# General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
# 02110-1301, USA.
19

    
20
"""Inject files into a directory
21

22
This program injects files into a target directory.
23
The files are passed to the program through a JSON string either read from a
24
file or from standard input.
25

26
"""
27

    
28
import sys
29
import os
30
import json
31
import datetime
32
import base64
33
from optparse import OptionParser
34

    
35

    
36
def timestamp():
37
    now = datetime.datetime.now()
38
    current_time = now.strftime("%Y%m%d.%H%M%S")
39
    return current_time
40

    
41

    
42
def parse_arguments(input_args):
43
    usage = "Usage: %prog [options] <target>"
44
    parser = OptionParser(usage=usage)
45
    parser.add_option("-i", "--input",
46
                      action="store", type='string', dest="input_file",
47
                      help="get input from FILE instead of stdin",
48
                      metavar="FILE")
49
    parser.add_option("-d", "--decode", action="store_true", dest="decode",
50
                      default=False,
51
                      help="decode files under target and create manifest")
52

    
53
    opts, args = parser.parse_args(input_args)
54

    
55
    if len(args) != 1:
56
        parser.error('target is missing')
57

    
58
    target = args[0]
59
    if not os.path.isdir(target):
60
        parser.error('target is not a directory')
61

    
62
    input_file = opts.input_file
63
    if input_file is None:
64
        input_file = sys.stdin
65
    else:
66
        if not os.path.isfile(input_file):
67
            parser.error('input file does not exist')
68
        input_file = open(input_file, 'r')
69

    
70
    return (input_file, target, opts.decode)
71

    
72

    
73
def main():
74
    (input_file, target, decode) = parse_arguments(sys.argv[1:])
75

    
76
    files = json.load(input_file)
77

    
78
    if decode:
79
        manifest = open(target + '/manifest', 'w')
80

    
81
    count = 0
82
    for f in files:
83
        count += 1
84
        owner = f['owner'] if 'owner' in f else ""
85
        group = f['group'] if 'group' in f else ""
86
        mode = f['mode'] if 'mode' in f else 0440
87

    
88
        filepath = f['path'] if not decode else str(count)
89
        filepath = target + "/" + filepath
90

    
91
        if os.path.lexists(filepath):
92
            backup_file = filepath + '.bak.' + timestamp()
93
            os.rename(filepath, backup_file)
94

    
95
        parentdir = os.path.dirname(filepath)
96
        if not os.path.exists(parentdir):
97
            os.makedirs(parentdir)
98

    
99
        newfile = open(filepath, 'w')
100
        newfile.write(base64.b64decode(f['contents']))
101
        newfile.close()
102

    
103
        if decode:
104
            manifest.write("%s\x00%s\x00%s\x00%o\x00%s\x00" %
105
                           (count, owner, group, mode, f['path']))
106

    
107
    if decode:
108
        manifest.close()
109

    
110
    input_file.close()
111
    return 0
112

    
113
if __name__ == "__main__":
114
    sys.exit(main())
115

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