2
by juanje
[project @ 53] |
1 |
#!/usr/bin/python
|
2 |
||
21
by antonio
[project @ 80] |
3 |
# Last modified by Antonio Olmo Titos <aolmo@emergya.info> on 26 july 2005.
|
4 |
||
2
by juanje
[project @ 53] |
5 |
import sys |
6 |
import shutil |
|
7 |
import os |
|
8 |
import subprocess |
|
9 |
import debconf |
|
10 |
||
11 |
class CommandFailed(Exception): pass |
|
12 |
||
13 |
class Installer: |
|
14 |
source = '/source' |
|
15 |
target = '/target' |
|
16 |
||
14
by juanje
[project @ 69] |
17 |
def frontend(self, type='noui'): |
18 |
ui = getattr(__import__('frontend.%s' % type), type) |
|
19 |
||
20 |
self.wizard = ui.Wizard() |
|
21 |
hostname = self.wizard.get_hostname() |
|
22 |
timezone, keymap, locales = self.wizard.get_locales() |
|
23 |
fullname, username, password = self.wizard.get_user() |
|
24 |
||
25 |
self.install(timezone,keymap,locales,username,password,fullname,hostname) |
|
26 |
||
27 |
def install(self, timezone, keymap, locales, username, password, fullname, hostname): |
|
28 |
mountpoints = self.wizard.get_partitions() |
|
2
by juanje
[project @ 53] |
29 |
self.mount_target(mountpoints) |
30 |
self.mount_source() |
|
31 |
try: |
|
32 |
self.copy_all() |
|
33 |
finally: |
|
34 |
self.unmount_source() |
|
35 |
||
36 |
try: |
|
37 |
self.configure_fstab(mountpoints) |
|
38 |
self.configure_timezone(timezone) |
|
39 |
self.configure_keymap(keymap) |
|
40 |
self.configure_user(username, password, fullname) |
|
41 |
self.configure_hostname(hostname) |
|
42 |
self.configure_network() |
|
43 |
self.configure_hardware() |
|
44 |
finally: |
|
45 |
self.unmount_target(mountpoints) |
|
46 |
||
14
by juanje
[project @ 69] |
47 |
|
2
by juanje
[project @ 53] |
48 |
def configure_fstab(self, mountpoints): |
49 |
fstab = open(os.path.join(self.target,'etc/fstab'), 'w') |
|
50 |
for path, device in mountpoints.items(): |
|
51 |
if path == '/': |
|
52 |
passno = 1 |
|
53 |
else: |
|
54 |
passno = 2 |
|
55 |
||
56 |
filesystem = 'ext3' |
|
57 |
options = 'defaults' |
|
58 |
||
59 |
print >>fstab, '%s\t%s\t%s\t%s\t%d\t%d' % (device, path, filesystem, options, 0, passno) |
|
60 |
fstab.close() |
|
61 |
||
62 |
def configure_timezone(self, timezone): |
|
63 |
# tzsetup ignores us if these exist
|
|
64 |
for tzfile in ('etc/timezone', 'etc/localtime'): |
|
65 |
path = os.path.join(self.target, tzfile) |
|
66 |
if os.path.exists(path): |
|
67 |
os.unlink(path) |
|
68 |
||
69 |
self.set_debconf('base-config', 'tzconfig/preseed_zone', timezone) |
|
70 |
self.chrex('tzsetup', '-y') |
|
71 |
||
72 |
def configure_keymap(self, keymap): |
|
73 |
self.set_debconf('debian-installer', 'debian-installer/keymap', keymap) |
|
74 |
self.chrex('install-keymap', keymap) |
|
75 |
||
76 |
def configure_user(self, username, password, fullname): |
|
77 |
self.chrex('passwd', '-l', 'root') |
|
78 |
self.set_debconf('passwd', 'passwd/username', username) |
|
79 |
self.set_debconf('passwd', 'passwd/user-fullname', fullname) |
|
80 |
self.set_debconf('passwd', 'passwd/user-password', password) |
|
81 |
self.set_debconf('passwd', 'passwd/user-password-again', password) |
|
82 |
self.reconfigure('passwd') |
|
83 |
||
84 |
def configure_hostname(self, hostname): |
|
85 |
fp = open(os.path.join(self.target, 'etc/hostname'), 'w') |
|
86 |
print >>fp, hostname |
|
87 |
fp.close() |
|
88 |
||
89 |
def configure_hardware(self): |
|
90 |
self.chrex('mount', '-t', 'proc', 'proc', '/proc') |
|
91 |
self.chrex('mount', '-t', 'sysfs', 'sysfs', '/sys') |
|
92 |
||
15
by juanje
[project @ 70] |
93 |
kernel_version = open('/proc/sys/kernel/osrelease').readline().strip() |
94 |
packages = ['gnome-panel', 'xserver-xorg', 'linux-image-' + kernel_version] |
|
2
by juanje
[project @ 53] |
95 |
|
96 |
try: |
|
15
by juanje
[project @ 70] |
97 |
for package in packages: |
2
by juanje
[project @ 53] |
98 |
self.copy_debconf(package) |
99 |
self.reconfigure(package) |
|
100 |
finally: |
|
101 |
self.chrex('umount', '/proc') |
|
102 |
self.chrex('umount', '/sys') |
|
103 |
||
104 |
def configure_network(self): |
|
105 |
shutil.copyfile('/etc/network/interfaces', |
|
106 |
os.path.join(self.target, 'etc/network/interfaces')) |
|
107 |
||
108 |
def mount_target(self, mountpoints): |
|
109 |
os.mkdir(self.target) |
|
110 |
self.ex('mount', mountpoints['/'], self.target) |
|
111 |
||
112 |
for path, device in mountpoints.items(): |
|
113 |
if path in ('/', 'swap'): |
|
114 |
continue
|
|
115 |
path = os.path.join(self.target, path[1:]) |
|
116 |
os.mkdir(path) |
|
117 |
self.ex('mount', device, path) |
|
118 |
||
119 |
def unmount_target(self, mountpoints): |
|
120 |
for path, device in mountpoints.items(): |
|
121 |
if path in ('/', 'swap'): |
|
122 |
continue
|
|
123 |
path = os.path.join(self.target, path[1:]) |
|
124 |
self.ex('umount', path) |
|
125 |
self.ex('umount', self.target) |
|
126 |
||
127 |
def copy_all(self): |
|
128 |
files = [] |
|
129 |
total_size = 0 |
|
130 |
||
131 |
for dirpath, dirnames, filenames in os.walk(self.source): |
|
132 |
sourcepath = dirpath[len(self.source)+1:] |
|
133 |
||
134 |
for name in dirnames + filenames: |
|
135 |
relpath = os.path.join(sourcepath, name) |
|
136 |
fqpath = os.path.join(self.source, dirpath, name) |
|
137 |
||
138 |
if os.path.isfile(fqpath): |
|
4
by juanje
[project @ 55] |
139 |
size = os.path.getsize(fqpath) |
140 |
total_size += size |
|
141 |
files.append((relpath, size)) |
|
2
by juanje
[project @ 53] |
142 |
else: |
143 |
files.append((relpath, None)) |
|
144 |
||
145 |
copy = subprocess.Popen(['cpio', '-d0mp', self.target], |
|
146 |
cwd=self.source, |
|
147 |
stdin=subprocess.PIPE) |
|
148 |
||
149 |
copied_bytes = 0 |
|
150 |
for path, size in files: |
|
151 |
copy.stdin.write(path + '\0') |
|
152 |
if size is not None: |
|
153 |
copied_bytes += size |
|
4
by juanje
[project @ 55] |
154 |
per = (copied_bytes * 100) / total_size |
155 |
self.wizard.set_progress(per) |
|
2
by juanje
[project @ 53] |
156 |
|
157 |
copy.stdin.close() |
|
158 |
copy.wait() |
|
159 |
||
160 |
||
161 |
def mount_source(self): |
|
162 |
from os import path |
|
9
by juanje
[project @ 64] |
163 |
files = ['/cdrom/casper/filesystem.cloop', '/cdrom/META/META.squashfs'] |
2
by juanje
[project @ 53] |
164 |
for f in files: |
165 |
if path.isfile(f) and path.splitext(f)[1] == '.cloop': |
|
166 |
file = f |
|
167 |
self.dev = '/dev/cloop1' |
|
168 |
elif path.isfile(f) and path.splitext(f)[1] == '.squashfs': |
|
169 |
file = f |
|
170 |
self.dev = '/dev/loop3' |
|
7
by juanje
[project @ 61] |
171 |
else: |
21
by antonio
[project @ 80] |
172 |
return -1 |
2
by juanje
[project @ 53] |
173 |
|
174 |
self.ex('losetup', self.dev, file) |
|
175 |
os.mkdir(self.source) |
|
176 |
self.ex('mount', self.dev, self.source) |
|
177 |
return 0 |
|
178 |
||
179 |
def unmount_source(self): |
|
180 |
self.ex('umount', self.source) |
|
181 |
self.ex('losetup', '-d', self.dev) |
|
182 |
||
183 |
def ex(self, *args): |
|
184 |
status = subprocess.call(args) |
|
185 |
if status != 0: |
|
186 |
raise CommandFailed(str(args)) |
|
187 |
||
188 |
def chrex(self, *args): |
|
189 |
self.ex('chroot', self.target, *args) |
|
190 |
||
191 |
def copy_debconf(self, package): |
|
192 |
targetdb = os.path.join(self.target, 'var/cache/debconf/config.dat') |
|
193 |
self.ex('debconf-copydb', 'configdb', 'targetdb', '-p', '^%s/' % package, |
|
194 |
'--config=Name:targetdb', '--config=Driver:File','--config=Filename:' + targetdb) |
|
195 |
||
196 |
def set_debconf(self, owner, question, value): |
|
197 |
dccomm = subprocess.Popen(['chroot', self.target, 'debconf-communicate', '-fnoninteractive', owner], |
|
198 |
stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True) |
|
199 |
dc = debconf.Debconf(read=dccomm.stdout, write=dccomm.stdin) |
|
200 |
dc.set(question, value) |
|
201 |
dc.fset(question, 'seen', 'true') |
|
202 |
dccomm.stdin.close() |
|
203 |
dccomm.wait() |
|
204 |
||
205 |
def reconfigure(self, package): |
|
206 |
self.chrex('dpkg-reconfigure', '-fnoninteractive', package) |
|
207 |
||
208 |
if __name__ == '__main__': |
|
14
by juanje
[project @ 69] |
209 |
Installer().frontend() |
4
by juanje
[project @ 55] |
210 |
|
21
by antonio
[project @ 80] |
211 |
# What to do when no arguments are provided:
|
212 |
if len (sys.argv) < 2: |
|
213 |
sys.stderr.write ('%s: no arguments provided.\n' % sys.argv [0]) |
|
214 |
sys.exit (2) |
|
215 |
else: |
|
216 |
Installer().install({'/' : sys.argv[1]}, 'US/Pacific', 'dvorak', 'mdz', 'mdz2', 'Matt Zimmerman', 'ubuntu') |
|
217 |
||
4
by juanje
[project @ 55] |
218 |
# vim:ai:et:sts=4:tw=80:sw=4:
|
21
by antonio
[project @ 80] |
219 |