Merge ~cloud-images-release-managers/cloud-images/+git/mfdiff:features/snap-diffs into ~cloud-images-release-managers/cloud-images/+git/mfdiff:master

Proposed by Tobias Koch
Status: Merged
Merged at revision: da2d5005aca2a41d392de2c788a69cfc2765ab83
Proposed branch: ~cloud-images-release-managers/cloud-images/+git/mfdiff:features/snap-diffs
Merge into: ~cloud-images-release-managers/cloud-images/+git/mfdiff:master
Diff against target: 654 lines (+268/-136)
6 files modified
test/test_manifest.py (+18/-15)
test/test_manifestdiff.py (+127/-46)
test/util.py (+12/-6)
ubuntu/cloudimage/mfdiff/cli.py (+15/-7)
ubuntu/cloudimage/mfdiff/manifest.py (+11/-20)
ubuntu/cloudimage/mfdiff/manifestdiff.py (+85/-42)
Reviewer Review Type Date Requested Status
Philip Roche Approve
Dan Watkins (community) Approve
Review via email: mp+361239@code.launchpad.net

Commit message

diff snaps

Description of the change

The output of the command looks like this now (shortened for readability):

new: {}
removed: {'python3-pam': '0.4.2-13.2ubuntu6'}
changed: ['dash', 'python3-twisted', 'python3-twisted-bin:amd64']
new snaps: {'test-snap': ['stable', '1']}
removed snaps: {'lxd': ['stable/ubuntu-19.04', '9795']}
changed snaps: ['core']
==== dash: 0.5.10.2-2 => 0.5.10.2-3ubuntu1 ====
==== dash
  * preinst is removed, thus divertion is not setup upon
  ...
==== twisted: 18.7.0-2 => 18.9.0-3 ====
==== python3-twisted python3-twisted-bin:amd64
  * Don't fix package substvars in binary-arch:, they did not depend on hamcrest
  ...

To post a comment you must log in.
Revision history for this message
Dan Watkins (oddbloke) wrote :

I haven't had time to do a full review, but I have a naming change suggestion: snaps are packages too, so using "pkgs" for debs is a little confusing. Could you do s/pkgs/debs/ (or deb_pkgs or something)?

Revision history for this message
Dan Watkins (oddbloke) wrote :

Other than the naming issue above, this looks really good. (FAOD, I'm not asking you to change every reference to debs as packages; just to modify the names that are introduced/modified in this MP.)

review: Needs Fixing
Revision history for this message
Tobias Koch (tobijk) wrote :

@daniel-thewatkins, ok like this?

Revision history for this message
Dan Watkins (oddbloke) wrote :

Thanks!

review: Approve
Revision history for this message
Philip Roche (philroche) wrote :

Nice

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/test/test_manifest.py b/test/test_manifest.py
index 29ab614..f3d38a7 100644
--- a/test/test_manifest.py
+++ b/test/test_manifest.py
@@ -9,34 +9,37 @@ class TestManifest(object):
9 manifest_file.write('')9 manifest_file.write('')
10 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')10 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')
11 assert len(manifest) == 011 assert len(manifest) == 0
12 assert manifest.dict == {}12 assert manifest.debs == {}
1313
14 def test_single_package(self, tmpdir):14 def test_single_deb(self, tmpdir):
15 package_name, package_version = 'package_name', '1.0-0ubuntu1'15 deb_name, deb_version = 'deb_name', '1.0-0ubuntu1'
16 manifest_file = tmpdir.join('manifest')16 manifest_file = tmpdir.join('manifest')
17 manifest_file.write(deb_package_line(package_name, package_version))17 manifest_file.write(deb_package_line(deb_name, deb_version))
18 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')18 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')
19 assert len(manifest) == 119 assert len(manifest) == 1
20 assert manifest.dict == { package_name: package_version }20 assert manifest.debs == { deb_name: deb_version }
2121
22 def test_snaps_are_skipped(self, tmpdir):22 def test_single_snap(self, tmpdir):
23 package_name, package_version = 'package_name', '1.0-0ubuntu1'23 snap_name, snap_channel, snap_version = ('snap_name', 'snap_channel',
24 'snap_version')
24 manifest_file = tmpdir.join('manifest')25 manifest_file = tmpdir.join('manifest')
25 manifest_file.write('\n'.join([26 manifest_file.write('\n'.join([
26 deb_package_line(package_name, package_version),
27 snap_package_line('snap_name', 'snap_channel', 'snap_version')27 snap_package_line('snap_name', 'snap_channel', 'snap_version')
28 ]))28 ]))
29 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')29 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')
30 assert len(manifest) == 130 assert len(manifest) == 1
31 assert manifest.dict == { package_name: package_version }31 assert manifest.snaps == { snap_name: [snap_channel, snap_version]}
3232
33 def test_deb_packages_starting_with_snap_arent_skipped(self, tmpdir):33 def test_deb_and_snap(self, tmpdir):
34 package_name, package_version = 'snapd', '1.0-0ubuntu1'34 deb_name, deb_version = 'snapd', '1.0-0ubuntu1'
35 snap_name, snap_channel, snap_version = ('snap_name', 'snap_channel',
36 'snap_version')
35 manifest_file = tmpdir.join('manifest')37 manifest_file = tmpdir.join('manifest')
36 manifest_file.write('\n'.join([38 manifest_file.write('\n'.join([
37 deb_package_line(package_name, package_version),39 deb_package_line(deb_name, deb_version),
38 snap_package_line('snap_name', 'snap_channel', 'snap_version')40 snap_package_line(snap_name, snap_channel, snap_version)
39 ]))41 ]))
40 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')42 manifest = Manifest(str(manifest_file), 'bionic', 'amd64')
41 assert len(manifest) == 143 assert len(manifest) == 2
42 assert manifest.dict == { package_name: package_version }44 assert manifest.debs == { deb_name: deb_version }
45 assert manifest.snaps == { snap_name: [snap_channel, snap_version]}
diff --git a/test/test_manifestdiff.py b/test/test_manifestdiff.py
index 3d33731..c391f17 100644
--- a/test/test_manifestdiff.py
+++ b/test/test_manifestdiff.py
@@ -5,11 +5,11 @@ from .util import deb_package_line, snap_package_line, write_manifest_file
5class TestManifestDiff(object):5class TestManifestDiff(object):
66
7 def test_incompatible_manifest_raise_error(self, tmpdir):7 def test_incompatible_manifest_raise_error(self, tmpdir):
8 package_name, package_version = 'package', '1.0-0ubuntu1'8 deb_name, deb_version = 'package', '1.0-0ubuntu1'
9 manifest_file1 = tmpdir.join('manifest1')9 manifest_file1 = tmpdir.join('manifest1')
10 manifest_file2 = tmpdir.join('manifest2')10 manifest_file2 = tmpdir.join('manifest2')
11 manifest_file1.write(deb_package_line(package_name, package_version))11 manifest_file1.write(deb_package_line(deb_name, deb_version))
12 manifest_file2.write(deb_package_line(package_name, package_version))12 manifest_file2.write(deb_package_line(deb_name, deb_version))
13 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')13 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
14 manifest2 = Manifest(str(manifest_file2), 'bionic', 'arm64')14 manifest2 = Manifest(str(manifest_file2), 'bionic', 'arm64')
1515
@@ -21,57 +21,57 @@ class TestManifestDiff(object):
2121
22 assert incompatible == True22 assert incompatible == True
2323
24 def test_find_added_packages(self, tmpdir):24 def test_find_added_debs(self, tmpdir):
25 package_list = [25 deb_list = [
26 ('package1', '1.0-1'),26 ('package1', '1.0-1'),
27 ('package2', '0.9.1-0ubuntu1'),27 ('package2', '0.9.1-0ubuntu1'),
28 ]28 ]
29 additional_packages = [29 additional_debs = [
30 ('package3', '0.8a~tp1-1ubuntu1'),30 ('package3', '0.8a~tp1-1ubuntu1'),
31 ]31 ]
3232
33 manifest_file1 = tmpdir.join('manifest1')33 manifest_file1 = tmpdir.join('manifest1')
34 manifest_file2 = tmpdir.join('manifest2')34 manifest_file2 = tmpdir.join('manifest2')
35 write_manifest_file(manifest_file1, package_list)35 write_manifest_file(manifest_file1, debs=deb_list)
36 write_manifest_file(manifest_file2, package_list36 write_manifest_file(manifest_file2, debs=deb_list
37 + additional_packages)37 + additional_debs)
3838
39 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')39 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
40 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')40 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')
4141
42 diff = ManifestDiff(manifest1, manifest2)42 diff = ManifestDiff(manifest1, manifest2)
43 added_packages = diff.get_added()43 added_debs = diff.get_added_debs()
44 assert added_packages == dict(additional_packages)44 assert added_debs == dict(additional_debs)
4545
46 def test_find_removed_packages(self, tmpdir):46 def test_find_removed_debs(self, tmpdir):
47 package_list = [47 deb_list = [
48 ('package1', '1.0-1'),48 ('package1', '1.0-1'),
49 ('package2', '0.9.1-0ubuntu1')49 ('package2', '0.9.1-0ubuntu1')
50 ]50 ]
51 additional_packages = [51 additional_debs = [
52 ('package3', '0.8a~tp1-1ubuntu1')52 ('package3', '0.8a~tp1-1ubuntu1')
53 ]53 ]
5454
55 manifest_file1 = tmpdir.join('manifest1')55 manifest_file1 = tmpdir.join('manifest1')
56 manifest_file2 = tmpdir.join('manifest2')56 manifest_file2 = tmpdir.join('manifest2')
57 write_manifest_file(manifest_file1, package_list57 write_manifest_file(manifest_file1, debs=deb_list
58 + additional_packages)58 + additional_debs)
59 write_manifest_file(manifest_file2, package_list)59 write_manifest_file(manifest_file2, debs=deb_list)
6060
61 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')61 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
62 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')62 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')
6363
64 diff = ManifestDiff(manifest1, manifest2)64 diff = ManifestDiff(manifest1, manifest2)
65 removed_packages = diff.get_removed()65 removed_debs = diff.get_removed_debs()
66 assert removed_packages == dict(additional_packages)66 assert removed_debs == dict(additional_debs)
6767
68 def test_find_changed_packages(self, tmpdir):68 def test_find_changed_debs(self, tmpdir):
69 package_list1 = [69 deb_list1 = [
70 ('package1', '1.0-1'),70 ('package1', '1.0-1'),
71 ('package2', '0.9.1-0ubuntu1'),71 ('package2', '0.9.1-0ubuntu1'),
72 ('package3', '2.0'),72 ('package3', '2.0'),
73 ]73 ]
74 package_list2 = [74 deb_list2 = [
75 ('package1', '1.0-1'),75 ('package1', '1.0-1'),
76 ('package2', '0.10.1-0ubuntu1'),76 ('package2', '0.10.1-0ubuntu1'),
77 ('package3', '2.0'),77 ('package3', '2.0'),
@@ -79,17 +79,61 @@ class TestManifestDiff(object):
7979
80 manifest_file1 = tmpdir.join('manifest1')80 manifest_file1 = tmpdir.join('manifest1')
81 manifest_file2 = tmpdir.join('manifest2')81 manifest_file2 = tmpdir.join('manifest2')
82 write_manifest_file(manifest_file1, package_list1)82 write_manifest_file(manifest_file1, debs=deb_list1)
83 write_manifest_file(manifest_file2, package_list2)83 write_manifest_file(manifest_file2, debs=deb_list2)
8484
85 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')85 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
86 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')86 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')
87 diff = ManifestDiff(manifest1, manifest2)87 diff = ManifestDiff(manifest1, manifest2)
88 changed_packages = diff.get_changed()88 changed_debs = diff.get_changed_debs()
89 assert changed_packages == ['package2']89 assert changed_debs == ['package2']
90
91 def test_find_added_snaps(self, tmpdir):
92 snap_list = [
93 ('snap1', ['stable', '1.0-1']),
94 ('snap2', ['edge', '0.9.1-0ubuntu1']),
95 ]
96 additional_snaps = [
97 ('snap3', ['stable/ubuntu-18.04', '0.8a~tp1-1ubuntu1']),
98 ]
99
100 manifest_file1 = tmpdir.join('manifest1')
101 manifest_file2 = tmpdir.join('manifest2')
102 write_manifest_file(manifest_file1, snaps=snap_list)
103 write_manifest_file(manifest_file2, snaps=snap_list
104 + additional_snaps)
105
106 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
107 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')
108
109 diff = ManifestDiff(manifest1, manifest2)
110 added_snaps = diff.get_added_snaps()
111 assert added_snaps == dict(additional_snaps)
112
113 def test_find_removed_snaps(self, tmpdir):
114 snap_list = [
115 ('snap1', ['stable', '1.0-1']),
116 ('snap2', ['edge', '0.9.1-0ubuntu1'])
117 ]
118 additional_snaps = [
119 ('package3', ['stable/ubuntu-18.04', '0.8a~tp1-1ubuntu1'])
120 ]
121
122 manifest_file1 = tmpdir.join('manifest1')
123 manifest_file2 = tmpdir.join('manifest2')
124 write_manifest_file(manifest_file1, snaps=snap_list
125 + additional_snaps)
126 write_manifest_file(manifest_file2, snaps=snap_list)
127
128 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
129 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')
130
131 diff = ManifestDiff(manifest1, manifest2)
132 removed_snaps = diff.get_removed_snaps()
133 assert removed_snaps == dict(additional_snaps)
90134
91 def test_find_added_removed_changed(self, tmpdir):135 def test_find_added_removed_changed(self, tmpdir):
92 package_list1 = [136 deb_list1 = [
93 ('package1', '1.0'),137 ('package1', '1.0'),
94 ('package4', '1.0'),138 ('package4', '1.0'),
95 ('package5', '1.0'),139 ('package5', '1.0'),
@@ -99,7 +143,7 @@ class TestManifestDiff(object):
99 ('package9', '1.0'),143 ('package9', '1.0'),
100 ('package10', '1.0')144 ('package10', '1.0')
101 ]145 ]
102 package_list2 = [146 deb_list2 = [
103 ('package1', '1.0'),147 ('package1', '1.0'),
104 ('package2', '1.0'),148 ('package2', '1.0'),
105 ('package3', '1.0'),149 ('package3', '1.0'),
@@ -110,40 +154,77 @@ class TestManifestDiff(object):
110 ('package10', '1.0')154 ('package10', '1.0')
111 ]155 ]
112156
157 snap_list1 = [
158 ('snap1', ['stable', '1.0']),
159 ('snap4', ['stable', '1.0']),
160 ('snap5', ['stable', '1.0']),
161 ('snap6', ['stable', '1.0']),
162 ('snap7', ['stable', '1.0']),
163 ('snap8', ['stable', '1.0']),
164 ('snap9', ['stable', '1.0']),
165 ('snap10', ['stable', '1.0']),
166 ]
167 snap_list2 = [
168 ('snap1', ['stable', '1.0']),
169 ('snap2', ['stable', '1.0']),
170 ('snap3', ['stable', '1.0']),
171 ('snap4', ['stable', '2.0']),
172 ('snap5', ['edge', '1.0']),
173 ('snap6', ['stable', '1.0']),
174 ('snap9', ['stable', '1.0']),
175 ('snap10', ['stable', '1.0']),
176 ]
177
113 manifest_file1 = tmpdir.join('manifest1')178 manifest_file1 = tmpdir.join('manifest1')
114 manifest_file2 = tmpdir.join('manifest2')179 manifest_file2 = tmpdir.join('manifest2')
115 write_manifest_file(manifest_file1, package_list1)180 write_manifest_file(manifest_file1, debs=deb_list1,
116 write_manifest_file(manifest_file2, package_list2)181 snaps=snap_list1)
182 write_manifest_file(manifest_file2, debs=deb_list2,
183 snaps=snap_list2)
117184
118 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')185 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
119 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')186 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')
120 diff = ManifestDiff(manifest1, manifest2)187 diff = ManifestDiff(manifest1, manifest2)
121188
122 added_packages = diff.get_added()189 added_debs = diff.get_added_debs()
123 removed_packages = diff.get_removed()190 removed_debs = diff.get_removed_debs()
124 changed_packages = diff.get_changed()191 changed_debs = diff.get_changed_debs()
192
193 assert added_debs == {'package2': '1.0', 'package3': '1.0'}
194 assert removed_debs == {'package7': '1.0', 'package8': '1.0'}
195 assert changed_debs == ['package4', 'package5']
196
197 added_snaps = diff.get_added_snaps()
198 removed_snaps = diff.get_removed_snaps()
199 changed_snaps = diff.get_changed_snaps()
125200
126 assert added_packages == {'package2': '1.0', 'package3': '1.0'}201 assert added_snaps == {
127 assert removed_packages == {'package7': '1.0', 'package8': '1.0'}202 'snap2': ['stable', '1.0'],
128 assert changed_packages == ['package4', 'package5']203 'snap3': ['stable', '1.0']
204 }
205 assert removed_snaps == {
206 'snap7': ['stable', '1.0'],
207 'snap8': ['stable', '1.0']
208 }
209 assert changed_snaps == ['snap4', 'snap5']
129210
130 def test_kernel_fixups(self, tmpdir):211 def test_kernel_fixups(self, tmpdir):
131 package_list1 = [('linux-image-4.13.0-16-generic', '4.13.0-16.19')]212 deb_list1 = [('linux-image-4.13.0-16-generic', '4.13.0-16.19')]
132 package_list2 = [('linux-image-4.13.0-25-generic', '4.13.0-25.29')]213 deb_list2 = [('linux-image-4.13.0-25-generic', '4.13.0-25.29')]
133214
134 manifest_file1 = tmpdir.join('manifest1')215 manifest_file1 = tmpdir.join('manifest1')
135 manifest_file2 = tmpdir.join('manifest2')216 manifest_file2 = tmpdir.join('manifest2')
136 write_manifest_file(manifest_file1, package_list1)217 write_manifest_file(manifest_file1, debs=deb_list1)
137 write_manifest_file(manifest_file2, package_list2)218 write_manifest_file(manifest_file2, debs=deb_list2)
138219
139 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')220 manifest1 = Manifest(str(manifest_file1), 'bionic', 'amd64')
140 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')221 manifest2 = Manifest(str(manifest_file2), 'bionic', 'amd64')
141 diff = ManifestDiff(manifest1, manifest2)222 diff = ManifestDiff(manifest1, manifest2)
142223
143 added_packages = diff.get_added()224 added_debs = diff.get_added_debs()
144 removed_packages = diff.get_removed()225 removed_debs = diff.get_removed_debs()
145 changed_packages = diff.get_changed()226 changed_debs = diff.get_changed_debs()
146227
147 assert added_packages == {}228 assert added_debs == {}
148 assert removed_packages == {}229 assert removed_debs == {}
149 assert changed_packages == ['linux-image-4.13.0-25-generic']230 assert changed_debs == ['linux-image-4.13.0-25-generic']
diff --git a/test/util.py b/test/util.py
index 9979a78..a39b7ec 100644
--- a/test/util.py
+++ b/test/util.py
@@ -1,6 +1,6 @@
1def deb_package_line(package_name, package_version):1def deb_package_line(deb_name, deb_version):
2 """Format a deb package manifest line"""2 """Format a deb package manifest line"""
3 return '\t'.join([package_name, package_version])3 return '\t'.join([deb_name, deb_version])
44
55
6def snap_package_line(snap_name, snap_channel, snap_version):6def snap_package_line(snap_name, snap_channel, snap_version):
@@ -8,14 +8,20 @@ def snap_package_line(snap_name, snap_channel, snap_version):
8 return '\t'.join(8 return '\t'.join(
9 ['snap:{}'.format(snap_name), snap_channel, snap_version])9 ['snap:{}'.format(snap_name), snap_channel, snap_version])
1010
11def write_manifest_file(path_obj, packages):11def write_manifest_file(path_obj, debs=None, snaps=None):
12 """Write a list of packages to a manifest file."""12 """Write a list of packages to a manifest file."""
13 manifest_lines = []13 manifest_lines = []
1414
15 # Then add more to the second.15 # Then add more to the second.
16 for package_name, package_version in packages:16 if debs is not None:
17 manifest_lines.append(deb_package_line(17 for deb_name, deb_version in debs:
18 package_name, package_version))18 manifest_lines.append(deb_package_line(
19 deb_name, deb_version))
20
21 if snaps is not None:
22 for snap_name, (snap_channel, snap_version) in snaps:
23 manifest_lines.append(snap_package_line(
24 snap_name, snap_channel, snap_version))
1925
20 path_obj.write("\n".join(manifest_lines))26 path_obj.write("\n".join(manifest_lines))
2127
diff --git a/ubuntu/cloudimage/mfdiff/cli.py b/ubuntu/cloudimage/mfdiff/cli.py
index ba8d102..5cc0629 100644
--- a/ubuntu/cloudimage/mfdiff/cli.py
+++ b/ubuntu/cloudimage/mfdiff/cli.py
@@ -128,14 +128,22 @@ def main():
128 manifest_from = Manifest(manifest_from_filename, release, arch)128 manifest_from = Manifest(manifest_from_filename, release, arch)
129 manifest_diff = ManifestDiff(manifest_from, manifest_to)129 manifest_diff = ManifestDiff(manifest_from, manifest_to)
130130
131 added_pkgs = manifest_diff.get_added()131 added_debs = manifest_diff.get_added_debs()
132 removed_pkgs = manifest_diff.get_removed()132 removed_debs = manifest_diff.get_removed_debs()
133 changed_pkgs = manifest_diff.get_changed()133 changed_debs = manifest_diff.get_changed_debs()
134134
135 print("new: %s" % added_pkgs)135 added_snaps = manifest_diff.get_added_snaps()
136 print("removed: %s" % removed_pkgs)136 removed_snaps = manifest_diff.get_removed_snaps()
137 print("changed: %s" % changed_pkgs)137 changed_snaps = manifest_diff.get_changed_snaps()
138
139 print("new: %s" % added_debs)
140 print("removed: %s" % removed_debs)
141 print("changed: %s" % changed_debs)
142
143 print("new snaps: %s" % added_snaps)
144 print("removed snaps: %s" % removed_snaps)
145 print("changed snaps: %s" % changed_snaps)
138146
139 # if modified packages, download all changelogs from changelogs.147 # if modified packages, download all changelogs from changelogs.
140 if changed_pkgs:148 if changed_debs:
141 print(manifest_diff.render_changelog())149 print(manifest_diff.render_changelog())
diff --git a/ubuntu/cloudimage/mfdiff/manifest.py b/ubuntu/cloudimage/mfdiff/manifest.py
index 6907ad8..bd1f416 100644
--- a/ubuntu/cloudimage/mfdiff/manifest.py
+++ b/ubuntu/cloudimage/mfdiff/manifest.py
@@ -27,23 +27,10 @@ class Manifest(object):
27 def __init__(self, filename, release, arch):27 def __init__(self, filename, release, arch):
28 self.release = release28 self.release = release
29 self.arch = arch29 self.arch = arch
30 self.dict = self._manifest_to_dict(filename)30 self.debs, self.snaps = self._manifest_to_dict(filename)
31
32 def __iter__(self):
33 for item in self.dict:
34 yield item
35
36 def __getitem__(self, key):
37 return self.dict[key]
38
39 def __setitem__(self, key, value):
40 self.dict[key] = value
41
42 def __delitem__(self, key):
43 del self.dict[key]
4431
45 def __len__(self):32 def __len__(self):
46 return len(self.dict)33 return len(self.debs) + len(self.snaps)
4734
48 @classmethod35 @classmethod
49 def _manifest_to_dict(cls, filename):36 def _manifest_to_dict(cls, filename):
@@ -54,12 +41,16 @@ class Manifest(object):
54 :return: List of package versions by name41 :return: List of package versions by name
55 :rtype: dict42 :rtype: dict
56 """43 """
57 ret = {}44 debs = {}
45 snaps = {}
46
58 logging.debug('Reading package manifest from %s', filename)47 logging.debug('Reading package manifest from %s', filename)
59 with open(filename, "r") as manifest:48 with open(filename, "r") as manifest:
60 for line in manifest:49 for line in manifest:
61 if line.startswith("snap:"):50 if line.startswith("snap:"):
62 continue51 (name, channel, ver) = line[5:].split()
63 (pkg, ver) = line.split()52 snaps[name] = [channel, ver]
64 ret[pkg] = ver53 else:
65 return ret54 (name, ver) = line.split()
55 debs[name] = ver
56 return debs, snaps
diff --git a/ubuntu/cloudimage/mfdiff/manifestdiff.py b/ubuntu/cloudimage/mfdiff/manifestdiff.py
index 20e7804..436e6fa 100644
--- a/ubuntu/cloudimage/mfdiff/manifestdiff.py
+++ b/ubuntu/cloudimage/mfdiff/manifestdiff.py
@@ -64,9 +64,12 @@ class ManifestDiff(object):
6464
65 self._manifest_from = manifest_from65 self._manifest_from = manifest_from
66 self._manifest_to = manifest_to66 self._manifest_to = manifest_to
67 self._added_pkgs = {}67 self._added_debs = {}
68 self._removed_pkgs = {}68 self._removed_debs = {}
69 self._changed_pkgs = []69 self._changed_debs = []
70 self._added_snaps = {}
71 self._removed_snaps = {}
72 self._changed_snaps = []
7073
71 self._cache = ManifestCache(manifest_from.release,74 self._cache = ManifestCache(manifest_from.release,
72 manifest_from.arch)75 manifest_from.arch)
@@ -74,37 +77,59 @@ class ManifestDiff(object):
74 if apply_fixups:77 if apply_fixups:
75 self.apply_kernel_fixups()78 self.apply_kernel_fixups()
7679
77 def get_added(self):80 def get_added_debs(self):
78 "Find new packages in manifest_to"81 "Find new packages in manifest_to"
79 if not self._added_pkgs:82 if not self._added_debs:
80 for pkg in sorted(viewkeys(self._manifest_to.dict) -83 self._added_debs = self._get_added_dict_items(
81 viewkeys(self._manifest_from.dict)):84 self._manifest_from.debs,
82 logging.debug('New package: %s', pkg)85 self._manifest_to.debs
83 self._added_pkgs[pkg] = self._manifest_to.dict[pkg]86 )
84 return self._added_pkgs87 return self._added_debs
8588
86 def get_removed(self):89 def get_removed_debs(self):
87 "Find packages removed from manifest_from"90 "Find packages removed from manifest_from"
88 if not self._removed_pkgs:91 if not self._removed_debs:
89 for pkg in sorted(viewkeys(self._manifest_from.dict) -92 self._removed_debs = self._get_removed_dict_items(
90 viewkeys(self._manifest_to.dict)):93 self._manifest_from.debs,
91 logging.debug('Removed package: %s', pkg)94 self._manifest_to.debs
92 self._removed_pkgs[pkg] = self._manifest_from[pkg]95 )
93 return self._removed_pkgs96 return self._removed_debs
9497
95 def get_changed(self):98 def get_changed_debs(self):
96 "Find modified packages"99 "Find modified packages"
97 if not self._changed_pkgs:100 if not self._changed_debs:
98 changed = []101 self._changed_debs = self._get_changed_dict_items(
99 for pkg in sorted(viewkeys(self._manifest_from.dict) &102 self._manifest_from.debs,
100 viewkeys(self._manifest_to.dict)):103 self._manifest_to.debs
101 if self._manifest_from[pkg] != self._manifest_to[pkg]:104 )
102 logging.debug('Changed package: %s', pkg)105 return self._changed_debs
103 changed.append(pkg)106
104107 def get_added_snaps(self):
105 self._changed_pkgs = changed108 "Find new snaps in manifest_to"
106109 if not self._added_snaps:
107 return self._changed_pkgs110 self._added_snaps = self._get_added_dict_items(
111 self._manifest_from.snaps,
112 self._manifest_to.snaps
113 )
114 return self._added_snaps
115
116 def get_removed_snaps(self):
117 "Find snaps removed from manifest_from"
118 if not self._removed_snaps:
119 self._removed_snaps = self._get_removed_dict_items(
120 self._manifest_from.snaps,
121 self._manifest_to.snaps
122 )
123 return self._removed_snaps
124
125 def get_changed_snaps(self):
126 "Find modified snaps"
127 if not self._changed_snaps:
128 self._changed_snaps = self._get_changed_dict_items(
129 self._manifest_from.snaps,
130 self._manifest_to.snaps
131 )
132 return self._changed_snaps
108133
109 def render_changelog(self):134 def render_changelog(self):
110 """135 """
@@ -114,7 +139,7 @@ class ManifestDiff(object):
114139
115 srcs = {}140 srcs = {}
116 errors = []141 errors = []
117 src2bins = self._cache.get_src2bin_mapping(self._changed_pkgs)142 src2bins = self._cache.get_src2bin_mapping(self._changed_debs)
118143
119 # Generate changelog data per unique source package144 # Generate changelog data per unique source package
120 for source_name in src2bins:145 for source_name in src2bins:
@@ -127,19 +152,19 @@ class ManifestDiff(object):
127 # Find the source version data for the binary in manifest #2152 # Find the source version data for the binary in manifest #2
128 try:153 try:
129 src['version_to'] = self._cache.source_version_for_binary(154 src['version_to'] = self._cache.source_version_for_binary(
130 binary_name, self._manifest_to[binary_name])155 binary_name, self._manifest_to.debs[binary_name])
131 except UnknownSourceVersionError as excp:156 except UnknownSourceVersionError as excp:
132 logging.error(str(excp))157 logging.error(str(excp))
133 errors.append(excp)158 errors.append(excp)
134 continue159 continue
135160
136 # Find the source version data for the binary in manifest #1161 # Find the source version data for the binary in manifest #1
137 binver_from = self._manifest_from[binary_name]162 binver_from = self._manifest_from.debs[binary_name]
138 try:163 try:
139 src['version_from'] = self._cache.source_version_for_binary(164 src['version_from'] = self._cache.source_version_for_binary(
140 binary_name, binver_from)165 binary_name, binver_from)
141 except UnknownSourceVersionError as excp:166 except UnknownSourceVersionError as excp:
142 if self._manifest_to[binary_name] == src['version_to']:167 if self._manifest_to.debs[binary_name] == src['version_to']:
143 logging.info('Could not find source version data in apt '168 logging.info('Could not find source version data in apt '
144 'cache. Assuming source %s version %s from '169 'cache. Assuming source %s version %s from '
145 'binary %s', source_name, binver_from,170 'binary %s', source_name, binver_from,
@@ -189,8 +214,8 @@ class ManifestDiff(object):
189 binlist = sorted(src2bins[source_name])214 binlist = sorted(src2bins[source_name])
190 binary = binlist[0]215 binary = binlist[0]
191 result.append("==== %s: %s => %s ====" %216 result.append("==== %s: %s => %s ====" %
192 (source_name, self._manifest_from[binary],217 (source_name, self._manifest_from.debs[binary],
193 self._manifest_to[binary]))218 self._manifest_to.debs[binary]))
194 result.append("==== %s" % ' '.join(binlist))219 result.append("==== %s" % ' '.join(binlist))
195 for block in srcs[source_name]["changeblocks"]:220 for block in srcs[source_name]["changeblocks"]:
196 entry = '\n'.join([x for x in block.changes() if x])221 entry = '\n'.join([x for x in block.changes() if x])
@@ -213,17 +238,17 @@ class ManifestDiff(object):
213 """238 """
214 kfixups = {}239 kfixups = {}
215 kmatch = re.compile("linux-image-[0-9]")240 kmatch = re.compile("linux-image-[0-9]")
216 for pkg in self._manifest_to:241 for pkg in self._manifest_to.debs:
217 # if this is a linux-image-* binary package do some hacks to make it242 # if this is a linux-image-* binary package do some hacks to make it
218 # look like manifest_from is the same (format like243 # look like manifest_from is the same (format like
219 # linux-image-2.6.32-32-virtual)244 # linux-image-2.6.32-32-virtual)
220 if kmatch.match(pkg):245 if kmatch.match(pkg):
221 logging.debug('Found kernel %s in manifest #2', pkg)246 logging.debug('Found kernel %s in manifest #2', pkg)
222 img_type = pkg.split("-")[-1]247 img_type = pkg.split("-")[-1]
223 if pkg in self._manifest_from:248 if pkg in self._manifest_from.debs:
224 logging.debug('Found same kernel in manifest #1')249 logging.debug('Found same kernel in manifest #1')
225 continue250 continue
226 for fpkg in self._manifest_from:251 for fpkg in self._manifest_from.debs:
227 if kmatch.match(fpkg) and fpkg.endswith("-%s" % img_type):252 if kmatch.match(fpkg) and fpkg.endswith("-%s" % img_type):
228 logging.debug('Found similar kernel %s in manifest #1',253 logging.debug('Found similar kernel %s in manifest #1',
229 fpkg)254 fpkg)
@@ -232,8 +257,8 @@ class ManifestDiff(object):
232 for pkg_to, pkg_from in iteritems(kfixups):257 for pkg_to, pkg_from in iteritems(kfixups):
233 logging.debug('Substituting kernel %s for %s in manifest #1 to '258 logging.debug('Substituting kernel %s for %s in manifest #1 to '
234 'enable version comparison', pkg_to, pkg_from)259 'enable version comparison', pkg_to, pkg_from)
235 self._manifest_from[pkg_to] = self._manifest_from[pkg_from]260 self._manifest_from.debs[pkg_to] = self._manifest_from.debs[pkg_from]
236 del self._manifest_from[pkg_from]261 del self._manifest_from.debs[pkg_from]
237262
238 def _filter_changelog(self, changelog_path, version_low, version_high):263 def _filter_changelog(self, changelog_path, version_low, version_high):
239 """264 """
@@ -282,3 +307,21 @@ class ManifestDiff(object):
282 logging.error(error_msg)307 logging.error(error_msg)
283 return change_blocks, error_msg308 return change_blocks, error_msg
284309
310 def _get_added_dict_items(self, from_dict, to_dict):
311 added = {}
312 for key in sorted(viewkeys(to_dict) - viewkeys(from_dict)):
313 added[key] = to_dict[key]
314 return added
315
316 def _get_removed_dict_items(self, from_dict, to_dict):
317 removed = {}
318 for key in sorted(viewkeys(from_dict) - viewkeys(to_dict)):
319 removed[key] = from_dict[key]
320 return removed
321
322 def _get_changed_dict_items(self, from_dict, to_dict):
323 changed = []
324 for key in sorted(viewkeys(from_dict) & viewkeys(to_dict)):
325 if from_dict[key] != to_dict[key]:
326 changed.append(key)
327 return changed

Subscribers

People subscribed via source and target branches