1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import sys
20 from collections import defaultdict
21
22 import apt_pkg
23
24 import daklib.archive
25 import daklib.config
26 import daklib.dbconn
27 import daklib.import_repository
28 import daklib.utils
29
30
31
32
33
35 print(
36 """
37 dak import-repository
38 --keyring=/usr/share/keyrings/debian-archive-keyring.gpg
39 [--key=${fingerprint}]
40 [--architectures=a,b,c (default: architectures in origin suite)]
41 [--components=main,contrib (default: components in origin suite)]
42 [--target-suite=${suite} (default: origin suite name)]
43 [--add-overrides]
44 [--max-packages=${n} (import at maximum ${n} packages, default: no limit)]
45 http://httpredir.debian.org/debian unstable
46
47 Things to think about:
48 - Import Built-Using sources
49 - all / only referenced
50 - Remove old packages:
51 - by-source: remove source X_v, if no X exists upstream
52 - by-version: remove source X_v, if no X_v exists upstream
53 (X denotes package name, v version, X_v package at a specific version)
54 - Import all or only newest?
55 - Expire binary packages?
56 """
57 )
58 sys.exit(status)
59
60
61 -def entry_is_newer(entry, packages):
62 version = entry["Version"]
63 for p in packages[entry["Package"]]:
64 if apt_pkg.version_compare(version, p.version) <= 0:
65 return False
66 return True
67
68
69 -def entry_in_packages(entry, packages):
70 return entry["Package"] in packages
71
72
74 sources = defaultdict(list)
75 for s in suite.sources:
76 sources[s.source].append(s)
77
78 packages = defaultdict(list)
79 for b in suite.binaries:
80 packages[b.package].append(b)
81
82 return sources, packages
83
84
85 -def import_sources(
86 base,
87 sources,
88 transaction,
89 target_suite,
90 component,
91 target_sources,
92 extra_sources,
93 extra_sources_comp,
94 max_packages=None,
95 ):
96 n = 0
97 for entry in sources:
98 if max_packages is not None and n > max_packages:
99 break
100 if entry.get("Extra-Source-Only", "no") == "yes":
101
102 key = (entry["Package"], entry["Version"])
103 extra_sources[key] = entry
104 extra_sources_comp[key].add(c)
105 continue
106 if not entry_in_packages(entry, target_sources) or entry_is_newer(
107 entry, target_sources
108 ):
109 print("Importing {0}={1}".format(entry["Package"], entry["Version"]))
110 daklib.import_repository.import_source_to_suite(
111 base, entry, transaction, target_suite, component
112 )
113 n += 1
114 return n
115
116
117 -def import_built_using(
118 base,
119 source,
120 version,
121 transaction,
122 target_suite,
123 component,
124 extra_sources,
125 extra_sources_comp,
126 ):
127 if not daklib.import_repository.source_in_archive(
128 bu_source, bu_version, target_suite.archive
129 ):
130 print("Importing extra source {0}={1}".format(bu_source, bu_version))
131 key = (bu_source, bu_version)
132 extra_entry = extra_sources.get(key)
133 if extra_entry is None:
134 raise Exception(
135 "Extra source {0}={1} referenced by {2}={3} ({4}) not found in source suite.".format(
136 bu_source,
137 bu_version,
138 entry["Package"],
139 entry["Version"],
140 architecture,
141 )
142 )
143
144 if c in components:
145 extra_component = component
146 else:
147
148 raise Exception("Not implemented.")
149 daklib.import_repository.import_source_to_suite(
150 base, extra_entry, transaction, target_suite, extra_component
151 )
152
153
154 -def import_packages(
155 base,
156 packages,
157 transaction,
158 target_suite,
159 component,
160 architecture,
161 target_binaries,
162 extra_sources,
163 extra_sources_comp,
164 max_packages=None,
165 ):
166 n = 0
167 for entry in packages:
168 if max_packages is not None and n > max_packages:
169 break
170 if not entry_in_packages(entry, target_binaries) or entry_is_newer(
171 entry, target_binaries
172 ):
173 print(
174 "Importing {0}={1} ({2})".format(
175 entry["Package"], entry["Version"], architecture
176 )
177 )
178
179 for bu_source, bu_version in daklib.utils.parse_built_using(entry):
180 import_built_using(
181 base,
182 bu_source,
183 bu_version,
184 transaction,
185 target_suite,
186 component,
187 extra_sources,
188 extra_sources_comp,
189 )
190
191 daklib.import_repository.import_package_to_suite(
192 base, entry, transaction, target_suite, component
193 )
194 n += 1
195 return n
196
197
198 -def main(argv=None):
199 if argv is None:
200 argv = sys.argv
201
202 arguments = [
203 ("h", "help", "Import-Repository::Help"),
204 ("k", "keyring", "Import-Repository::Keyring", "HasArg"),
205 ("K", "key", "Import-Repository::Key", "HasArg"),
206 ("a", "architectures", "Import-Repository::Architectures", "HasArg"),
207 ("c", "components", "Import-Repository::Components", "HasArg"),
208 ("t", "target-suite", "Import-Repository::Target-Suite", "HasArg"),
209 ("A", "add-overrides", "Import-Repository::AddOverrides"),
210 ("n", "max-packages", "Import-Repository::MaxPackages", "HasArg"),
211 ]
212
213 cnf = daklib.config.Config()
214 argv = apt_pkg.parse_commandline(cnf.Cnf, arguments, argv)
215 options = cnf.subtree("Import-Repository")
216
217 if "Help" in options or len(argv) < 2:
218 usage(0)
219
220 keyring = options.find("Keyring") or None
221 if keyring is None:
222 print("Error: No keyring specified")
223 print()
224
225 if "Key" in options:
226 raise Exception("Not implemented.")
227
228 if "AddOverrides" in options:
229 raise Exception("Not implemented.")
230
231 if "MaxPackages" in options:
232 max_packages = int(options["MaxPackages"])
233 else:
234 max_packages = None
235
236 base, suite = argv[0:2]
237
238 target_suite_name = options.find("Target-Suite") or suite
239
240 print(
241 "Importing packages from {0}/dists/{1} to {2}".format(
242 base, suite, target_suite_name
243 )
244 )
245 with daklib.archive.ArchiveTransaction() as transaction:
246 target_suite = daklib.dbconn.get_suite(target_suite_name, transaction.session)
247 if target_suite is None:
248 daklib.utils.fubar(
249 "Target suite '{0}' is unknown.".format(target_suite_name)
250 )
251
252 release = daklib.import_repository.obtain_release(base, suite, keyring)
253 target_sources, target_binaries = get_packages_in_suite(target_suite)
254
255 if "Architectures" in options:
256 architectures = options["Architectures"].split(",")
257 else:
258 architectures = ["all"] + release.architectures()
259
260 if "Components" in options:
261 components = options["Components"].split(",")
262 else:
263 components = release.components()
264
265
266
267 n = 0
268
269
270
271
272 extra_sources = dict()
273 extra_sources_comp = defaultdict(set)
274
275 for c in components:
276 component = daklib.dbconn.get_component(c, transaction.session)
277 print("Processing {0}/source...".format(c))
278 sources = release.sources(c)
279 imported = import_sources(
280 base,
281 sources,
282 transaction,
283 target_suite,
284 component,
285 target_sources,
286 extra_sources,
287 extra_sources_comp,
288 max_packages,
289 )
290 print(" imported {0} source packages".format(imported))
291 n += imported
292 if max_packages is not None:
293 max_packages -= n
294
295 for c in components:
296 component = daklib.dbconn.get_component(c, transaction.session)
297 for architecture in architectures:
298 print("Processing {0}/{1}...".format(c, architecture))
299 packages = release.packages(c, architecture)
300 imported = import_packages(
301 base,
302 packages,
303 transaction,
304 target_suite,
305 component,
306 architecture,
307 target_binaries,
308 extra_sources,
309 extra_sources_comp,
310 max_packages,
311 )
312 print(" imported {0} binary packages".format(imported))
313 n += imported
314 if max_packages is not None:
315 max_packages -= n
316
317 transaction.rollback()
318
319
320 if __name__ == "__main__":
321 main()
322