3
Install all packages with a desktop file in app-install-data
7
from __future__ import print_function
15
# global install blacklist
18
# whitelist regexp to include only certain packages (useful for e.g.
19
# installing only all python packages)
22
class InstallProgress(apt.progress.base.InstallProgress):
23
" Out install progress that can automatically remove broken pkgs "
24
def error(self, pkg, errormsg):
26
# - add failing package to "install_failures.txt" [done]
27
# - remove package from best.txt [done]
28
# FIXME: - remove all rdepends from best.txt
29
# - remove the failed install attempts [done]
30
# * explode if a package can not be removed and let the user cleanup
31
open("install_failures.txt","a").write("%s _:_ %s" % (pkg, errormsg))
33
bad.add(os.path.basename(pkg).split("_")[0])
34
# FIXME: just run apt-cache rdepends $pkg here?
35
# or use apt.Package.candidateDependencies ?
36
# or calculate the set again? <- BEST!
38
new_best = open("best.txt").read().replace(name+"\n","")
39
open("best.txt","w").write(new_best)
40
open("install_blacklist.cfg","a").write("# auto added by install_all.py\n%s\n" % name)
42
def do_install(cache):
47
while current < maxRetries:
48
print("Retry: ", current)
50
res = cache.commit(apt.progress.text.AcquireProgress(),
54
# fetch failed, will be retried
56
print("Retrying to fetch: ", current, e)
58
except SystemError as e:
59
print("Error installing packages! ")
61
print("Install result: ", res)
63
# check for failed packages and remove them
64
if os.path.exists("install_failures.txt"):
65
with open("install_failures.txt") as install_failures:
66
failures = set([os.path.basename(s.split("_:_")[0]).split("_")[0]
67
for s in install_failures])
68
print("failed: ", failures)
69
assert(os.system("dpkg -r %s" % " ".join(failures)) == 0)
70
assert(os.system("dpkg --configure -a") == 0)
71
# remove pos.txt and best.txt to force recalculation
76
def blacklisted(name):
78
if pkg_blacklist is None and os.path.exists("install_blacklist.cfg"):
80
with open("install_blacklist.cfg") as blacklist_file:
81
for line in blacklist_file:
83
if name and not name.startswith("#"):
84
pkg_blacklist.add(name)
85
print("blacklist: ", pkg_blacklist)
87
for b in pkg_blacklist:
92
def reapply(cache, pkgnames):
94
cache[name].mark_install(False)
96
def contains_blacklisted_pkg(cache):
98
if pkg.marked_install and blacklisted(pkg.name):
102
def appinstall_pkgs():
106
import ConfigParser as configparser
108
APPINSTALL_DIR = "/usr/share/app-install/desktop"
110
content = configparser.ConfigParser()
113
# List of sections to skip. This must be a valid regular expression
114
# We must exclude window managers to not kill ourselves
115
for dsk in os.listdir(APPINSTALL_DIR):
116
dskfile = os.path.join(APPINSTALL_DIR, dsk)
117
if not 'desktop' in dsk[-7:]:
120
content.read(dskfile)
121
pkg = content.get('Desktop Entry', 'X-AppInstall-Package')
125
print("Error: unable to parse %s" % dskfile)
130
# ----------------------------------------------------------------
132
#apt_pkg.config.set("Dir::State::status","./empty")
135
#apt_pkg.config.set("Debug::pkgProblemResolver","true")
136
#apt_pkg.config.set("Debug::pkgDepCache::AutoInstall","true")
137
#apt_pkg.config.set("Debug::pkgDpkgPM","true")
139
# Increase the maxsize limits here
141
# this code in apt that splits the argument list if its too long
142
# is problematic, because it may happen that
143
# the argument list is split in a way that A depends on B
144
# and they are in the same "--configure A B" run
145
# - with the split they may now be configured in different
148
apt_pkg.config.set("Dpkg::MaxArgs",str(16*1024))
149
apt_pkg.config.set("Dpkg::MaxArgBytes",str(64*1024))
151
print("*** installings all packages from app-install-data ***")
152
os.environ["DEBIAN_FRONTEND"] = "noninteractive"
153
os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
157
# dapper does not have this yet
158
group = cache.actiongroup()
159
#print([pkg.name for pkg in cache if pkg.is_installed])
161
# see what gives us problems
165
# first install all of main, then the rest
166
comps= ["main","universe"]
169
# reapply checkpoints
170
if os.path.exists("best.txt"):
171
with open("best.txt") as best_file:
172
best = [line.strip() for line in best_file]
176
if os.path.exists("pos.txt"):
177
(comp, i) = open("pos.txt").read().split()
180
sorted_pkgs = appinstall_pkgs()
183
for pkgname in sorted_pkgs[i:]:
184
# skip multiarch packages
191
print("WARNING: No package named %s" % pkg)
193
percent = (float(i)/len(sorted_pkgs))*100.0
194
print("\r%.3f " % percent, end="")
196
# ignore stuff that does not match the whitelist pattern
199
if not re.match(pkg_whitelist, pkg.name):
200
#print("skipping '%s' (not in whitelist)" % pkg.name)
202
print("looking at ", pkg.name)
203
# only work on stuff that has a origin
205
for c in pkg.candidate.origins:
207
if not (pkg.is_installed or blacklisted(pkg.name)):
208
current = set([p.name for p in cache if p.marked_install])
211
except SystemError as e:
212
print("Installing '%s' cause problems: %s" % (pkg.name, e))
215
if contains_blacklisted_pkg(cache):
219
new = set([p.name for p in cache if p.marked_install])
220
#if not pkg.marked_install or len(new) < len(current):
221
if not (pkg.is_installed or pkg.marked_install):
222
print("Can't install: %s" % pkg.name)
223
if len(current-new) > 0:
224
troublemaker.add(pkg.name)
225
print("Installing '%s' caused removals %s" % (pkg.name, current - new))
226
# FIXME: instead of len() use score() and score packages
227
# according to criteria like "in main", "priority" etc
228
if len(new) >= len(best):
230
open("best.txt","w").write("\n".join(best))
231
open("pos.txt","w").write("%s %s" % (comp, i))
233
print("Installing '%s' reduced the set (%s < %s)" % (pkg.name, len(new), len(best)))
238
# make sure that the ubuntu base packages are installed (and a bootloader)
239
print(len(troublemaker))
240
for pkg in ["ubuntu-desktop", "ubuntu-minimal", "ubuntu-standard", "grub-pc"]:
241
cache[pkg].mark_install()
243
# make sure we don't install blacklisted stuff
245
if blacklisted(pkg.name):
249
print("We can install:", len([pkg.name for pkg in cache if pkg.marked_install]))
251
pm = apt_pkg.PackageManager(cache._depcache)
252
fetcher = apt_pkg.Acquire()
253
pm.get_archives(fetcher, cache._list, cache._records)
254
print("Download: ", apt_pkg.size_to_str(fetcher.fetch_needed))
255
print("Total space: ", apt_pkg.size_to_str(cache._depcache.usr_size))
257
# write out file with all pkgs
258
outf = "all_pkgs.cfg"
259
print("writing out file with the selected package names to '%s'" % outf)
261
f.write("\n".join([pkg.name for pkg in cache if pkg.marked_install]))
264
# now do the real install
265
res = do_install(cache)
268
# FIXME: re-exec itself