launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #23245
[Merge] lp:~cjwatson/launchpad-buildd/proxy-configs into lp:launchpad-buildd
Colin Watson has proposed merging lp:~cjwatson/launchpad-buildd/proxy-configs into lp:launchpad-buildd.
Commit message:
Allow configuring APT or snap store proxies via a new [proxy] configuration file section.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad-buildd/proxy-configs/+merge/362332
This makes testing builds behind a slow connection 90% less annoying.
While python-requests and python-six are new direct dependencies in this branch, they were already indirect dependencies.
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad-buildd/proxy-configs into lp:launchpad-buildd.
=== modified file 'debian/changelog'
--- debian/changelog 2019-01-28 13:11:11 +0000
+++ debian/changelog 2019-01-28 15:15:21 +0000
@@ -1,3 +1,10 @@
+launchpad-buildd (167) UNRELEASED; urgency=medium
+
+ * Allow configuring APT or snap store proxies via a new [proxy]
+ configuration file section.
+
+ -- Colin Watson <cjwatson@xxxxxxxxxx> Mon, 28 Jan 2019 14:23:16 +0000
+
launchpad-buildd (166) xenial; urgency=medium
[ Colin Watson ]
=== modified file 'debian/control'
--- debian/control 2018-06-07 16:23:18 +0000
+++ debian/control 2019-01-28 15:15:21 +0000
@@ -17,7 +17,10 @@
python-mock,
python-netaddr,
python-pylxd,
+ python-requests,
+ python-responses,
python-setuptools,
+ python-six,
python-systemfixtures,
python-testtools,
python-twisted,
=== modified file 'lpbuildd/debian.py'
--- lpbuildd/debian.py 2018-10-19 06:41:14 +0000
+++ lpbuildd/debian.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
# Authors: Daniel Silverstone <daniel.silverstone@xxxxxxxxxxxxx>
@@ -13,6 +13,10 @@
import re
import signal
+from six.moves.configparser import (
+ NoOptionError,
+ NoSectionError,
+ )
from twisted.internet import (
defer,
threads,
@@ -63,7 +67,14 @@
Mainly used for PPA builds.
"""
- self.runTargetSubProcess("override-sources-list", *self.sources_list)
+ args = []
+ try:
+ apt_proxy_url = self._slave._config.get("proxy", "apt")
+ args.extend(["--apt-proxy-url", apt_proxy_url])
+ except (NoSectionError, NoOptionError):
+ pass
+ args.extend(self.sources_list)
+ self.runTargetSubProcess("override-sources-list", *args)
def doTrustedKeys(self):
"""Add trusted keys."""
=== modified file 'lpbuildd/livefs.py'
--- lpbuildd/livefs.py 2019-01-28 13:07:53 +0000
+++ lpbuildd/livefs.py 2019-01-28 15:15:21 +0000
@@ -1,10 +1,15 @@
-# Copyright 2013-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2013-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
import os
+from six.moves.configparser import (
+ NoOptionError,
+ NoSectionError,
+ )
+
from lpbuildd.debian import (
DebianBuildManager,
DebianBuildState,
@@ -71,6 +76,12 @@
args.extend(["--repo-snapshot-stamp", self.repo_snapshot_stamp])
if self.cohort_key:
args.extend(["--cohort-key", self.cohort_key])
+ try:
+ snap_store_proxy_url = self._slave._config.get(
+ "proxy", "snapstore")
+ args.extend(["--snap-store-proxy-url", snap_store_proxy_url])
+ except (NoSectionError, NoOptionError):
+ pass
if self.debug:
args.append("--debug")
self.runTargetSubProcess("buildlivefs", *args)
=== modified file 'lpbuildd/snap.py'
--- lpbuildd/snap.py 2018-10-19 06:41:14 +0000
+++ lpbuildd/snap.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2015-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2015-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
from __future__ import print_function
@@ -29,6 +29,10 @@
)
from urlparse import urlparse
+from six.moves.configparser import (
+ NoOptionError,
+ NoSectionError,
+ )
from twisted.application import strports
from twisted.internet import reactor
from twisted.internet.interfaces import IHalfCloseableProtocol
@@ -348,6 +352,12 @@
args.extend(["--git-path", self.git_path])
if self.build_source_tarball:
args.append("--build-source-tarball")
+ try:
+ snap_store_proxy_url = self._slave._config.get(
+ "proxy", "snapstore")
+ args.extend(["--snap-store-proxy-url", snap_store_proxy_url])
+ except (NoSectionError, NoOptionError):
+ pass
args.append(self.name)
self.runTargetSubProcess("buildsnap", *args)
=== modified file 'lpbuildd/target/apt.py'
--- lpbuildd/target/apt.py 2017-08-22 15:55:44 +0000
+++ lpbuildd/target/apt.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
from __future__ import print_function
@@ -26,6 +26,8 @@
def add_arguments(cls, parser):
super(OverrideSourcesList, cls).add_arguments(parser)
parser.add_argument(
+ "--apt-proxy-url", metavar="URL", help="APT proxy URL")
+ parser.add_argument(
"archives", metavar="ARCHIVE", nargs="+",
help="sources.list lines")
@@ -37,6 +39,16 @@
sources_list.flush()
os.fchmod(sources_list.fileno(), 0o644)
self.backend.copy_in(sources_list.name, "/etc/apt/sources.list")
+ if self.args.apt_proxy_url is not None:
+ with tempfile.NamedTemporaryFile() as apt_proxy_conf:
+ print(
+ 'Acquire::http::Proxy "{}";'.format(
+ self.args.apt_proxy_url),
+ file=apt_proxy_conf)
+ apt_proxy_conf.flush()
+ os.fchmod(apt_proxy_conf.fileno(), 0o644)
+ self.backend.copy_in(
+ apt_proxy_conf.name, "/etc/apt/apt.conf.d/99proxy")
return 0
=== modified file 'lpbuildd/target/build_livefs.py'
--- lpbuildd/target/build_livefs.py 2019-01-28 13:10:24 +0000
+++ lpbuildd/target/build_livefs.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2013-2017 Canonical Ltd. This software is licensed under the
+# Copyright 2013-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
from __future__ import print_function
@@ -10,6 +10,7 @@
import os
from lpbuildd.target.operation import Operation
+from lpbuildd.target.snapstore import SnapStoreOperationMixin
RETCODE_FAILURE_INSTALL = 200
@@ -29,7 +30,7 @@
return os.path.join(os.environ["HOME"], "build-" + build_id, *extra)
-class BuildLiveFS(Operation):
+class BuildLiveFS(SnapStoreOperationMixin, Operation):
description = "Build a live file system."
@@ -94,6 +95,8 @@
if self.backend.is_package_available(dep):
deps.append(dep)
self.backend.run(["apt-get", "-y", "install"] + deps)
+ if self.args.backend in ("lxd", "fake"):
+ self.snap_store_set_proxy()
if self.args.arch == "i386":
self.backend.run([
"apt-get", "-y", "--no-install-recommends", "install",
=== modified file 'lpbuildd/target/build_snap.py'
--- lpbuildd/target/build_snap.py 2018-10-11 08:59:22 +0000
+++ lpbuildd/target/build_snap.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2015-2017 Canonical Ltd. This software is licensed under the
+# Copyright 2015-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
from __future__ import print_function
@@ -18,6 +18,7 @@
from urlparse import urlparse
from lpbuildd.target.operation import Operation
+from lpbuildd.target.snapstore import SnapStoreOperationMixin
from lpbuildd.target.vcs import VCSOperationMixin
@@ -28,7 +29,7 @@
logger = logging.getLogger(__name__)
-class BuildSnap(VCSOperationMixin, Operation):
+class BuildSnap(VCSOperationMixin, SnapStoreOperationMixin, Operation):
description = "Build a snap."
@@ -126,6 +127,8 @@
else:
deps.append("snapcraft")
self.backend.run(["apt-get", "-y", "install"] + deps)
+ if self.args.backend in ("lxd", "fake"):
+ self.snap_store_set_proxy()
if self.args.channel_core:
self.backend.run(
["snap", "install",
=== added file 'lpbuildd/target/snapstore.py'
--- lpbuildd/target/snapstore.py 1970-01-01 00:00:00 +0000
+++ lpbuildd/target/snapstore.py 2019-01-28 15:15:21 +0000
@@ -0,0 +1,54 @@
+# Copyright 2019 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+from __future__ import print_function
+
+__metaclass__ = type
+
+import requests
+from six.moves.urllib.parse import (
+ urljoin,
+ urlparse,
+ urlunparse,
+ )
+
+
+class SnapStoreOperationMixin:
+ """Methods supporting operations that interact with the snap store."""
+
+ @classmethod
+ def add_arguments(cls, parser):
+ super(SnapStoreOperationMixin, cls).add_arguments(parser)
+ parser.add_argument(
+ "--snap-store-proxy-url", metavar="URL",
+ help="snap store proxy URL")
+
+ def snap_store_set_proxy(self):
+ if self.args.snap_store_proxy_url is None:
+ return
+ # Canonicalise: proxy registration always sends only the scheme and
+ # domain.
+ parsed_url = urlparse(self.args.snap_store_proxy_url)
+ canonical_url = urlunparse(
+ [parsed_url.scheme, parsed_url.netloc, "", "", "", ""])
+ assertions_response = requests.get(
+ urljoin(canonical_url, "v2/auth/store/assertions"))
+ assertions_response.raise_for_status()
+ self.backend.run(
+ ["snap", "ack", "/dev/stdin"], input_text=assertions_response.text)
+ store_assertion = self.backend.run(
+ ["snap", "known", "store", "url={}".format(canonical_url)],
+ get_output=True)
+ # Very cheap parser. Not at all robust, but snapd has already
+ # handled validation for us, and if we get more than one assertion
+ # back from "snap known" despite filtering then we only care about
+ # the first.
+ for line in store_assertion.split("\n\n")[0].splitlines():
+ if line.startswith("store: "):
+ store_id = line[len("store: "):]
+ break
+ else:
+ store_id = None
+ if store_id is not None:
+ self.backend.run(
+ ["snap", "set", "core", "proxy.store={}".format(store_id)])
=== modified file 'lpbuildd/target/tests/test_apt.py'
--- lpbuildd/target/tests/test_apt.py 2017-08-22 15:55:44 +0000
+++ lpbuildd/target/tests/test_apt.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2017 Canonical Ltd. This software is licensed under the
+# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -53,6 +53,27 @@
""").encode("UTF-8"), stat.S_IFREG | 0o644),
override_sources_list.backend.backend_fs["/etc/apt/sources.list"])
+ def test_apt_proxy(self):
+ args = [
+ "override-sources-list",
+ "--backend=fake", "--series=xenial", "--arch=amd64", "1",
+ "--apt-proxy-url", "http://apt-proxy.example:3128/",
+ "deb http://archive.ubuntu.com/ubuntu xenial main",
+ ]
+ override_sources_list = parse_args(args=args).operation
+ self.assertEqual(0, override_sources_list.run())
+ self.assertEqual(
+ (dedent("""\
+ deb http://archive.ubuntu.com/ubuntu xenial main
+ """).encode("UTF-8"), stat.S_IFREG | 0o644),
+ override_sources_list.backend.backend_fs["/etc/apt/sources.list"])
+ self.assertEqual(
+ (dedent("""\
+ Acquire::http::Proxy "http://apt-proxy.example:3128/";
+ """).encode("UTF-8"), stat.S_IFREG | 0o644),
+ override_sources_list.backend.backend_fs[
+ "/etc/apt/apt.conf.d/99proxy"])
+
class TestAddTrustedKeys(TestCase):
=== modified file 'lpbuildd/target/tests/test_build_livefs.py'
--- lpbuildd/target/tests/test_build_livefs.py 2018-01-12 20:01:24 +0000
+++ lpbuildd/target/tests/test_build_livefs.py 2019-01-28 15:15:21 +0000
@@ -1,11 +1,13 @@
-# Copyright 2017 Canonical Ltd. This software is licensed under the
+# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
import subprocess
+from textwrap import dedent
from fixtures import FakeLogger
+import responses
from testtools import TestCase
from testtools.matchers import (
AnyMatch,
@@ -26,12 +28,17 @@
class RanCommand(MatchesListwise):
- def __init__(self, args, echo=None, cwd=None, **env):
+ def __init__(self, args, echo=None, cwd=None, input_text=None,
+ get_output=None, **env):
kwargs_matcher = {}
if echo is not None:
kwargs_matcher["echo"] = Is(echo)
if cwd:
kwargs_matcher["cwd"] = Equals(cwd)
+ if input_text:
+ kwargs_matcher["input_text"] = Equals(input_text)
+ if get_output is not None:
+ kwargs_matcher["get_output"] = Is(get_output)
if env:
kwargs_matcher["env"] = MatchesDict(
{key: Equals(value) for key, value in env.items()})
@@ -113,6 +120,44 @@
"--install-recommends", "install", "ubuntu-defaults-builder"),
]))
+ @responses.activate
+ def test_install_snap_store_proxy(self):
+ store_assertion = dedent("""\
+ type: store
+ store: store-id
+ url: http://snap-store-proxy.example
+
+ body
+ """)
+
+ class SnapCommands(FakeMethod):
+ def __call__(self, run_args, *args, **kwargs):
+ super(SnapCommands, self).__call__(run_args, *args, **kwargs)
+ if run_args[0] == "snap" and run_args[1] == "known":
+ return store_assertion
+
+ responses.add(
+ "GET", "http://snap-store-proxy.example/v2/auth/store/assertions",
+ body=store_assertion)
+ args = [
+ "buildlivefs",
+ "--backend=fake", "--series=xenial", "--arch=amd64", "1",
+ "--snap-store-proxy-url", "http://snap-store-proxy.example/",
+ ]
+ build_livefs = parse_args(args=args).operation
+ build_livefs.backend.run = SnapCommands()
+ build_livefs.install()
+ self.assertThat(build_livefs.backend.run.calls, MatchesListwise([
+ RanAptGet("install", "livecd-rootfs"),
+ RanCommand(
+ ["snap", "ack", "/dev/stdin"], input_text=store_assertion),
+ RanCommand(
+ ["snap", "known", "store",
+ "url=http://snap-store-proxy.example"],
+ get_output=True),
+ RanCommand(["snap", "set", "core", "proxy.store=store-id"]),
+ ]))
+
def test_build(self):
args = [
"buildlivefs",
=== modified file 'lpbuildd/target/tests/test_build_snap.py'
--- lpbuildd/target/tests/test_build_snap.py 2018-10-11 08:59:22 +0000
+++ lpbuildd/target/tests/test_build_snap.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2017 Canonical Ltd. This software is licensed under the
+# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -7,11 +7,13 @@
import os.path
import stat
import subprocess
+from textwrap import dedent
from fixtures import (
FakeLogger,
TempDir,
)
+import responses
from systemfixtures import FakeFilesystem
from testtools import TestCase
from testtools.matchers import (
@@ -33,14 +35,17 @@
class RanCommand(MatchesListwise):
- def __init__(self, args, get_output=None, echo=None, cwd=None, **env):
+ def __init__(self, args, echo=None, cwd=None, input_text=None,
+ get_output=None, **env):
kwargs_matcher = {}
- if get_output is not None:
- kwargs_matcher["get_output"] = Is(get_output)
if echo is not None:
kwargs_matcher["echo"] = Is(echo)
if cwd:
kwargs_matcher["cwd"] = Equals(cwd)
+ if input_text:
+ kwargs_matcher["input_text"] = Equals(input_text)
+ if get_output is not None:
+ kwargs_matcher["get_output"] = Is(get_output)
if env:
kwargs_matcher["env"] = MatchesDict(
{key: Equals(value) for key, value in env.items()})
@@ -132,6 +137,46 @@
RanAptGet("install", "git", "snapcraft"),
]))
+ @responses.activate
+ def test_install_snap_store_proxy(self):
+ store_assertion = dedent("""\
+ type: store
+ store: store-id
+ url: http://snap-store-proxy.example
+
+ body
+ """)
+
+ class SnapCommands(FakeMethod):
+ def __call__(self, run_args, *args, **kwargs):
+ super(SnapCommands, self).__call__(run_args, *args, **kwargs)
+ if run_args[0] == "snap" and run_args[1] == "known":
+ return store_assertion
+
+ responses.add(
+ "GET", "http://snap-store-proxy.example/v2/auth/store/assertions",
+ body=store_assertion)
+ args = [
+ "buildsnap",
+ "--backend=fake", "--series=xenial", "--arch=amd64", "1",
+ "--git-repository", "lp:foo",
+ "--snap-store-proxy-url", "http://snap-store-proxy.example/",
+ "test-snap",
+ ]
+ build_snap = parse_args(args=args).operation
+ build_snap.backend.run = SnapCommands()
+ build_snap.install()
+ self.assertThat(build_snap.backend.run.calls, MatchesListwise([
+ RanAptGet("install", "git", "snapcraft"),
+ RanCommand(
+ ["snap", "ack", "/dev/stdin"], input_text=store_assertion),
+ RanCommand(
+ ["snap", "known", "store",
+ "url=http://snap-store-proxy.example"],
+ get_output=True),
+ RanCommand(["snap", "set", "core", "proxy.store=store-id"]),
+ ]))
+
def test_install_proxy(self):
args = [
"buildsnap",
=== modified file 'lpbuildd/tests/fakeslave.py'
--- lpbuildd/tests/fakeslave.py 2017-11-10 20:55:33 +0000
+++ lpbuildd/tests/fakeslave.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2013 Canonical Ltd. This software is licensed under the
+# Copyright 2013-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -9,12 +9,18 @@
'UncontainedBackend',
]
+from collections import defaultdict
import hashlib
import os
import shutil
import stat
import subprocess
+from six.moves.configparser import (
+ NoOptionError,
+ NoSectionError,
+ )
+
from lpbuildd.target.backend import Backend
from lpbuildd.util import (
set_personality,
@@ -78,8 +84,22 @@
class FakeConfig:
+ def __init__(self):
+ self._overrides = defaultdict(dict)
+
def get(self, section, key):
- return key
+ if key in self._overrides[section]:
+ return self._overrides[section][key]
+ elif section == "proxy":
+ if not self._overrides[section]:
+ raise NoSectionError(section)
+ else:
+ raise NoOptionError(section, key)
+ else:
+ return key
+
+ def set(self, section, key, value):
+ self._overrides[section][key] = value
class FakeSlave:
=== modified file 'lpbuildd/tests/test_debian.py'
--- lpbuildd/tests/test_debian.py 2018-05-02 09:00:10 +0000
+++ lpbuildd/tests/test_debian.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2017 Canonical Ltd. This software is licensed under the
+# Copyright 2017-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -421,3 +421,33 @@
self.assertTrue(self.slave.wasCalled('buildOK'))
self.assertTrue(self.slave.wasCalled('buildComplete'))
+ def test_iterate_apt_proxy(self):
+ # The build manager can be configured to use an APT proxy.
+ self.slave._config.set(
+ 'proxy', 'apt', 'http://apt-proxy.example:3128/')
+ extra_args = {
+ 'arch_tag': 'amd64',
+ 'archives': [
+ 'deb http://ppa.launchpad.dev/owner/name/ubuntu xenial main',
+ ],
+ 'series': 'xenial',
+ }
+ self.startBuild(extra_args)
+
+ self.buildmanager.iterate(0)
+ self.assertEqual(DebianBuildState.UNPACK, self.getState())
+ self.buildmanager.iterate(0)
+ self.assertEqual(DebianBuildState.MOUNT, self.getState())
+ self.buildmanager.iterate(0)
+ self.assertEqual(DebianBuildState.SOURCES, self.getState())
+ self.assertEqual(
+ (['sharepath/slavebin/in-target', 'in-target',
+ 'override-sources-list',
+ '--backend=chroot', '--series=xenial', '--arch=amd64',
+ self.buildid,
+ '--apt-proxy-url', 'http://apt-proxy.example:3128/',
+ 'deb http://ppa.launchpad.dev/owner/name/ubuntu xenial main'],
+ None),
+ self.buildmanager.commands[-1])
+ self.assertEqual(
+ self.buildmanager.iterate, self.buildmanager.iterators[-1])
=== modified file 'lpbuildd/tests/test_livefs.py'
--- lpbuildd/tests/test_livefs.py 2018-10-05 15:43:40 +0000
+++ lpbuildd/tests/test_livefs.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2013-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2013-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -58,7 +58,7 @@
return self.buildmanager._state
@defer.inlineCallbacks
- def startBuild(self):
+ def startBuild(self, options=None):
# The build manager's iterate() kicks off the consecutive states
# after INIT.
extra_args = {
@@ -86,6 +86,8 @@
"--backend=lxd", "--series=saucy", "--arch=i386", self.buildid,
"--project", "ubuntu",
]
+ if options is not None:
+ expected_command.extend(options)
self.assertEqual(expected_command, self.buildmanager.commands[-1])
self.assertEqual(
self.buildmanager.iterate, self.buildmanager.iterators[-1])
@@ -134,6 +136,15 @@
self.assertFalse(self.slave.wasCalled("buildFail"))
@defer.inlineCallbacks
+ def test_iterate_snap_store_proxy(self):
+ # The build manager can be told to use a snap store proxy.
+ self.slave._config.set(
+ "proxy", "snapstore", "http://snap-store-proxy.example/")
+ expected_options = [
+ "--snap-store-proxy-url", "http://snap-store-proxy.example/"]
+ yield self.startBuild(options=expected_options)
+
+ @defer.inlineCallbacks
def test_omits_symlinks(self):
# Symlinks in the build output are not included in gathered results.
yield self.startBuild()
=== modified file 'lpbuildd/tests/test_snap.py'
--- lpbuildd/tests/test_snap.py 2018-10-05 15:43:40 +0000
+++ lpbuildd/tests/test_snap.py 2019-01-28 15:15:21 +0000
@@ -1,4 +1,4 @@
-# Copyright 2015-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2015-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -252,6 +252,15 @@
self.buildmanager.iterate, self.buildmanager.iterators[-1])
self.assertFalse(self.slave.wasCalled("buildFail"))
+ @defer.inlineCallbacks
+ def test_iterate_snap_store_proxy(self):
+ # The build manager can be told to use a snap store proxy.
+ self.slave._config.set(
+ "proxy", "snapstore", "http://snap-store-proxy.example/")
+ expected_options = [
+ "--snap-store-proxy-url", "http://snap-store-proxy.example/"]
+ yield self.startBuild(options=expected_options)
+
def getListenerURL(self, listener):
port = listener.getHost().port
return b"http://localhost:%d/" % port
=== modified file 'setup.py'
--- setup.py 2018-10-25 09:04:12 +0000
+++ setup.py 2019-01-28 15:15:21 +0000
@@ -1,6 +1,6 @@
#!/usr/bin/env python
-# Copyright 2015 Canonical Ltd. All rights reserved.
+# Copyright 2015-2019 Canonical Ltd. All rights reserved.
#
# This file is part of launchpad-buildd.
#
@@ -59,6 +59,8 @@
# causes problems for Launchpad's build system.
#'python-apt',
'python-debian>=0.1.23',
+ 'requests',
+ 'six',
'Twisted',
'zope.interface',
],
@@ -69,6 +71,7 @@
tests_require=[
'fixtures',
'mock',
+ 'responses',
'systemfixtures',
'testtools',
'txfixtures',