← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~andrey-fedoseev/launchpad-buildd:snap-target-architectures into launchpad-buildd:master

 

Andrey Fedoseev has proposed merging ~andrey-fedoseev/launchpad-buildd:snap-target-architectures into launchpad-buildd:master.

Commit message:
Allow specifying target architectures for snaps
    
The list of target architectures is passed as an extra argument to `SnapBuildManager`
    
At the moment, we use only the first architecture from the list as
snapcraft doesn't allow multi-arch at the moment.
    
The target architecture is passed to `snapcraft` via
`SNAPCRAFT_BUILD_TO` env variable

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~andrey-fedoseev/launchpad-buildd/+git/launchpad-buildd/+merge/424145
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~andrey-fedoseev/launchpad-buildd:snap-target-architectures into launchpad-buildd:master.
diff --git a/lpbuildd/snap.py b/lpbuildd/snap.py
index 8d1d2c6..720b1d8 100644
--- a/lpbuildd/snap.py
+++ b/lpbuildd/snap.py
@@ -51,6 +51,7 @@ class SnapBuildManager(BuildManagerProxyMixin, DebianBuildManager):
             "build_source_tarball", False)
         self.private = extra_args.get("private", False)
         self.proxy_service = None
+        self.target_architectures = extra_args.get("target_architectures")
 
         super().initiate(files, chroot, extra_args)
 
@@ -85,6 +86,9 @@ class SnapBuildManager(BuildManagerProxyMixin, DebianBuildManager):
             args.extend(["--snap-store-proxy-url", snap_store_proxy_url])
         except (NoSectionError, NoOptionError):
             pass
+        if self.target_architectures:
+            for arch in self.target_architectures:
+                args.extend(["--target-arch", arch])
         args.append(self.name)
         self.runTargetSubProcess("buildsnap", *args)
 
diff --git a/lpbuildd/target/build_snap.py b/lpbuildd/target/build_snap.py
index a4930b8..5fdfcc8 100644
--- a/lpbuildd/target/build_snap.py
+++ b/lpbuildd/target/build_snap.py
@@ -71,6 +71,12 @@ class BuildSnap(BuilderProxyOperationMixin, VCSOperationMixin,
         parser.add_argument(
             "--private", default=False, action="store_true",
             help="build a private snap")
+        parser.add_argument(
+            "--target-arch",
+            dest="target_architectures",
+            action="append",
+            help="build for the specified architectures"
+        )
         parser.add_argument("name", help="name of snap to build")
 
     def install_svn_servers(self):
@@ -179,6 +185,8 @@ class BuildSnap(BuilderProxyOperationMixin, VCSOperationMixin,
             env["SNAPCRAFT_BUILD_INFO"] = "1"
         env["SNAPCRAFT_IMAGE_INFO"] = self.image_info
         env["SNAPCRAFT_BUILD_ENVIRONMENT"] = "host"
+        if self.args.target_architectures:
+            env["SNAPCRAFT_BUILD_TO"] = self.args.target_architectures[0]
         self.run_build_command(
             ["snapcraft"],
             cwd=os.path.join("/build", self.args.name),
diff --git a/lpbuildd/target/tests/test_build_snap.py b/lpbuildd/target/tests/test_build_snap.py
index d9025eb..c625abe 100644
--- a/lpbuildd/target/tests/test_build_snap.py
+++ b/lpbuildd/target/tests/test_build_snap.py
@@ -473,6 +473,24 @@ class TestBuildSnap(TestCase):
                 SNAPCRAFT_BUILD_ENVIRONMENT="host"),
             ]))
 
+    def test_build_target_architectures(self):
+        args = [
+            "buildsnap",
+            "--backend=fake", "--series=xenial", "--arch=amd64", "1",
+            "--branch", "lp:foo",
+            "--target-arch", "i386",
+            "--target-arch", "amd64",
+            "test-snap",
+            ]
+        build_snap = parse_args(args=args).operation
+        build_snap.build()
+        self.assertThat(build_snap.backend.run.calls, MatchesListwise([
+            RanBuildCommand(
+                ["snapcraft"], cwd="/build/test-snap",
+                SNAPCRAFT_BUILD_INFO="1", SNAPCRAFT_IMAGE_INFO="{}",
+                SNAPCRAFT_BUILD_ENVIRONMENT="host", SNAPCRAFT_BUILD_TO="i386"),
+            ]))
+
     # XXX cjwatson 2017-08-07: Test revoke_token.  It may be easiest to
     # convert it to requests first.
 
diff --git a/lpbuildd/tests/test_snap.py b/lpbuildd/tests/test_snap.py
index 59f0446..c2bce38 100644
--- a/lpbuildd/tests/test_snap.py
+++ b/lpbuildd/tests/test_snap.py
@@ -446,6 +446,27 @@ class TestSnapBuildManagerIteration(TestCase):
             "--snap-store-proxy-url", "http://snap-store-proxy.example/";]
         yield self.startBuild(options=expected_options)
 
+    @defer.inlineCallbacks
+    def test_iterate_target_architectures(self):
+        args = {
+            "build_request_id": 13,
+            "build_request_timestamp": "2018-04-13T14:50:02Z",
+            "build_url": "https://launchpad.example/build";,
+            "git_repository": "https://git.launchpad.dev/~example/+git/snap";,
+            "git_path": "master",
+            "target_architectures": ["i386", "amd64"],
+            }
+        expected_options = [
+            "--build-request-id", "13",
+            "--build-request-timestamp", "2018-04-13T14:50:02Z",
+            "--build-url", "https://launchpad.example/build";,
+            "--git-repository", "https://git.launchpad.dev/~example/+git/snap";,
+            "--git-path", "master",
+            "--target-arch", "i386",
+            "--target-arch", "amd64",
+            ]
+        yield self.startBuild(args, expected_options)
+
     def getListenerURL(self, listener):
         port = listener.getHost().port
         return "http://localhost:%d/"; % port