Merge lp:~bjornt/landscape-client/lxd-update-fail into lp:~landscape/landscape-client/trunk

Proposed by Björn Tillenius
Status: Merged
Approved by: Adam Collard
Approved revision: 961
Merged at revision: 962
Proposed branch: lp:~bjornt/landscape-client/lxd-update-fail
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 151 lines (+107/-0)
2 files modified
landscape/package/reporter.py (+19/-0)
landscape/package/tests/test_reporter.py (+88/-0)
To merge this branch: bzr merge lp:~bjornt/landscape-client/lxd-update-fail
Reviewer Review Type Date Requested Status
Alberto Donato (community) Approve
Adam Collard (community) Approve
🤖 Landscape Builder test results Approve
Review via email: mp+320213@code.launchpad.net

Commit message

Don't report packages that are coming from backports.

The reason for this is that backports are enabled by default from
xenial, but landscape doesn't handle that well, since we don't support
pinning properly.

If we report packages from backports, it means that Landscape will
upgrade to those version if you use an upgrade profile or select all
upgrades to their latest versions.

Description of the change

Don't report packages that are coming from backports.

The reason for this is that backports are enabled by default from
xenial, but landscape doesn't handle that well, since we don't support
pinning properly.

If we report packages from backports, it means that Landscape will
upgrade to those version if you use an upgrade profile or select all
upgrades to their latest versions.

Testing instructions:

   Use this branch for a xenial machine that has lxd installed
   Register it with Landscape
   Ensure that Landscape doesn't off to upgrade lxd to 2.8

To post a comment you must log in.
Revision history for this message
🤖 Landscape Builder (landscape-builder) :
review: Abstain (executing tests)
Revision history for this message
🤖 Landscape Builder (landscape-builder) wrote :

Command: TRIAL_ARGS=-j4 make check
Result: Success
Revno: 961
Branch: lp:~bjornt/landscape-client/lxd-update-fail
Jenkins: https://ci.lscape.net/job/latch-test-xenial/3638/

review: Approve (test results)
Revision history for this message
Adam Collard (adam-collard) wrote :

LGTM, +1. Thanks for the work on this!

review: Approve
Revision history for this message
Alberto Donato (ack) wrote :

Nice fix, +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/package/reporter.py'
2--- landscape/package/reporter.py 2017-03-17 09:26:45 +0000
3+++ landscape/package/reporter.py 2017-03-17 15:43:18 +0000
4@@ -18,6 +18,7 @@
5 from landscape.lib.twisted_util import gather_results, spawn_process
6 from landscape.lib.fetch import fetch_async
7 from landscape.lib.fs import touch_file
8+from landscape.lib.lsb_release import parse_lsb_release, LSB_RELEASE_FILENAME
9
10 from landscape.compat import convert_buffer_to_string
11 from landscape.package.taskhandler import (
12@@ -551,8 +552,26 @@
13 current_available = set()
14 current_upgrades = set()
15 current_locked = set()
16+ lsb = parse_lsb_release(LSB_RELEASE_FILENAME)
17+ backports_archive = "{}-backports".format(lsb["code-name"])
18
19 for package in self._facade.get_packages():
20+ # Don't include package versions from the official backports
21+ # archive. The backports archive is enabled by default since
22+ # xenial with a pinning policy of 100. Ideally we would
23+ # support pinning, but we don't yet. In the mean time, we
24+ # ignore backports, so that packages don't get automatically
25+ # upgraded to the backports version.
26+ backport_origins = [
27+ origin for origin in package.origins
28+ if origin.archive == backports_archive]
29+ if backport_origins and (
30+ len(backport_origins) == len(package.origins)):
31+ # Ignore the version if it's only in the official
32+ # backports archive. If it's somewhere else as well,
33+ # e.g. a PPA, we assume it was added manually and the
34+ # user wants to get updates from it.
35+ continue
36 hash = self._facade.get_package_hash(package)
37 id = self._store.get_hash_id(hash)
38 if id is not None:
39
40=== modified file 'landscape/package/tests/test_reporter.py'
41--- landscape/package/tests/test_reporter.py 2017-03-17 09:26:45 +0000
42+++ landscape/package/tests/test_reporter.py 2017-03-17 15:43:18 +0000
43@@ -3,6 +3,7 @@
44 import time
45 import apt_pkg
46 import mock
47+import shutil
48
49 from twisted.internet.defer import Deferred, succeed, fail, inlineCallbacks
50 from twisted.internet import reactor
51@@ -11,6 +12,7 @@
52 from landscape.lib import bpickle
53 from landscape.lib.fs import create_text_file, touch_file
54 from landscape.lib.fetch import FetchError
55+from landscape.lib.lsb_release import parse_lsb_release, LSB_RELEASE_FILENAME
56 from landscape.package.store import (
57 PackageStore, UnknownHashIDRequest, FakePackageStore)
58 from landscape.package.reporter import (
59@@ -925,6 +927,92 @@
60 result = self.reporter.detect_packages_changes()
61 return result.addCallback(got_result)
62
63+ def test_detect_packages_changes_with_backports(self):
64+ """
65+ Package versions coming from backports aren't considered to be
66+ available.
67+
68+ This is because we don't support pinning, and the backports
69+ archive is enabled by default since xenial.
70+ """
71+ message_store = self.broker_service.message_store
72+ message_store.set_accepted_types(["packages"])
73+
74+ lsb = parse_lsb_release(LSB_RELEASE_FILENAME)
75+ release_path = os.path.join(self.repository_dir, "Release")
76+ with open(release_path, "w") as release:
77+ release.write("Suite: {}-backports".format(lsb["code-name"]))
78+
79+ self.store.set_hash_ids({HASH1: 1, HASH2: 2, HASH3: 3})
80+
81+ def got_result(result):
82+ self.assertMessages(message_store.get_pending_messages(), [])
83+
84+ self.assertEqual(sorted(self.store.get_available()), [])
85+
86+ result = self.reporter.detect_packages_changes()
87+ return result.addCallback(got_result)
88+
89+ def test_detect_packages_changes_with_backports_others(self):
90+ """
91+ Packages coming from backport archives that aren't named like
92+ the official backports archive are considered to be available.
93+ """
94+ message_store = self.broker_service.message_store
95+ message_store.set_accepted_types(["packages"])
96+
97+ release_path = os.path.join(self.repository_dir, "Release")
98+ with open(release_path, "w") as release:
99+ release.write("Suite: my-personal-backports")
100+
101+ self.store.set_hash_ids({HASH1: 1, HASH2: 2, HASH3: 3})
102+
103+ def got_result(result):
104+ self.assertMessages(message_store.get_pending_messages(),
105+ [{"type": "packages", "available": [(1, 3)]}])
106+
107+ self.assertEqual(sorted(self.store.get_available()), [1, 2, 3])
108+
109+ result = self.reporter.detect_packages_changes()
110+ return result.addCallback(got_result)
111+
112+ def test_detect_packages_changes_with_backports_both(self):
113+ """
114+ If a package is both in the official backports archive and in
115+ some other archive (e.g. a PPA), the package is considered to be
116+ available.
117+
118+ The reason for this is that if you have enabled a PPA, you most
119+ likely want to get updates from it.
120+ """
121+ message_store = self.broker_service.message_store
122+ message_store.set_accepted_types(["packages"])
123+
124+ temp_dir = self.makeDir()
125+ other_backport_dir = os.path.join(temp_dir, "my-personal-backports")
126+ shutil.copytree(self.repository_dir, other_backport_dir)
127+ os.remove(os.path.join(other_backport_dir, "Packages"))
128+ self.facade.add_channel_deb_dir(other_backport_dir)
129+
130+ lsb = parse_lsb_release(LSB_RELEASE_FILENAME)
131+ official_release_path = os.path.join(self.repository_dir, "Release")
132+ with open(official_release_path, "w") as release:
133+ release.write("Suite: {}-backports".format(lsb["code-name"]))
134+ unofficial_release_path = os.path.join(other_backport_dir, "Release")
135+ with open(unofficial_release_path, "w") as release:
136+ release.write("Suite: my-personal-backports")
137+
138+ self.store.set_hash_ids({HASH1: 1, HASH2: 2, HASH3: 3})
139+
140+ def got_result(result):
141+ self.assertMessages(message_store.get_pending_messages(),
142+ [{"type": "packages", "available": [(1, 3)]}])
143+
144+ self.assertEqual(sorted(self.store.get_available()), [1, 2, 3])
145+
146+ result = self.reporter.detect_packages_changes()
147+ return result.addCallback(got_result)
148+
149 @inlineCallbacks
150 def test_detect_packages_after_tasks(self):
151 """

Subscribers

People subscribed via source and target branches

to all changes: