Statistics
| Branch: | Tag: | Revision:

root / image_creator / os_type / __init__.py @ d9aff2ae

History | View | Annotate | Download (10.7 kB)

1 121f3bc0 Nikos Skalkotos
# -*- coding: utf-8 -*-
2 121f3bc0 Nikos Skalkotos
#
3 ae48a082 Nikos Skalkotos
# Copyright 2012 GRNET S.A. All rights reserved.
4 ae48a082 Nikos Skalkotos
#
5 ae48a082 Nikos Skalkotos
# Redistribution and use in source and binary forms, with or
6 ae48a082 Nikos Skalkotos
# without modification, are permitted provided that the following
7 ae48a082 Nikos Skalkotos
# conditions are met:
8 ae48a082 Nikos Skalkotos
#
9 ae48a082 Nikos Skalkotos
#   1. Redistributions of source code must retain the above
10 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
11 ae48a082 Nikos Skalkotos
#      disclaimer.
12 ae48a082 Nikos Skalkotos
#
13 ae48a082 Nikos Skalkotos
#   2. Redistributions in binary form must reproduce the above
14 ae48a082 Nikos Skalkotos
#      copyright notice, this list of conditions and the following
15 ae48a082 Nikos Skalkotos
#      disclaimer in the documentation and/or other materials
16 ae48a082 Nikos Skalkotos
#      provided with the distribution.
17 ae48a082 Nikos Skalkotos
#
18 ae48a082 Nikos Skalkotos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
19 ae48a082 Nikos Skalkotos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 ae48a082 Nikos Skalkotos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 ae48a082 Nikos Skalkotos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
22 ae48a082 Nikos Skalkotos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 ae48a082 Nikos Skalkotos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 ae48a082 Nikos Skalkotos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 ae48a082 Nikos Skalkotos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 ae48a082 Nikos Skalkotos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 ae48a082 Nikos Skalkotos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 ae48a082 Nikos Skalkotos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 ae48a082 Nikos Skalkotos
# POSSIBILITY OF SUCH DAMAGE.
30 ae48a082 Nikos Skalkotos
#
31 ae48a082 Nikos Skalkotos
# The views and conclusions contained in the software and
32 ae48a082 Nikos Skalkotos
# documentation are those of the authors and should not be
33 ae48a082 Nikos Skalkotos
# interpreted as representing official policies, either expressed
34 ae48a082 Nikos Skalkotos
# or implied, of GRNET S.A.
35 aa2062ba Nikos Skalkotos
36 121f3bc0 Nikos Skalkotos
"""This package provides various classes for preparing different Operating
37 121f3bc0 Nikos Skalkotos
Systems for image creation.
38 121f3bc0 Nikos Skalkotos
"""
39 121f3bc0 Nikos Skalkotos
40 e77e66a9 Nikos Skalkotos
from image_creator.util import FatalError
41 979096dd Nikos Skalkotos
42 f165adc0 Nikos Skalkotos
import textwrap
43 8c574358 Nikos Skalkotos
import re
44 d415dda2 Nikos Skalkotos
from collections import namedtuple
45 8c574358 Nikos Skalkotos
46 8c574358 Nikos Skalkotos
47 bb4db5a8 Nikos Skalkotos
def os_cls(distro, osfamily):
48 88f83027 Nikos Skalkotos
    """Given the distro name and the osfamily, return the appropriate class"""
49 5b801534 Nikos Skalkotos
    module = None
50 5b801534 Nikos Skalkotos
    classname = None
51 5b801534 Nikos Skalkotos
    try:
52 f99fe99d Nikos Skalkotos
        module = __import__("image_creator.os_type.%s" % distro,
53 f99fe99d Nikos Skalkotos
                            fromlist=['image_creator.os_type'])
54 5b801534 Nikos Skalkotos
        classname = distro.capitalize()
55 5b801534 Nikos Skalkotos
    except ImportError:
56 f99fe99d Nikos Skalkotos
        module = __import__("image_creator.os_type.%s" % osfamily,
57 f99fe99d Nikos Skalkotos
                            fromlist=['image_creator.os_type'])
58 5b801534 Nikos Skalkotos
        classname = osfamily.capitalize()
59 5b801534 Nikos Skalkotos
60 5b801534 Nikos Skalkotos
    return getattr(module, classname)
61 5b801534 Nikos Skalkotos
62 5b801534 Nikos Skalkotos
63 0d5a999d Nikos Skalkotos
def add_prefix(target):
64 0d5a999d Nikos Skalkotos
    def wrapper(self, *args):
65 0d5a999d Nikos Skalkotos
        prefix = args[0]
66 0d5a999d Nikos Skalkotos
        return map(lambda x: prefix + x, target(self, *args))
67 0d5a999d Nikos Skalkotos
    return wrapper
68 0d5a999d Nikos Skalkotos
69 51fab9c9 Nikos Skalkotos
70 f165adc0 Nikos Skalkotos
def sysprep(enabled=True):
71 88f83027 Nikos Skalkotos
    """Decorator for system preparation tasks"""
72 f165adc0 Nikos Skalkotos
    def wrapper(func):
73 f165adc0 Nikos Skalkotos
        func.sysprep = True
74 f165adc0 Nikos Skalkotos
        func.enabled = enabled
75 fa65eda1 Nikos Skalkotos
        func.executed = False
76 f165adc0 Nikos Skalkotos
        return func
77 f165adc0 Nikos Skalkotos
    return wrapper
78 8c574358 Nikos Skalkotos
79 51fab9c9 Nikos Skalkotos
80 aa2062ba Nikos Skalkotos
class OSBase(object):
81 3b2f6619 Nikos Skalkotos
    """Basic operating system class"""
82 f165adc0 Nikos Skalkotos
83 d415dda2 Nikos Skalkotos
    SysprepParam = namedtuple('SysprepParam',
84 d415dda2 Nikos Skalkotos
                              'name description length validator')
85 d415dda2 Nikos Skalkotos
86 d415dda2 Nikos Skalkotos
    def __init__(self, image, **kargs):
87 0c505946 Nikos Skalkotos
        self.image = image
88 0c505946 Nikos Skalkotos
89 0c505946 Nikos Skalkotos
        self.root = image.root
90 0c505946 Nikos Skalkotos
        self.g = image.g
91 0c505946 Nikos Skalkotos
        self.out = image.out
92 0c505946 Nikos Skalkotos
93 d415dda2 Nikos Skalkotos
        self.sysprep_params = \
94 d415dda2 Nikos Skalkotos
            kargs['sysprep_params'] if 'sysprep_params' in kargs else {}
95 d415dda2 Nikos Skalkotos
96 5886f568 Nikos Skalkotos
        self.meta = {}
97 71b0ab28 Nikos Skalkotos
98 71b0ab28 Nikos Skalkotos
    def collect_metadata(self):
99 71b0ab28 Nikos Skalkotos
        """Collect metadata about the OS"""
100 71b0ab28 Nikos Skalkotos
        try:
101 71b0ab28 Nikos Skalkotos
            if not self.mount(readonly=True):
102 71b0ab28 Nikos Skalkotos
                raise FatalError("Unable to mount the media read-only")
103 71b0ab28 Nikos Skalkotos
104 71b0ab28 Nikos Skalkotos
            self.out.output('Collecting image metadata ...', False)
105 71b0ab28 Nikos Skalkotos
            self._do_collect_metadata()
106 71b0ab28 Nikos Skalkotos
            self.out.success('done')
107 71b0ab28 Nikos Skalkotos
        finally:
108 71b0ab28 Nikos Skalkotos
            self.umount()
109 71b0ab28 Nikos Skalkotos
110 121f3bc0 Nikos Skalkotos
        self.out.output()
111 76d4a1c9 Nikos Skalkotos
112 d415dda2 Nikos Skalkotos
    def needed_sysprep_params(self):
113 d415dda2 Nikos Skalkotos
        """Returns a list of needed sysprep parameters. Each element in the
114 d415dda2 Nikos Skalkotos
        list is a SysprepParam object.
115 d415dda2 Nikos Skalkotos
        """
116 d415dda2 Nikos Skalkotos
        return []
117 d415dda2 Nikos Skalkotos
118 f165adc0 Nikos Skalkotos
    def list_syspreps(self):
119 121f3bc0 Nikos Skalkotos
        """Returns a list of sysprep objects"""
120 f99fe99d Nikos Skalkotos
        objs = [getattr(self, name) for name in dir(self)
121 f99fe99d Nikos Skalkotos
                if not name.startswith('_')]
122 f165adc0 Nikos Skalkotos
123 fa65eda1 Nikos Skalkotos
        return [x for x in objs if self._is_sysprep(x) and x.executed is False]
124 f165adc0 Nikos Skalkotos
125 12078c7e Nikos Skalkotos
    def sysprep_info(self, obj):
126 121f3bc0 Nikos Skalkotos
        """Returns information about a sysprep object"""
127 12078c7e Nikos Skalkotos
        assert self._is_sysprep(obj), "Object is not a sysprep"
128 12078c7e Nikos Skalkotos
129 12078c7e Nikos Skalkotos
        return (obj.__name__.replace('_', '-'), textwrap.dedent(obj.__doc__))
130 12078c7e Nikos Skalkotos
131 e7cbfb0a Nikos Skalkotos
    def get_sysprep_by_name(self, name):
132 e7cbfb0a Nikos Skalkotos
        """Returns the sysprep object with the given name"""
133 f165adc0 Nikos Skalkotos
        error_msg = "Syprep operation %s does not exist for %s" % \
134 e7cbfb0a Nikos Skalkotos
                    (name, self.__class__.__name__)
135 f165adc0 Nikos Skalkotos
136 f165adc0 Nikos Skalkotos
        method_name = name.replace('-', '_')
137 f165adc0 Nikos Skalkotos
        method = None
138 f165adc0 Nikos Skalkotos
        try:
139 f165adc0 Nikos Skalkotos
            method = getattr(self, method_name)
140 f165adc0 Nikos Skalkotos
        except AttributeError:
141 f165adc0 Nikos Skalkotos
            raise FatalError(error_msg)
142 f165adc0 Nikos Skalkotos
143 f165adc0 Nikos Skalkotos
        if not self._is_sysprep(method):
144 f165adc0 Nikos Skalkotos
            raise FatalError(error_msg)
145 f165adc0 Nikos Skalkotos
146 e7cbfb0a Nikos Skalkotos
        return method
147 f165adc0 Nikos Skalkotos
148 e7cbfb0a Nikos Skalkotos
    def enable_sysprep(self, obj):
149 dcf9274b Vangelis Koukis
        """Enable a system preparation operation"""
150 e7cbfb0a Nikos Skalkotos
        setattr(obj.im_func, 'enabled', True)
151 f165adc0 Nikos Skalkotos
152 e7cbfb0a Nikos Skalkotos
    def disable_sysprep(self, obj):
153 dcf9274b Vangelis Koukis
        """Disable a system preparation operation"""
154 e7cbfb0a Nikos Skalkotos
        setattr(obj.im_func, 'enabled', False)
155 f165adc0 Nikos Skalkotos
156 f165adc0 Nikos Skalkotos
    def print_syspreps(self):
157 dcf9274b Vangelis Koukis
        """Print enabled and disabled system preparation operations."""
158 76d4a1c9 Nikos Skalkotos
159 2e50092b Nikos Skalkotos
        syspreps = self.list_syspreps()
160 2e50092b Nikos Skalkotos
        enabled = filter(lambda x: x.enabled, syspreps)
161 2e50092b Nikos Skalkotos
        disabled = filter(lambda x: not x.enabled, syspreps)
162 76d4a1c9 Nikos Skalkotos
163 f165adc0 Nikos Skalkotos
        wrapper = textwrap.TextWrapper()
164 f165adc0 Nikos Skalkotos
        wrapper.subsequent_indent = '\t'
165 f165adc0 Nikos Skalkotos
        wrapper.initial_indent = '\t'
166 4a2fd05c Nikos Skalkotos
        wrapper.width = 72
167 f165adc0 Nikos Skalkotos
168 dcf9274b Vangelis Koukis
        self.out.output("Enabled system preparation operations:")
169 f165adc0 Nikos Skalkotos
        if len(enabled) == 0:
170 e77e66a9 Nikos Skalkotos
            self.out.output("(none)")
171 f165adc0 Nikos Skalkotos
        else:
172 f165adc0 Nikos Skalkotos
            for sysprep in enabled:
173 f165adc0 Nikos Skalkotos
                name = sysprep.__name__.replace('_', '-')
174 4a2fd05c Nikos Skalkotos
                descr = wrapper.fill(textwrap.dedent(sysprep.__doc__))
175 e77e66a9 Nikos Skalkotos
                self.out.output('    %s:\n%s\n' % (name, descr))
176 f165adc0 Nikos Skalkotos
177 dcf9274b Vangelis Koukis
        self.out.output("Disabled system preparation operations:")
178 f165adc0 Nikos Skalkotos
        if len(disabled) == 0:
179 e77e66a9 Nikos Skalkotos
            self.out.output("(none)")
180 f165adc0 Nikos Skalkotos
        else:
181 f165adc0 Nikos Skalkotos
            for sysprep in disabled:
182 f165adc0 Nikos Skalkotos
                name = sysprep.__name__.replace('_', '-')
183 4a2fd05c Nikos Skalkotos
                descr = wrapper.fill(textwrap.dedent(sysprep.__doc__))
184 e77e66a9 Nikos Skalkotos
                self.out.output('    %s:\n%s\n' % (name, descr))
185 76d4a1c9 Nikos Skalkotos
186 d9aff2ae Nikos Skalkotos
    def print_sysprep_params(self):
187 d9aff2ae Nikos Skalkotos
        """Print the system preparation parameter the user may use"""
188 d9aff2ae Nikos Skalkotos
189 d9aff2ae Nikos Skalkotos
        self.out.output("Needed system preparation parameters:")
190 d9aff2ae Nikos Skalkotos
191 d9aff2ae Nikos Skalkotos
        params = self.needed_sysprep_params()
192 d9aff2ae Nikos Skalkotos
193 d9aff2ae Nikos Skalkotos
        if len(params) == 0:
194 d9aff2ae Nikos Skalkotos
            self.out.output("(none)")
195 d9aff2ae Nikos Skalkotos
            return
196 d9aff2ae Nikos Skalkotos
197 d9aff2ae Nikos Skalkotos
        for param in params:
198 d9aff2ae Nikos Skalkotos
            self.out.output("\t%s (%s): %s" %
199 d9aff2ae Nikos Skalkotos
                            (param.description, param.name,
200 d9aff2ae Nikos Skalkotos
                             self.sysprep_params[param.name] if param.name in
201 d9aff2ae Nikos Skalkotos
                             self.sysprep_params else "(none)"))
202 d9aff2ae Nikos Skalkotos
203 121f3bc0 Nikos Skalkotos
    def do_sysprep(self):
204 121f3bc0 Nikos Skalkotos
        """Prepare system for image creation."""
205 121f3bc0 Nikos Skalkotos
206 121f3bc0 Nikos Skalkotos
        try:
207 121f3bc0 Nikos Skalkotos
            if not self.mount(readonly=False):
208 121f3bc0 Nikos Skalkotos
                raise FatalError("Unable to mount the media read-write")
209 121f3bc0 Nikos Skalkotos
210 121f3bc0 Nikos Skalkotos
            self.out.output('Preparing system for image creation:')
211 121f3bc0 Nikos Skalkotos
212 121f3bc0 Nikos Skalkotos
            tasks = self.list_syspreps()
213 121f3bc0 Nikos Skalkotos
            enabled = filter(lambda x: x.enabled, tasks)
214 121f3bc0 Nikos Skalkotos
215 121f3bc0 Nikos Skalkotos
            size = len(enabled)
216 121f3bc0 Nikos Skalkotos
            cnt = 0
217 121f3bc0 Nikos Skalkotos
            for task in enabled:
218 121f3bc0 Nikos Skalkotos
                cnt += 1
219 121f3bc0 Nikos Skalkotos
                self.out.output(('(%d/%d)' % (cnt, size)).ljust(7), False)
220 121f3bc0 Nikos Skalkotos
                task()
221 121f3bc0 Nikos Skalkotos
                setattr(task.im_func, 'executed', True)
222 121f3bc0 Nikos Skalkotos
        finally:
223 121f3bc0 Nikos Skalkotos
            self.umount()
224 121f3bc0 Nikos Skalkotos
225 121f3bc0 Nikos Skalkotos
        self.out.output()
226 121f3bc0 Nikos Skalkotos
227 121f3bc0 Nikos Skalkotos
    def mount(self, readonly=False):
228 121f3bc0 Nikos Skalkotos
        """Mount image."""
229 121f3bc0 Nikos Skalkotos
230 121f3bc0 Nikos Skalkotos
        if getattr(self, "mounted", False):
231 121f3bc0 Nikos Skalkotos
            return True
232 121f3bc0 Nikos Skalkotos
233 121f3bc0 Nikos Skalkotos
        mount_type = 'read-only' if readonly else 'read-write'
234 121f3bc0 Nikos Skalkotos
        self.out.output("Mounting the media %s ..." % mount_type, False)
235 121f3bc0 Nikos Skalkotos
236 121f3bc0 Nikos Skalkotos
        if not self._do_mount(readonly):
237 121f3bc0 Nikos Skalkotos
            return False
238 121f3bc0 Nikos Skalkotos
239 121f3bc0 Nikos Skalkotos
        self.mounted = True
240 121f3bc0 Nikos Skalkotos
        self.out.success('done')
241 121f3bc0 Nikos Skalkotos
        return True
242 121f3bc0 Nikos Skalkotos
243 121f3bc0 Nikos Skalkotos
    def umount(self):
244 121f3bc0 Nikos Skalkotos
        """Umount all mounted filesystems."""
245 121f3bc0 Nikos Skalkotos
246 121f3bc0 Nikos Skalkotos
        self.out.output("Umounting the media ...", False)
247 121f3bc0 Nikos Skalkotos
        self.g.umount_all()
248 121f3bc0 Nikos Skalkotos
        self.mounted = False
249 121f3bc0 Nikos Skalkotos
        self.out.success('done')
250 121f3bc0 Nikos Skalkotos
251 121f3bc0 Nikos Skalkotos
    def _is_sysprep(self, obj):
252 121f3bc0 Nikos Skalkotos
        """Checks if an object is a sysprep"""
253 121f3bc0 Nikos Skalkotos
        return getattr(obj, 'sysprep', False) and callable(obj)
254 121f3bc0 Nikos Skalkotos
255 0d5a999d Nikos Skalkotos
    @add_prefix
256 121f3bc0 Nikos Skalkotos
    def _ls(self, directory):
257 3b2f6619 Nikos Skalkotos
        """List the name of all files under a directory"""
258 8c574358 Nikos Skalkotos
        return self.g.ls(directory)
259 0d5a999d Nikos Skalkotos
260 0d5a999d Nikos Skalkotos
    @add_prefix
261 121f3bc0 Nikos Skalkotos
    def _find(self, directory):
262 3b2f6619 Nikos Skalkotos
        """List the name of all files recursively under a directory"""
263 8c574358 Nikos Skalkotos
        return self.g.find(directory)
264 8c574358 Nikos Skalkotos
265 121f3bc0 Nikos Skalkotos
    def _foreach_file(self, directory, action, **kargs):
266 3b2f6619 Nikos Skalkotos
        """Perform an action recursively on all files under a directory.
267 8c574358 Nikos Skalkotos

268 3b2f6619 Nikos Skalkotos
        The following options are allowed:
269 3b2f6619 Nikos Skalkotos

270 3b2f6619 Nikos Skalkotos
        * maxdepth: If defined the action will not be performed on
271 3b2f6619 Nikos Skalkotos
          files that are below this level of directories under the
272 3b2f6619 Nikos Skalkotos
          directory parameter.
273 3b2f6619 Nikos Skalkotos

274 3b2f6619 Nikos Skalkotos
        * ftype: The action will only be performed on files of this
275 3b2f6619 Nikos Skalkotos
          type. For a list of all allowed filetypes, see here:
276 3b2f6619 Nikos Skalkotos
          http://libguestfs.org/guestfs.3.html#guestfs_readdir
277 3b2f6619 Nikos Skalkotos

278 3b2f6619 Nikos Skalkotos
        * exclude: Exclude all files that follow this pattern.
279 3b2f6619 Nikos Skalkotos
        """
280 8c574358 Nikos Skalkotos
        maxdepth = None if 'maxdepth' not in kargs else kargs['maxdepth']
281 8c574358 Nikos Skalkotos
        if maxdepth == 0:
282 8c574358 Nikos Skalkotos
            return
283 8c574358 Nikos Skalkotos
284 8c574358 Nikos Skalkotos
        # maxdepth -= 1
285 8c574358 Nikos Skalkotos
        maxdepth = None if maxdepth is None else maxdepth - 1
286 8c574358 Nikos Skalkotos
        kargs['maxdepth'] = maxdepth
287 8c574358 Nikos Skalkotos
288 8c574358 Nikos Skalkotos
        exclude = None if 'exclude' not in kargs else kargs['exclude']
289 8c574358 Nikos Skalkotos
        ftype = None if 'ftype' not in kargs else kargs['ftype']
290 8c574358 Nikos Skalkotos
        has_ftype = lambda x, y: y is None and True or x['ftyp'] == y
291 8c574358 Nikos Skalkotos
292 8c574358 Nikos Skalkotos
        for f in self.g.readdir(directory):
293 8c574358 Nikos Skalkotos
            if f['name'] in ('.', '..'):
294 8c574358 Nikos Skalkotos
                continue
295 8c574358 Nikos Skalkotos
296 8c574358 Nikos Skalkotos
            full_path = "%s/%s" % (directory, f['name'])
297 8c574358 Nikos Skalkotos
298 8c574358 Nikos Skalkotos
            if exclude and re.match(exclude, full_path):
299 8c574358 Nikos Skalkotos
                continue
300 8c574358 Nikos Skalkotos
301 8c574358 Nikos Skalkotos
            if has_ftype(f, 'd'):
302 121f3bc0 Nikos Skalkotos
                self._foreach_file(full_path, action, **kargs)
303 8c574358 Nikos Skalkotos
304 8c574358 Nikos Skalkotos
            if has_ftype(f, ftype):
305 8c574358 Nikos Skalkotos
                action(full_path)
306 0d5a999d Nikos Skalkotos
307 121f3bc0 Nikos Skalkotos
    def _do_collect_metadata(self):
308 121f3bc0 Nikos Skalkotos
        """helper method for collect_metadata"""
309 121f3bc0 Nikos Skalkotos
        self.meta['ROOT_PARTITION'] = "%d" % self.g.part_to_partnum(self.root)
310 121f3bc0 Nikos Skalkotos
        self.meta['OSFAMILY'] = self.g.inspect_get_type(self.root)
311 121f3bc0 Nikos Skalkotos
        self.meta['OS'] = self.g.inspect_get_distro(self.root)
312 121f3bc0 Nikos Skalkotos
        if self.meta['OS'] == "unknown":
313 121f3bc0 Nikos Skalkotos
            self.meta['OS'] = self.meta['OSFAMILY']
314 121f3bc0 Nikos Skalkotos
        self.meta['DESCRIPTION'] = self.g.inspect_get_product_name(self.root)
315 71b0ab28 Nikos Skalkotos
316 71b0ab28 Nikos Skalkotos
    def _do_mount(self, readonly):
317 121f3bc0 Nikos Skalkotos
        """helper method for mount"""
318 71b0ab28 Nikos Skalkotos
        try:
319 71b0ab28 Nikos Skalkotos
            self.g.mount_options('ro' if readonly else 'rw', self.root, '/')
320 71b0ab28 Nikos Skalkotos
        except RuntimeError as msg:
321 71b0ab28 Nikos Skalkotos
            self.out.warn("unable to mount the root partition: %s" % msg)
322 71b0ab28 Nikos Skalkotos
            return False
323 71b0ab28 Nikos Skalkotos
324 71b0ab28 Nikos Skalkotos
        return True
325 71b0ab28 Nikos Skalkotos
326 aa2062ba Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :