Status: | Merged |
---|---|
Merged at revision: | 64 |
Proposed branch: | lp:~ev/apt-clone/739489 |
Merge into: | lp:apt-clone |
Diff against target: |
304 lines (+216/-5) 4 files modified
apt_clone.py (+57/-5) tests/data/lucid-sources.list (+53/-0) tests/data/natty-sources.list (+56/-0) tests/test_merge_sources.py (+50/-0) |
To merge this branch: | bzr merge lp:~ev/apt-clone/739489 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Vogt | Pending | ||
Review via email: mp+56574@code.launchpad.net |
Commit message
Description of the change
See bug 739489 for the details.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'apt_clone.py' |
2 | --- apt_clone.py 2011-03-31 11:26:40 +0000 |
3 | +++ apt_clone.py 2011-04-06 14:12:27 +0000 |
4 | @@ -17,6 +17,7 @@ |
5 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
6 | |
7 | import apt |
8 | +from apt.cache import FetchFailedException |
9 | import apt_pkg |
10 | import logging |
11 | import glob |
12 | @@ -69,6 +70,11 @@ |
13 | ret = subprocess.call(["debootstrap", distro, targetdir]) |
14 | return (ret == 0) |
15 | |
16 | + def merge_keys(self, fromkeyfile, intokeyfile): |
17 | + ret = subprocess.call(['apt-key', '--keyring', intokeyfile, |
18 | + 'add', fromkeyfile]) |
19 | + return (ret == 0) |
20 | + |
21 | class AptClone(object): |
22 | """ clone the package selection/installation of a existing system |
23 | using the information that apt provides |
24 | @@ -298,7 +304,12 @@ |
25 | if new_distro: |
26 | self._rewrite_sources_list(target, new_distro) |
27 | cache = self._cache_cls(rootdir=target) |
28 | - cache.update(apt.progress.base.AcquireProgress()) |
29 | + try: |
30 | + cache.update(apt.progress.base.AcquireProgress()) |
31 | + except FetchFailedException: |
32 | + # This cannot be resolved here, but it should not be interpreted as |
33 | + # a fatal error. |
34 | + pass |
35 | cache.open() |
36 | # try to replay cache and see thats missing |
37 | missing = self._restore_package_selection_in_cache(statefile, cache) |
38 | @@ -306,6 +317,9 @@ |
39 | |
40 | def _restore_sources_list(self, statefile, targetdir): |
41 | tar = tarfile.open(statefile) |
42 | + existing = os.path.join(targetdir, "etc", "apt", "sources.list") |
43 | + if os.path.exists(existing): |
44 | + shutil.copy(existing, '%s.apt-clone' % existing) |
45 | tar.extract("./etc/apt/sources.list", targetdir) |
46 | try: |
47 | tar.extract("./etc/apt/sources.list.d", targetdir) |
48 | @@ -313,6 +327,10 @@ |
49 | pass |
50 | |
51 | def _restore_apt_keyring(self, statefile, targetdir): |
52 | + existing = os.path.join(targetdir, "etc", "apt", "trusted.gpg") |
53 | + backup = '%s.apt-clone' % existing |
54 | + if os.path.exists(existing): |
55 | + shutil.copy(existing, backup) |
56 | tar = tarfile.open(statefile) |
57 | try: |
58 | tar.extract("./etc/apt/trusted.gpg", targetdir) |
59 | @@ -322,6 +340,9 @@ |
60 | tar.extract("./etc/apt/trusted.gpg.d", targetdir) |
61 | except KeyError: |
62 | pass |
63 | + if os.path.exists(backup): |
64 | + self.commands.merge_keys(backup, existing) |
65 | + os.remove(backup) |
66 | |
67 | def _restore_package_selection_in_cache(self, statefile, cache): |
68 | # reinstall packages |
69 | @@ -366,7 +387,12 @@ |
70 | def _restore_package_selection(self, statefile, targetdir): |
71 | # create new cache |
72 | cache = self._cache_cls(rootdir=targetdir) |
73 | - cache.update(self.fetch_progress) |
74 | + try: |
75 | + cache.update(self.fetch_progress) |
76 | + except FetchFailedException: |
77 | + # This cannot be resolved here, but it should not be interpreted as |
78 | + # a fatal error. |
79 | + pass |
80 | cache.open() |
81 | self._restore_package_selection_in_cache(statefile, cache) |
82 | # do it |
83 | @@ -386,7 +412,7 @@ |
84 | self.commands.install_debs(debs, targetdir) |
85 | |
86 | def _rewrite_sources_list(self, targetdir, new_distro): |
87 | - from aptsources.sourceslist import SourcesList |
88 | + from aptsources.sourceslist import SourcesList, SourceEntry |
89 | apt_pkg.config.set( |
90 | "Dir::Etc::sourcelist", |
91 | os.path.abspath(os.path.join(targetdir, "etc", "apt", "sources.list"))) |
92 | @@ -394,10 +420,36 @@ |
93 | "Dir::Etc::sourceparts", |
94 | os.path.abspath(os.path.join(targetdir, "etc", "apt", "sources.list.d"))) |
95 | sources = SourcesList() |
96 | + |
97 | for entry in sources.list[:]: |
98 | if entry.invalid or entry.disabled: |
99 | continue |
100 | - entry.dist = new_distro |
101 | + replacement = '' |
102 | + for pocket in ('updates', 'security', 'backports'): |
103 | + if entry.dist.endswith('-%s' % pocket): |
104 | + replacement = '%s-%s' % (new_distro, pocket) |
105 | + break |
106 | + if replacement: |
107 | + entry.dist = replacement |
108 | + else: |
109 | + entry.dist = new_distro |
110 | + |
111 | + existing = os.path.join(targetdir, "etc", "apt", |
112 | + "sources.list.apt-clone") |
113 | + sourcelist = apt_pkg.config.find_file("Dir::Etc::sourcelist") |
114 | + if os.path.exists(existing): |
115 | + with open(existing, 'r') as fp: |
116 | + for line in fp: |
117 | + src = SourceEntry(line, sourcelist) |
118 | + if (src.invalid or src.disabled) or src not in sources: |
119 | + sources.list.append(src) |
120 | + os.remove(existing) |
121 | + |
122 | + for entry in sources.list: |
123 | + if entry.uri.startswith('cdrom:'): |
124 | + # Make sure CD entries come first. |
125 | + sources.list.remove(entry) |
126 | + sources.list.insert(0, entry) |
127 | + entry.disabled = True |
128 | sources.save() |
129 | |
130 | - |
131 | |
132 | === added file 'tests/data/lucid-sources.list' |
133 | --- tests/data/lucid-sources.list 1970-01-01 00:00:00 +0000 |
134 | +++ tests/data/lucid-sources.list 2011-04-06 14:12:27 +0000 |
135 | @@ -0,0 +1,53 @@ |
136 | +#deb cdrom:[Ubuntu 10.04.2 LTS _Lucid Lynx_ - Release i386 (20110211.1)]/ lucid main restricted |
137 | +# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to |
138 | +# newer versions of the distribution. |
139 | + |
140 | +deb http://gb.archive.ubuntu.com/ubuntu/ lucid main restricted |
141 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid main restricted |
142 | + |
143 | +## Major bug fix updates produced after the final release of the |
144 | +## distribution. |
145 | +deb http://gb.archive.ubuntu.com/ubuntu/ lucid-updates main restricted |
146 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid-updates main restricted |
147 | + |
148 | +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
149 | +## team. Also, please note that software in universe WILL NOT receive any |
150 | +## review or updates from the Ubuntu security team. |
151 | +deb http://gb.archive.ubuntu.com/ubuntu/ lucid universe |
152 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid universe |
153 | +deb http://gb.archive.ubuntu.com/ubuntu/ lucid-updates universe |
154 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid-updates universe |
155 | + |
156 | +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
157 | +## team, and may not be under a free licence. Please satisfy yourself as to |
158 | +## your rights to use the software. Also, please note that software in |
159 | +## multiverse WILL NOT receive any review or updates from the Ubuntu |
160 | +## security team. |
161 | +deb http://gb.archive.ubuntu.com/ubuntu/ lucid multiverse |
162 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid multiverse |
163 | +deb http://gb.archive.ubuntu.com/ubuntu/ lucid-updates multiverse |
164 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid-updates multiverse |
165 | + |
166 | +## Uncomment the following two lines to add software from the 'backports' |
167 | +## repository. |
168 | +## N.B. software from this repository may not have been tested as |
169 | +## extensively as that contained in the main release, although it includes |
170 | +## newer versions of some applications which may provide useful features. |
171 | +## Also, please note that software in backports WILL NOT receive any review |
172 | +## or updates from the Ubuntu security team. |
173 | +# deb http://gb.archive.ubuntu.com/ubuntu/ lucid-backports main restricted universe multiverse |
174 | +# deb-src http://gb.archive.ubuntu.com/ubuntu/ lucid-backports main restricted universe multiverse |
175 | + |
176 | +## Uncomment the following two lines to add software from Canonical's |
177 | +## 'partner' repository. |
178 | +## This software is not part of Ubuntu, but is offered by Canonical and the |
179 | +## respective vendors as a service to Ubuntu users. |
180 | +# deb http://archive.canonical.com/ubuntu lucid partner |
181 | +# deb-src http://archive.canonical.com/ubuntu lucid partner |
182 | + |
183 | +deb http://security.ubuntu.com/ubuntu lucid-security main restricted |
184 | +deb-src http://security.ubuntu.com/ubuntu lucid-security main restricted |
185 | +deb http://security.ubuntu.com/ubuntu lucid-security universe |
186 | +deb-src http://security.ubuntu.com/ubuntu lucid-security universe |
187 | +deb http://security.ubuntu.com/ubuntu lucid-security multiverse |
188 | +deb-src http://security.ubuntu.com/ubuntu lucid-security multiverse |
189 | |
190 | === added file 'tests/data/natty-sources.list' |
191 | --- tests/data/natty-sources.list 1970-01-01 00:00:00 +0000 |
192 | +++ tests/data/natty-sources.list 2011-04-06 14:12:27 +0000 |
193 | @@ -0,0 +1,56 @@ |
194 | +deb cdrom:[Ubuntu 11.04 _Natty Narwhal_ - Alpha i386 (20110324)]/ natty main restricted |
195 | + |
196 | +# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to |
197 | +# newer versions of the distribution. |
198 | +deb http://gb.archive.ubuntu.com/ubuntu/ natty main restricted |
199 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ natty main restricted |
200 | + |
201 | +## Major bug fix updates produced after the final release of the |
202 | +## distribution. |
203 | +deb http://gb.archive.ubuntu.com/ubuntu/ natty-updates main restricted |
204 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ natty-updates main restricted |
205 | + |
206 | +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
207 | +## team. Also, please note that software in universe WILL NOT receive any |
208 | +## review or updates from the Ubuntu security team. |
209 | +deb http://gb.archive.ubuntu.com/ubuntu/ natty universe |
210 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ natty universe |
211 | +deb http://gb.archive.ubuntu.com/ubuntu/ natty-updates universe |
212 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ natty-updates universe |
213 | + |
214 | +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
215 | +## team, and may not be under a free licence. Please satisfy yourself as to |
216 | +## your rights to use the software. Also, please note that software in |
217 | +## multiverse WILL NOT receive any review or updates from the Ubuntu |
218 | +## security team. |
219 | +deb http://gb.archive.ubuntu.com/ubuntu/ natty multiverse |
220 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ natty multiverse |
221 | +deb http://gb.archive.ubuntu.com/ubuntu/ natty-updates multiverse |
222 | +deb-src http://gb.archive.ubuntu.com/ubuntu/ natty-updates multiverse |
223 | + |
224 | +## Uncomment the following two lines to add software from the 'backports' |
225 | +## repository. |
226 | +## N.B. software from this repository may not have been tested as |
227 | +## extensively as that contained in the main release, although it includes |
228 | +## newer versions of some applications which may provide useful features. |
229 | +## Also, please note that software in backports WILL NOT receive any review |
230 | +## or updates from the Ubuntu security team. |
231 | +# deb http://gb.archive.ubuntu.com/ubuntu/ natty-backports main restricted universe multiverse |
232 | +# deb-src http://gb.archive.ubuntu.com/ubuntu/ natty-backports main restricted universe multiverse |
233 | + |
234 | +deb http://security.ubuntu.com/ubuntu natty-security main restricted |
235 | +deb-src http://security.ubuntu.com/ubuntu natty-security main restricted |
236 | +deb http://security.ubuntu.com/ubuntu natty-security universe |
237 | +deb-src http://security.ubuntu.com/ubuntu natty-security universe |
238 | +deb http://security.ubuntu.com/ubuntu natty-security multiverse |
239 | +deb-src http://security.ubuntu.com/ubuntu natty-security multiverse |
240 | + |
241 | +## This software is not part of Ubuntu, but is offered by Canonical and the |
242 | +## respective vendors as a service to Ubuntu users. |
243 | +deb http://archive.canonical.com/ubuntu natty partner |
244 | +deb-src http://archive.canonical.com/ubuntu natty partner |
245 | + |
246 | +## This software is not part of Ubuntu, but is offered by third-party |
247 | +## developers who want to ship their latest software. |
248 | +deb http://extras.ubuntu.com/ubuntu natty main |
249 | +deb-src http://extras.ubuntu.com/ubuntu natty main |
250 | |
251 | === added file 'tests/test_merge_sources.py' |
252 | --- tests/test_merge_sources.py 1970-01-01 00:00:00 +0000 |
253 | +++ tests/test_merge_sources.py 2011-04-06 14:12:27 +0000 |
254 | @@ -0,0 +1,50 @@ |
255 | +import unittest |
256 | +import tempfile |
257 | +import os |
258 | +import shutil |
259 | +import sys |
260 | + |
261 | +sys.path.insert(0, "..") |
262 | +from apt_clone import AptClone |
263 | + |
264 | +class TestMergeSources(unittest.TestCase): |
265 | + def test_merge_sources(self): |
266 | + clone = AptClone() |
267 | + tmpdir = tempfile.mkdtemp() |
268 | + self.addCleanup(shutil.rmtree, tmpdir) |
269 | + sources_list = os.path.join(tmpdir, "etc", "apt", "sources.list") |
270 | + os.makedirs(os.path.dirname(sources_list)) |
271 | + shutil.copy('data/lucid-sources.list', sources_list) |
272 | + backup = os.path.join(tmpdir, "etc", "apt", "sources.list.apt-clone") |
273 | + shutil.copy('data/natty-sources.list', backup) |
274 | + clone._rewrite_sources_list(tmpdir, 'natty') |
275 | + with open(sources_list) as fp: |
276 | + # Tally the occurances of every source line. |
277 | + from collections import defaultdict |
278 | + tally = defaultdict(int) |
279 | + for line in fp: |
280 | + if line != '\n' and not line.startswith('#'): |
281 | + tally[line] += 1 |
282 | + # There should not be any duplicate source lines. |
283 | + for line, count in tally.iteritems(): |
284 | + self.failUnless(count == 1, '"%s" occurred %d times.' |
285 | + % (line, count)) |
286 | + |
287 | + # Check for extras, others... |
288 | + l = (('partner', |
289 | + 'deb http://archive.canonical.com/ubuntu natty partner\n'), |
290 | + ('extras', |
291 | + 'deb http://extras.ubuntu.com/ubuntu natty main\n'), |
292 | + ('main', |
293 | + 'deb http://gb.archive.ubuntu.com/ubuntu/ natty main restricted\n')) |
294 | + for pocket, match in l: |
295 | + fp.seek(0) |
296 | + found = False |
297 | + for line in fp: |
298 | + if line == match: |
299 | + found = True |
300 | + self.failUnless(found, |
301 | + '%s repository not present or disabled.' % pocket) |
302 | + |
303 | +if __name__ == "__main__": |
304 | + unittest.main() |
I was curious if we should instead assume a 'release-pocket' format, rather than hard code backports, updates, etc in.