aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2022-07-25 14:58:47 +0200
committerQuentin Dufour <quentin@deuxfleurs.fr>2022-07-26 18:27:52 +0200
commit5fb858424793de8dc35dce8deaa8981a384e064f (patch)
tree868f63cfeaffe3107a9d357b26565664cc2849ec
parent96561c48a154a7617cf2766bdee70d581be67b93 (diff)
downloadgarage-5fb858424793de8dc35dce8deaa8981a384e064f.tar.gz
garage-5fb858424793de8dc35dce8deaa8981a384e064f.zip
Refactor default.nix to follow Nix Flakes patterns
-rw-r--r--.drone.yml87
-rw-r--r--default.nix161
-rw-r--r--nix/compile.nix140
-rw-r--r--nix/nix.conf2
4 files changed, 201 insertions, 189 deletions
diff --git a/.drone.yml b/.drone.yml
index 726387a4..f76e162d 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -36,7 +36,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - nix-build --no-build-output --no-out-link shell.nix -A rust.inputDerivation -A integration.inputDerivation -A release.inputDerivation
+ - nix-build --no-build-output --no-out-link shell.nix -A rust.inputDerivation -A integration.inputDerivation
- name: code quality
image: nixpkgs/nix:nixos-22.05
@@ -57,7 +57,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - nix-build --no-build-output --argstr target x86_64-unknown-linux-musl --arg release false --argstr git_version $DRONE_COMMIT
+ - nix-build --no-build-output --attr pkgs.amd64.debug --argstr git_version $DRONE_COMMIT
- nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage"
- name: unit + func tests
@@ -70,12 +70,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - |
- nix-build \
- --no-build-output \
- --option log-lines 100 \
- --argstr target x86_64-unknown-linux-musl \
- --argstr compileMode test
+ - nix-build --no-build-output --attr test.amd64
- ./result/bin/garage_api-*
- ./result/bin/garage_model-*
- ./result/bin/garage_rpc-*
@@ -93,7 +88,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - nix-build --no-build-output --argstr target x86_64-unknown-linux-musl --arg release false --argstr git_version $DRONE_COMMIT
+ - nix-build --no-build-output --attr pkgs.amd64.debug --argstr git_version $DRONE_COMMIT
- nix-shell --attr integration --run ./script/test-smoke.sh || (cat /tmp/garage.log; false)
trigger:
@@ -107,7 +102,7 @@ trigger:
---
kind: pipeline
type: docker
-name: release-linux-x86_64
+name: release-linux-amd64
volumes:
- name: nix_store
@@ -116,20 +111,18 @@ volumes:
- name: nix_config
temp: {}
-environment:
- TARGET: x86_64-unknown-linux-musl
-
steps:
- - name: setup nix
+ - name: nix maintainance
image: nixpkgs/nix:nixos-22.05
volumes:
- name: nix_store
- path: /nix
+ path: /mnt
- name: nix_config
path: /etc/nix
commands:
- - cp nix/nix.conf /etc/nix/nix.conf
- - nix-build --no-build-output --no-out-link shell.nix -A rust.inputDerivation -A integration.inputDerivation -A release.inputDerivation
+ - "[ -d /mnt/store/3vpyn2qz5ay057nq9x68sh0r328d77ng-nix-2.8.1/ ] || (mkdir -p /mnt/store && cp -r /nix/store/* /mnt/store/)"
+ - "[ -d /mnt/var/ ] || cp -r /nix/var /mnt/"
+ - cp nix/nix.conf /etc/nix/nix.conf
- name: build
image: nixpkgs/nix:nixos-22.05
@@ -139,7 +132,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - nix-build --no-build-output --argstr target $TARGET --arg release true --argstr git_version $DRONE_COMMIT
+ - nix-build --no-build-output --attr pkgs.amd64.release --argstr git_version $DRONE_COMMIT
- nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage"
- name: integration
@@ -195,7 +188,7 @@ trigger:
---
kind: pipeline
type: docker
-name: release-linux-i686
+name: release-linux-i386
volumes:
- name: nix_store
@@ -204,20 +197,18 @@ volumes:
- name: nix_config
temp: {}
-environment:
- TARGET: i686-unknown-linux-musl
-
steps:
- - name: setup nix
+ - name: nix maintainance
image: nixpkgs/nix:nixos-22.05
volumes:
- name: nix_store
- path: /nix
+ path: /mnt
- name: nix_config
path: /etc/nix
commands:
- - cp nix/nix.conf /etc/nix/nix.conf
- - nix-build --no-build-output --no-out-link shell.nix -A rust.inputDerivation -A integration.inputDerivation -A release.inputDerivation
+ - "[ -d /mnt/store/3vpyn2qz5ay057nq9x68sh0r328d77ng-nix-2.8.1/ ] || (mkdir -p /mnt/store && cp -r /nix/store/* /mnt/store/)"
+ - "[ -d /mnt/var/ ] || cp -r /nix/var /mnt/"
+ - cp nix/nix.conf /etc/nix/nix.conf
- name: build
image: nixpkgs/nix:nixos-22.05
@@ -227,7 +218,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - nix-build --no-build-output --argstr target $TARGET --arg release true --argstr git_version $DRONE_COMMIT
+ - nix-build --no-build-output --attr pkgs.i386.release --argstr git_version $DRONE_COMMIT
- nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage"
- name: integration
@@ -282,7 +273,7 @@ trigger:
---
kind: pipeline
type: docker
-name: release-linux-aarch64
+name: release-linux-arm64
volumes:
- name: nix_store
@@ -291,20 +282,18 @@ volumes:
- name: nix_config
temp: {}
-environment:
- TARGET: aarch64-unknown-linux-musl
-
steps:
- - name: setup nix
+ - name: nix maintainance
image: nixpkgs/nix:nixos-22.05
volumes:
- name: nix_store
- path: /nix
+ path: /mnt
- name: nix_config
path: /etc/nix
commands:
- - cp nix/nix.conf /etc/nix/nix.conf
- - nix-build --no-build-output --no-out-link shell.nix -A rust.inputDerivation -A integration.inputDerivation -A release.inputDerivation
+ - "[ -d /mnt/store/3vpyn2qz5ay057nq9x68sh0r328d77ng-nix-2.8.1/ ] || (mkdir -p /mnt/store && cp -r /nix/store/* /mnt/store/)"
+ - "[ -d /mnt/var/ ] || cp -r /nix/var /mnt/"
+ - cp nix/nix.conf /etc/nix/nix.conf
- name: build
image: nixpkgs/nix:nixos-22.05
@@ -314,7 +303,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - nix-build --no-build-output --argstr target $TARGET --arg release true --argstr git_version $DRONE_COMMIT
+ - nix-build --no-build-output --attr pkgs.arm64.release --argstr git_version $DRONE_COMMIT
- nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage"
- name: push static binary
@@ -359,7 +348,7 @@ trigger:
---
kind: pipeline
type: docker
-name: release-linux-armv6l
+name: release-linux-arm
volumes:
- name: nix_store
@@ -368,20 +357,18 @@ volumes:
- name: nix_config
temp: {}
-environment:
- TARGET: armv6l-unknown-linux-musleabihf
-
steps:
- - name: setup nix
+ - name: nix maintainance
image: nixpkgs/nix:nixos-22.05
volumes:
- name: nix_store
- path: /nix
+ path: /mnt
- name: nix_config
path: /etc/nix
commands:
- - cp nix/nix.conf /etc/nix/nix.conf
- - nix-build --no-build-output --no-out-link shell.nix -A rust.inputDerivation -A integration.inputDerivation -A release.inputDerivation
+ - "[ -d /mnt/store/3vpyn2qz5ay057nq9x68sh0r328d77ng-nix-2.8.1/ ] || (mkdir -p /mnt/store && cp -r /nix/store/* /mnt/store/)"
+ - "[ -d /mnt/var/ ] || cp -r /nix/var /mnt/"
+ - cp nix/nix.conf /etc/nix/nix.conf
- name: build
image: nixpkgs/nix:nixos-22.05
@@ -391,7 +378,7 @@ steps:
- name: nix_config
path: /etc/nix
commands:
- - nix-build --no-build-output --argstr target $TARGET --arg release true --argstr git_version $DRONE_COMMIT
+ - nix-build --no-build-output --attr pkgs.arm.release --argstr git_version $DRONE_COMMIT
- nix-shell --attr rust --run "./script/not-dynamic.sh result/bin/garage"
- name: push static binary
@@ -459,10 +446,10 @@ steps:
- nix-shell --attr release --run "refresh_index"
depends_on:
- - release-linux-x86_64
- - release-linux-i686
- - release-linux-aarch64
- - release-linux-armv6l
+ - release-linux-amd64
+ - release-linux-i386
+ - release-linux-arm64
+ - release-linux-arm
trigger:
event:
@@ -471,6 +458,6 @@ trigger:
---
kind: signature
-hmac: 12b06094741a9b6da448e3a176d2fc37b2c261ab87acefa60a070e67a55352b0
+hmac: 9789d5fd470fc4273adcfd05946833268d1e466462c5f36abeb8f607d62fdb4b
...
diff --git a/default.nix b/default.nix
index 296c7592..5634f0af 100644
--- a/default.nix
+++ b/default.nix
@@ -1,149 +1,32 @@
{
system ? builtins.currentSystem,
- release ? false,
- target ? "x86_64-unknown-linux-musl",
- compileMode ? null,
git_version ? null,
}:
with import ./nix/common.nix;
-let
- crossSystem = { config = target; };
-in let
- log = v: builtins.trace v v;
-
- pkgs = import pkgsSrc {
- inherit system crossSystem;
- overlays = [ cargo2nixOverlay ];
- };
-
-
- /*
- Rust and Nix triples are not the same. Cargo2nix has a dedicated library
- to convert Nix triples to Rust ones. We need this conversion as we want to
- set later options linked to our (rust) target in a generic way. Not only
- the triple terminology is different, but also the "roles" are named differently.
- Nix uses a build/host/target terminology where Nix's "host" maps to Cargo's "target".
- */
- rustTarget = log (pkgs.rustBuilder.rustLib.rustTriple pkgs.stdenv.hostPlatform);
-
- /*
- Cargo2nix is built for rustOverlay which installs Rust from Mozilla releases.
- We want our own Rust to avoid incompatibilities, like we had with musl 1.2.0.
- rustc was built with musl < 1.2.0 and nix shipped musl >= 1.2.0 which lead to compilation breakage.
- So we want a Rust release that is bound to our Nix repository to avoid these problems.
- See here for more info: https://musl.libc.org/time64.html
- Because Cargo2nix does not support the Rust environment shipped by NixOS,
- we emulate the structure of the Rust object created by rustOverlay.
- In practise, rustOverlay ships rustc+cargo in a single derivation while
- NixOS ships them in separate ones. We reunite them with symlinkJoin.
- */
- rustChannel = pkgs.symlinkJoin {
- name ="rust-channel";
- paths = [
- pkgs.rustPlatform.rust.rustc
- pkgs.rustPlatform.rust.cargo
- ];
+let
+ compile = import ./nix/compile.nix;
+ build_debug_and_release = (target: {
+ debug = (compile { inherit target; release = false; }).workspace.garage { compileMode = "build"; };
+ release = (compile { inherit target; release = true; }).workspace.garage { compileMode = "build"; };
+ });
+
+in {
+ pkgs = {
+ amd64 = build_debug_and_release "x86_64-unknown-linux-musl";
+ i386 = build_debug_and_release "i686-unknown-linux-musl";
+ arm64 = build_debug_and_release "aarch64-unknown-linux-musl";
+ arm = build_debug_and_release "armv6l-unknown-linux-musleabihf";
};
-
- /*
- Cargo2nix provides many overrides by default, you can take inspiration from them:
- https://github.com/cargo2nix/cargo2nix/blob/master/overlay/overrides.nix
-
- You can have a complete list of the available options by looking at the overriden object, mkcrate:
- https://github.com/cargo2nix/cargo2nix/blob/master/overlay/mkcrate.nix
- */
- overrides = pkgs.rustBuilder.overrides.all ++ [
- /*
- [1] We need to alter Nix hardening to make static binaries: PIE,
- Position Independent Executables seems to be supported only on amd64. Having
- this flag set either 1. make our executables crash or 2. compile as dynamic on some platforms.
- Here, we deactivate it. Later (find `codegenOpts`), we reactivate it for supported targets
- (only amd64 curently) through the `-static-pie` flag.
- PIE is a feature used by ASLR, which helps mitigate security issues.
- Learn more about Nix Hardening at: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/cc-wrapper/add-hardening.sh
- */
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage";
- overrideAttrs = drv: { hardeningDisable = [ "pie" ]; };
- })
-
- (pkgs.rustBuilder.rustLib.makeOverride {
- name = "garage_rpc";
-
- /*
- [2] We want to inject the git version while keeping the build deterministic.
- As we do not want to consider the .git folder as part of the input source,
- we ask the user (the CI often) to pass the value to Nix.
- */
- overrideAttrs = drv:
- (if git_version != null then {
- preConfigure = ''
- ${drv.preConfigure or ""}
- export GIT_VERSION="${git_version}"
- '';
- } else {});
-
- /*
- [3] We ship some parts of the code disabled by default by putting them behind a flag.
- It speeds up the compilation (when the feature is not required) and released crates have less dependency by default (less attack surface, disk space, etc.).
- But we want to ship these additional features when we release Garage.
- In the end, we chose to exclude all features from debug builds while putting (all of) them in the release builds.
- Currently, the only feature of Garage is kubernetes-discovery from the garage_rpc crate.
- */
- overrideArgs = old: {
- features = if release then [ "kubernetes-discovery" ] else [];
+ test = {
+ amd64 = let
+ pkgs = import pkgsSrc { };
+ rustPkgs = compile { target = "x86_64-unknown-linux-musl"; };
+ in
+ pkgs.symlinkJoin {
+ name ="garage-tests";
+ paths = builtins.map (key: rustPkgs.workspace.${key} { compileMode = "test"; }) (builtins.attrNames rustPkgs.workspace);
};
- })
-
- ];
-
- packageFun = import ./Cargo.nix;
-
- /*
- We compile fully static binaries with musl to simplify deployment on most systems.
- When possible, we reactivate PIE hardening (see above).
-
- Also, if you set the RUSTFLAGS environment variable, the following parameters will
- be ignored.
-
- For more information on static builds, please refer to Rust's RFC 1721.
- https://rust-lang.github.io/rfcs/1721-crt-static.html#specifying-dynamicstatic-c-runtime-linkage
- */
-
- codegenOpts = {
- "armv6l-unknown-linux-musleabihf" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* compile as dynamic with static-pie */
- "aarch64-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* segfault with static-pie */
- "i686-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* segfault with static-pie */
- "x86_64-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static-pie" ];
};
-
- /*
- The following definition is not elegant as we use a low level function of Cargo2nix
- that enables us to pass our custom rustChannel object. We need this low level definition
- to pass Nix's Rust toolchains instead of Mozilla's one.
-
- target is mandatory but must be kept to null to allow cargo2nix to set it to the appropriate value
- for each crate.
- */
- rustPkgs = pkgs.rustBuilder.makePackageSet {
- inherit packageFun rustChannel release codegenOpts;
- packageOverrides = overrides;
- target = null;
-
- buildRustPackages = pkgs.buildPackages.rustBuilder.makePackageSet {
- inherit rustChannel packageFun codegenOpts;
- packageOverrides = overrides;
- target = null;
- };
- };
-
-
-in
- if compileMode == "test"
- then pkgs.symlinkJoin {
- name ="garage-tests";
- paths = builtins.map (key: rustPkgs.workspace.${key} { inherit compileMode; }) (builtins.attrNames rustPkgs.workspace);
- }
- else rustPkgs.workspace.garage { inherit compileMode; }
+}
diff --git a/nix/compile.nix b/nix/compile.nix
new file mode 100644
index 00000000..972e2f2e
--- /dev/null
+++ b/nix/compile.nix
@@ -0,0 +1,140 @@
+{
+ system ? builtins.currentSystem,
+ target ? "x86_64-unknown-linux-musl",
+ release ? false,
+ git_version ? null,
+}:
+
+with import ./common.nix;
+
+let
+ crossSystem = { config = target; };
+
+ log = v: builtins.trace v v;
+
+ pkgs = import pkgsSrc {
+ inherit system crossSystem;
+ overlays = [ cargo2nixOverlay ];
+ };
+
+
+ /*
+ Rust and Nix triples are not the same. Cargo2nix has a dedicated library
+ to convert Nix triples to Rust ones. We need this conversion as we want to
+ set later options linked to our (rust) target in a generic way. Not only
+ the triple terminology is different, but also the "roles" are named differently.
+ Nix uses a build/host/target terminology where Nix's "host" maps to Cargo's "target".
+ */
+ rustTarget = log (pkgs.rustBuilder.rustLib.rustTriple pkgs.stdenv.hostPlatform);
+
+ /*
+ Cargo2nix is built for rustOverlay which installs Rust from Mozilla releases.
+ We want our own Rust to avoid incompatibilities, like we had with musl 1.2.0.
+ rustc was built with musl < 1.2.0 and nix shipped musl >= 1.2.0 which lead to compilation breakage.
+ So we want a Rust release that is bound to our Nix repository to avoid these problems.
+ See here for more info: https://musl.libc.org/time64.html
+ Because Cargo2nix does not support the Rust environment shipped by NixOS,
+ we emulate the structure of the Rust object created by rustOverlay.
+ In practise, rustOverlay ships rustc+cargo in a single derivation while
+ NixOS ships them in separate ones. We reunite them with symlinkJoin.
+ */
+ rustChannel = pkgs.symlinkJoin {
+ name ="rust-channel";
+ paths = [
+ pkgs.rustPlatform.rust.rustc
+ pkgs.rustPlatform.rust.cargo
+ ];
+ };
+
+ /*
+ Cargo2nix provides many overrides by default, you can take inspiration from them:
+ https://github.com/cargo2nix/cargo2nix/blob/master/overlay/overrides.nix
+
+ You can have a complete list of the available options by looking at the overriden object, mkcrate:
+ https://github.com/cargo2nix/cargo2nix/blob/master/overlay/mkcrate.nix
+ */
+ overrides = pkgs.rustBuilder.overrides.all ++ [
+ /*
+ [1] We need to alter Nix hardening to make static binaries: PIE,
+ Position Independent Executables seems to be supported only on amd64. Having
+ this flag set either 1. make our executables crash or 2. compile as dynamic on some platforms.
+ Here, we deactivate it. Later (find `codegenOpts`), we reactivate it for supported targets
+ (only amd64 curently) through the `-static-pie` flag.
+ PIE is a feature used by ASLR, which helps mitigate security issues.
+ Learn more about Nix Hardening at: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/cc-wrapper/add-hardening.sh
+ */
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage";
+ overrideAttrs = drv: { hardeningDisable = [ "pie" ]; };
+ })
+
+ (pkgs.rustBuilder.rustLib.makeOverride {
+ name = "garage_rpc";
+
+ /*
+ [2] We want to inject the git version while keeping the build deterministic.
+ As we do not want to consider the .git folder as part of the input source,
+ we ask the user (the CI often) to pass the value to Nix.
+ */
+ overrideAttrs = drv:
+ (if git_version != null then {
+ preConfigure = ''
+ ${drv.preConfigure or ""}
+ export GIT_VERSION="${git_version}"
+ '';
+ } else {});
+
+ /*
+ [3] We ship some parts of the code disabled by default by putting them behind a flag.
+ It speeds up the compilation (when the feature is not required) and released crates have less dependency by default (less attack surface, disk space, etc.).
+ But we want to ship these additional features when we release Garage.
+ In the end, we chose to exclude all features from debug builds while putting (all of) them in the release builds.
+ Currently, the only feature of Garage is kubernetes-discovery from the garage_rpc crate.
+ */
+ overrideArgs = old: {
+ features = if release then [ "kubernetes-discovery" ] else [];
+ };
+ })
+
+ ];
+
+ packageFun = import ../Cargo.nix;
+
+ /*
+ We compile fully static binaries with musl to simplify deployment on most systems.
+ When possible, we reactivate PIE hardening (see above).
+
+ Also, if you set the RUSTFLAGS environment variable, the following parameters will
+ be ignored.
+
+ For more information on static builds, please refer to Rust's RFC 1721.
+ https://rust-lang.github.io/rfcs/1721-crt-static.html#specifying-dynamicstatic-c-runtime-linkage
+ */
+
+ codegenOpts = {
+ "armv6l-unknown-linux-musleabihf" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* compile as dynamic with static-pie */
+ "aarch64-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* segfault with static-pie */
+ "i686-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static" ]; /* segfault with static-pie */
+ "x86_64-unknown-linux-musl" = [ "target-feature=+crt-static" "link-arg=-static-pie" ];
+ };
+
+in
+ /*
+ The following definition is not elegant as we use a low level function of Cargo2nix
+ that enables us to pass our custom rustChannel object. We need this low level definition
+ to pass Nix's Rust toolchains instead of Mozilla's one.
+
+ target is mandatory but must be kept to null to allow cargo2nix to set it to the appropriate value
+ for each crate.
+ */
+ pkgs.rustBuilder.makePackageSet {
+ inherit packageFun rustChannel release codegenOpts;
+ packageOverrides = overrides;
+ target = null;
+
+ buildRustPackages = pkgs.buildPackages.rustBuilder.makePackageSet {
+ inherit rustChannel packageFun codegenOpts;
+ packageOverrides = overrides;
+ target = null;
+ };
+ }
diff --git a/nix/nix.conf b/nix/nix.conf
index f3defe69..de2ede71 100644
--- a/nix/nix.conf
+++ b/nix/nix.conf
@@ -5,3 +5,5 @@ cores = 4
log-lines = 200
filter-syscalls = false
sandbox = false
+keep-outputs = true
+keep-derivations = true