|
215
by carranza
[project @ 488] |
1 |
#!/usr/bin/python
|
|
190
by carranza
[project @ 360] |
2 |
# -*- coding: utf-8 -*-
|
|
114
by juanje
[project @ 222] |
3 |
|
|
830
by Colin Watson
copyright/licence notice, as best I can |
4 |
# Copyright (C) 2005 Javier Carranza and others for Guadalinex
|
5 |
# Copyright (C) 2005, 2006 Canonical Ltd.
|
|
|
2108.1.30
by Mario Limonciello
Add support to disable/enable the bootloader installation |
6 |
# Copyright (C) 2007 Mario Limonciello
|
|
830
by Colin Watson
copyright/licence notice, as best I can |
7 |
#
|
8 |
# This program is free software; you can redistribute it and/or modify
|
|
9 |
# it under the terms of the GNU General Public License as published by
|
|
10 |
# the Free Software Foundation; either version 2 of the License, or
|
|
11 |
# (at your option) any later version.
|
|
12 |
#
|
|
13 |
# This program is distributed in the hope that it will be useful,
|
|
14 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16 |
# GNU General Public License for more details.
|
|
17 |
#
|
|
18 |
# You should have received a copy of the GNU General Public License
|
|
19 |
# along with this program; if not, write to the Free Software
|
|
20 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
21 |
||
|
820
by Colin Watson
* Notice and exit on errors from the copy and configuration stages. |
22 |
import sys |
|
120
by juanje
[project @ 228] |
23 |
import os |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
24 |
import platform |
|
833
by Colin Watson
* Install language packs according to the selected language. |
25 |
import errno |
|
921
by Colin Watson
* Change permissions of log file in /target to 600 to guard against any |
26 |
import stat |
|
833
by Colin Watson
* Install language packs according to the selected language. |
27 |
import re |
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
28 |
import textwrap |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
29 |
import shutil |
|
134
by juanje
[project @ 246] |
30 |
import subprocess |
|
315
by carranza
[project @ 665] |
31 |
import time |
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
32 |
import struct |
33 |
import socket |
|
34 |
import fcntl |
|
|
1380
by Colin Watson
* Save tracebacks from install.py and slurp them back into the traceback |
35 |
import traceback |
|
1495
by Colin Watson
* Send all internal log messages to syslog rather than stderr. |
36 |
import syslog |
|
1698
by Colin Watson
* Save /target/var/lib/dpkg/status to |
37 |
import gzip |
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
38 |
import debconf |
|
833
by Colin Watson
* Install language packs according to the selected language. |
39 |
import apt_pkg |
40 |
from apt.cache import Cache |
|
41 |
from apt.progress import FetchProgress, InstallProgress |
|
|
1395
by Colin Watson
fix sys.path for scripts/install.py |
42 |
|
43 |
sys.path.insert(0, '/usr/lib/ubiquity') |
|
44 |
||
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
45 |
from ubiquity import misc |
|
2173
by Colin Watson
* Reimplement more of oem-config-udeb (ugh): disable the hwdb-client |
46 |
from ubiquity import osextras |
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
47 |
from ubiquity.components import language_apply, apt_setup, timezone_apply, \ |
|
1518.1.1
by Colin Watson
* Move from kbd-chooser to console-setup |
48 |
clock_setup, console_setup_apply, \ |
|
1435.1.8
by Evan Dandrea
Merged with Ubiquity HEAD |
49 |
usersetup_apply, hw_detect, check_kernels, \ |
|
1853
by Colin Watson
indentation, minor style nits |
50 |
migrationassistant_apply
|
|
126
by juanje
[project @ 234] |
51 |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
52 |
class DebconfFetchProgress(FetchProgress): |
53 |
"""An object that reports apt's fetching progress using debconf."""
|
|
54 |
||
|
975
by Colin Watson
* Avoid a long pause without any info message while updating apt's indices |
55 |
def __init__(self, db, title, info_starting, info): |
|
833
by Colin Watson
* Install language packs according to the selected language. |
56 |
FetchProgress.__init__(self) |
57 |
self.db = db |
|
58 |
self.title = title |
|
|
975
by Colin Watson
* Avoid a long pause without any info message while updating apt's indices |
59 |
self.info_starting = info_starting |
|
833
by Colin Watson
* Install language packs according to the selected language. |
60 |
self.info = info |
61 |
self.old_capb = None |
|
62 |
self.eta = 0.0 |
|
63 |
||
64 |
def start(self): |
|
65 |
self.db.progress('START', 0, 100, self.title) |
|
|
975
by Colin Watson
* Avoid a long pause without any info message while updating apt's indices |
66 |
if self.info_starting is not None: |
67 |
self.db.progress('INFO', self.info_starting) |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
68 |
self.old_capb = self.db.capb() |
69 |
capb_list = self.old_capb.split() |
|
70 |
capb_list.append('progresscancel') |
|
71 |
self.db.capb(' '.join(capb_list)) |
|
72 |
||
73 |
# TODO cjwatson 2006-02-27: implement updateStatus
|
|
74 |
||
75 |
def pulse(self): |
|
76 |
FetchProgress.pulse(self) |
|
77 |
try: |
|
78 |
self.db.progress('SET', int(self.percent)) |
|
79 |
except debconf.DebconfError: |
|
80 |
return False |
|
81 |
if self.eta != 0.0: |
|
82 |
time_str = "%d:%02d" % divmod(int(self.eta), 60) |
|
83 |
self.db.subst(self.info, 'TIME', time_str) |
|
84 |
try: |
|
85 |
self.db.progress('INFO', self.info) |
|
86 |
except debconf.DebconfError: |
|
87 |
return False |
|
88 |
return True |
|
89 |
||
90 |
def stop(self): |
|
91 |
if self.old_capb is not None: |
|
92 |
self.db.capb(self.old_capb) |
|
93 |
self.old_capb = None |
|
94 |
self.db.progress('STOP') |
|
95 |
||
96 |
class DebconfInstallProgress(InstallProgress): |
|
97 |
"""An object that reports apt's installation progress using debconf."""
|
|
98 |
||
|
1416
by Colin Watson
* Silence apt errors while installing language packs, since we ignore them |
99 |
def __init__(self, db, title, info, error=None): |
|
833
by Colin Watson
* Install language packs according to the selected language. |
100 |
InstallProgress.__init__(self) |
101 |
self.db = db |
|
102 |
self.title = title |
|
103 |
self.info = info |
|
|
914
by Colin Watson
* Fix variable/method name clash in Install's apt error handling. |
104 |
self.error_template = error |
|
833
by Colin Watson
* Install language packs according to the selected language. |
105 |
self.started = False |
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
106 |
# InstallProgress uses a non-blocking status fd; our run()
|
107 |
# implementation doesn't need that, and in fact we spin unless the
|
|
108 |
# fd is blocking.
|
|
109 |
flags = fcntl.fcntl(self.statusfd.fileno(), fcntl.F_GETFL) |
|
110 |
fcntl.fcntl(self.statusfd.fileno(), fcntl.F_SETFL, |
|
111 |
flags & ~os.O_NONBLOCK) |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
112 |
|
113 |
def startUpdate(self): |
|
114 |
self.db.progress('START', 0, 100, self.title) |
|
115 |
self.started = True |
|
116 |
||
117 |
def error(self, pkg, errormsg): |
|
|
1416
by Colin Watson
* Silence apt errors while installing language packs, since we ignore them |
118 |
if self.error_template is not None: |
119 |
self.db.subst(self.error_template, 'PACKAGE', pkg) |
|
120 |
self.db.subst(self.error_template, 'MESSAGE', errormsg) |
|
121 |
self.db.input('critical', self.error_template) |
|
122 |
self.db.go() |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
123 |
|
124 |
def statusChange(self, pkg, percent, status): |
|
125 |
self.percent = percent |
|
126 |
self.status = status |
|
127 |
self.db.progress('SET', int(percent)) |
|
128 |
self.db.subst(self.info, 'DESCRIPTION', status) |
|
129 |
self.db.progress('INFO', self.info) |
|
130 |
||
131 |
def updateInterface(self): |
|
132 |
# TODO cjwatson 2006-02-28: InstallProgress.updateInterface doesn't
|
|
133 |
# give us a handy way to spot when percentages/statuses change and
|
|
134 |
# aren't pmerror/pmconffile, so we have to reimplement it here.
|
|
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
135 |
if self.statusfd is None: |
136 |
return False |
|
137 |
try: |
|
138 |
while not self.read.endswith("\n"): |
|
139 |
r = os.read(self.statusfd.fileno(),1) |
|
140 |
if not r: |
|
141 |
return False |
|
142 |
self.read += r |
|
143 |
except OSError, (err,errstr): |
|
144 |
print errstr |
|
145 |
if self.read.endswith("\n"): |
|
146 |
s = self.read |
|
147 |
(status, pkg, percent, status_str) = s.split(":", 3) |
|
148 |
if status == "pmerror": |
|
149 |
self.error(pkg, status_str) |
|
150 |
elif status == "pmconffile": |
|
151 |
# we get a string like this:
|
|
152 |
# 'current-conffile' 'new-conffile' useredited distedited
|
|
153 |
match = re.compile("\s*\'(.*)\'\s*\'(.*)\'.*").match(status_str) |
|
154 |
if match: |
|
155 |
self.conffile(match.group(1), match.group(2)) |
|
156 |
else: |
|
157 |
self.statusChange(pkg, float(percent), status_str.strip()) |
|
158 |
self.read = "" |
|
159 |
return True |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
160 |
|
|
841
by Colin Watson
* Make sure that stdout from language pack maintainer scripts doesn't |
161 |
def run(self, pm): |
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
162 |
# Create a subprocess to deal with turning apt status messages into
|
163 |
# debconf protocol messages.
|
|
164 |
child_pid = self.fork() |
|
165 |
if child_pid == 0: |
|
|
841
by Colin Watson
* Make sure that stdout from language pack maintainer scripts doesn't |
166 |
# child
|
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
167 |
os.close(self.writefd) |
168 |
try: |
|
169 |
while self.updateInterface(): |
|
170 |
pass
|
|
171 |
except (KeyboardInterrupt, SystemExit): |
|
172 |
pass # we're going to exit anyway |
|
173 |
except: |
|
|
1495
by Colin Watson
* Send all internal log messages to syslog rather than stderr. |
174 |
for line in traceback.format_exc().split('\n'): |
|
1536
by Colin Watson
* syslog.LOG_WARN -> syslog.LOG_WARNING (closes: Malone #59257). |
175 |
syslog.syslog(syslog.LOG_WARNING, line) |
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
176 |
os._exit(0) |
177 |
||
178 |
self.statusfd.close() |
|
179 |
||
|
2170
by Colin Watson
* Run apt's DoInstall() method with stdin redirected from /dev/null, to |
180 |
# Redirect stdin from /dev/null and stdout to stderr to avoid them
|
181 |
# interfering with our debconf protocol stream.
|
|
182 |
saved_stdin = os.dup(0) |
|
183 |
try: |
|
184 |
null = os.open('/dev/null', os.O_RDONLY) |
|
185 |
os.dup2(null, 0) |
|
186 |
os.close(null) |
|
187 |
except OSError: |
|
188 |
pass
|
|
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
189 |
saved_stdout = os.dup(1) |
190 |
os.dup2(2, 1) |
|
191 |
||
192 |
# Make sure all packages are installed non-interactively. We
|
|
193 |
# don't have enough passthrough magic here to deal with any
|
|
194 |
# debconf questions they might ask.
|
|
195 |
saved_environ_keys = ('DEBIAN_FRONTEND', 'DEBIAN_HAS_FRONTEND', |
|
196 |
'DEBCONF_USE_CDEBCONF') |
|
197 |
saved_environ = {} |
|
198 |
for key in saved_environ_keys: |
|
199 |
if key in os.environ: |
|
200 |
saved_environ[key] = os.environ[key] |
|
201 |
os.environ['DEBIAN_FRONTEND'] = 'noninteractive' |
|
202 |
if 'DEBIAN_HAS_FRONTEND' in os.environ: |
|
203 |
del os.environ['DEBIAN_HAS_FRONTEND'] |
|
204 |
if 'DEBCONF_USE_CDEBCONF' in os.environ: |
|
205 |
# Probably not a good idea to use this in /target too ...
|
|
206 |
del os.environ['DEBCONF_USE_CDEBCONF'] |
|
207 |
||
208 |
res = pm.ResultFailed |
|
209 |
try: |
|
|
841
by Colin Watson
* Make sure that stdout from language pack maintainer scripts doesn't |
210 |
res = pm.DoInstall(self.writefd) |
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
211 |
finally: |
212 |
# Reap the status-to-debconf subprocess.
|
|
213 |
os.close(self.writefd) |
|
214 |
while True: |
|
215 |
try: |
|
216 |
(pid, status) = os.waitpid(child_pid, 0) |
|
217 |
if pid != child_pid: |
|
218 |
break
|
|
219 |
if os.WIFEXITED(status) or os.WIFSIGNALED(status): |
|
220 |
break
|
|
221 |
except OSError: |
|
222 |
break
|
|
223 |
||
|
2170
by Colin Watson
* Run apt's DoInstall() method with stdin redirected from /dev/null, to |
224 |
# Put back stdin and stdout.
|
225 |
os.dup2(saved_stdin, 0) |
|
226 |
os.close(saved_stdin) |
|
|
1415
by Colin Watson
* Turn DebconfInstallProgress upside-down so that the main process handles |
227 |
os.dup2(saved_stdout, 1) |
228 |
os.close(saved_stdout) |
|
229 |
||
230 |
# Put back the environment.
|
|
231 |
for key in saved_environ_keys: |
|
232 |
if key in saved_environ: |
|
233 |
os.environ[key] = saved_environ[key] |
|
234 |
elif key in os.environ: |
|
235 |
del os.environ[key] |
|
236 |
||
|
841
by Colin Watson
* Make sure that stdout from language pack maintainer scripts doesn't |
237 |
return res |
238 |
||
|
833
by Colin Watson
* Install language packs according to the selected language. |
239 |
def finishUpdate(self): |
240 |
if self.started: |
|
241 |
self.db.progress('STOP') |
|
242 |
self.started = False |
|
243 |
||
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
244 |
class InstallStepError(Exception): |
245 |
"""Raised when an install step fails.
|
|
246 |
||
247 |
Attributes:
|
|
248 |
message -- message returned with exception
|
|
249 |
||
250 |
"""
|
|
251 |
||
252 |
def __init__(self, message): |
|
|
1487
by Colin Watson
* Fix stringification of our derived exceptions (InstallStepError and |
253 |
Exception.__init__(self, message) |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
254 |
self.message = message |
255 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
256 |
class Install: |
|
120
by juanje
[project @ 228] |
257 |
|
|
795
by Colin Watson
* Rip all the /target unmounting code out of espresso.backend.copy and do |
258 |
def __init__(self): |
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
259 |
"""Initial attributes."""
|
|
361
by carranza
[project @ 749] |
260 |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
261 |
if os.path.isdir('/rofs'): |
262 |
self.source = '/rofs' |
|
|
1376
by Colin Watson
/KNOPPIX -> /UNIONFS |
263 |
elif os.path.isdir('/UNIONFS'): |
264 |
# Klaus Knopper says this may not actually work very well
|
|
265 |
# because it'll copy the WHOLE WORLD (~12GB).
|
|
266 |
self.source = '/UNIONFS' |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
267 |
else: |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
268 |
self.source = '/var/lib/ubiquity/source' |
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
269 |
self.target = '/target' |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
270 |
self.kernel_version = platform.release() |
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
271 |
self.db = debconf.Debconf() |
|
126
by juanje
[project @ 234] |
272 |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
273 |
apt_pkg.InitConfig() |
274 |
apt_pkg.Config.Set("Dir", "/target") |
|
|
1417
by Colin Watson
* Point apt at /target/var/lib/dpkg/status rather than |
275 |
apt_pkg.Config.Set("Dir::State::status", "/target/var/lib/dpkg/status") |
|
833
by Colin Watson
* Install language packs according to the selected language. |
276 |
apt_pkg.Config.Set("APT::GPGV::TrustedKeyring", |
277 |
"/target/etc/apt/trusted.gpg") |
|
|
1166
by Colin Watson
* Write out /target/etc/apt/apt.conf.d/00IgnoreTimeConflict for the |
278 |
apt_pkg.Config.Set("Acquire::gpgv::Options::", |
279 |
"--ignore-time-conflict") |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
280 |
apt_pkg.Config.Set("DPkg::Options::", "--root=/target") |
281 |
# We don't want apt-listchanges or dpkg-preconfigure, so just clear
|
|
282 |
# out the list of pre-installation hooks.
|
|
283 |
apt_pkg.Config.Clear("DPkg::Pre-Install-Pkgs") |
|
284 |
apt_pkg.InitSystem() |
|
|
2212
by Evan Dandrea
* Temporary fix for the language packs no longer installing bug (LP: |
285 |
# TODO evand 2007-09-06: Temporary fix until I can get to the bottom of
|
286 |
# the real cause of the cache being out of sync with respect to the
|
|
287 |
# language packs (LP: #131294).
|
|
288 |
apt_pkg.init() |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
289 |
|
|
1380
by Colin Watson
* Save tracebacks from install.py and slurp them back into the traceback |
290 |
def excepthook(self, exctype, excvalue, exctb): |
291 |
"""Crash handler. Dump the traceback to a file so that it can be
|
|
292 |
read by the caller."""
|
|
293 |
||
294 |
if (issubclass(exctype, KeyboardInterrupt) or |
|
295 |
issubclass(exctype, SystemExit)): |
|
296 |
return
|
|
297 |
||
298 |
tbtext = ''.join(traceback.format_exception(exctype, excvalue, exctb)) |
|
|
1503
by Colin Watson
syslog.LOG_ERROR -> syslog.LOG_ERR |
299 |
syslog.syslog(syslog.LOG_ERR, "Exception during installation:") |
|
1495
by Colin Watson
* Send all internal log messages to syslog rather than stderr. |
300 |
for line in tbtext.split('\n'): |
|
1503
by Colin Watson
syslog.LOG_ERROR -> syslog.LOG_ERR |
301 |
syslog.syslog(syslog.LOG_ERR, line) |
|
1380
by Colin Watson
* Save tracebacks from install.py and slurp them back into the traceback |
302 |
tbfile = open('/var/lib/ubiquity/install.trace', 'w') |
303 |
print >>tbfile, tbtext |
|
304 |
tbfile.close() |
|
305 |
||
306 |
sys.exit(1) |
|
307 |
||
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
308 |
def run(self): |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
309 |
"""Run the install stage: copy everything to the target system, then
|
310 |
configure it as necessary."""
|
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
311 |
|
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
312 |
self.db.progress('START', 0, 100, 'ubiquity/install/title') |
313 |
self.db.progress('INFO', 'ubiquity/install/mounting_source') |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
314 |
|
315 |
try: |
|
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
316 |
if self.source == '/var/lib/ubiquity/source': |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
317 |
self.mount_source() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
318 |
|
319 |
self.db.progress('SET', 1) |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
320 |
self.db.progress('REGION', 1, 75) |
|
1626
by Colin Watson
* Catch ENOENT, EIO, ENOTDIR, and EROFS while copying files, try to figure |
321 |
try: |
322 |
self.copy_all() |
|
|
1685
by Colin Watson
* Handle EFAULT IOError exceptions while copying files (closes: Malone |
323 |
except EnvironmentError, e: |
324 |
if e.errno in (errno.ENOENT, errno.EIO, errno.EFAULT, |
|
325 |
errno.ENOTDIR, errno.EROFS): |
|
|
1626
by Colin Watson
* Catch ENOENT, EIO, ENOTDIR, and EROFS while copying files, try to figure |
326 |
if e.filename is None: |
327 |
error_template = 'cd_hd_fault' |
|
328 |
elif e.filename.startswith('/target'): |
|
329 |
error_template = 'hd_fault' |
|
330 |
else: |
|
331 |
error_template = 'cd_fault' |
|
332 |
error_template = ('ubiquity/install/copying_error/%s' % |
|
333 |
error_template) |
|
334 |
self.db.subst(error_template, 'ERROR', str(e)) |
|
335 |
self.db.input('critical', error_template) |
|
336 |
self.db.go() |
|
337 |
# Exit code 3 signals to the frontend that we have
|
|
338 |
# handled this error.
|
|
339 |
sys.exit(3) |
|
340 |
else: |
|
341 |
raise
|
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
342 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
343 |
self.db.progress('SET', 75) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
344 |
self.db.progress('REGION', 75, 76) |
345 |
self.db.progress('INFO', 'ubiquity/install/locales') |
|
346 |
self.configure_locales() |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
347 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
348 |
self.db.progress('SET', 76) |
349 |
self.db.progress('REGION', 76, 77) |
|
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
350 |
self.db.progress('INFO', 'ubiquity/install/user') |
351 |
self.configure_user() |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
352 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
353 |
self.db.progress('SET', 77) |
354 |
self.db.progress('REGION', 77, 78) |
|
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
355 |
self.run_target_config_hooks() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
356 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
357 |
self.db.progress('SET', 78) |
358 |
self.db.progress('REGION', 78, 79) |
|
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
359 |
self.db.progress('INFO', 'ubiquity/install/network') |
360 |
self.configure_network() |
|
|
1511
by Colin Watson
* Configure locales and the user account before running target-config |
361 |
|
362 |
self.db.progress('SET', 79) |
|
363 |
self.db.progress('REGION', 79, 80) |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
364 |
self.db.progress('INFO', 'ubiquity/install/apt') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
365 |
self.configure_apt() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
366 |
|
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
367 |
self.db.progress('SET', 80) |
368 |
self.db.progress('REGION', 80, 85) |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
369 |
# Ignore failures from language pack installation.
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
370 |
try: |
371 |
self.install_language_packs() |
|
372 |
except InstallStepError: |
|
373 |
pass
|
|
374 |
except IOError: |
|
375 |
pass
|
|
376 |
except SystemError: |
|
377 |
pass
|
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
378 |
|
|
1511
by Colin Watson
* Configure locales and the user account before running target-config |
379 |
self.db.progress('SET', 85) |
380 |
self.db.progress('REGION', 85, 86) |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
381 |
self.db.progress('INFO', 'ubiquity/install/timezone') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
382 |
self.configure_timezone() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
383 |
|
|
1511
by Colin Watson
* Configure locales and the user account before running target-config |
384 |
self.db.progress('SET', 86) |
|
1435.1.8
by Evan Dandrea
Merged with Ubiquity HEAD |
385 |
self.db.progress('REGION', 86, 87) |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
386 |
self.db.progress('INFO', 'ubiquity/install/keyboard') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
387 |
self.configure_keyboard() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
388 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
389 |
self.db.progress('SET', 87) |
390 |
self.db.progress('REGION', 87, 88) |
|
|
1435.1.5
by Evan Dandrea
migration-assistant works inside Ubiquity running after partitioning now. |
391 |
self.db.progress('INFO', 'ubiquity/install/migrationassistant') |
392 |
self.configure_ma() |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
393 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
394 |
self.db.progress('SET', 88) |
|
1674
by Colin Watson
* Remove kernels before running update-initramfs so that we update the |
395 |
self.db.progress('REGION', 88, 89) |
396 |
self.remove_unusable_kernels() |
|
397 |
||
398 |
self.db.progress('SET', 89) |
|
399 |
self.db.progress('REGION', 89, 93) |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
400 |
self.db.progress('INFO', 'ubiquity/install/hardware') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
401 |
self.configure_hardware() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
402 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
403 |
self.db.progress('SET', 93) |
404 |
self.db.progress('REGION', 93, 94) |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
405 |
self.db.progress('INFO', 'ubiquity/install/bootloader') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
406 |
self.configure_bootloader() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
407 |
|
|
1439
by Colin Watson
* Add 3% to the "Removing extra packages" stage of the installation |
408 |
self.db.progress('SET', 94) |
|
2137
by Colin Watson
* Install packages passed to apt-install even if they aren't on the live |
409 |
self.db.progress('REGION', 94, 95) |
410 |
self.db.progress('INFO', 'ubiquity/install/installing') |
|
411 |
self.install_extras() |
|
412 |
||
413 |
self.db.progress('SET', 95) |
|
414 |
self.db.progress('REGION', 95, 99) |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
415 |
self.db.progress('INFO', 'ubiquity/install/removing') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
416 |
self.remove_extras() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
417 |
|
418 |
self.db.progress('SET', 99) |
|
419 |
self.db.progress('INFO', 'ubiquity/install/log_files') |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
420 |
self.copy_logs() |
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
421 |
|
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
422 |
self.db.progress('SET', 100) |
423 |
finally: |
|
|
1369
by Colin Watson
* Use try/finally in install.py to ensure that PROGRESS STOP is always |
424 |
self.cleanup() |
425 |
try: |
|
426 |
self.db.progress('STOP') |
|
427 |
except (KeyboardInterrupt, SystemExit): |
|
428 |
raise
|
|
429 |
except: |
|
430 |
pass
|
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
431 |
|
432 |
||
433 |
def copy_all(self): |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
434 |
"""Core copy process. This is the most important step of this
|
435 |
stage. It clones live filesystem into a local partition in the
|
|
436 |
selected hard disk."""
|
|
437 |
||
438 |
files = [] |
|
439 |
total_size = 0 |
|
440 |
||
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
441 |
self.db.progress('START', 0, 100, 'ubiquity/install/title') |
442 |
self.db.progress('INFO', 'ubiquity/install/scanning') |
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
443 |
|
444 |
# Obviously doing os.walk() twice is inefficient, but I'd rather not
|
|
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
445 |
# suck the list into ubiquity's memory, and I'm guessing that the
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
446 |
# kernel's dentry cache will avoid most of the slowness anyway.
|
447 |
walklen = 0 |
|
448 |
for entry in os.walk(self.source): |
|
449 |
walklen += 1 |
|
450 |
walkpos = 0 |
|
451 |
walkprogress = 0 |
|
452 |
||
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
453 |
for dirpath, dirnames, filenames in os.walk(self.source): |
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
454 |
walkpos += 1 |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
455 |
if int(float(walkpos) / walklen * 10) != walkprogress: |
456 |
walkprogress = int(float(walkpos) / walklen * 10) |
|
457 |
self.db.progress('SET', walkprogress) |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
458 |
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
459 |
sourcepath = dirpath[len(self.source) + 1:] |
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
460 |
|
461 |
for name in dirnames + filenames: |
|
462 |
relpath = os.path.join(sourcepath, name) |
|
463 |
fqpath = os.path.join(self.source, dirpath, name) |
|
464 |
||
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
465 |
total_size += os.lstat(fqpath).st_size |
466 |
files.append(relpath) |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
467 |
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
468 |
self.db.progress('SET', 10) |
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
469 |
self.db.progress('INFO', 'ubiquity/install/copying') |
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
470 |
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
471 |
# Progress bar handling:
|
472 |
# We sample progress every half-second (assuming time.time() gives
|
|
473 |
# us sufficiently good granularity) and use the average of progress
|
|
474 |
# over the last minute or so to decide how much time remains. We
|
|
475 |
# don't bother displaying any progress for the first ten seconds in
|
|
476 |
# order to allow things to settle down, and we only update the "time
|
|
477 |
# remaining" indicator at most every two seconds after that.
|
|
478 |
||
479 |
copy_progress = 0 |
|
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
480 |
copied_size, counter = 0, 0 |
|
980
by Colin Watson
apply timestamps to directories properly |
481 |
directory_times = [] |
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
482 |
time_start = time.time() |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
483 |
times = [(time_start, copied_size)] |
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
484 |
long_enough = False |
485 |
time_last_update = time_start |
|
486 |
||
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
487 |
old_umask = os.umask(0) |
488 |
for path in files: |
|
489 |
sourcepath = os.path.join(self.source, path) |
|
490 |
targetpath = os.path.join(self.target, path) |
|
491 |
st = os.lstat(sourcepath) |
|
|
981
by Colin Watson
chmod after chown, to get setgid directories right |
492 |
mode = stat.S_IMODE(st.st_mode) |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
493 |
if stat.S_ISLNK(st.st_mode): |
|
1356
by Colin Watson
* When copying symlinks, check for existing dangling symlinks as well as |
494 |
if not os.path.lexists(targetpath): |
|
998
by Colin Watson
* Don't copy regular files or symlinks if they already exist in the target |
495 |
linkto = os.readlink(sourcepath) |
496 |
os.symlink(linkto, targetpath) |
|
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
497 |
elif stat.S_ISDIR(st.st_mode): |
|
981
by Colin Watson
chmod after chown, to get setgid directories right |
498 |
if not os.path.isdir(targetpath): |
499 |
os.mkdir(targetpath, mode) |
|
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
500 |
elif stat.S_ISCHR(st.st_mode): |
|
981
by Colin Watson
chmod after chown, to get setgid directories right |
501 |
os.mknod(targetpath, stat.S_IFCHR | mode, st.st_rdev) |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
502 |
elif stat.S_ISBLK(st.st_mode): |
|
981
by Colin Watson
chmod after chown, to get setgid directories right |
503 |
os.mknod(targetpath, stat.S_IFBLK | mode, st.st_rdev) |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
504 |
elif stat.S_ISFIFO(st.st_mode): |
|
981
by Colin Watson
chmod after chown, to get setgid directories right |
505 |
os.mknod(targetpath, stat.S_IFIFO | mode) |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
506 |
elif stat.S_ISSOCK(st.st_mode): |
|
981
by Colin Watson
chmod after chown, to get setgid directories right |
507 |
os.mknod(targetpath, stat.S_IFSOCK | mode) |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
508 |
elif stat.S_ISREG(st.st_mode): |
|
998
by Colin Watson
* Don't copy regular files or symlinks if they already exist in the target |
509 |
if not os.path.exists(targetpath): |
|
2043
by Colin Watson
* Use code based on shutil.copyfileobj rather than shutil.copyfile to copy |
510 |
sourcefh = None |
511 |
targetfh = None |
|
512 |
try: |
|
513 |
sourcefh = open(sourcepath, 'rb') |
|
514 |
targetfh = open(targetpath, 'wb') |
|
515 |
shutil.copyfileobj(sourcefh, targetfh) |
|
516 |
finally: |
|
517 |
if targetfh: |
|
518 |
targetfh.close() |
|
519 |
if sourcefh: |
|
520 |
sourcefh.close() |
|
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
521 |
|
522 |
copied_size += st.st_size |
|
|
979
by Colin Watson
set ownership of symlinks too |
523 |
os.lchown(targetpath, st.st_uid, st.st_gid) |
|
981
by Colin Watson
chmod after chown, to get setgid directories right |
524 |
if not stat.S_ISLNK(st.st_mode): |
525 |
os.chmod(targetpath, mode) |
|
|
980
by Colin Watson
apply timestamps to directories properly |
526 |
if stat.S_ISDIR(st.st_mode): |
527 |
directory_times.append((targetpath, st.st_atime, st.st_mtime)) |
|
|
982
by Colin Watson
clarify utime comment for symlinks |
528 |
# os.utime() sets timestamp of target, not link
|
|
980
by Colin Watson
apply timestamps to directories properly |
529 |
elif not stat.S_ISLNK(st.st_mode): |
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
530 |
os.utime(targetpath, (st.st_atime, st.st_mtime)) |
531 |
||
532 |
if int((copied_size * 90) / total_size) != copy_progress: |
|
533 |
copy_progress = int((copied_size * 90) / total_size) |
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
534 |
self.db.progress('SET', 10 + copy_progress) |
535 |
||
536 |
time_now = time.time() |
|
537 |
if (time_now - times[-1][0]) >= 0.5: |
|
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
538 |
times.append((time_now, copied_size)) |
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
539 |
if not long_enough and time_now - times[0][0] >= 10: |
540 |
long_enough = True |
|
541 |
if long_enough and time_now - time_last_update >= 2: |
|
542 |
time_last_update = time_now |
|
543 |
while (time_now - times[0][0] > 60 and |
|
544 |
time_now - times[1][0] >= 60): |
|
545 |
times.pop(0) |
|
546 |
speed = ((times[-1][1] - times[0][1]) / |
|
547 |
(times[-1][0] - times[0][0])) |
|
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
548 |
time_remaining = int((total_size - copied_size) / speed) |
|
1619
by Colin Watson
* Replace the rather jittery time-remaining message while copying files |
549 |
if time_remaining < 60: |
550 |
self.db.progress( |
|
551 |
'INFO', 'ubiquity/install/copying_minute') |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
552 |
|
|
980
by Colin Watson
apply timestamps to directories properly |
553 |
# Apply timestamps to all directories now that the items within them
|
554 |
# have been copied.
|
|
555 |
for dirtime in directory_times: |
|
556 |
(directory, atime, mtime) = dirtime |
|
|
1554
by Colin Watson
* Ignore failures from os.utime on directories. I don't know why I get a |
557 |
try: |
558 |
os.utime(directory, (atime, mtime)) |
|
559 |
except OSError: |
|
560 |
# I have no idea why I've been getting lots of bug reports
|
|
561 |
# about this failing, but I really don't care. Ignore it.
|
|
562 |
pass
|
|
|
980
by Colin Watson
apply timestamps to directories properly |
563 |
|
|
972
by Colin Watson
* Fix estimated install copying time. We no longer use cpio to do the |
564 |
os.umask(old_umask) |
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
565 |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
566 |
self.db.progress('SET', 100) |
567 |
self.db.progress('STOP') |
|
568 |
||
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
569 |
|
570 |
def copy_logs(self): |
|
571 |
"""copy log files into installed system."""
|
|
572 |
||
|
1199
by Colin Watson
* Save /var/log/partman to installed system as /var/log/installer/partman. |
573 |
target_dir = os.path.join(self.target, 'var/log/installer') |
574 |
if not os.path.exists(target_dir): |
|
575 |
os.makedirs(target_dir) |
|
576 |
||
|
1500
by Colin Watson
* Remove /var/log/installer/syslog from all error messages etc., as |
577 |
for log_file in ('/var/log/syslog', '/var/log/partman', |
|
2093
by Colin Watson
* Save /var/log/casper.log to installed system (LP: #119993). |
578 |
'/var/log/installer/version', '/var/log/casper.log'): |
|
1199
by Colin Watson
* Save /var/log/partman to installed system as /var/log/installer/partman. |
579 |
target_log_file = os.path.join(target_dir, |
580 |
os.path.basename(log_file)) |
|
|
2066
by Colin Watson
more ex -> execute renaming |
581 |
if not misc.execute('cp', '-a', log_file, target_log_file): |
|
1503
by Colin Watson
syslog.LOG_ERROR -> syslog.LOG_ERR |
582 |
syslog.syslog(syslog.LOG_ERR, |
|
1495
by Colin Watson
* Send all internal log messages to syslog rather than stderr. |
583 |
'Failed to copy installation log file') |
|
1199
by Colin Watson
* Save /var/log/partman to installed system as /var/log/installer/partman. |
584 |
os.chmod(target_log_file, stat.S_IRUSR | stat.S_IWUSR) |
|
1698
by Colin Watson
* Save /target/var/lib/dpkg/status to |
585 |
try: |
586 |
status = open(os.path.join(self.target, 'var/lib/dpkg/status')) |
|
587 |
status_gz = gzip.open(os.path.join(target_dir, |
|
588 |
'initial-status.gz'), 'w') |
|
589 |
while True: |
|
590 |
data = status.read(65536) |
|
|
1711
by Colin Watson
* Fix infinite loop while creating initial-status log. |
591 |
if not data: |
592 |
break
|
|
|
1698
by Colin Watson
* Save /target/var/lib/dpkg/status to |
593 |
status_gz.write(data) |
594 |
status_gz.close() |
|
595 |
status.close() |
|
596 |
except IOError: |
|
597 |
pass
|
|
|
2125
by Colin Watson
- Ask for a unique identifier for this batch of installations, and save |
598 |
try: |
599 |
if self.db.get('oem-config/enable') == 'true': |
|
600 |
oem_id = self.db.get('oem-config/id') |
|
601 |
oem_id_file = open( |
|
602 |
os.path.join(self.target, 'var/log/installer/oem-id')) |
|
603 |
print >>oem_id_file, oem_id |
|
604 |
oem_id_file.close() |
|
605 |
except (debconf.DebconfError, IOError): |
|
606 |
pass
|
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
607 |
|
608 |
||
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
609 |
def mount_one_image(self, fsfile, mountpoint=None): |
610 |
if os.path.splitext(fsfile)[1] == '.cloop': |
|
611 |
blockdev_prefix = 'cloop' |
|
612 |
elif os.path.splitext(fsfile)[1] == '.squashfs': |
|
613 |
blockdev_prefix = 'loop' |
|
614 |
||
615 |
if blockdev_prefix == '': |
|
616 |
raise InstallStepError("No source device found for %s" % fsfile) |
|
617 |
||
618 |
dev = '' |
|
619 |
sysloops = filter(lambda x: x.startswith(blockdev_prefix), |
|
620 |
os.listdir('/sys/block')) |
|
621 |
sysloops.sort() |
|
622 |
for sysloop in sysloops: |
|
623 |
try: |
|
624 |
sysloopf = open(os.path.join('/sys/block', sysloop, 'size')) |
|
|
1527
by Colin Watson
fd leak |
625 |
sysloopsize = sysloopf.readline().strip() |
626 |
sysloopf.close() |
|
|
1528
by Colin Watson
s/=/==/ in previous change, whoops |
627 |
if sysloopsize == '0': |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
628 |
devnull = open('/dev/null') |
629 |
udevinfo = subprocess.Popen( |
|
630 |
['udevinfo', '-q', 'name', |
|
631 |
'-p', os.path.join('/block', sysloop)], |
|
632 |
stdout=subprocess.PIPE, stderr=devnull) |
|
633 |
devbase = udevinfo.communicate()[0] |
|
634 |
devnull.close() |
|
|
1639
by Colin Watson
* Fix various bugs when mounting source filesystems natively rather than |
635 |
if udevinfo.returncode != 0: |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
636 |
devbase = sysloop |
637 |
dev = '/dev/%s' % devbase |
|
638 |
break
|
|
639 |
except: |
|
640 |
continue
|
|
641 |
||
642 |
if dev == '': |
|
643 |
raise InstallStepError("No loop device available for %s" % fsfile) |
|
644 |
||
|
2066
by Colin Watson
more ex -> execute renaming |
645 |
misc.execute('losetup', dev, fsfile) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
646 |
if mountpoint is None: |
647 |
mountpoint = '/var/lib/ubiquity/%s' % sysloop |
|
648 |
if not os.path.isdir(mountpoint): |
|
649 |
os.mkdir(mountpoint) |
|
|
2066
by Colin Watson
more ex -> execute renaming |
650 |
misc.execute('mount', dev, mountpoint) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
651 |
|
652 |
return (dev, mountpoint) |
|
653 |
||
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
654 |
def mount_source(self): |
655 |
"""mounting loop system from cloop or squashfs system."""
|
|
656 |
||
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
657 |
self.devs = [] |
658 |
self.mountpoints = [] |
|
659 |
||
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
660 |
if not os.path.isdir(self.source): |
|
1495
by Colin Watson
* Send all internal log messages to syslog rather than stderr. |
661 |
syslog.syslog('mkdir %s' % self.source) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
662 |
os.mkdir(self.source) |
663 |
||
664 |
fs_preseed = self.db.get('ubiquity/install/filesystem-images') |
|
665 |
||
666 |
if fs_preseed == '': |
|
667 |
# Simple autodetection on unionfs systems
|
|
|
1778
by Colin Watson
fix filehandle leaks |
668 |
mounts = open('/proc/mounts') |
669 |
for line in mounts: |
|
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
670 |
(device, fstype) = line.split()[1:3] |
671 |
if fstype == 'squashfs' and os.path.exists(device): |
|
|
2066
by Colin Watson
more ex -> execute renaming |
672 |
misc.execute('mount', '--bind', device, self.source) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
673 |
self.mountpoints.append(self.source) |
|
1778
by Colin Watson
fix filehandle leaks |
674 |
mounts.close() |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
675 |
return
|
|
1778
by Colin Watson
fix filehandle leaks |
676 |
mounts.close() |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
677 |
|
678 |
# Manual detection on non-unionfs systems
|
|
679 |
fsfiles = ['/cdrom/casper/filesystem.cloop', |
|
680 |
'/cdrom/casper/filesystem.squashfs', |
|
681 |
'/cdrom/META/META.squashfs'] |
|
682 |
||
683 |
for fsfile in fsfiles: |
|
684 |
if fsfile != '' and os.path.isfile(fsfile): |
|
685 |
dev, mountpoint = self.mount_one_image(fsfile, self.source) |
|
|
1639
by Colin Watson
* Fix various bugs when mounting source filesystems natively rather than |
686 |
self.devs.append(dev) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
687 |
self.mountpoints.append(mountpoint) |
688 |
||
689 |
elif len(fs_preseed.split()) == 1: |
|
690 |
# Just one preseeded image.
|
|
691 |
if not os.path.isfile(fs_preseed): |
|
692 |
raise InstallStepError( |
|
693 |
"Preseeded filesystem image %s not found" % fs_preseed) |
|
694 |
||
695 |
dev, mountpoint = self.mount_one_image(fsfile, self.source) |
|
|
1639
by Colin Watson
* Fix various bugs when mounting source filesystems natively rather than |
696 |
self.devs.append(dev) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
697 |
self.mountpoints.append(mountpoint) |
698 |
else: |
|
699 |
# OK, so we need to mount multiple images and unionfs them
|
|
700 |
# together.
|
|
701 |
for fsfile in fs_preseed.split(): |
|
702 |
if not os.path.isfile(fsfile): |
|
703 |
raise InstallStepError( |
|
704 |
"Preseeded filesystem image %s not found" % fsfile) |
|
705 |
||
706 |
dev, mountpoint = self.mount_one_image(fsfile) |
|
707 |
self.devs.append(dev) |
|
708 |
self.mountpoints.append(mountpoint) |
|
709 |
||
710 |
assert self.devs |
|
711 |
assert self.mountpoints |
|
712 |
||
|
2066
by Colin Watson
more ex -> execute renaming |
713 |
misc.execute('mount', '-t', 'unionfs', '-o', |
|
2094
by Colin Watson
* Fix typo in unionfs dirs= option generation (LP: #118742). |
714 |
'dirs=' + ':'.join(map(lambda x: '%s=ro' % x, |
715 |
self.mountpoints)), |
|
|
2066
by Colin Watson
more ex -> execute renaming |
716 |
'unionfs', self.source) |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
717 |
self.mountpoints.append(self.source) |
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
718 |
|
719 |
def umount_source(self): |
|
720 |
"""umounting loop system from cloop or squashfs system."""
|
|
721 |
||
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
722 |
devs = self.devs |
723 |
devs.reverse() |
|
724 |
mountpoints = self.mountpoints |
|
725 |
mountpoints.reverse() |
|
726 |
||
727 |
for mountpoint in mountpoints: |
|
|
2066
by Colin Watson
more ex -> execute renaming |
728 |
if not misc.execute('umount', mountpoint): |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
729 |
raise InstallStepError("Failed to unmount %s" % mountpoint) |
730 |
for dev in devs: |
|
|
2066
by Colin Watson
more ex -> execute renaming |
731 |
if dev != '' and not misc.execute('losetup', '-d', dev): |
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
732 |
raise InstallStepError( |
733 |
"Failed to detach loopback device %s" % dev) |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
734 |
|
735 |
||
|
1968
by Colin Watson
* Install dummy policy-rc.d and start-stop-daemon while doing anything |
736 |
def chroot_setup(self): |
737 |
"""Set up /target for safe package management operations."""
|
|
738 |
policy_rc_d = os.path.join(self.target, 'usr/sbin/policy-rc.d') |
|
739 |
f = open(policy_rc_d, 'w') |
|
740 |
print >>f, """\ |
|
741 |
#!/bin/sh
|
|
742 |
exit 101"""
|
|
743 |
f.close() |
|
744 |
os.chmod(policy_rc_d, 0755) |
|
745 |
||
746 |
start_stop_daemon = os.path.join(self.target, 'sbin/start-stop-daemon') |
|
747 |
if os.path.exists(start_stop_daemon): |
|
748 |
os.rename(start_stop_daemon, '%s.REAL' % start_stop_daemon) |
|
749 |
f = open(start_stop_daemon, 'w') |
|
750 |
print >>f, """\ |
|
751 |
#!/bin/sh
|
|
752 |
echo 1>&2
|
|
753 |
echo 'Warning: Fake start-stop-daemon called, doing nothing.' 1>&2
|
|
754 |
exit 0"""
|
|
755 |
f.close() |
|
756 |
os.chmod(start_stop_daemon, 0755) |
|
757 |
||
758 |
if not os.path.exists(os.path.join(self.target, 'proc/cmdline')): |
|
759 |
self.chrex('mount', '-t', 'proc', 'proc', '/proc') |
|
760 |
if not os.path.exists(os.path.join(self.target, 'sys/devices')): |
|
761 |
self.chrex('mount', '-t', 'sysfs', 'sysfs', '/sys') |
|
762 |
||
763 |
def chroot_cleanup(self): |
|
764 |
"""Undo the work done by chroot_setup."""
|
|
765 |
self.chrex('umount', '/sys') |
|
766 |
self.chrex('umount', '/proc') |
|
767 |
||
768 |
start_stop_daemon = os.path.join(self.target, 'sbin/start-stop-daemon') |
|
769 |
os.rename('%s.REAL' % start_stop_daemon, start_stop_daemon) |
|
770 |
||
771 |
policy_rc_d = os.path.join(self.target, 'usr/sbin/policy-rc.d') |
|
772 |
os.unlink(policy_rc_d) |
|
773 |
||
774 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
775 |
def run_target_config_hooks(self): |
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
776 |
"""Run hook scripts from /usr/lib/ubiquity/target-config. This allows
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
777 |
casper to hook into us and repeat bits of its configuration in the
|
778 |
target system."""
|
|
779 |
||
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
780 |
hookdir = '/usr/lib/ubiquity/target-config' |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
781 |
|
782 |
if os.path.isdir(hookdir): |
|
783 |
# Exclude hooks containing '.', so that *.dpkg-* et al are avoided.
|
|
784 |
hooks = filter(lambda entry: '.' not in entry, os.listdir(hookdir)) |
|
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
785 |
self.db.progress('START', 0, len(hooks), 'ubiquity/install/title') |
|
1940
by Colin Watson
* Use just one progress message for all target-config hooks, to avoid |
786 |
self.db.progress('INFO', 'ubiquity/install/target_hooks') |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
787 |
for hookentry in hooks: |
788 |
hook = os.path.join(hookdir, hookentry) |
|
789 |
if not os.access(hook, os.X_OK): |
|
790 |
self.db.progress('STEP', 1) |
|
791 |
continue
|
|
792 |
# Errors are ignored at present, although this may change.
|
|
|
1510
by Colin Watson
allow target-config hooks to get hold of stdout again, so that they can use debconf |
793 |
subprocess.call(['log-output', '-t', 'ubiquity', |
794 |
'--pass-stdout', hook]) |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
795 |
self.db.progress('STEP', 1) |
796 |
self.db.progress('STOP') |
|
797 |
||
798 |
||
|
995
by Colin Watson
get_locales no longer needs to mess with the keymap; rename to configure_locales |
799 |
def configure_locales(self): |
800 |
"""Apply locale settings to installed system."""
|
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
801 |
dbfilter = language_apply.LanguageApply(None) |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
802 |
ret = dbfilter.run_command(auto_process=True) |
803 |
if ret != 0: |
|
|
1412
by Colin Watson
* Fix typoed variable name while raising InstallStepError. |
804 |
raise InstallStepError("LanguageApply failed with code %d" % ret) |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
805 |
|
|
1668
by Colin Watson
* Run fontconfig-voodoo to tweak fontconfig configuration for the selected |
806 |
# fontconfig configuration needs to be adjusted based on the
|
807 |
# selected locale (from language-selector-common.postinst). Ignore
|
|
808 |
# errors.
|
|
809 |
self.chrex('fontconfig-voodoo', '--auto', '--quiet') |
|
810 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
811 |
|
|
1036
by Colin Watson
* Use choose-mirror and apt-setup to set up a standard |
812 |
def configure_apt(self): |
813 |
"""Configure /etc/apt/sources.list."""
|
|
|
1166
by Colin Watson
* Write out /target/etc/apt/apt.conf.d/00IgnoreTimeConflict for the |
814 |
|
|
2134
by Colin Watson
* Replicate the apt configuration done by base-installer (trust CD-ROMs, |
815 |
# TODO cjwatson 2007-07-06: Much of the following is
|
816 |
# cloned-and-hacked from base-installer/debian/postinst. Perhaps we
|
|
817 |
# should come up with a way to avoid this.
|
|
818 |
||
819 |
# Make apt trust CDs. This is not on by default (we think).
|
|
820 |
# This will be left in place on the installed system.
|
|
821 |
apt_conf_tc = open(os.path.join( |
|
822 |
self.target, 'etc/apt/apt.conf.d/00trustcdrom'), 'w') |
|
823 |
print >>apt_conf_tc, 'APT::Authentication::TrustCDROM "true";' |
|
824 |
apt_conf_tc.close() |
|
825 |
||
|
1166
by Colin Watson
* Write out /target/etc/apt/apt.conf.d/00IgnoreTimeConflict for the |
826 |
# Avoid clock skew causing gpg verification issues.
|
827 |
# This file will be left in place until the end of the install.
|
|
828 |
apt_conf_itc = open(os.path.join( |
|
829 |
self.target, 'etc/apt/apt.conf.d/00IgnoreTimeConflict'), 'w') |
|
|
2134
by Colin Watson
* Replicate the apt configuration done by base-installer (trust CD-ROMs, |
830 |
print >>apt_conf_itc, \ |
831 |
'Acquire::gpgv::Options { "--ignore-time-conflict"; };'
|
|
|
1166
by Colin Watson
* Write out /target/etc/apt/apt.conf.d/00IgnoreTimeConflict for the |
832 |
apt_conf_itc.close() |
833 |
||
|
2134
by Colin Watson
* Replicate the apt configuration done by base-installer (trust CD-ROMs, |
834 |
try: |
835 |
if self.db.get('debian-installer/allow_unauthenticated') == 'true': |
|
836 |
apt_conf_au = open( |
|
837 |
os.path.join(self.target, |
|
838 |
'etc/apt/apt.conf.d/00AllowUnauthenticated'), |
|
839 |
'w') |
|
840 |
print >>apt_conf_au, 'APT::Get::AllowUnauthenticated "true";' |
|
841 |
print >>apt_conf_au, \ |
|
842 |
'Aptitude::CmdLine::Ignore-Trust-Violations "true";'
|
|
843 |
apt_conf_au.close() |
|
844 |
except debconf.DebconfError: |
|
845 |
pass
|
|
846 |
||
847 |
# let apt inside the chroot see the cdrom
|
|
848 |
target_cdrom = os.path.join(self.target, 'cdrom') |
|
849 |
misc.execute('umount', target_cdrom) |
|
850 |
if not os.path.exists(target_cdrom): |
|
851 |
os.mkdir(target_cdrom) |
|
852 |
misc.execute('mount', '--bind', '/cdrom', target_cdrom) |
|
853 |
||
854 |
# Make apt-cdrom and apt not unmount/mount CD-ROMs.
|
|
855 |
# This file will be left in place until the end of the install.
|
|
856 |
apt_conf_nmc = open(os.path.join( |
|
857 |
self.target, 'etc/apt/apt.conf.d/00NoMountCDROM'), 'w') |
|
858 |
print >>apt_conf_nmc, textwrap.dedent("""\ |
|
859 |
APT::CDROM::NoMount "true";
|
|
860 |
Acquire::cdrom {
|
|
861 |
mount "/cdrom";
|
|
862 |
"/cdrom/" {
|
|
863 |
Mount "true";
|
|
864 |
UMount "true";
|
|
865 |
};
|
|
866 |
}""") |
|
867 |
apt_conf_nmc.close() |
|
868 |
||
|
1036
by Colin Watson
* Use choose-mirror and apt-setup to set up a standard |
869 |
dbfilter = apt_setup.AptSetup(None) |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
870 |
ret = dbfilter.run_command(auto_process=True) |
871 |
if ret != 0: |
|
|
1412
by Colin Watson
* Fix typoed variable name while raising InstallStepError. |
872 |
raise InstallStepError("AptSetup failed with code %d" % ret) |
|
1036
by Colin Watson
* Use choose-mirror and apt-setup to set up a standard |
873 |
|
874 |
||
|
844
by Colin Watson
factor out broken has_key workaround to new get_cache_pkg method |
875 |
def get_cache_pkg(self, cache, pkg): |
|
833
by Colin Watson
* Install language packs according to the selected language. |
876 |
# work around broken has_key in python-apt 0.6.16
|
877 |
try: |
|
|
844
by Colin Watson
factor out broken has_key workaround to new get_cache_pkg method |
878 |
return cache[pkg] |
|
833
by Colin Watson
* Install language packs according to the selected language. |
879 |
except KeyError: |
|
844
by Colin Watson
factor out broken has_key workaround to new get_cache_pkg method |
880 |
return None |
881 |
||
882 |
||
|
847
by Colin Watson
make sure not to remove packages that were already installed and then dynamically marked for installation too |
883 |
def record_installed(self, pkgs): |
884 |
"""Record which packages we've explicitly installed so that we don't
|
|
885 |
try to remove them later."""
|
|
886 |
||
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
887 |
record_file = "/var/lib/ubiquity/apt-installed" |
|
847
by Colin Watson
make sure not to remove packages that were already installed and then dynamically marked for installation too |
888 |
if not os.path.exists(os.path.dirname(record_file)): |
889 |
os.makedirs(os.path.dirname(record_file)) |
|
890 |
record = open(record_file, "a") |
|
891 |
||
892 |
for pkg in pkgs: |
|
893 |
print >>record, pkg |
|
894 |
||
895 |
record.close() |
|
896 |
||
897 |
||
|
2135
by Colin Watson
factor out reading of apt-installed file |
898 |
def query_recorded_installed(self): |
899 |
apt_installed = set() |
|
900 |
if os.path.exists("/var/lib/ubiquity/apt-installed"): |
|
901 |
record_file = open("/var/lib/ubiquity/apt-installed") |
|
902 |
for line in record_file: |
|
903 |
apt_installed.add(line.strip()) |
|
904 |
record_file.close() |
|
905 |
return apt_installed |
|
906 |
||
907 |
||
|
844
by Colin Watson
factor out broken has_key workaround to new get_cache_pkg method |
908 |
def mark_install(self, cache, pkg): |
909 |
cachedpkg = self.get_cache_pkg(cache, pkg) |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
910 |
if cachedpkg is not None and not cachedpkg.isInstalled: |
911 |
apt_error = False |
|
912 |
try: |
|
913 |
cachedpkg.markInstall() |
|
914 |
except SystemError: |
|
915 |
apt_error = True |
|
916 |
if cache._depcache.BrokenCount > 0 or apt_error: |
|
|
1802
by Colin Watson
* Fix language pack installation to clean up any broken packages in the |
917 |
brokenpkgs = self.broken_packages(cache) |
918 |
while brokenpkgs: |
|
919 |
for brokenpkg in brokenpkgs: |
|
920 |
self.get_cache_pkg(cache, brokenpkg).markKeep() |
|
921 |
new_brokenpkgs = self.broken_packages(cache) |
|
922 |
if brokenpkgs == new_brokenpkgs: |
|
923 |
break # we can do nothing more |
|
924 |
brokenpkgs = new_brokenpkgs |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
925 |
assert cache._depcache.BrokenCount == 0 |
926 |
||
927 |
||
928 |
def install_language_packs(self): |
|
929 |
langpacks = [] |
|
930 |
try: |
|
|
1518
by Colin Watson
* Drop backward compatibility for base-config/language-packs preseeding |
931 |
langpack_db = self.db.get('pkgsel/language-packs') |
|
833
by Colin Watson
* Install language packs according to the selected language. |
932 |
langpacks = langpack_db.replace(',', '').split() |
933 |
except debconf.DebconfError: |
|
934 |
pass
|
|
935 |
if not langpacks: |
|
936 |
try: |
|
937 |
langpack_db = self.db.get('localechooser/supported-locales') |
|
938 |
langpack_set = set() |
|
939 |
for locale in langpack_db.replace(',', '').split(): |
|
940 |
langpack_set.add(locale.split('_')[0]) |
|
941 |
langpacks = sorted(langpack_set) |
|
942 |
except debconf.DebconfError: |
|
943 |
pass
|
|
944 |
if not langpacks: |
|
945 |
langpack_db = self.db.get('debian-installer/locale') |
|
946 |
langpacks = [langpack_db.split('_')[0]] |
|
|
1495
by Colin Watson
* Send all internal log messages to syslog rather than stderr. |
947 |
syslog.syslog('keeping language packs for: %s' % ' '.join(langpacks)) |
|
833
by Colin Watson
* Install language packs according to the selected language. |
948 |
|
949 |
try: |
|
950 |
lppatterns = self.db.get('pkgsel/language-pack-patterns').split() |
|
951 |
except debconf.DebconfError: |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
952 |
return
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
953 |
|
|
1116
by Colin Watson
* Make sure to keep language packs even if the apt update fails. |
954 |
to_install = [] |
955 |
for lp in langpacks: |
|
956 |
# Basic language packs, required to get localisation working at
|
|
957 |
# all. We install these almost unconditionally; if you want to
|
|
958 |
# get rid of even these, you can preseed pkgsel/language-packs
|
|
959 |
# to the empty string.
|
|
960 |
to_install.append('language-pack-%s' % lp) |
|
961 |
# Other language packs, typically selected by preseeding.
|
|
962 |
for pattern in lppatterns: |
|
963 |
to_install.append(pattern.replace('$LL', lp)) |
|
964 |
# More extensive language support packages.
|
|
965 |
to_install.append('language-support-%s' % lp) |
|
|
2137
by Colin Watson
* Install packages passed to apt-install even if they aren't on the live |
966 |
|
967 |
self.do_install(to_install, langpacks=True) |
|
|
833
by Colin Watson
* Install language packs according to the selected language. |
968 |
|
969 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
970 |
def configure_timezone(self): |
971 |
"""Set timezone on installed system."""
|
|
972 |
||
973 |
dbfilter = timezone_apply.TimezoneApply(None) |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
974 |
ret = dbfilter.run_command(auto_process=True) |
975 |
if ret != 0: |
|
|
1412
by Colin Watson
* Fix typoed variable name while raising InstallStepError. |
976 |
raise InstallStepError("TimezoneApply failed with code %d" % ret) |
|
1280
by Colin Watson
* Add basic clock-setup integration; there's no UI at present, but it will |
977 |
|
978 |
dbfilter = clock_setup.ClockSetup(None) |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
979 |
ret = dbfilter.run_command(auto_process=True) |
980 |
if ret != 0: |
|
|
1412
by Colin Watson
* Fix typoed variable name while raising InstallStepError. |
981 |
raise InstallStepError("ClockSetup failed with code %d" % ret) |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
982 |
|
983 |
||
|
1024
by Colin Watson
* Propagate selected keymap to installed system (closes: Malone #37748). |
984 |
def configure_keyboard(self): |
985 |
"""Set keyboard in installed system."""
|
|
986 |
||
|
1518.1.1
by Colin Watson
* Move from kbd-chooser to console-setup |
987 |
dbfilter = console_setup_apply.ConsoleSetupApply(None) |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
988 |
ret = dbfilter.run_command(auto_process=True) |
989 |
if ret != 0: |
|
|
1518.1.1
by Colin Watson
* Move from kbd-chooser to console-setup |
990 |
raise InstallStepError( |
991 |
"ConsoleSetupApply failed with code %d" % ret) |
|
|
1024
by Colin Watson
* Propagate selected keymap to installed system (closes: Malone #37748). |
992 |
|
993 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
994 |
def configure_user(self): |
995 |
"""create the user selected along the installation process
|
|
996 |
into the installed system. Default user from live system is
|
|
997 |
deleted and skel for this new user is copied to $HOME."""
|
|
998 |
||
999 |
dbfilter = usersetup_apply.UserSetupApply(None) |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1000 |
ret = dbfilter.run_command(auto_process=True) |
1001 |
if ret != 0: |
|
|
1412
by Colin Watson
* Fix typoed variable name while raising InstallStepError. |
1002 |
raise InstallStepError("UserSetupApply failed with code %d" % ret) |
|
2109
by Colin Watson
* If oem-config/enable is true, then: |
1003 |
|
|
1435.1.5
by Evan Dandrea
migration-assistant works inside Ubiquity running after partitioning now. |
1004 |
def configure_ma(self): |
1005 |
"""import documents, settings, and users from previous operating
|
|
1006 |
systems."""
|
|
1007 |
||
|
1435.2.7
by Evan Dandrea
When m-a is disabled, don't try to run its apply script. |
1008 |
if 'UBIQUITY_MIGRATION_ASSISTANT' in os.environ: |
1009 |
dbfilter = migrationassistant_apply.MigrationAssistantApply(None) |
|
1010 |
ret = dbfilter.run_command(auto_process=True) |
|
1011 |
if ret != 0: |
|
1012 |
raise InstallStepError("MigrationAssistantApply failed with code %d" % ret) |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1013 |
|
1014 |
||
|
1222
by Colin Watson
* Mimic base-installer's logic to configure initramfs-tools with an |
1015 |
def get_resume_partition(self): |
1016 |
biggest_size = 0 |
|
1017 |
biggest_partition = None |
|
1018 |
swaps = open('/proc/swaps') |
|
1019 |
for line in swaps: |
|
1020 |
words = line.split() |
|
1021 |
if words[1] != 'partition': |
|
1022 |
continue
|
|
1023 |
size = int(words[2]) |
|
1024 |
if size > biggest_size: |
|
1025 |
biggest_size = size |
|
1026 |
biggest_partition = words[0] |
|
1027 |
swaps.close() |
|
1028 |
return biggest_partition |
|
1029 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1030 |
def configure_hardware(self): |
1031 |
"""reconfiguring several packages which depends on the
|
|
1032 |
hardware system in which has been installed on and need some
|
|
1033 |
automatic configurations to get work."""
|
|
1034 |
||
|
1968
by Colin Watson
* Install dummy policy-rc.d and start-stop-daemon while doing anything |
1035 |
self.chroot_setup() |
1036 |
try: |
|
1037 |
dbfilter = hw_detect.HwDetect(None, self.db) |
|
1038 |
ret = dbfilter.run_command(auto_process=True) |
|
1039 |
if ret != 0: |
|
1040 |
raise InstallStepError("HwDetect failed with code %d" % ret) |
|
1041 |
finally: |
|
1042 |
self.chroot_cleanup() |
|
|
1221
by Colin Watson
* Run hw-detect to set up /etc/modules properly (closes: Malone #40826). |
1043 |
|
|
1330
by Colin Watson
* Set a slightly more meaningful progress info message while reconfiguring |
1044 |
self.db.progress('INFO', 'ubiquity/install/hardware') |
1045 |
||
|
2066
by Colin Watson
more ex -> execute renaming |
1046 |
misc.execute('/usr/lib/ubiquity/debian-installer-utils' |
1047 |
'/register-module.post-base-installer') |
|
|
1221
by Colin Watson
* Run hw-detect to set up /etc/modules properly (closes: Malone #40826). |
1048 |
|
|
1222
by Colin Watson
* Mimic base-installer's logic to configure initramfs-tools with an |
1049 |
resume = self.get_resume_partition() |
1050 |
if resume is not None: |
|
|
1432
by Colin Watson
* Write out the resume partition as a UUID if possible. |
1051 |
resume_uuid = None |
1052 |
try: |
|
1053 |
resume_uuid = subprocess.Popen( |
|
1054 |
['vol_id', '-u', resume], |
|
1055 |
stdout=subprocess.PIPE).communicate()[0].rstrip('\n') |
|
1056 |
except OSError: |
|
1057 |
pass
|
|
1058 |
if resume_uuid: |
|
1059 |
resume = "UUID=%s" % resume_uuid |
|
|
1418
by Colin Watson
* Handle new initramfs-tools configuration directory. |
1060 |
if os.path.exists(os.path.join(self.target, |
1061 |
'etc/initramfs-tools/conf.d')): |
|
1062 |
configdir = os.path.join(self.target, |
|
1063 |
'etc/initramfs-tools/conf.d') |
|
1064 |
elif os.path.exists(os.path.join(self.target, |
|
1065 |
'etc/mkinitramfs/conf.d')): |
|
1066 |
configdir = os.path.join(self.target, |
|
1067 |
'etc/mkinitramfs/conf.d') |
|
1068 |
else: |
|
1069 |
configdir = None |
|
1070 |
if configdir is not None: |
|
1071 |
configfile = open(os.path.join(configdir, 'resume'), 'w') |
|
1072 |
print >>configfile, "RESUME=%s" % resume |
|
1073 |
configfile.close() |
|
|
1222
by Colin Watson
* Mimic base-installer's logic to configure initramfs-tools with an |
1074 |
|
|
1539
by Colin Watson
* Reconfigure popularity-contest. |
1075 |
try: |
|
1548
by Colin Watson
* Reconfigure usplash (closes: Malone #59320). |
1076 |
os.unlink('/target/etc/usplash.conf') |
1077 |
except OSError: |
|
1078 |
pass
|
|
1079 |
||
1080 |
try: |
|
|
1544
by Colin Watson
/etc/popularity-contest.conf -> /target/etc/popularity-contest.conf |
1081 |
os.unlink('/target/etc/popularity-contest.conf') |
|
1539
by Colin Watson
* Reconfigure popularity-contest. |
1082 |
except OSError: |
1083 |
pass
|
|
|
1818
by Colin Watson
* Copy value of popularity-contest/participate into /target (LP: #78972). |
1084 |
try: |
1085 |
participate = self.db.get('popularity-contest/participate') |
|
1086 |
self.set_debconf('popularity-contest/participate', participate) |
|
|
1841
by Colin Watson
* Fix crash due to underqualification of debconf.DebconfError (thanks, |
1087 |
except debconf.DebconfError: |
|
1818
by Colin Watson
* Copy value of popularity-contest/participate into /target (LP: #78972). |
1088 |
pass
|
|
1539
by Colin Watson
* Reconfigure popularity-contest. |
1089 |
|
|
2058
by Colin Watson
* Reconfigure /etc/papersize on installation (LP: #104160). |
1090 |
try: |
1091 |
os.unlink('/target/etc/papersize') |
|
1092 |
except OSError: |
|
1093 |
pass
|
|
|
2244
by Colin Watson
* Purge ucf's state for /etc/papersize so that it will be recreated |
1094 |
self.chrex('ucf', '--purge', '/etc/papersize') |
|
2058
by Colin Watson
* Reconfigure /etc/papersize on installation (LP: #104160). |
1095 |
try: |
1096 |
self.set_debconf('libpaper/defaultpaper', '') |
|
1097 |
except debconf.DebconfError: |
|
1098 |
pass
|
|
1099 |
||
|
1968
by Colin Watson
* Install dummy policy-rc.d and start-stop-daemon while doing anything |
1100 |
self.chroot_setup() |
|
1549
by Colin Watson
* Divert away update-initramfs while configuring hardware-specific |
1101 |
self.chrex('dpkg-divert', '--package', 'ubiquity', '--rename', |
1102 |
'--quiet', '--add', '/usr/sbin/update-initramfs') |
|
1103 |
try: |
|
1104 |
os.symlink('/bin/true', '/target/usr/sbin/update-initramfs') |
|
1105 |
except OSError: |
|
1106 |
pass
|
|
1107 |
||
|
1157
by Colin Watson
* Reconfigure linux-restricted-modules-$KVER as well as linux-image-$KVER |
1108 |
packages = ['linux-image-' + self.kernel_version, |
|
1539
by Colin Watson
* Reconfigure popularity-contest. |
1109 |
'linux-restricted-modules-' + self.kernel_version, |
|
1548
by Colin Watson
* Reconfigure usplash (closes: Malone #59320). |
1110 |
'usplash', |
|
2058
by Colin Watson
* Reconfigure /etc/papersize on installation (LP: #104160). |
1111 |
'popularity-contest', |
1112 |
'libpaper1'] |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1113 |
|
1114 |
try: |
|
1115 |
for package in packages: |
|
1116 |
self.reconfigure(package) |
|
1117 |
finally: |
|
|
1549
by Colin Watson
* Divert away update-initramfs while configuring hardware-specific |
1118 |
try: |
1119 |
os.unlink('/target/usr/sbin/update-initramfs') |
|
1120 |
except OSError: |
|
1121 |
pass
|
|
1122 |
self.chrex('dpkg-divert', '--package', 'ubiquity', '--rename', |
|
1123 |
'--quiet', '--remove', '/usr/sbin/update-initramfs') |
|
|
1678
by Colin Watson
* Use update-initramfs -c -k "$(uname -r)" rather than update-initramfs |
1124 |
self.chrex('update-initramfs', '-c', '-k', os.uname()[2]) |
|
1968
by Colin Watson
* Install dummy policy-rc.d and start-stop-daemon while doing anything |
1125 |
self.chroot_cleanup() |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1126 |
|
|
1674
by Colin Watson
* Remove kernels before running update-initramfs so that we update the |
1127 |
# Fix up kernel symlinks now that the initrd exists. Depending on
|
1128 |
# the architecture, these may be in / or in /boot.
|
|
1129 |
bootdir = os.path.join(self.target, 'boot') |
|
1130 |
if self.db.get('base-installer/kernel/linux/link_in_boot') == 'true': |
|
1131 |
linkdir = bootdir |
|
1132 |
linkprefix = '' |
|
1133 |
else: |
|
1134 |
linkdir = self.target |
|
1135 |
linkprefix = 'boot' |
|
1136 |
||
1137 |
# Remove old symlinks. We'll set them up from scratch.
|
|
1138 |
re_symlink = re.compile('vmlinu[xz]|initrd.img$') |
|
1139 |
for entry in os.listdir(linkdir): |
|
1140 |
if re_symlink.match(entry) is not None: |
|
1141 |
filename = os.path.join(linkdir, entry) |
|
1142 |
if os.path.islink(filename): |
|
1143 |
os.unlink(filename) |
|
1144 |
if linkdir != self.target: |
|
1145 |
# Remove symlinks in /target too, which may have been created on
|
|
1146 |
# the live filesystem. This isn't necessary, but it may help
|
|
1147 |
# avoid confusion.
|
|
1148 |
for entry in os.listdir(self.target): |
|
1149 |
if re_symlink.match(entry) is not None: |
|
1150 |
filename = os.path.join(self.target, entry) |
|
1151 |
if os.path.islink(filename): |
|
1152 |
os.unlink(filename) |
|
1153 |
||
1154 |
# Create symlinks. Prefer our current kernel version if possible,
|
|
1155 |
# but if not (perhaps due to a customised live filesystem image),
|
|
1156 |
# it's better to create some symlinks than none at all.
|
|
1157 |
re_image = re.compile('(vmlinu[xz]|initrd.img)-') |
|
1158 |
for entry in os.listdir(bootdir): |
|
1159 |
match = re_image.match(entry) |
|
1160 |
if match is not None: |
|
1161 |
imagetype = match.group(1) |
|
1162 |
linksrc = os.path.join(linkprefix, entry) |
|
1163 |
linkdst = os.path.join(linkdir, imagetype) |
|
1164 |
if os.path.exists(linkdst): |
|
1165 |
if entry.endswith('-' + self.kernel_version): |
|
1166 |
os.unlink(linkdst) |
|
1167 |
else: |
|
1168 |
continue
|
|
1169 |
os.symlink(linksrc, linkdst) |
|
1170 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1171 |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1172 |
def get_all_interfaces(self): |
1173 |
"""Get all non-local network interfaces."""
|
|
1174 |
ifs = [] |
|
1175 |
ifs_file = open('/proc/net/dev') |
|
1176 |
# eat header
|
|
1177 |
ifs_file.readline() |
|
1178 |
ifs_file.readline() |
|
1179 |
||
1180 |
for line in ifs_file: |
|
1181 |
name = re.match('(.*?(?::\d+)?):', line.strip()).group(1) |
|
1182 |
if name == 'lo': |
|
1183 |
continue
|
|
1184 |
ifs.append(name) |
|
1185 |
||
1186 |
ifs_file.close() |
|
1187 |
return ifs |
|
1188 |
||
1189 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1190 |
def configure_network(self): |
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1191 |
"""Automatically configure the network.
|
|
2143
by Colin Watson
more trailing whitespace |
1192 |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1193 |
At present, the only thing the user gets to tweak in the UI is the
|
1194 |
hostname. Some other things will be copied from the live filesystem,
|
|
1195 |
so changes made there will be reflected in the installed system.
|
|
|
2143
by Colin Watson
more trailing whitespace |
1196 |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1197 |
Unfortunately, at present we have to duplicate a fair bit of netcfg
|
1198 |
here, because it's hard to drive netcfg in a way that won't try to
|
|
1199 |
bring interfaces up and down."""
|
|
1200 |
||
1201 |
# TODO cjwatson 2006-03-30: just call netcfg instead of doing all
|
|
1202 |
# this; requires a netcfg binary that doesn't bring interfaces up
|
|
1203 |
# and down
|
|
1204 |
||
1205 |
for path in ('/etc/network/interfaces', '/etc/resolv.conf'): |
|
1206 |
if os.path.exists(path): |
|
|
1021
by Colin Watson
* Fix copying of /etc/network/interfaces and /etc/resolv.conf. |
1207 |
shutil.copy2(path, os.path.join(self.target, path[1:])) |
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1208 |
|
1209 |
try: |
|
1210 |
hostname = self.db.get('netcfg/get_hostname') |
|
1211 |
except debconf.DebconfError: |
|
1212 |
hostname = '' |
|
|
1772
by Colin Watson
* Sync up hostname handling with netcfg; it now allows hostnames between 2 |
1213 |
try: |
1214 |
domain = self.db.get('netcfg/get_domain') |
|
1215 |
except debconf.DebconfError: |
|
1216 |
domain = '' |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1217 |
if hostname == '': |
1218 |
hostname = 'ubuntu' |
|
|
1772
by Colin Watson
* Sync up hostname handling with netcfg; it now allows hostnames between 2 |
1219 |
|
|
996
by Colin Watson
reorder method definitions to match calling sequence |
1220 |
fp = open(os.path.join(self.target, 'etc/hostname'), 'w') |
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1221 |
print >>fp, hostname |
|
996
by Colin Watson
reorder method definitions to match calling sequence |
1222 |
fp.close() |
1223 |
||
1224 |
hosts = open(os.path.join(self.target, 'etc/hosts'), 'w') |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1225 |
print >>hosts, "127.0.0.1\tlocalhost" |
|
1772
by Colin Watson
* Sync up hostname handling with netcfg; it now allows hostnames between 2 |
1226 |
if domain: |
1227 |
print >>hosts, "127.0.1.1\t%s.%s\t%s" % (hostname, domain, |
|
1228 |
hostname) |
|
1229 |
else: |
|
1230 |
print >>hosts, "127.0.1.1\t%s" % hostname |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1231 |
print >>hosts, textwrap.dedent("""\ |
|
996
by Colin Watson
reorder method definitions to match calling sequence |
1232 |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1233 |
# The following lines are desirable for IPv6 capable hosts
|
1234 |
::1 ip6-localhost ip6-loopback
|
|
1235 |
fe00::0 ip6-localnet
|
|
1236 |
ff00::0 ip6-mcastprefix
|
|
1237 |
ff02::1 ip6-allnodes
|
|
1238 |
ff02::2 ip6-allrouters
|
|
1239 |
ff02::3 ip6-allhosts""") |
|
|
996
by Colin Watson
reorder method definitions to match calling sequence |
1240 |
hosts.close() |
1241 |
||
|
2100
by Colin Watson
* If /etc/udev/rules.d/70-persistent-net.rules exists, copy it rather than |
1242 |
persistent_net = '/etc/udev/rules.d/70-persistent-net.rules' |
1243 |
if os.path.exists(persistent_net): |
|
1244 |
shutil.copy2(persistent_net, |
|
1245 |
os.path.join(self.target, persistent_net[1:])) |
|
1246 |
else: |
|
1247 |
# TODO cjwatson 2006-03-30: from <bits/ioctls.h>; ugh, but no
|
|
1248 |
# binding available
|
|
1249 |
SIOCGIFHWADDR = 0x8927 |
|
1250 |
# <net/if_arp.h>
|
|
1251 |
ARPHRD_ETHER = 1 |
|
1252 |
||
1253 |
if_names = {} |
|
1254 |
sock = socket.socket(socket.SOCK_DGRAM) |
|
1255 |
interfaces = self.get_all_interfaces() |
|
1256 |
for i in range(len(interfaces)): |
|
1257 |
if_names[interfaces[i]] = struct.unpack('H6s', |
|
1258 |
fcntl.ioctl(sock.fileno(), SIOCGIFHWADDR, |
|
1259 |
struct.pack('256s', interfaces[i]))[16:24]) |
|
1260 |
sock.close() |
|
1261 |
||
1262 |
iftab = open(os.path.join(self.target, 'etc/iftab'), 'w') |
|
1263 |
||
1264 |
print >>iftab, textwrap.dedent("""\ |
|
1265 |
# This file assigns persistent names to network interfaces.
|
|
1266 |
# See iftab(5) for syntax.
|
|
1267 |
""") |
|
1268 |
||
1269 |
for i in range(len(interfaces)): |
|
1270 |
dup = False |
|
1271 |
with_arp = False |
|
1272 |
||
1273 |
if_name = if_names[interfaces[i]] |
|
1274 |
if if_name is None or if_name[0] != ARPHRD_ETHER: |
|
1275 |
continue
|
|
1276 |
||
1277 |
for j in range(len(interfaces)): |
|
1278 |
if i == j or if_names[interfaces[j]] is None: |
|
1279 |
continue
|
|
1280 |
if if_name[1] != if_names[interfaces[j]][1]: |
|
1281 |
continue
|
|
1282 |
||
1283 |
if if_names[interfaces[j]][0] == ARPHRD_ETHER: |
|
1284 |
dup = True |
|
1285 |
||
1286 |
if dup: |
|
1287 |
continue
|
|
1288 |
||
1289 |
line = (interfaces[i] + " mac " + |
|
1290 |
':'.join(['%02x' % ord(if_name[1][c]) |
|
1291 |
for c in range(6)])) |
|
1292 |
line += " arp %d" % if_name[0] |
|
1293 |
print >>iftab, line |
|
1294 |
||
1295 |
iftab.close() |
|
|
997
by Colin Watson
* Perform network configuration: we copy /etc/network/interfaces and |
1296 |
|
|
996
by Colin Watson
reorder method definitions to match calling sequence |
1297 |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1298 |
def configure_bootloader(self): |
1299 |
"""configuring and installing boot loader into installed
|
|
1300 |
hardware system."""
|
|
|
2108.1.30
by Mario Limonciello
Add support to disable/enable the bootloader installation |
1301 |
install_bootloader = self.db.get('ubiquity/install_bootloader') |
1302 |
if install_bootloader == "true": |
|
1303 |
misc.execute('mount', '--bind', '/proc', self.target + '/proc') |
|
1304 |
misc.execute('mount', '--bind', '/dev', self.target + '/dev') |
|
1305 |
||
1306 |
archdetect = subprocess.Popen(['archdetect'], stdout=subprocess.PIPE) |
|
1307 |
subarch = archdetect.communicate()[0].strip() |
|
1308 |
||
1309 |
try: |
|
1310 |
if subarch.startswith('amd64/') or subarch.startswith('i386/'): |
|
1311 |
from ubiquity.components import grubinstaller |
|
1312 |
dbfilter = grubinstaller.GrubInstaller(None) |
|
1313 |
ret = dbfilter.run_command(auto_process=True) |
|
1314 |
if ret != 0: |
|
1315 |
raise InstallStepError( |
|
1316 |
"GrubInstaller failed with code %d" % ret) |
|
1317 |
elif subarch == 'powerpc/ps3': |
|
1318 |
from ubiquity.components import kbootinstaller |
|
1319 |
dbfilter = kbootinstaller.KbootInstaller(None) |
|
1320 |
ret = dbfilter.run_command(auto_process=True) |
|
1321 |
if ret != 0: |
|
1322 |
raise InstallStepError( |
|
1323 |
"KbootInstaller failed with code %d" % ret) |
|
1324 |
elif subarch.startswith('powerpc/'): |
|
1325 |
from ubiquity.components import yabootinstaller |
|
1326 |
dbfilter = yabootinstaller.YabootInstaller(None) |
|
1327 |
ret = dbfilter.run_command(auto_process=True) |
|
1328 |
if ret != 0: |
|
1329 |
raise InstallStepError( |
|
1330 |
"YabootInstaller failed with code %d" % ret) |
|
1331 |
else: |
|
1332 |
raise InstallStepError("No bootloader installer found") |
|
1333 |
except ImportError: |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1334 |
raise InstallStepError("No bootloader installer found") |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1335 |
|
|
2108.1.30
by Mario Limonciello
Add support to disable/enable the bootloader installation |
1336 |
misc.execute('umount', '-f', self.target + '/proc') |
1337 |
misc.execute('umount', '-f', self.target + '/dev') |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1338 |
|
1339 |
||
|
1671
by Colin Watson
attempt multiple broken package resolution passes while removing packages (more work on Malone #66406) |
1340 |
def broken_packages(self, cache): |
1341 |
brokenpkgs = set() |
|
1342 |
for pkg in cache.keys(): |
|
|
1709
by Colin Watson
* Work around a crash in broken_packages() due to inadequate python-apt |
1343 |
try: |
1344 |
if cache._depcache.IsInstBroken(cache._cache[pkg]): |
|
1345 |
brokenpkgs.add(pkg) |
|
1346 |
except KeyError: |
|
1347 |
# Apparently sometimes the cache goes a bit bonkers ...
|
|
|
1684
by Colin Watson
* Defend a bit more against the apt cache going insane (closes: Malone |
1348 |
continue
|
|
1671
by Colin Watson
attempt multiple broken package resolution passes while removing packages (more work on Malone #66406) |
1349 |
return brokenpkgs |
1350 |
||
|
2137
by Colin Watson
* Install packages passed to apt-install even if they aren't on the live |
1351 |
def do_install(self, to_install, langpacks=False): |
1352 |
if langpacks: |
|
1353 |
self.db.progress('START', 0, 10, 'ubiquity/langpacks/title') |
|
1354 |
else: |
|
1355 |
self.db.progress('START', 0, 10, 'ubiquity/install/title') |
|
1356 |
self.db.progress('INFO', 'ubiquity/install/find_installables') |
|
1357 |
||
1358 |
if langpacks: |
|
1359 |
# ... otherwise we're installing packages that have already been
|
|
1360 |
# recorded
|
|
1361 |
self.record_installed(to_install) |
|
1362 |
||
1363 |
self.db.progress('REGION', 0, 1) |
|
1364 |
fetchprogress = DebconfFetchProgress( |
|
1365 |
self.db, 'ubiquity/install/title', |
|
1366 |
'ubiquity/install/apt_indices_starting', |
|
1367 |
'ubiquity/install/apt_indices') |
|
1368 |
cache = Cache() |
|
1369 |
||
1370 |
if cache._depcache.BrokenCount > 0: |
|
1371 |
syslog.syslog( |
|
1372 |
'not installing additional packages, since there are broken '
|
|
1373 |
'packages: %s' % ', '.join(self.broken_packages(cache))) |
|
1374 |
self.db.progress('STOP') |
|
1375 |
return
|
|
1376 |
||
1377 |
for pkg in to_install: |
|
1378 |
self.mark_install(cache, pkg) |
|
1379 |
||
1380 |
self.db.progress('SET', 1) |
|
1381 |
self.db.progress('REGION', 1, 10) |
|
1382 |
if langpacks: |
|
1383 |
fetchprogress = DebconfFetchProgress( |
|
1384 |
self.db, 'ubiquity/langpacks/title', None, |
|
1385 |
'ubiquity/langpacks/packages') |
|
1386 |
installprogress = DebconfInstallProgress( |
|
1387 |
self.db, 'ubiquity/langpacks/title', |
|
1388 |
'ubiquity/install/apt_info') |
|
1389 |
else: |
|
1390 |
fetchprogress = DebconfFetchProgress( |
|
1391 |
self.db, 'ubiquity/install/title', None, |
|
1392 |
'ubiquity/install/fetch_remove') |
|
1393 |
installprogress = DebconfInstallProgress( |
|
1394 |
self.db, 'ubiquity/install/title', |
|
1395 |
'ubiquity/install/apt_info', |
|
1396 |
'ubiquity/install/apt_error_install') |
|
1397 |
self.chroot_setup() |
|
1398 |
commit_error = None |
|
1399 |
try: |
|
1400 |
try: |
|
1401 |
if not cache.commit(fetchprogress, installprogress): |
|
1402 |
fetchprogress.stop() |
|
1403 |
installprogress.finishUpdate() |
|
1404 |
self.db.progress('STOP') |
|
1405 |
return
|
|
1406 |
except IOError, e: |
|
1407 |
for line in str(e).split('\n'): |
|
1408 |
syslog.syslog(syslog.LOG_ERR, line) |
|
1409 |
commit_error = str(e) |
|
1410 |
except SystemError, e: |
|
1411 |
for line in str(e).split('\n'): |
|
1412 |
syslog.syslog(syslog.LOG_ERR, line) |
|
1413 |
commit_error = str(e) |
|
1414 |
finally: |
|
1415 |
self.chroot_cleanup() |
|
1416 |
self.db.progress('SET', 10) |
|
1417 |
||
1418 |
cache.open(None) |
|
1419 |
if commit_error or cache._depcache.BrokenCount > 0: |
|
1420 |
if commit_error is None: |
|
1421 |
commit_error = '' |
|
1422 |
brokenpkgs = self.broken_packages(cache) |
|
1423 |
syslog.syslog('broken packages after installation: ' |
|
1424 |
'%s' % ', '.join(brokenpkgs)) |
|
1425 |
self.db.subst('ubiquity/install/broken_install', 'ERROR', |
|
1426 |
commit_error) |
|
1427 |
self.db.subst('ubiquity/install/broken_install', 'PACKAGES', |
|
1428 |
', '.join(brokenpkgs)) |
|
1429 |
self.db.input('critical', 'ubiquity/install/broken_install') |
|
1430 |
self.db.go() |
|
1431 |
||
1432 |
self.db.progress('STOP') |
|
1433 |
||
1434 |
||
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1435 |
def do_remove(self, to_remove, recursive=False): |
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
1436 |
self.db.progress('START', 0, 5, 'ubiquity/install/title') |
1437 |
self.db.progress('INFO', 'ubiquity/install/find_removables') |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1438 |
|
1439 |
fetchprogress = DebconfFetchProgress( |
|
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
1440 |
self.db, 'ubiquity/install/title', |
1441 |
'ubiquity/install/apt_indices_starting', |
|
1442 |
'ubiquity/install/apt_indices') |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1443 |
cache = Cache() |
1444 |
||
|
1989
by Colin Watson
* If installing or removing packages fails, then display a helpful error |
1445 |
if cache._depcache.BrokenCount > 0: |
1446 |
syslog.syslog( |
|
1447 |
'not processing removals, since there are broken packages: '
|
|
1448 |
'%s' % ', '.join(self.broken_packages(cache))) |
|
1449 |
self.db.progress('STOP') |
|
1450 |
return
|
|
1451 |
||
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1452 |
while True: |
1453 |
removed = set() |
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1454 |
for pkg in to_remove: |
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1455 |
cachedpkg = self.get_cache_pkg(cache, pkg) |
1456 |
if cachedpkg is not None and cachedpkg.isInstalled: |
|
1457 |
apt_error = False |
|
1458 |
try: |
|
|
1064
by Colin Watson
* When removing packages that don't belong on the installed system, purge |
1459 |
cachedpkg.markDelete(autoFix=False, purge=True) |
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1460 |
except SystemError: |
1461 |
apt_error = True |
|
1462 |
if apt_error: |
|
1463 |
cachedpkg.markKeep() |
|
1464 |
elif cache._depcache.BrokenCount > 0: |
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1465 |
# If we're recursively removing packages, or if all
|
1466 |
# of the broken packages are in the set of packages
|
|
1467 |
# to remove anyway, then go ahead and try to remove
|
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1468 |
# them too.
|
|
1671
by Colin Watson
attempt multiple broken package resolution passes while removing packages (more work on Malone #66406) |
1469 |
brokenpkgs = self.broken_packages(cache) |
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1470 |
broken_removed = set() |
|
1671
by Colin Watson
attempt multiple broken package resolution passes while removing packages (more work on Malone #66406) |
1471 |
while brokenpkgs and (recursive or |
1472 |
brokenpkgs <= to_remove): |
|
1473 |
broken_removed_inner = set() |
|
|
1666
by Colin Watson
* Fix incorrect loop variable reuse in do_remove (closes: Malone #66406). |
1474 |
for pkg2 in brokenpkgs: |
1475 |
cachedpkg2 = self.get_cache_pkg(cache, pkg2) |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1476 |
if cachedpkg2 is not None: |
|
1671
by Colin Watson
attempt multiple broken package resolution passes while removing packages (more work on Malone #66406) |
1477 |
broken_removed_inner.add(pkg2) |
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1478 |
try: |
|
1064
by Colin Watson
* When removing packages that don't belong on the installed system, purge |
1479 |
cachedpkg2.markDelete(autoFix=False, |
1480 |
purge=True) |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1481 |
except SystemError: |
1482 |
apt_error = True |
|
1483 |
break
|
|
|
1671
by Colin Watson
attempt multiple broken package resolution passes while removing packages (more work on Malone #66406) |
1484 |
broken_removed |= broken_removed_inner |
1485 |
if apt_error or not broken_removed_inner: |
|
1486 |
break
|
|
1487 |
brokenpkgs = self.broken_packages(cache) |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1488 |
if apt_error or cache._depcache.BrokenCount > 0: |
1489 |
# That didn't work. Revert all the removals we
|
|
1490 |
# just tried.
|
|
|
1666
by Colin Watson
* Fix incorrect loop variable reuse in do_remove (closes: Malone #66406). |
1491 |
for pkg2 in broken_removed: |
1492 |
self.get_cache_pkg(cache, pkg2).markKeep() |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1493 |
cachedpkg.markKeep() |
1494 |
else: |
|
1495 |
removed.add(pkg) |
|
1496 |
removed |= broken_removed |
|
1497 |
else: |
|
1498 |
removed.add(pkg) |
|
1499 |
assert cache._depcache.BrokenCount == 0 |
|
|
1671
by Colin Watson
attempt multiple broken package resolution passes while removing packages (more work on Malone #66406) |
1500 |
if not removed: |
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1501 |
break
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1502 |
to_remove -= removed |
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1503 |
|
1504 |
self.db.progress('SET', 1) |
|
1505 |
self.db.progress('REGION', 1, 5) |
|
1506 |
fetchprogress = DebconfFetchProgress( |
|
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
1507 |
self.db, 'ubiquity/install/title', None, |
1508 |
'ubiquity/install/fetch_remove') |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1509 |
installprogress = DebconfInstallProgress( |
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
1510 |
self.db, 'ubiquity/install/title', 'ubiquity/install/apt_info', |
1511 |
'ubiquity/install/apt_error_remove') |
|
|
1968
by Colin Watson
* Install dummy policy-rc.d and start-stop-daemon while doing anything |
1512 |
self.chroot_setup() |
|
1989
by Colin Watson
* If installing or removing packages fails, then display a helpful error |
1513 |
commit_error = None |
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1514 |
try: |
|
1968
by Colin Watson
* Install dummy policy-rc.d and start-stop-daemon while doing anything |
1515 |
try: |
1516 |
if not cache.commit(fetchprogress, installprogress): |
|
1517 |
fetchprogress.stop() |
|
1518 |
installprogress.finishUpdate() |
|
1519 |
self.db.progress('STOP') |
|
1520 |
return
|
|
1521 |
except SystemError, e: |
|
1522 |
for line in str(e).split('\n'): |
|
1523 |
syslog.syslog(syslog.LOG_ERR, line) |
|
|
1989
by Colin Watson
* If installing or removing packages fails, then display a helpful error |
1524 |
commit_error = str(e) |
|
1968
by Colin Watson
* Install dummy policy-rc.d and start-stop-daemon while doing anything |
1525 |
finally: |
1526 |
self.chroot_cleanup() |
|
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1527 |
self.db.progress('SET', 5) |
1528 |
||
|
1989
by Colin Watson
* If installing or removing packages fails, then display a helpful error |
1529 |
cache.open(None) |
1530 |
if commit_error or cache._depcache.BrokenCount > 0: |
|
1531 |
if commit_error is None: |
|
1532 |
commit_error = '' |
|
1533 |
brokenpkgs = self.broken_packages(cache) |
|
1534 |
syslog.syslog('broken packages after removal: ' |
|
1535 |
'%s' % ', '.join(brokenpkgs)) |
|
1536 |
self.db.subst('ubiquity/install/broken_remove', 'ERROR', |
|
1537 |
commit_error) |
|
1538 |
self.db.subst('ubiquity/install/broken_remove', 'PACKAGES', |
|
1539 |
', '.join(brokenpkgs)) |
|
1540 |
self.db.input('critical', 'ubiquity/install/broken_remove') |
|
1541 |
self.db.go() |
|
1542 |
||
|
846
by Colin Watson
* Remove packages specific to the live CD after installation (relies on |
1543 |
self.db.progress('STOP') |
1544 |
||
1545 |
||
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1546 |
def remove_unusable_kernels(self): |
1547 |
"""Remove unusable kernels; keeping them may cause us to be unable
|
|
1548 |
to boot."""
|
|
1549 |
||
|
1674
by Colin Watson
* Remove kernels before running update-initramfs so that we update the |
1550 |
self.db.progress('START', 0, 5, 'ubiquity/install/title') |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1551 |
|
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
1552 |
self.db.progress('INFO', 'ubiquity/install/find_removables') |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1553 |
|
1554 |
# Check for kernel packages to remove.
|
|
1555 |
dbfilter = check_kernels.CheckKernels(None) |
|
1556 |
dbfilter.run_command(auto_process=True) |
|
1557 |
||
|
1675
by Colin Watson
revert remove_kernels -> self.remove_kernels change, no longer necessary |
1558 |
remove_kernels = set() |
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
1559 |
if os.path.exists("/var/lib/ubiquity/remove-kernels"): |
|
1778
by Colin Watson
fix filehandle leaks |
1560 |
remove_kernels_file = open("/var/lib/ubiquity/remove-kernels") |
1561 |
for line in remove_kernels_file: |
|
|
1675
by Colin Watson
revert remove_kernels -> self.remove_kernels change, no longer necessary |
1562 |
remove_kernels.add(line.strip()) |
|
1778
by Colin Watson
fix filehandle leaks |
1563 |
remove_kernels_file.close() |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1564 |
|
|
1675
by Colin Watson
revert remove_kernels -> self.remove_kernels change, no longer necessary |
1565 |
if len(remove_kernels) == 0: |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1566 |
self.db.progress('STOP') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1567 |
return
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1568 |
|
1569 |
self.db.progress('SET', 1) |
|
1570 |
self.db.progress('REGION', 1, 5) |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1571 |
try: |
|
1675
by Colin Watson
revert remove_kernels -> self.remove_kernels change, no longer necessary |
1572 |
self.do_remove(remove_kernels, recursive=True) |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1573 |
except: |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1574 |
self.db.progress('STOP') |
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1575 |
raise
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1576 |
self.db.progress('SET', 5) |
1577 |
self.db.progress('STOP') |
|
1578 |
||
1579 |
||
|
2137
by Colin Watson
* Install packages passed to apt-install even if they aren't on the live |
1580 |
def install_extras(self): |
1581 |
"""Try to install additional packages requested by installer
|
|
1582 |
components."""
|
|
1583 |
||
1584 |
# We only ever install these packages from the CD.
|
|
1585 |
sources_list = os.path.join(self.target, 'etc/apt/sources.list') |
|
1586 |
os.rename(sources_list, "%s.apt-setup" % sources_list) |
|
1587 |
old_sources = open("%s.apt-setup" % sources_list) |
|
1588 |
new_sources = open(sources_list, 'w') |
|
1589 |
found_cdrom = False |
|
1590 |
for line in old_sources: |
|
1591 |
if 'cdrom:' in line: |
|
1592 |
print >>new_sources, line, |
|
1593 |
found_cdrom = True |
|
1594 |
new_sources.close() |
|
1595 |
old_sources.close() |
|
1596 |
if not found_cdrom: |
|
1597 |
os.rename("%s.apt-setup" % sources_list, sources_list) |
|
1598 |
||
1599 |
self.do_install(self.query_recorded_installed()) |
|
1600 |
||
1601 |
if found_cdrom: |
|
1602 |
os.rename("%s.apt-setup" % sources_list, sources_list) |
|
1603 |
||
|
2173
by Colin Watson
* Reimplement more of oem-config-udeb (ugh): disable the hwdb-client |
1604 |
# TODO cjwatson 2007-08-09: python reimplementation of
|
1605 |
# oem-config/finish-install.d/07oem-config-user. This really needs
|
|
1606 |
# to die in a great big chemical fire and call the same shell script
|
|
1607 |
# instead.
|
|
|
2172
by Colin Watson
* Move oem-config post-user-creation hacks to the end of install_extras, |
1608 |
try: |
1609 |
if self.db.get('oem-config/enable') == 'true': |
|
1610 |
if os.path.isdir(os.path.join(self.target, 'home/oem')): |
|
|
2173
by Colin Watson
* Reimplement more of oem-config-udeb (ugh): disable the hwdb-client |
1611 |
open(os.path.join(self.target, 'home/oem/.hwdb'), |
1612 |
'w').close() |
|
1613 |
||
|
2172
by Colin Watson
* Move oem-config post-user-creation hacks to the end of install_extras, |
1614 |
for desktop_file in ( |
1615 |
'usr/share/applications/oem-config-prepare-gtk.desktop', |
|
1616 |
'usr/share/applications/kde/oem-config-prepare-kde.desktop'): |
|
1617 |
if os.path.exists(os.path.join(self.target, |
|
1618 |
desktop_file)): |
|
1619 |
desktop_base = os.path.basename(desktop_file) |
|
1620 |
self.chrex('install', '-D', |
|
1621 |
'-o', 'oem', '-g', 'oem', |
|
1622 |
'/%s' % desktop_file, |
|
1623 |
'/home/oem/Desktop/%s' % desktop_base) |
|
1624 |
break
|
|
|
2173
by Colin Watson
* Reimplement more of oem-config-udeb (ugh): disable the hwdb-client |
1625 |
|
1626 |
# Some serious horribleness is needed here to handle absolute
|
|
1627 |
# symlinks.
|
|
1628 |
for name in ('gdm-cdd.conf', 'gdm.conf'): |
|
1629 |
gdm_conf = osextras.realpath_root( |
|
1630 |
self.target, os.path.join('/etc/gdm', name)) |
|
1631 |
if os.path.isfile(gdm_conf): |
|
|
2326
by Colin Watson
* Shell out to sed for now rather than using flaky, complicated, and above |
1632 |
self.chrex('sed', '-i.oem', |
1633 |
'-e', 's/^AutomaticLoginEnable=.*$/AutomaticLoginEnable=true/', |
|
1634 |
'-e', 's/^AutomaticLogin=.*$/AutomaticLogin=oem/', |
|
1635 |
'-e', 's/^TimedLoginEnable=.*$/TimedLoginEnable=true/', |
|
1636 |
'-e', 's/^TimedLogin=.*$/TimedLogin=oem/', |
|
1637 |
'-e', 's/^TimedLoginDelay=.*$/TimedLoginDelay=10/', |
|
1638 |
os.path.join('/etc/gdm', name)); |
|
|
2173
by Colin Watson
* Reimplement more of oem-config-udeb (ugh): disable the hwdb-client |
1639 |
break
|
1640 |
||
1641 |
kdmrc = os.path.join(self.target, 'etc/kde3/kdm/kdmrc') |
|
1642 |
if os.path.isfile(kdmrc): |
|
|
2326
by Colin Watson
* Shell out to sed for now rather than using flaky, complicated, and above |
1643 |
misc.execute('sed', '-i.oem', '-r', |
1644 |
'-e', 's/^#?AutoLoginEnable=.*$/AutoLoginEnable=true/', |
|
1645 |
'-e', 's/^#?AutoLoginUser=.*$/AutoLoginUser=oem/', |
|
1646 |
'-e', 's/^#?AutoReLogin=.*$/AutoReLogin=true/', |
|
1647 |
kdmrc) |
|
|
2173
by Colin Watson
* Reimplement more of oem-config-udeb (ugh): disable the hwdb-client |
1648 |
|
1649 |
if osextras.find_on_path_root(self.target, 'kpersonalizer'): |
|
1650 |
kpersonalizerrc = os.path.join(self.target, |
|
1651 |
'etc/kde3/kpersonalizerrc') |
|
1652 |
if not os.path.isfile(kpersonalizerrc): |
|
1653 |
kpersonalizerrc_file = open(kpersonalizerrc, 'w') |
|
1654 |
print >>kpersonalizerrc_file, '[General]' |
|
1655 |
print >>kpersonalizerrc_file, 'FirstLogin=false' |
|
1656 |
kpersonalizerrc_file.close() |
|
1657 |
open('%s.created-by-oem', 'w').close() |
|
|
2172
by Colin Watson
* Move oem-config post-user-creation hacks to the end of install_extras, |
1658 |
except debconf.DebconfError: |
1659 |
pass
|
|
1660 |
||
|
2137
by Colin Watson
* Install packages passed to apt-install even if they aren't on the live |
1661 |
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1662 |
def remove_extras(self): |
1663 |
"""Try to remove packages that are needed on the live CD but not on
|
|
1664 |
the installed system."""
|
|
1665 |
||
1666 |
# Looking through files for packages to remove is pretty quick, so
|
|
1667 |
# don't bother with a progress bar for that.
|
|
1668 |
||
1669 |
# Check for packages specific to the live CD.
|
|
1670 |
if (os.path.exists("/cdrom/casper/filesystem.manifest-desktop") and |
|
1671 |
os.path.exists("/cdrom/casper/filesystem.manifest")): |
|
1672 |
desktop_packages = set() |
|
|
1778
by Colin Watson
fix filehandle leaks |
1673 |
manifest = open("/cdrom/casper/filesystem.manifest-desktop") |
1674 |
for line in manifest: |
|
|
1173
by Colin Watson
* Ignore comments and blank lines in manifest files, so that we can put |
1675 |
if line.strip() != '' and not line.startswith('#'): |
1676 |
desktop_packages.add(line.split()[0]) |
|
|
1778
by Colin Watson
fix filehandle leaks |
1677 |
manifest.close() |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1678 |
live_packages = set() |
|
1778
by Colin Watson
fix filehandle leaks |
1679 |
manifest = open("/cdrom/casper/filesystem.manifest") |
1680 |
for line in manifest: |
|
|
1173
by Colin Watson
* Ignore comments and blank lines in manifest files, so that we can put |
1681 |
if line.strip() != '' and not line.startswith('#'): |
1682 |
live_packages.add(line.split()[0]) |
|
|
1778
by Colin Watson
fix filehandle leaks |
1683 |
manifest.close() |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1684 |
difference = live_packages - desktop_packages |
1685 |
else: |
|
1686 |
difference = set() |
|
1687 |
||
1688 |
# Keep packages we explicitly installed.
|
|
|
2135
by Colin Watson
factor out reading of apt-installed file |
1689 |
difference -= self.query_recorded_installed() |
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1690 |
|
1691 |
if len(difference) == 0: |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1692 |
return
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1693 |
|
|
1349
by Colin Watson
* Ignore failures while removing extra packages from installed system |
1694 |
# Don't worry about failures removing packages; it will be easier
|
1695 |
# for the user to sort them out with a graphical package manager (or
|
|
1696 |
# whatever) after installation than it will be to try to deal with
|
|
1697 |
# them automatically here.
|
|
1698 |
self.do_remove(difference) |
|
|
1065
by Colin Watson
* Remove kernels that aren't appropriate for the current system, using |
1699 |
|
1700 |
||
|
1166
by Colin Watson
* Write out /target/etc/apt/apt.conf.d/00IgnoreTimeConflict for the |
1701 |
def cleanup(self): |
1702 |
"""Miscellaneous cleanup tasks."""
|
|
|
2134
by Colin Watson
* Replicate the apt configuration done by base-installer (trust CD-ROMs, |
1703 |
|
1704 |
misc.execute('umount', os.path.join(self.target, 'cdrom')) |
|
1705 |
||
1706 |
for apt_conf in ('00NoMountCDROM', '00IgnoreTimeConflict', |
|
1707 |
'00AllowUnauthenticated'): |
|
1708 |
try: |
|
1709 |
os.unlink(os.path.join( |
|
1710 |
self.target, 'etc/apt/apt.conf.d', apt_conf)) |
|
1711 |
except: |
|
1712 |
pass
|
|
1713 |
||
|
1523
by Colin Watson
* Add a ubiquity/install/filesystem-images template, which can be |
1714 |
if self.source == '/var/lib/ubiquity/source': |
1715 |
self.umount_source() |
|
|
1166
by Colin Watson
* Write out /target/etc/apt/apt.conf.d/00IgnoreTimeConflict for the |
1716 |
|
1717 |
||
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1718 |
def chrex(self, *args): |
1719 |
"""executes commands on chroot system (provided by *args)."""
|
|
|
2066
by Colin Watson
more ex -> execute renaming |
1720 |
return misc.execute('chroot', self.target, *args) |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1721 |
|
1722 |
||
1723 |
def copy_debconf(self, package): |
|
1724 |
"""setting debconf database into installed system."""
|
|
1725 |
||
1726 |
# TODO cjwatson 2006-02-25: unusable here now because we have a
|
|
1727 |
# running debconf frontend that's locked the database; fortunately
|
|
1728 |
# this isn't critical. We still need to think about how to handle
|
|
1729 |
# preseeding in general, though.
|
|
1730 |
targetdb = os.path.join(self.target, 'var/cache/debconf/config.dat') |
|
1731 |
||
|
2066
by Colin Watson
more ex -> execute renaming |
1732 |
misc.execute('debconf-copydb', 'configdb', 'targetdb', '-p', |
1733 |
'^%s/' % package, '--config=Name:targetdb', |
|
1734 |
'--config=Driver:File','--config=Filename:' + targetdb) |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1735 |
|
1736 |
||
|
840
by Colin Watson
* Various pychecker-induced cleanups. |
1737 |
def set_debconf(self, question, value): |
|
1499
by Colin Watson
use log-output to spawn external processes so that their output goes to syslog |
1738 |
dccomm = subprocess.Popen(['log-output', '-t', 'ubiquity', |
1739 |
'--pass-stdout', |
|
1740 |
'chroot', self.target, |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1741 |
'debconf-communicate', |
|
1121
by Colin Watson
* Rename from espresso to ubiquity, to better suggest an association with |
1742 |
'-fnoninteractive', 'ubiquity'], |
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1743 |
stdin=subprocess.PIPE, |
1744 |
stdout=subprocess.PIPE, close_fds=True) |
|
|
2059
by Colin Watson
* When changing values of debconf questions in /target, make sure to shut |
1745 |
try: |
1746 |
dc = debconf.Debconf(read=dccomm.stdout, write=dccomm.stdin) |
|
1747 |
dc.set(question, value) |
|
1748 |
dc.fset(question, 'seen', 'true') |
|
1749 |
finally: |
|
1750 |
dccomm.stdin.close() |
|
1751 |
dccomm.wait() |
|
|
828
by Colin Watson
* The Copy/Config split is more inconvenient than useful, so merge the two |
1752 |
|
1753 |
||
1754 |
def reconfigure(self, package): |
|
1755 |
"""executes a dpkg-reconfigure into installed system to each
|
|
1756 |
package which provided by args."""
|
|
1757 |
||
1758 |
self.chrex('dpkg-reconfigure', '-fnoninteractive', package) |
|
1759 |
||
1760 |
||
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
1761 |
if __name__ == '__main__': |
|
1380
by Colin Watson
* Save tracebacks from install.py and slurp them back into the traceback |
1762 |
if not os.path.exists('/var/lib/ubiquity'): |
1763 |
os.makedirs('/var/lib/ubiquity') |
|
1764 |
if os.path.exists('/var/lib/ubiquity/install.trace'): |
|
1765 |
os.unlink('/var/lib/ubiquity/install.trace') |
|
1766 |
||
1767 |
install = Install() |
|
1768 |
sys.excepthook = install.excepthook |
|
|
1398
by Colin Watson
* Use exceptions to communicate all failures in install.py, so that we get |
1769 |
install.run() |
1770 |
sys.exit(0) |
|
|
801
by Colin Watson
* Rework copy and configuration progress bars using debconffilter. This |
1771 |
|
|
715.1.1
by Tollef Fog Heen
fix severe python style issues |
1772 |
# vim:ai:et:sts=4:tw=80:sw=4:
|