Merge lp:~adam-collard/landscape-charm/install-sources-keys into lp:landscape-charm

Proposed by Adam Collard on 2019-01-17
Status: Merged
Approved by: Simon Poirier on 2019-01-17
Approved revision: 397
Merged at revision: 395
Proposed branch: lp:~adam-collard/landscape-charm/install-sources-keys
Merge into: lp:landscape-charm
Diff against target: 278 lines (+93/-17)
11 files modified
Makefile (+1/-1)
config.yaml (+24/-1)
dev/ubuntu-deps (+2/-1)
lib/apt.py (+18/-1)
lib/callbacks/tests/test_apt.py (+1/-1)
lib/tests/stubs.py (+8/-1)
lib/tests/test_apt.py (+34/-6)
lib/tests/test_install.py (+1/-1)
lib/tests/test_services.py (+1/-1)
lib/tests/test_upgrade.py (+1/-1)
tests/helpers.py (+2/-2)
To merge this branch: bzr merge lp:~adam-collard/landscape-charm/install-sources-keys
Reviewer Review Type Date Requested Status
Simon Poirier 2019-01-17 Approve on 2019-01-17
Landscape Builder test results Approve on 2019-01-17
Review via email: mp+361892@code.launchpad.net

Commit message

Add support for the harmonised configuration keys for setting sources.list: install_sources, install_keys.

Description of the change

Integration tests pass modulo a test for update_security_db.sh cron job which we can look into separately.

To post a comment you must log in.
review: Abstain (executing tests)
review: Approve (test results)
394. By Adam Collard on 2019-01-17

Noop change

395. By Adam Collard on 2019-01-17

Merge from trunk

396. By Adam Collard on 2019-01-17

392 alive again

397. By Adam Collard on 2019-01-17

393 alive again

review: Abstain (executing tests)
review: Approve (test results)
review: Abstain (executing tests)
review: Approve (test results)
Simon Poirier (simpoir) wrote :

+1 LGTM.

Also bundletester is a pain to get working nowadays

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile'
2--- Makefile 2019-01-17 14:18:28 +0000
3+++ Makefile 2019-01-17 14:24:17 +0000
4@@ -45,7 +45,7 @@
5 fi
6
7 integration-test: test-depends
8- ~/.local/bin/bundletester -v -l DEBUG --skip-implicit -t .
9+ python2 ~/.local/bin/bundletester -v -l DEBUG --skip-implicit -t .
10
11 # Run integration tests using the LDS package from the lds-trunk PPA
12 integration-test-trunk: secrets
13
14=== modified file 'config.yaml'
15--- config.yaml 2019-01-17 14:18:28 +0000
16+++ config.yaml 2019-01-17 14:24:17 +0000
17@@ -1,8 +1,29 @@
18 options:
19+ install_sources:
20+ default: "['ppa:landscape/18.03']"
21+ type: string
22+ description: >
23+ List of extra apt sources, per charm-helpers standard format (a
24+ yaml list of strings encoded as a string). Each source may be either a line
25+ that can be added directly to sources.list(5), or in the form ppa:<user>/<ppa-name>
26+ for adding Personal Package Archives, or a distribution component to enable.
27+ install_keys:
28+ default: ""
29+ type: string
30+ description: >
31+ List of signing keys for install_sources package sources, per
32+ charmhelpers standard format (a yaml list of strings encoded as a string).
33+ The keys should be the full ASCII armoured GPG public keys. While GPG key
34+ ids are also supported and looked up on a keyserver, operators should be aware
35+ that this mechanism is insecure. null can be used if a standard package signing
36+ key is used that will already be installed on the machine, and for PPA sources
37+ where the package signing key is securely retrieved from Launchpad.\n"
38 source:
39- default: "ppa:landscape/18.03"
40+ default: ""
41 type: string
42 description: |
43+ *DEPRECATED*. See install_sources
44+
45 The source from which to install the landscape packages. Possible
46 values are:
47 - A version number: "16.06"
48@@ -16,6 +37,8 @@
49 default: ""
50 type: string
51 description: |
52+ *DEPRECATED*. See install_keys
53+
54 Key ID to import to the apt keyring to support use with arbitary source
55 configuration from outside of Launchpad archives or PPA's.
56 In case multiple repositories are specified in the 'source' config key,
57
58=== modified file 'dev/ubuntu-deps'
59--- dev/ubuntu-deps 2019-01-17 14:18:28 +0000
60+++ dev/ubuntu-deps 2019-01-17 14:24:17 +0000
61@@ -14,7 +14,8 @@
62 python3-yaml curl python3-zope.testrunner \
63 python3-amulet python3-fixtures python3-jinja2 python3-fixtures \
64 python3-psutil python3-twisted python3-flake8 \
65- python3-path python3-libcharmstore python3-zope.testrunner python3-six
66+ python3-path python3-libcharmstore python3-zope.testrunner python3-six \
67+ python-twisted-core
68
69 sudo apt-get -y install python-fixtures python-six python-yaml dpkg-dev \
70 pbuilder dh-make python-jinja2 python-psutil python-six
71
72=== modified file 'lib/apt.py'
73--- lib/apt.py 2019-01-17 14:18:28 +0000
74+++ lib/apt.py 2019-01-17 14:24:17 +0000
75@@ -53,13 +53,22 @@
76
77
78 class AptSourceAndKeyDontMatchError(CharmError):
79- """Provided config values for 'source' and 'key' do not match.."""
80+ """Provided config values for 'source' and 'key' do not match."""
81
82 def __init__(self):
83 message = "The 'source' and 'key' lists have different lengths"
84 super(AptSourceAndKeyDontMatchError, self).__init__(message)
85
86
87+class SourceConflictError(CharmError):
88+ """Config values for 'source' and 'install_sources' are present."""
89+
90+ def __init__(self, install_sources, source):
91+ message = ("install_sources: {!r} and source: {!r} are "
92+ "mutually exclusive.").format(install_sources, source)
93+ super(SourceConflictError, self).__init__(message)
94+
95+
96 class Apt(object):
97 """Perform APT-related tasks as setting sources and installing packages.
98
99@@ -130,6 +139,14 @@
100 """Set the remote APT repository to use, if new or changed."""
101 config = self._hookenv.config()
102 source = config.get("source")
103+
104+ # New style install sources
105+ install_sources = config.get("install_sources")
106+ if install_sources and source:
107+ raise SourceConflictError(install_sources, source)
108+ if install_sources:
109+ self._fetch.configure_sources()
110+ return
111 if not source:
112 raise AptNoSourceConfigError()
113
114
115=== modified file 'lib/callbacks/tests/test_apt.py'
116--- lib/callbacks/tests/test_apt.py 2019-01-17 14:18:28 +0000
117+++ lib/callbacks/tests/test_apt.py 2019-01-17 14:24:17 +0000
118@@ -7,7 +7,7 @@
119
120 def setUp(self):
121 super(SetAPTSourcesTest, self).setUp()
122- self.fetch = FetchStub()
123+ self.fetch = FetchStub(self.hookenv.config)
124 self.subprocess = SubprocessStub()
125 self.callback = SetAPTSources(
126 hookenv=self.hookenv, fetch=self.fetch, subprocess=self.subprocess)
127
128=== modified file 'lib/tests/stubs.py'
129--- lib/tests/stubs.py 2019-01-17 14:18:28 +0000
130+++ lib/tests/stubs.py 2019-01-17 14:24:17 +0000
131@@ -107,7 +107,9 @@
132 class FetchStub(object):
133 """Provide a testable stub for C{charmhelpers.fetch}."""
134
135- def __init__(self):
136+ def __init__(self, config):
137+ self._config = config
138+ self.configured_sources = []
139 self.sources = []
140 self.updates = []
141 self.filtered = []
142@@ -126,6 +128,11 @@
143 def apt_install(self, packages, options=None, fatal=False):
144 self.installed.append((packages, options, fatal))
145
146+ def configure_sources(self):
147+ install_sources = self._config().get('install_sources')
148+ install_keys = self._config().get('install_keys')
149+ self.configured_sources.append((install_sources, install_keys))
150+
151
152 class HostStub(object):
153 """Testable stub for C{charmhelpers.core.host}."""
154
155=== modified file 'lib/tests/test_apt.py'
156--- lib/tests/test_apt.py 2019-01-17 14:18:28 +0000
157+++ lib/tests/test_apt.py 2019-01-17 14:24:17 +0000
158@@ -5,8 +5,8 @@
159
160 from lib.apt import (
161 Apt, AptNoSourceConfigError, AptSourceAndKeyDontMatchError,
162- INSTALL_PACKAGES, DEFAULT_INSTALL_OPTIONS, SAMPLE_HASHIDS_PPA,
163- SAMPLE_HASHIDS_KEY)
164+ SourceConflictError, INSTALL_PACKAGES, DEFAULT_INSTALL_OPTIONS,
165+ SAMPLE_HASHIDS_PPA, SAMPLE_HASHIDS_KEY)
166 from lib.tests.stubs import FetchStub, SubprocessStub
167 from lib.tests.helpers import HookenvTest
168 from lib.tests.rootdir import RootDir
169@@ -16,7 +16,9 @@
170
171 def setUp(self):
172 super(AptTest, self).setUp()
173- self.fetch = FetchStub()
174+ # charmhelpers.fetch doesn't support dependency injection, so
175+ # we pass in our config to be able to inspect what was used
176+ self.fetch = FetchStub(self.hookenv.config)
177 self.subprocess = SubprocessStub()
178 self.root_dir = self.useFixture(RootDir())
179 self.paths = self.root_dir.paths
180@@ -64,6 +66,8 @@
181 self.apt.set_sources()
182 self.assertEqual([("ppa:landscape/14.10", None)], self.fetch.sources)
183 self.assertEqual([True], self.fetch.updates)
184+ # With source set, fetch.configure_sources is not called
185+ self.assertEqual(self.fetch.configured_sources, [])
186
187 def test_set_shorthand_sources(self):
188 """
189@@ -154,9 +158,33 @@
190 self.hookenv.config()["key"] = "xyz"
191 with self.assertRaises(AptSourceAndKeyDontMatchError) as error:
192 self.apt.set_sources()
193- self.assertEqual(
194- "The 'source' and 'key' lists have different lengths",
195- str(error))
196+ self.assertEqual(
197+ "The 'source' and 'key' lists have different lengths",
198+ str(error.exception))
199+
200+ def test_set_sources_and_install_sources(self):
201+ """
202+ If sources and install_sources are set set_sources complains.
203+ """
204+ self.hookenv.config()["source"] = "ppa:landscape/14.10"
205+ self.hookenv.config()["install_sources"] = "anything"
206+ with self.assertRaises(SourceConflictError) as error:
207+ self.apt.set_sources()
208+ self.assertEqual(
209+ "install_sources: 'anything' and source: 'ppa:landscape/14.10' "
210+ "are mutually exclusive.",
211+ str(error.exception))
212+
213+ def test_install_sources(self):
214+ """
215+ If install_sources is set, it's passed to fetch.configure_sources.
216+ """
217+ self.hookenv.config()["install_sources"] = "ppa:landscape/19.01"
218+ self.hookenv.config()["install_keys"] = "DEADBEEF"
219+ self.apt.set_sources()
220+ self.assertEqual(
221+ self.fetch.configured_sources,
222+ [('ppa:landscape/19.01', 'DEADBEEF')])
223
224 def test_local_tarball(self):
225 """
226
227=== modified file 'lib/tests/test_install.py'
228--- lib/tests/test_install.py 2019-01-17 14:18:28 +0000
229+++ lib/tests/test_install.py 2019-01-17 14:24:17 +0000
230@@ -9,7 +9,7 @@
231
232 def setUp(self):
233 super(InstallHookTest, self).setUp()
234- self.fetch = FetchStub()
235+ self.fetch = FetchStub(self.hookenv.config)
236 self.subprocess = SubprocessStub()
237 self.subprocess.add_fake_executable("apt-mark")
238 self.hook = InstallHook(
239
240=== modified file 'lib/tests/test_services.py'
241--- lib/tests/test_services.py 2019-01-17 14:18:28 +0000
242+++ lib/tests/test_services.py 2019-01-17 14:24:17 +0000
243@@ -31,7 +31,7 @@
244 self.root_dir = self.useFixture(RootDir())
245 self.paths = self.root_dir.paths
246 self.root_dir = self.useFixture(RootDir())
247- self.fetch = FetchStub()
248+ self.fetch = FetchStub(self.hookenv.config)
249 self.psutil = PsutilStub(num_cpus=2, physical_memory=1*1024**3)
250 self.hook = ServicesHook(
251 hookenv=self.hookenv, host=self.host, subprocess=self.subprocess,
252
253=== modified file 'lib/tests/test_upgrade.py'
254--- lib/tests/test_upgrade.py 2019-01-17 14:18:28 +0000
255+++ lib/tests/test_upgrade.py 2019-01-17 14:24:17 +0000
256@@ -11,7 +11,7 @@
257
258 def setUp(self):
259 super(UpgradeActionTest, self).setUp()
260- self.fetch = FetchStub()
261+ self.fetch = FetchStub(self.hookenv.config)
262 self.subprocess = SubprocessStub()
263 self.subprocess.add_fake_executable("apt-mark")
264 self.root_dir = self.useFixture(RootDir())
265
266=== modified file 'tests/helpers.py'
267--- tests/helpers.py 2019-01-17 14:18:28 +0000
268+++ tests/helpers.py 2019-01-17 14:24:17 +0000
269@@ -501,8 +501,8 @@
270 extra_config = yaml.safe_load(fd.read())
271 else:
272 extra_config = {
273- "source": source,
274- "key": os.environ.get("LS_CHARM_KEY", "4652B4E6")
275+ "install_sources": source,
276+ "install_keys": os.environ.get("LS_CHARM_KEY", "4652B4E6")
277 }
278 context["landscape"].update(extra_config)
279

Subscribers

People subscribed via source and target branches