Revision a83f5185

b/image_creator/os_type/linux.py
1 1
from image_creator.os_type.unix import Unix
2
import re
2 3

  
3 4

  
4 5
class Linux(Unix):
5
    pass
6
    def __init__(self, rootdev, ghandler):
7
        super(Linux, self).__init__(rootdev, ghandler)
8
        self._uuid = dict()
9
        self._persistent = re.compile('/dev/[hsv]d[a-z][1-9]*')
10

  
11
    def is_persistent(self, dev):
12
        return not self._persistent.match(dev)
13

  
14
    def get_uuid(self, dev):
15
        if dev in self._uuid:
16
            return self._uuid[dev]
17

  
18
        for attr in self.g.blkid(dev):
19
            if attr[0] == 'UUID':
20
                self._uuid[dev] = attr[1]
21
                return attr[1]
22

  
23
    def convert_to_persistent_dev(self):
24
        # convert all devices in fstab to persistent
25
        persistent_root = self._persistent_fstab()
26

  
27
        # convert all devices in grub1 to persistent
28
        self._persistent_grub1(persistent_root)
29

  
30
    def _persistent_grub1(self, conf, new_root):
31
        if self.g.is_file('/boot/grub/menu.lst'):
32
            grub1 = '/boot/grub/menu.lst'
33
        elif self.g.is_file('/etc/grub.conf'):
34
            grub1 = '/etc/grub.conf'
35
        else:
36
            return
37

  
38
        self.g.aug_init('/', 0)
39
        try:
40
            roots = self.g.aug_match('/files%s/title[*]/kernel/root' % grub1)
41
            for root in roots:
42
                dev = self.g.aug_get(root)
43
                if not self.is_persistent(dev):
44
                    # This is not always correct. Grub may contain root entries
45
                    # for other systems, but we only support 1 OS per hard
46
                    # disk, so this shouldn't harm.
47
                    self.g.aug_set(root, new_root)
48
        finally:
49
            self.g.aug_save()
50
            self.g.aug_close()
51

  
52
    def _persistent_fstab(self):
53
        mpoints = self.g.mountpoints()
54
        if len(mpoints) == 0:
55
            pass  # TODO: error handling
56

  
57
        device_dict = dict([[mpoint, dev] for dev, mpoint in mpoints])
58

  
59
        root_dev = None
60
        new_fstab = ""
61
        fstab = self.g.cat('/etc/fstab')
62
        for line in fstab.splitlines():
63

  
64
            line, dev, mpoint = self._convert_fstab_line(line, device_dict)
65
            new_fstab += "%s\n" % line
66

  
67
            if mpoint == '/':
68
                root_dev = dev
69

  
70
        self.g.write('/etc/fstab', new_fstab)
71
        if root_dev is None:
72
            pass  # TODO: error handling
73

  
74
        return root_dev
75

  
76
    def _convert_fstab_line(self, line, devices):
77
        orig = line
78
        line = line.split('#')[0].strip()
79
        if len(line) == 0:
80
            return orig, "", ""
81

  
82
        entry = line.split()
83
        if len(entry) != 6:
84
            print "Warning: detected abnorman entry in fstab"
85
            return orig, "", ""
86

  
87
        dev = entry[0]
88
        mpoint = entry[1]
89

  
90
        if not self.is_persistent(dev):
91
            if mpoint in devices:
92
                dev = "UUID=%s" % self.get_uuid(devices[mpoint])
93
                entry[0] = dev
94
            else:
95
                # comment out the entry
96
                entry[0] = "#%s" % dev
97
            return " ".join(entry), dev, mpoint
98

  
99
        return orig, dev, mpoint
6 100

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

Also available in: Unified diff