-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdpkg-origins
executable file
·122 lines (94 loc) · 3.62 KB
/
dpkg-origins
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python
"""
(c) 2008 Cory Dodt
Released under the terms of the MIT license.
dpkg-origins v0.9
Print out every system package, grouped by origin, for system recovery.
Requires 'python-apt' and 'python-twisted' packages.
dpkg-origins > selections.txt
To recover the system packages, take the output (which you have previously
saved off or emailed to yourself) and do:
cat selections.txt | sudo dpkg --set-selections && sudo apt-get -u dselect-upgrade
"""
import warnings
warnings.simplefilter('ignore', FutureWarning)
import sys, os
import subprocess
import itertools
from twisted.python import usage
import apt
import apt_pkg
apt_pkg.init()
class Options(usage.Options):
synopsis = "dpkg-origins | mail ..."
def postOptions(self):
origins = sorted(self.packageOrigins())
sourceTypes = [((lambda s: s==''), 'blank'),
((lambda s: 'ubuntu' in s), 'ubuntu'),
((lambda s: 'ubuntu' not in s), 'thirdParty')
]
def getType(site):
for fn, key in sourceTypes:
if fn(site): return key
assert 0, "This site doesn't match any known type"
for key, grouper in itertools.groupby(origins, lambda o: o[0]):
type = getType(key)
printer = getattr(self, 'printGroup_%s' % type)
printer(grouper)
print ''
def printGroup_blank(self, grouper):
print '#' * 78
print '## No apt archive - packages were installed manually from .deb'
print '## or other dodgy source (including preinstalled by ISP).'
print '## Note - this list may contain packages from third-party archives if the'
print '## PPA is configured incorrectly.'
print ''
for package in grouper:
print "# %s == %s" % (package[1], package[2])
def printGroup_thirdParty(self, grouper):
print '#' * 78
print '''## Third-party apt archive packages
## Add the following archives to your sources list, then uncomment all the
## following packages and pipe into dpkg --set-selections'''
print ''
sources = apt_pkg.GetPkgSourceList()
sources.ReadMainList()
for meta in sources.List:
if 'ubuntu.com' not in meta.URI:
print '## deb %s %s main' % (meta.URI, meta.Dist)
print ''
for package in grouper:
print "# %s install" % (package[1],)
def printGroup_ubuntu(self, grouper):
print '#' * 78
print '## Canonical packages'
print '## Pipe the following into dpkg --set-selections'''
print ''
for package in grouper:
print '%s install' % (package[1],)
def packageOrigins(self):
dpkg = subprocess.Popen(r"dpkg-query -W -f'${Status}\t${Package}\t${Version}\n'",
stdout=subprocess.PIPE, shell=True)
cache = apt.Cache()
for n, line in enumerate(dpkg.stdout.readlines()):
status, package, version = line.strip().split('\t')
if not status.startswith('install ok'):
continue
try:
cpkg = cache[package]
origin = cpkg.candidateOrigin[0] # FIXME - is it always the first??
yield (origin.site, package, version)
except KeyError:
yield ("manual", package, version )
def run(argv=None):
if argv is None:
argv = sys.argv
o = Options()
try:
o.parseOptions(argv[1:])
except usage.UsageError, e:
print str(o)
print str(e)
return 1
return 0
if __name__ == '__main__': sys.exit(run())