Statistics
| Branch: | Tag: | Revision:

root / image_creator / os_type / __init__.py @ 76d4a1c9

History | View | Annotate | Download (7.6 kB)

1
# Copyright 2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from image_creator.util import output
35

    
36
import re
37

    
38

    
39
def add_prefix(target):
40
    def wrapper(self, *args):
41
        prefix = args[0]
42
        return map(lambda x: prefix + x, target(self, *args))
43
    return wrapper
44

    
45

    
46
def exclude_task(func):
47
    func.excluded = True
48
    return func
49

    
50

    
51
class OSBase(object):
52
    """Basic operating system class"""
53
    def __init__(self, rootdev, ghandler):
54
        self.root = rootdev
55
        self.g = ghandler
56

    
57
        self.sysprep_regexp = re.compile('^sysprep_')
58
        self.data_cleanup_regexp = re.compile('^data_cleanup_')
59

    
60
    def _print_task(self, task):
61
        name = task.__name__
62

    
63
        if self.sysprep_regexp.match(name):
64
            name = self.sysprep_regexp.sub("", name)
65
        elif self.data_cleanup_regexp.match(name):
66
            name = self.data_cleanup_regexp.sub("", name)
67
        else:
68
            raise FatalError("%s is not a task" % name)
69

    
70
        name = name.replace('_', '-')
71

    
72
        output("  %s:\n    %s" % (name, task.__doc__))
73

    
74
    @add_prefix
75
    def ls(self, directory):
76
        """List the name of all files under a directory"""
77
        return self.g.ls(directory)
78

    
79
    @add_prefix
80
    def find(self, directory):
81
        """List the name of all files recursively under a directory"""
82
        return self.g.find(directory)
83

    
84
    def foreach_file(self, directory, action, **kargs):
85
        """Perform an action recursively on all files under a directory.
86

87
        The following options are allowed:
88

89
        * maxdepth: If defined the action will not be performed on
90
          files that are below this level of directories under the
91
          directory parameter.
92

93
        * ftype: The action will only be performed on files of this
94
          type. For a list of all allowed filetypes, see here:
95
          http://libguestfs.org/guestfs.3.html#guestfs_readdir
96

97
        * exclude: Exclude all files that follow this pattern.
98
        """
99
        maxdepth = None if 'maxdepth' not in kargs else kargs['maxdepth']
100
        if maxdepth == 0:
101
            return
102

    
103
        # maxdepth -= 1
104
        maxdepth = None if maxdepth is None else maxdepth - 1
105
        kargs['maxdepth'] = maxdepth
106

    
107
        exclude = None if 'exclude' not in kargs else kargs['exclude']
108
        ftype = None if 'ftype' not in kargs else kargs['ftype']
109
        has_ftype = lambda x, y: y is None and True or x['ftyp'] == y
110

    
111
        for f in self.g.readdir(directory):
112
            if f['name'] in ('.', '..'):
113
                continue
114

    
115
            full_path = "%s/%s" % (directory, f['name'])
116

    
117
            if exclude and re.match(exclude, full_path):
118
                continue
119

    
120
            if has_ftype(f, 'd'):
121
                self.foreach_file(full_path, action, **kargs)
122

    
123
            if has_ftype(f, ftype):
124
                action(full_path)
125

    
126
    def get_metadata(self):
127
        """Returns some descriptive metadata about the OS."""
128
        meta = {}
129
        meta['ROOT_PARTITION'] = "%d" % self.g.part_to_partnum(self.root)
130
        meta['OSFAMILY'] = self.g.inspect_get_type(self.root)
131
        meta['OS'] = self.g.inspect_get_distro(self.root)
132
        meta['DESCRIPTION'] = self.g.inspect_get_product_name(self.root)
133

    
134
        return meta
135

    
136
    def list_sysprep(self):
137
        """List all sysprep actions"""
138

    
139
        is_sysprep = lambda x: x.startswith('sysprep_') and \
140
                                                    callable(getattr(self, x))
141
        tasks = [getattr(self, x) for x in dir(self) if is_sysprep(x)]
142

    
143
        included = [t for t in tasks if not getattr(t, "excluded", False)]
144
        excluded = [t for t in tasks if getattr(t, "excluded", False)]
145

    
146
        return included, excluded
147

    
148
    def list_data_cleanup(self):
149
        """List all data_cleanup actions"""
150

    
151
        is_cleanup = lambda x: x.startswith('data_cleanup_') and \
152
                                                    callable(getattr(self, x))
153
        tasks = [getattr(self, x) for x in dir(self) if is_cleanup(x)]
154

    
155
        included = [t for t in tasks if not getattr(t, "excluded", False)]
156
        excluded = [t for t in tasks if getattr(t, "excluded", False)]
157

    
158
        return included, excluded
159

    
160
    def data_cleanup(self):
161
        """Cleanup sensitive data out of the OS image."""
162

    
163
        output('Cleaning up sensitive data out of the OS image:')
164

    
165
        tasks, _ = self.list_data_cleanup()
166
        size = len(tasks)
167
        cnt = 0
168
        for task in tasks:
169
            cnt += 1
170
            output(('(%d/%d)' % (cnt, size)).ljust(7), False)
171
            task()
172
        output()
173

    
174
    def sysprep(self):
175
        """Prepere system for image creation."""
176

    
177
        output('Preparing system for image creation:')
178

    
179
        tasks, _ = self.list_sysprep()
180
        size = len(tasks)
181
        cnt = 0
182
        for task in tasks:
183
            cnt += 1
184
            output(('(%d/%d)' % (cnt, size)).ljust(7), False)
185
            task()
186
        output()
187

    
188
    def print_task(self, task):
189
        name = task.__name__
190

    
191
        if self.sysprep_regexp.match(name):
192
            name = self.sysprep_regexp.sub("", name)
193
        elif self.data_cleanup_regexp.match(name):
194
            name = self.data_cleanup_regexp.sub("", name)
195
        else:
196
            raise FatalError("%s is not a task" % name)
197

    
198
        name = name.replace('_', '-')
199

    
200
        output("  %s:\n    %s" % (name, task.__doc__))
201

    
202
    def print_data_cleanup(self):
203
        included, excluded = self.list_data_cleanup()
204

    
205
        output("Included data cleanup operations:")
206
        if len(included) == 0:
207
            ouput("(none)")
208
        else:
209
            for task in included:
210
                self._print_task(task)
211
        output("Ommited data cleanup operations:")
212
        if len(excluded) == 0:
213
            ouput("(none)")
214
        else:
215
            for task in excluded:
216
                self._print_task(task)
217

    
218
    def print_sysprep(self):
219
        included, excluded = self.list_sysprep()
220

    
221
        output("Included sysprep operations:")
222
        if len(included) == 0:
223
            ouput("(none)")
224
        else:
225
            for task in included:
226
                self._print_task(task)
227
        output("Ommited sysprep operations:")
228
        if len(excluded) == 0:
229
            output("(none)")
230
        else:
231
            for task in excluded:
232
                self._print_task(task)
233

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