Revision 121f3bc0 image_creator/os_type/linux.py

b/image_creator/os_type/linux.py
1
# -*- coding: utf-8 -*-
2
#
1 3
# Copyright 2012 GRNET S.A. All rights reserved.
2 4
#
3 5
# Redistribution and use in source and binary forms, with or
......
31 33
# interpreted as representing official policies, either expressed
32 34
# or implied, of GRNET S.A.
33 35

  
36
"""This module hosts OS-specific code for Linux"""
37

  
34 38
from image_creator.os_type.unix import Unix, sysprep
35 39

  
36 40
import re
......
44 48
        self._uuid = dict()
45 49
        self._persistent = re.compile('/dev/[hsv]d[a-z][1-9]*')
46 50

  
47
    def _do_collect_metadata(self):
48
        """Collect metadata about the OS"""
49

  
50
        super(Linux, self)._do_collect_metadata()
51
        self.meta["USERS"] = " ".join(self._get_passworded_users())
52

  
53
        # Delete the USERS metadata if empty
54
        if not len(self.meta['USERS']):
55
            self.out.warn("No passworded users found!")
56
            del self.meta['USERS']
57

  
58
    def _get_passworded_users(self):
59
        users = []
60
        regexp = re.compile('(\S+):((?:!\S+)|(?:[^!*]\S+)|):(?:\S*:){6}')
61

  
62
        for line in self.g.cat('/etc/shadow').splitlines():
63
            match = regexp.match(line)
64
            if not match:
65
                continue
66

  
67
            user, passwd = match.groups()
68
            if len(passwd) > 0 and passwd[0] == '!':
69
                self.out.warn("Ignoring locked %s account." % user)
70
            else:
71
                users.append(user)
72

  
73
        return users
74

  
75
    def is_persistent(self, dev):
76
        return not self._persistent.match(dev)
77

  
78
    def get_uuid(self, dev):
79
        if dev in self._uuid:
80
            return self._uuid[dev]
81

  
82
        uuid = self.g.vfs_uuid(dev)
83
        assert len(uuid)
84
        self._uuid[dev] = uuid
85
        return uuid
86

  
87 51
    @sysprep(enabled=False)
88 52
    def remove_user_accounts(self, print_header=True):
89 53
        """Remove all user accounts with id greater than 1000"""
......
179 143

  
180 144
        event_exp = re.compile('event=(.+)', re.I)
181 145
        action_exp = re.compile('action=(.+)', re.I)
182
        for f in self.g.readdir(events_dir):
183
            if f['ftyp'] != 'r':
146
        for events_file in self.g.readdir(events_dir):
147
            if events_file['ftyp'] != 'r':
184 148
                continue
185 149

  
186
            fullpath = "%s/%s" % (events_dir, f['name'])
150
            fullpath = "%s/%s" % (events_dir, events_file['name'])
187 151
            event = ""
188 152
            action = ""
189 153
            for line in self.g.cat(fullpath).splitlines():
190
                m = event_exp.match(line)
191
                if m:
192
                    event = m.group(1)
154
                match = event_exp.match(line)
155
                if match:
156
                    event = match.group(1)
193 157
                    continue
194
                m = action_exp.match(line)
195
                if m:
196
                    action = m.group(1)
158
                match = action_exp.match(line)
159
                if match:
160
                    action = match.group(1)
197 161
                    continue
198 162

  
199 163
            if event.strip() in ("button[ /]power", "button/power.*"):
......
275 239
        self._persistent_grub1(persistent_root)
276 240

  
277 241
    def _persistent_grub1(self, new_root):
242
        """Replaces non-persistent device name occurencies with persistent
243
        ones in GRUB1 configuration files.
244
        """
278 245
        if self.g.is_file('/boot/grub/menu.lst'):
279 246
            grub1 = '/boot/grub/menu.lst'
280 247
        elif self.g.is_file('/etc/grub.conf'):
......
287 254
            roots = self.g.aug_match('/files%s/title[*]/kernel/root' % grub1)
288 255
            for root in roots:
289 256
                dev = self.g.aug_get(root)
290
                if not self.is_persistent(dev):
257
                if not self._is_persistent(dev):
291 258
                    # This is not always correct. Grub may contain root entries
292 259
                    # for other systems, but we only support 1 OS per hard
293 260
                    # disk, so this shouldn't harm.
......
297 264
            self.g.aug_close()
298 265

  
299 266
    def _persistent_fstab(self):
267
        """Replaces non-persistent device name occurencies in /etc/fstab with
268
        persistent ones.
269
        """
300 270
        mpoints = self.g.mountpoints()
301 271
        if len(mpoints) == 0:
302 272
            pass  # TODO: error handling
......
321 291
        return root_dev
322 292

  
323 293
    def _convert_fstab_line(self, line, devices):
294
        """Replace non-persistent device names in an fstab line to their UUID
295
        equivalent
296
        """
324 297
        orig = line
325 298
        line = line.split('#')[0].strip()
326 299
        if len(line) == 0:
......
334 307
        dev = entry[0]
335 308
        mpoint = entry[1]
336 309

  
337
        if not self.is_persistent(dev):
310
        if not self._is_persistent(dev):
338 311
            if mpoint in devices:
339
                dev = "UUID=%s" % self.get_uuid(devices[mpoint])
312
                dev = "UUID=%s" % self._get_uuid(devices[mpoint])
340 313
                entry[0] = dev
341 314
            else:
342 315
                # comment out the entry
......
345 318

  
346 319
        return orig, dev, mpoint
347 320

  
321
    def _do_collect_metadata(self):
322
        """Collect metadata about the OS"""
323
        super(Linux, self)._do_collect_metadata()
324
        self.meta["USERS"] = " ".join(self._get_passworded_users())
325

  
326
        # Delete the USERS metadata if empty
327
        if not len(self.meta['USERS']):
328
            self.out.warn("No passworded users found!")
329
            del self.meta['USERS']
330

  
331
    def _get_passworded_users(self):
332
        """Returns a list of non-locked user accounts"""
333
        users = []
334
        regexp = re.compile('(\S+):((?:!\S+)|(?:[^!*]\S+)|):(?:\S*:){6}')
335

  
336
        for line in self.g.cat('/etc/shadow').splitlines():
337
            match = regexp.match(line)
338
            if not match:
339
                continue
340

  
341
            user, passwd = match.groups()
342
            if len(passwd) > 0 and passwd[0] == '!':
343
                self.out.warn("Ignoring locked %s account." % user)
344
            else:
345
                users.append(user)
346

  
347
        return users
348

  
349
    def _is_persistent(self, dev):
350
        """Checks if a device name is persistent."""
351
        return not self._persistent.match(dev)
352

  
353
    def _get_uuid(self, dev):
354
        """Returns the UUID corresponding to a device"""
355
        if dev in self._uuid:
356
            return self._uuid[dev]
357

  
358
        uuid = self.g.vfs_uuid(dev)
359
        assert len(uuid)
360
        self._uuid[dev] = uuid
361
        return uuid
362

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

Also available in: Unified diff