summary refs log tree commit diff
path: root/pkgs/build-support/snap
diff options
context:
space:
mode:
authorGraham Christensen <graham@grahamc.com>2019-06-18 18:51:58 +0200
committerGraham Christensen <graham@grahamc.com>2019-06-18 18:51:58 +0200
commita82901fb5e7f244d2db6b1e6a90e9a7a23ca588a (patch)
tree66b4e9a0ef69c439117e370ee885b980812e9527 /pkgs/build-support/snap
parentb5cf5ff20f92d790b703db00d202a72231943845 (diff)
downloadnixpkgs-a82901fb5e7f244d2db6b1e6a90e9a7a23ca588a.tar
nixpkgs-a82901fb5e7f244d2db6b1e6a90e9a7a23ca588a.tar.gz
nixpkgs-a82901fb5e7f244d2db6b1e6a90e9a7a23ca588a.tar.bz2
nixpkgs-a82901fb5e7f244d2db6b1e6a90e9a7a23ca588a.tar.lz
nixpkgs-a82901fb5e7f244d2db6b1e6a90e9a7a23ca588a.tar.xz
nixpkgs-a82901fb5e7f244d2db6b1e6a90e9a7a23ca588a.tar.zst
nixpkgs-a82901fb5e7f244d2db6b1e6a90e9a7a23ca588a.zip
snapTools.makeSnap: init
Diffstat (limited to 'pkgs/build-support/snap')
-rw-r--r--pkgs/build-support/snap/default.nix4
-rw-r--r--pkgs/build-support/snap/example-firefox.nix28
-rw-r--r--pkgs/build-support/snap/example-hello.nix12
-rw-r--r--pkgs/build-support/snap/make-snap.nix84
4 files changed, 128 insertions, 0 deletions
diff --git a/pkgs/build-support/snap/default.nix b/pkgs/build-support/snap/default.nix
new file mode 100644
index 00000000000..ba527186891
--- /dev/null
+++ b/pkgs/build-support/snap/default.nix
@@ -0,0 +1,4 @@
+{ callPackage, hello }:
+{
+  makeSnap = callPackage ./make-snap.nix { };
+}
diff --git a/pkgs/build-support/snap/example-firefox.nix b/pkgs/build-support/snap/example-firefox.nix
new file mode 100644
index 00000000000..d58c98a65a2
--- /dev/null
+++ b/pkgs/build-support/snap/example-firefox.nix
@@ -0,0 +1,28 @@
+let
+  inherit (import <nixpkgs> { }) snapTools firefox;
+in snapTools.makeSnap {
+  meta = {
+    name = "nix-example-firefox";
+    summary = firefox.meta.description;
+    architectures = [ "amd64" ];
+    apps.nix-example-firefox = {
+      command = "${firefox}/bin/firefox";
+      plugs = [
+        "pulseaudio"
+        "camera"
+        "browser-support"
+        "avahi-observe"
+        "cups-control"
+        "desktop"
+        "desktop-legacy"
+        "gsettings"
+        "home"
+        "network"
+        "mount-observe"
+        "removable-media"
+        "x11"
+      ];
+    };
+    confinement = "strict";
+  };
+}
diff --git a/pkgs/build-support/snap/example-hello.nix b/pkgs/build-support/snap/example-hello.nix
new file mode 100644
index 00000000000..123da80c547
--- /dev/null
+++ b/pkgs/build-support/snap/example-hello.nix
@@ -0,0 +1,12 @@
+let
+  inherit (import <nixpkgs> { }) snapTools hello;
+in snapTools.makeSnap {
+  meta = {
+    name = "hello";
+    summary = hello.meta.description;
+    description = hello.meta.longDescription;
+    architectures = [ "amd64" ];
+    confinement = "strict";
+    apps.hello.command = "${hello}/bin/hello";
+  };
+}
diff --git a/pkgs/build-support/snap/make-snap.nix b/pkgs/build-support/snap/make-snap.nix
new file mode 100644
index 00000000000..cef7500bcba
--- /dev/null
+++ b/pkgs/build-support/snap/make-snap.nix
@@ -0,0 +1,84 @@
+{
+  runCommand, squashfsTools, closureInfo, lib, jq, writeText
+}:
+
+{
+  # The meta parameter is the contents of the `snap.yaml`, NOT the
+  # `snapcraft.yaml`.
+  #
+  # - `snap.yaml` is what is inside of the final Snap,
+  # - `snapcraft.yaml` is used by `snapcraft` to build snaps
+  #
+  # Since we skip the `snapcraft` tool, we skip the `snapcraft.yaml`
+  # file. For more information:
+  #
+  #   https://docs.snapcraft.io/snap-format
+  #
+  # Note: unsquashfs'ing an existing snap from the store can be helpful
+  # for determining what you you're missing.
+  #
+  meta
+}: let
+    snap_yaml = let
+      # Validate the snap's meta contains a name.
+      # Also: automatically set the `base` parameter and the layout for
+      # the `/nix` bind.
+      validate = { name, ... } @ args:
+        args // {
+          # Combine the provided arguments with the required options.
+
+          # base: built from https://github.com/NixOS/snapd-nix-base
+          # and published as The NixOS Foundation on the Snapcraft store.
+          base = "nix-base";
+          layout = (args.layout or {}) // {
+            # Bind mount the Snap's root nix directory to `/nix` in the
+            # execution environment's filesystem namespace.
+            "/nix".bind = "$SNAP/nix";
+          };
+        };
+    in writeText "snap.yaml"
+      (builtins.toJSON (validate meta));
+
+  # These are specifically required by snapd, so don't change them
+  # unless you've verified snapcraft / snapd can handle them. Best bet
+  # is to just mirror this list against how snapcraft creates images.
+  # from: https://github.com/snapcore/snapcraft/blob/b88e378148134383ffecf3658e3a940b67c9bcc9/snapcraft/internal/lifecycle/_packer.py#L96-L98
+  mksquashfs_args = [
+    "-noappend" "-comp" "xz" "-no-xattrs" "-no-fragments"
+
+    # Note: We want -all-root every time, since all the files are
+    # owned by root anyway. This is true for Nix, but not true for
+    # other builds.
+    # from: https://github.com/snapcore/snapcraft/blob/b88e378148134383ffecf3658e3a940b67c9bcc9/snapcraft/internal/lifecycle/_packer.py#L100
+    "-all-root"
+  ];
+
+in runCommand "squashfs.img" {
+  nativeBuildInputs = [ squashfsTools jq ];
+
+  closureInfo = closureInfo {
+    rootPaths = [ snap_yaml ];
+  };
+} ''
+  root=$PWD/root
+  mkdir $root
+
+  (
+    # Put the snap.yaml in to `/meta/snap.yaml`, setting the version
+    # to the hash part of the store path
+    mkdir $root/meta
+    version=$(echo $out | cut -d/ -f4 | cut -d- -f1)
+    cat ${snap_yaml} | jq  ". + { version: \"$version\" }" \
+      > $root/meta/snap.yaml
+  )
+
+  (
+    # Copy the store closure in to the root
+    mkdir -p $root/nix/store
+    cat $closureInfo/store-paths | xargs -I{} cp -r {} $root/nix/store/
+  )
+
+  # Generate the squashfs image.
+  mksquashfs $root $out \
+    ${lib.concatStringsSep " " mksquashfs_args}
+''