← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~pelpsi/launchpad-buildd:snapd-proxy-configuration into launchpad-buildd:master

 

Simone Pelosi has proposed merging ~pelpsi/launchpad-buildd:snapd-proxy-configuration into launchpad-buildd:master.

Commit message:
Add snapd proxy configuration
    
This configuration is required for remote builds to correctly
interact with snapcraft using the fetch-service.


Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~pelpsi/launchpad-buildd/+git/launchpad-buildd/+merge/467056
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~pelpsi/launchpad-buildd:snapd-proxy-configuration into launchpad-buildd:master.
diff --git a/lpbuildd/target/build_snap.py b/lpbuildd/target/build_snap.py
index 8cf414e..2c7c295 100644
--- a/lpbuildd/target/build_snap.py
+++ b/lpbuildd/target/build_snap.py
@@ -123,8 +123,7 @@ class BuildSnap(
         requests when fetching dependencies.
         """
         with self.backend.open(
-            "/usr/local/share/ca-certificates/local-ca.crt",
-            mode="wb"
+            "/usr/local/share/ca-certificates/local-ca.crt", mode="wb"
         ) as local_ca_cert:
             # Certificate is passed as a Base64 encoded string.
             # It's encoded using `base64 -w0` on the cert file.
@@ -217,7 +216,10 @@ class BuildSnap(
     def repo(self):
         """Collect git or bzr branch."""
         logger.info("Running repo phase...")
-        env = self.build_proxy_environment(proxy_url=self.args.proxy_url)
+        env = self.build_proxy_environment(
+            proxy_url=self.args.proxy_url,
+            use_fetch_service=self.args.use_fetch_service,
+        )
         self.vcs_fetch(self.args.name, cwd="/build", env=env)
         self.vcs_update_status(os.path.join("/build", self.args.name))
 
@@ -235,7 +237,10 @@ class BuildSnap(
     def pull(self):
         """Run pull phase."""
         logger.info("Running pull phase...")
-        env = self.build_proxy_environment(proxy_url=self.args.proxy_url)
+        env = self.build_proxy_environment(
+            proxy_url=self.args.proxy_url,
+            use_fetch_service=self.args.use_fetch_service,
+        )
         env["SNAPCRAFT_LOCAL_SOURCES"] = "1"
         env["SNAPCRAFT_SETUP_CORE"] = "1"
         if not self.args.private:
@@ -281,7 +286,10 @@ class BuildSnap(
     def build(self):
         """Run all build, stage and snap phases."""
         logger.info("Running build phase...")
-        env = self.build_proxy_environment(proxy_url=self.args.proxy_url)
+        env = self.build_proxy_environment(
+            proxy_url=self.args.proxy_url,
+            use_fetch_service=self.args.use_fetch_service,
+        )
         if not self.args.private:
             env["SNAPCRAFT_BUILD_INFO"] = "1"
         env["SNAPCRAFT_IMAGE_INFO"] = self.image_info
diff --git a/lpbuildd/target/proxy.py b/lpbuildd/target/proxy.py
index 2f264c1..9905747 100644
--- a/lpbuildd/target/proxy.py
+++ b/lpbuildd/target/proxy.py
@@ -32,7 +32,9 @@ class BuilderProxyOperationMixin:
             "/usr/local/bin/lpbuildd-git-proxy",
         )
 
-    def build_proxy_environment(self, proxy_url=None, env=None):
+    def build_proxy_environment(
+        self, proxy_url=None, env=None, use_fetch_service=False
+    ):
         """Extend a command environment to include http proxy variables."""
         full_env = OrderedDict()
         if env:
@@ -44,4 +46,11 @@ class BuilderProxyOperationMixin:
             # Avoid needing to keep track of snap store CDNs in proxy
             # configuration.
             full_env["SNAPPY_STORE_NO_CDN"] = "1"
+        if use_fetch_service:
+            self.backend.run(
+                ["snap", "set", "system", f"proxy.http={proxy_url}"]
+            )
+            self.backend.run(
+                ["snap", "set", "system", f"proxy.https={proxy_url}"]
+            )
         return full_env
diff --git a/lpbuildd/target/tests/test_build_snap.py b/lpbuildd/target/tests/test_build_snap.py
index 33b1e0d..4db8b1c 100644
--- a/lpbuildd/target/tests/test_build_snap.py
+++ b/lpbuildd/target/tests/test_build_snap.py
@@ -539,6 +539,84 @@ class TestBuildSnap(TestCase):
         with open(status_path) as status:
             self.assertEqual({"revision_id": "0" * 40}, json.load(status))
 
+    def test_repo_fetch_service(self):
+        args = [
+            "buildsnap",
+            "--backend=fake",
+            "--series=xenial",
+            "--arch=amd64",
+            "1",
+            "--git-repository",
+            "lp:foo",
+            "--proxy-url",
+            "http://proxy.example:3128/";,
+            "test-snap",
+            "--use_fetch_service",
+        ]
+        build_snap = parse_args(args=args).operation
+        build_snap.backend.build_path = self.useFixture(TempDir()).path
+        build_snap.backend.run = FakeRevisionID("0" * 40)
+        build_snap.repo()
+        env = {
+            "http_proxy": "http://proxy.example:3128/";,
+            "https_proxy": "http://proxy.example:3128/";,
+            "GIT_PROXY_COMMAND": "/usr/local/bin/lpbuildd-git-proxy",
+            "SNAPPY_STORE_NO_CDN": "1",
+        }
+        self.assertThat(
+            build_snap.backend.run.calls,
+            MatchesListwise(
+                [
+                    RanCommand(
+                        [
+                            "snap",
+                            "set",
+                            "system",
+                            "proxy.http=http://proxy.example:3128/";,
+                        ]
+                    ),
+                    RanCommand(
+                        [
+                            "snap",
+                            "set",
+                            "system",
+                            "proxy.https=http://proxy.example:3128/";,
+                        ]
+                    ),
+                    RanBuildCommand(
+                        ["git", "clone", "-n", "lp:foo", "test-snap"],
+                        cwd="/build",
+                        **env,
+                    ),
+                    RanBuildCommand(
+                        ["git", "checkout", "-q", "HEAD"],
+                        cwd="/build/test-snap",
+                        **env,
+                    ),
+                    RanBuildCommand(
+                        [
+                            "git",
+                            "submodule",
+                            "update",
+                            "--init",
+                            "--recursive",
+                        ],
+                        cwd="/build/test-snap",
+                        **env,
+                    ),
+                    RanBuildCommand(
+                        ["git", "rev-parse", "HEAD^{}"],
+                        cwd="/build/test-snap",
+                        get_output=True,
+                        universal_newlines=True,
+                    ),
+                ]
+            ),
+        )
+        status_path = os.path.join(build_snap.backend.build_path, "status")
+        with open(status_path) as status:
+            self.assertEqual({"revision_id": "0" * 40}, json.load(status))
+
     def test_pull(self):
         args = [
             "buildsnap",
@@ -611,6 +689,64 @@ class TestBuildSnap(TestCase):
             ),
         )
 
+    def test_pull_fetch_service(self):
+        args = [
+            "buildsnap",
+            "--backend=fake",
+            "--series=xenial",
+            "--arch=amd64",
+            "1",
+            "--build-url",
+            "https://launchpad.example/build";,
+            "--branch",
+            "lp:foo",
+            "--proxy-url",
+            "http://proxy.example:3128/";,
+            "test-snap",
+            "--use_fetch_service",
+        ]
+        build_snap = parse_args(args=args).operation
+        build_snap.pull()
+        env = {
+            "SNAPCRAFT_LOCAL_SOURCES": "1",
+            "SNAPCRAFT_SETUP_CORE": "1",
+            "SNAPCRAFT_BUILD_INFO": "1",
+            "SNAPCRAFT_IMAGE_INFO": (
+                '{"build_url": "https://launchpad.example/build"}'
+            ),
+            "SNAPCRAFT_BUILD_ENVIRONMENT": "host",
+            "http_proxy": "http://proxy.example:3128/";,
+            "https_proxy": "http://proxy.example:3128/";,
+            "GIT_PROXY_COMMAND": "/usr/local/bin/lpbuildd-git-proxy",
+            "SNAPPY_STORE_NO_CDN": "1",
+        }
+        self.assertThat(
+            build_snap.backend.run.calls,
+            MatchesListwise(
+                [
+                    RanCommand(
+                        [
+                            "snap",
+                            "set",
+                            "system",
+                            "proxy.http=http://proxy.example:3128/";,
+                        ]
+                    ),
+                    RanCommand(
+                        [
+                            "snap",
+                            "set",
+                            "system",
+                            "proxy.https=http://proxy.example:3128/";,
+                        ]
+                    ),
+                    RanBuildCommand(
+                        ["snapcraft", "pull"], cwd="/build/test-snap", **env
+                    ),
+                ]
+            ),
+        )
+
     @responses.activate
     def test_pull_disable_proxy_after_pull(self):
         self.useFixture(FakeLogger())
@@ -827,6 +963,69 @@ class TestBuildSnap(TestCase):
             ),
         )
 
+    def test_build_fetch_service(self):
+        args = [
+            "buildsnap",
+            "--backend=fake",
+            "--series=xenial",
+            "--arch=amd64",
+            "1",
+            "--build-url",
+            "https://launchpad.example/build";,
+            "--branch",
+            "lp:foo",
+            "--proxy-url",
+            "http://proxy.example:3128/";,
+            "test-snap",
+            "--use_fetch_service",
+        ]
+        build_snap = parse_args(args=args).operation
+        build_snap.backend.run = FakeSnapcraft(
+            build_snap.backend, "test-snap_1.snap"
+        )
+        build_snap.build()
+        env = {
+            "SNAPCRAFT_BUILD_INFO": "1",
+            "SNAPCRAFT_IMAGE_INFO": (
+                '{"build_url": "https://launchpad.example/build"}'
+            ),
+            "SNAPCRAFT_BUILD_ENVIRONMENT": "host",
+            "http_proxy": "http://proxy.example:3128/";,
+            "https_proxy": "http://proxy.example:3128/";,
+            "GIT_PROXY_COMMAND": "/usr/local/bin/lpbuildd-git-proxy",
+            "SNAPPY_STORE_NO_CDN": "1",
+        }
+        self.assertThat(
+            build_snap.backend.run.calls,
+            MatchesListwise(
+                [
+                    RanCommand(
+                        [
+                            "snap",
+                            "set",
+                            "system",
+                            "proxy.http=http://proxy.example:3128/";,
+                        ]
+                    ),
+                    RanCommand(
+                        [
+                            "snap",
+                            "set",
+                            "system",
+                            "proxy.https=http://proxy.example:3128/";,
+                        ]
+                    ),
+                    RanBuildCommand(
+                        ["snapcraft"], cwd="/build/test-snap", **env
+                    ),
+                    RanBuildCommand(
+                        ["sha512sum", "test-snap_1.snap"],
+                        cwd="/build/test-snap",
+                    ),
+                ]
+            ),
+        )
+
     def test_build_private(self):
         args = [
             "buildsnap",