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