Statistics
| Branch: | Tag: | Revision:

root / image_creator / os_type / linux.py @ 9cbb5794

History | View | Annotate | Download (4.3 kB)

1 aa2062ba Nikos Skalkotos
from image_creator.os_type.unix import Unix
2 a83f5185 Nikos Skalkotos
import re
3 aa2062ba Nikos Skalkotos
4 8c574358 Nikos Skalkotos
5 aa2062ba Nikos Skalkotos
class Linux(Unix):
6 a83f5185 Nikos Skalkotos
    def __init__(self, rootdev, ghandler):
7 a83f5185 Nikos Skalkotos
        super(Linux, self).__init__(rootdev, ghandler)
8 a83f5185 Nikos Skalkotos
        self._uuid = dict()
9 a83f5185 Nikos Skalkotos
        self._persistent = re.compile('/dev/[hsv]d[a-z][1-9]*')
10 a83f5185 Nikos Skalkotos
11 a83f5185 Nikos Skalkotos
    def is_persistent(self, dev):
12 a83f5185 Nikos Skalkotos
        return not self._persistent.match(dev)
13 a83f5185 Nikos Skalkotos
14 a83f5185 Nikos Skalkotos
    def get_uuid(self, dev):
15 a83f5185 Nikos Skalkotos
        if dev in self._uuid:
16 a83f5185 Nikos Skalkotos
            return self._uuid[dev]
17 a83f5185 Nikos Skalkotos
18 a83f5185 Nikos Skalkotos
        for attr in self.g.blkid(dev):
19 a83f5185 Nikos Skalkotos
            if attr[0] == 'UUID':
20 a83f5185 Nikos Skalkotos
                self._uuid[dev] = attr[1]
21 a83f5185 Nikos Skalkotos
                return attr[1]
22 a83f5185 Nikos Skalkotos
23 9cbb5794 Nikos Skalkotos
    def sysprep(self):
24 9cbb5794 Nikos Skalkotos
        """Prepere system for image creation."""
25 9cbb5794 Nikos Skalkotos
        self.sysprep_acpid()
26 9cbb5794 Nikos Skalkotos
        self.sysprep_persistent_net_rules()
27 9cbb5794 Nikos Skalkotos
        self.sysprep_persistent_devs()
28 feab499d Nikos Skalkotos
29 9cbb5794 Nikos Skalkotos
    def sysprep_acpid(self):
30 9cbb5794 Nikos Skalkotos
        """Replace acpid powerdown action scripts to automatically shutdown
31 9cbb5794 Nikos Skalkotos
        the system without checking if a GUI is running.
32 9cbb5794 Nikos Skalkotos
        """
33 9cbb5794 Nikos Skalkotos
        action = '#!/bin/sh\n\nPATH=/sbin:/bin:/usr/bin\n shutdown -h now '
34 9cbb5794 Nikos Skalkotos
        '\"Power button pressed\"'
35 9cbb5794 Nikos Skalkotos
36 9cbb5794 Nikos Skalkotos
        if self.g.is_file('/etc/acpi/powerbtn.sh'):
37 9cbb5794 Nikos Skalkotos
            self.g.write(action, '/etc/acpi/powerbtn.sh')
38 9cbb5794 Nikos Skalkotos
        elif self.g.is_file('/etc/acpi/actions/power.sh'):
39 9cbb5794 Nikos Skalkotos
            self.g.write(actions, '/etc/acpi/actions/power.sh')
40 9cbb5794 Nikos Skalkotos
        else:
41 9cbb5794 Nikos Skalkotos
            print "Warning: No acpid action file found"
42 9cbb5794 Nikos Skalkotos
43 9cbb5794 Nikos Skalkotos
    def sysprep_persistent_net_rules(self):
44 9cbb5794 Nikos Skalkotos
        """Remove udev rules that will keep network interface names persistent
45 9cbb5794 Nikos Skalkotos
        after hardware changes and reboots. Those rules will be created again
46 9cbb5794 Nikos Skalkotos
        the next time the image runs.
47 9cbb5794 Nikos Skalkotos
        """
48 9cbb5794 Nikos Skalkotos
        rule_file = '/etc/udev/rules.d/70-persistent-net.rules'
49 9cbb5794 Nikos Skalkotos
        if self.g.is_file(rule_file):
50 9cbb5794 Nikos Skalkotos
            self.g.rm(rule_file)
51 9cbb5794 Nikos Skalkotos
52 9cbb5794 Nikos Skalkotos
    def sysprep_persistent_devs(self):
53 9cbb5794 Nikos Skalkotos
        """Scan fstab and grub configuration files and replace all
54 9cbb5794 Nikos Skalkotos
        non-persistent device appearences with UUIDs.
55 9cbb5794 Nikos Skalkotos
        """
56 a83f5185 Nikos Skalkotos
        # convert all devices in fstab to persistent
57 a83f5185 Nikos Skalkotos
        persistent_root = self._persistent_fstab()
58 a83f5185 Nikos Skalkotos
59 a83f5185 Nikos Skalkotos
        # convert all devices in grub1 to persistent
60 a83f5185 Nikos Skalkotos
        self._persistent_grub1(persistent_root)
61 a83f5185 Nikos Skalkotos
62 9cbb5794 Nikos Skalkotos
    def _persistent_grub1(self, new_root):
63 a83f5185 Nikos Skalkotos
        if self.g.is_file('/boot/grub/menu.lst'):
64 a83f5185 Nikos Skalkotos
            grub1 = '/boot/grub/menu.lst'
65 a83f5185 Nikos Skalkotos
        elif self.g.is_file('/etc/grub.conf'):
66 a83f5185 Nikos Skalkotos
            grub1 = '/etc/grub.conf'
67 a83f5185 Nikos Skalkotos
        else:
68 a83f5185 Nikos Skalkotos
            return
69 a83f5185 Nikos Skalkotos
70 a83f5185 Nikos Skalkotos
        self.g.aug_init('/', 0)
71 a83f5185 Nikos Skalkotos
        try:
72 a83f5185 Nikos Skalkotos
            roots = self.g.aug_match('/files%s/title[*]/kernel/root' % grub1)
73 a83f5185 Nikos Skalkotos
            for root in roots:
74 a83f5185 Nikos Skalkotos
                dev = self.g.aug_get(root)
75 a83f5185 Nikos Skalkotos
                if not self.is_persistent(dev):
76 a83f5185 Nikos Skalkotos
                    # This is not always correct. Grub may contain root entries
77 a83f5185 Nikos Skalkotos
                    # for other systems, but we only support 1 OS per hard
78 a83f5185 Nikos Skalkotos
                    # disk, so this shouldn't harm.
79 a83f5185 Nikos Skalkotos
                    self.g.aug_set(root, new_root)
80 a83f5185 Nikos Skalkotos
        finally:
81 a83f5185 Nikos Skalkotos
            self.g.aug_save()
82 a83f5185 Nikos Skalkotos
            self.g.aug_close()
83 a83f5185 Nikos Skalkotos
84 a83f5185 Nikos Skalkotos
    def _persistent_fstab(self):
85 a83f5185 Nikos Skalkotos
        mpoints = self.g.mountpoints()
86 a83f5185 Nikos Skalkotos
        if len(mpoints) == 0:
87 a83f5185 Nikos Skalkotos
            pass  # TODO: error handling
88 a83f5185 Nikos Skalkotos
89 a83f5185 Nikos Skalkotos
        device_dict = dict([[mpoint, dev] for dev, mpoint in mpoints])
90 a83f5185 Nikos Skalkotos
91 a83f5185 Nikos Skalkotos
        root_dev = None
92 a83f5185 Nikos Skalkotos
        new_fstab = ""
93 a83f5185 Nikos Skalkotos
        fstab = self.g.cat('/etc/fstab')
94 a83f5185 Nikos Skalkotos
        for line in fstab.splitlines():
95 a83f5185 Nikos Skalkotos
96 a83f5185 Nikos Skalkotos
            line, dev, mpoint = self._convert_fstab_line(line, device_dict)
97 a83f5185 Nikos Skalkotos
            new_fstab += "%s\n" % line
98 a83f5185 Nikos Skalkotos
99 a83f5185 Nikos Skalkotos
            if mpoint == '/':
100 a83f5185 Nikos Skalkotos
                root_dev = dev
101 a83f5185 Nikos Skalkotos
102 a83f5185 Nikos Skalkotos
        self.g.write('/etc/fstab', new_fstab)
103 a83f5185 Nikos Skalkotos
        if root_dev is None:
104 a83f5185 Nikos Skalkotos
            pass  # TODO: error handling
105 a83f5185 Nikos Skalkotos
106 a83f5185 Nikos Skalkotos
        return root_dev
107 a83f5185 Nikos Skalkotos
108 a83f5185 Nikos Skalkotos
    def _convert_fstab_line(self, line, devices):
109 a83f5185 Nikos Skalkotos
        orig = line
110 a83f5185 Nikos Skalkotos
        line = line.split('#')[0].strip()
111 a83f5185 Nikos Skalkotos
        if len(line) == 0:
112 a83f5185 Nikos Skalkotos
            return orig, "", ""
113 a83f5185 Nikos Skalkotos
114 a83f5185 Nikos Skalkotos
        entry = line.split()
115 a83f5185 Nikos Skalkotos
        if len(entry) != 6:
116 a83f5185 Nikos Skalkotos
            print "Warning: detected abnorman entry in fstab"
117 a83f5185 Nikos Skalkotos
            return orig, "", ""
118 a83f5185 Nikos Skalkotos
119 a83f5185 Nikos Skalkotos
        dev = entry[0]
120 a83f5185 Nikos Skalkotos
        mpoint = entry[1]
121 a83f5185 Nikos Skalkotos
122 a83f5185 Nikos Skalkotos
        if not self.is_persistent(dev):
123 a83f5185 Nikos Skalkotos
            if mpoint in devices:
124 a83f5185 Nikos Skalkotos
                dev = "UUID=%s" % self.get_uuid(devices[mpoint])
125 a83f5185 Nikos Skalkotos
                entry[0] = dev
126 a83f5185 Nikos Skalkotos
            else:
127 a83f5185 Nikos Skalkotos
                # comment out the entry
128 a83f5185 Nikos Skalkotos
                entry[0] = "#%s" % dev
129 a83f5185 Nikos Skalkotos
            return " ".join(entry), dev, mpoint
130 a83f5185 Nikos Skalkotos
131 a83f5185 Nikos Skalkotos
        return orig, dev, mpoint
132 aa2062ba Nikos Skalkotos
133 aa2062ba Nikos Skalkotos
# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :