root / image_creator / os_type / linux.py @ a83f5185
History | View | Annotate | Download (3 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 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
|
100 |
|
101 |
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :
|