Statistics
| Branch: | Tag: | Revision:

root / image_creator / os_type / linux.py @ feab499d

History | View | Annotate | Download (3.2 kB)

1
from image_creator.os_type.unix import Unix
2
import re
3

    
4

    
5
class Linux(Unix):
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 remove_persistent_net(self):
24
        persistent_net_rule = '/etc/udev/rules.d/70-persistent-net.rules'
25
        if self.g.is_file(persistent_net_rule):
26
            self.g.rm(persistent_net_rule)
27

    
28
    def convert_to_persistent_dev(self):
29
        # convert all devices in fstab to persistent
30
        persistent_root = self._persistent_fstab()
31

    
32
        # convert all devices in grub1 to persistent
33
        self._persistent_grub1(persistent_root)
34

    
35
    def _persistent_grub1(self, conf, new_root):
36
        if self.g.is_file('/boot/grub/menu.lst'):
37
            grub1 = '/boot/grub/menu.lst'
38
        elif self.g.is_file('/etc/grub.conf'):
39
            grub1 = '/etc/grub.conf'
40
        else:
41
            return
42

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

    
57
    def _persistent_fstab(self):
58
        mpoints = self.g.mountpoints()
59
        if len(mpoints) == 0:
60
            pass  # TODO: error handling
61

    
62
        device_dict = dict([[mpoint, dev] for dev, mpoint in mpoints])
63

    
64
        root_dev = None
65
        new_fstab = ""
66
        fstab = self.g.cat('/etc/fstab')
67
        for line in fstab.splitlines():
68

    
69
            line, dev, mpoint = self._convert_fstab_line(line, device_dict)
70
            new_fstab += "%s\n" % line
71

    
72
            if mpoint == '/':
73
                root_dev = dev
74

    
75
        self.g.write('/etc/fstab', new_fstab)
76
        if root_dev is None:
77
            pass  # TODO: error handling
78

    
79
        return root_dev
80

    
81
    def _convert_fstab_line(self, line, devices):
82
        orig = line
83
        line = line.split('#')[0].strip()
84
        if len(line) == 0:
85
            return orig, "", ""
86

    
87
        entry = line.split()
88
        if len(entry) != 6:
89
            print "Warning: detected abnorman entry in fstab"
90
            return orig, "", ""
91

    
92
        dev = entry[0]
93
        mpoint = entry[1]
94

    
95
        if not self.is_persistent(dev):
96
            if mpoint in devices:
97
                dev = "UUID=%s" % self.get_uuid(devices[mpoint])
98
                entry[0] = dev
99
            else:
100
                # comment out the entry
101
                entry[0] = "#%s" % dev
102
            return " ".join(entry), dev, mpoint
103

    
104
        return orig, dev, mpoint
105

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