diff --git a/nix/app.nix b/nix/app.nix new file mode 100644 index 0000000..64addd5 --- /dev/null +++ b/nix/app.nix @@ -0,0 +1,56 @@ +# This is a function that returns a derivation for the compiled Rust project. +{ craneLib +, lib +, hostPlatform +, openssl +, libiconv +, pkg-config +, protobuf +, darwin +}: +let + buildArgs = { + pname = "ndc-bigquery"; + version = "0.1.0"; + + src = + let + isJsonFile = path: _type: builtins.match ".*json" path != null; + isSqlFile = path: _type: builtins.match ".*sql" path != null; + isSourceFile = path: type: + isJsonFile path type + || isSqlFile path type + || craneLib.filterCargoSources path type; + in + lib.cleanSourceWith { src = craneLib.path ./..; filter = isSourceFile; }; + + strictDeps = true; + + # build-time inputs + nativeBuildInputs = [ + openssl.dev # required to build Rust crates that can conduct TLS connections + pkg-config # required to find OpenSSL + ]; + + # runtime inputs + buildInputs = [ + openssl # required for TLS connections + protobuf # required by opentelemetry-proto, a dependency of axum-tracing-opentelemetry + ] ++ lib.optionals hostPlatform.isDarwin [ + # macOS-specific dependencies + libiconv + darwin.apple_sdk.frameworks.CoreFoundation + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.SystemConfiguration + ]; + }; + + # Build the dependencies first. + cargoArtifacts = craneLib.buildDepsOnly buildArgs; +in +# Then build the crate. +craneLib.buildPackage + (buildArgs // { + inherit cargoArtifacts; + doCheck = false; + }) diff --git a/nix/cargo-build.nix b/nix/cargo-build.nix deleted file mode 100644 index b4b6496..0000000 --- a/nix/cargo-build.nix +++ /dev/null @@ -1,105 +0,0 @@ -# This is a function that returns a derivation for the compiled Rust project. -# Supports cross-compiling, and statically-links builds compiled for Linux. -# -# The derivation includes some extra attributes with some of the resources that -# were used to produce the derivation: -# -# - buildArgs -# - cargoArtifacts -# - craneLib -# - rustToolchain -{ - # `crateExpression` must be a function that takes an arguments set, and - # returns a derivation made by calling `craneLib.buildPackage`. Any packages - # listed in the argument set will be populated automatically. In addition - # these special attributes will be given: - # - # - craneLib - see https://crane.dev/API.html#cranelibbuildpackage - # - staticallyLinked - boolean to indicate whether we are linking statically - # - crateExpression -, nixpkgs -, crane -, rust-overlay -, localSystem -, binary-name -, crossSystem ? localSystem -}: - -let - pkgs = import nixpkgs { - inherit crossSystem localSystem; - overlays = [ rust-overlay.overlays.default ]; - }; - - # `hostPlatform` is the cross-compilation output platform; - # `buildPlatform` is the platform we are compiling on - buildPlatform = pkgs.stdenv.buildPlatform; - hostPlatform = pkgs.stdenv.hostPlatform; - - # We can statically-link if the cross-compilation target is Linux, and the - # build system is 64-bit because these are the conditions where Nix has musl - # packages available. - staticallyLinked = hostPlatform.isLinux && buildPlatform.is64bit; - - # `config` is a cpu-vendor-os-abi string like "aarch64-unknown-linux-gnu". To - # statically link we need to change the ABI from "gnu" to "musl". - # - # Ideally we would pass in a crossSystem argument of the form - # "aarch64-unknown-linux-musl" instead of doing this fixup. But that doesn't - # seem to work. - buildTarget = - if staticallyLinked then builtins.replaceStrings [ "gnu" ] [ "musl" ] hostPlatform.config - else hostPlatform.config; - - # When possibly cross-compiling we get several versions of nixpkgs of the - # form, `pkgs.pkgs`. We use - # `pkgs.pkgsBuildHost` to get packages that run at build time (so run on the - # build platform), and that produce outputs for the host platform which is the - # cross-compilation target. - rustToolchain = (pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml).override { - targets = [ buildTarget ]; - }; - - lib = pkgs.pkgsBuildHost.lib; - - craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain; - - # Converts host system string for use in environment variable names - envCase = triple: lib.strings.toUpper (builtins.replaceStrings [ "-" ] [ "_" ] triple); - - buildArgs = { - CARGO_BUILD_TARGET = buildTarget; - "CARGO_TARGET_${envCase buildTarget}_LINKER" = "${pkgs.stdenv.cc.targetPrefix}cc"; - - # This environment variable may be necessary if any of your dependencies use - # a build-script which invokes the `cc` crate to build some other code. The - # `cc` crate should automatically pick up on our target-specific linker - # above, but this may be necessary if the build script needs to compile and - # run some extra code on the build system. - HOST_CC = "${pkgs.stdenv.cc.nativePrefix}cc"; - } - // lib.optionalAttrs staticallyLinked { - CARGO_BUILD_RUSTFLAGS = "-C target-feature=+crt-static"; - }; - - # Call the given crateExpression to build the crate - or rather to get - # a derivation that will build the crate. - crate = pkgs.callPackage crateExpression { - inherit craneLib staticallyLinked binary-name; - }; -in -# Override the derivation to add cross-compilation and static linking environment variables. -crate.overrideAttrs (previous: buildArgs // { - # We also have to override the cargoArtifacts derivation with the same - # changes. - cargoArtifacts = previous.cargoArtifacts.overrideAttrs (previous: buildArgs); - - # Add craneLib and rustToolchain to the returned derivation so that we can - # access them from the caller. And pass buildArgs forward from the - # outupt of crateExpression. - passthru = { - inherit craneLib rustToolchain; - inherit (crate) buildArgs; - }; -}) diff --git a/nix/docker.nix b/nix/docker.nix index a7a03d0..1e254aa 100644 --- a/nix/docker.nix +++ b/nix/docker.nix @@ -1,24 +1,41 @@ # This is a function that returns a derivation for a docker image. -{ ndc-agent -, binary-name -, dockerTools +{ dockerTools , lib -, architecture ? null +, package , image-name +, architecture ? null , tag ? null # defaults to the output hash , extraConfig ? { } # see config options at: https://github.com/moby/moby/blob/master/image/spec/v1.2.md#image-json-field-descriptions }: let + seconds = 1000 * 1000 * 1000; # nanoseconds in 1 second args = { name = image-name; created = "now"; - contents = [ ndc-agent ]; + contents = [ package ]; config = { Entrypoint = [ - "/bin/${binary-name}" + "/bin/${package.pname}" + ]; + Cmd = [ + "serve" + ]; + Env = [ + ''HASURA_CONFIGURATION_DIRECTORY=/etc/connector'' ]; - ExposedPorts = { "8100/tcp" = { }; }; + ExposedPorts = { "8080/tcp" = { }; }; + Healthcheck = { + Test = [ + "CMD" + "/bin/${package.pname}" + "check-health" + ]; + StartInterval = 1 * seconds; + Interval = 5 * seconds; + Timeout = 10 * seconds; + Retries = 3; + }; } // extraConfig; } // lib.optionalAttrs (tag != null) { diff --git a/nix/ndc-agent.nix b/nix/ndc-agent.nix deleted file mode 100644 index c8f7a1b..0000000 --- a/nix/ndc-agent.nix +++ /dev/null @@ -1,80 +0,0 @@ -# Dependencies and build configuration for the postgres-agent crate. -# -# To add runtime library dependencies, add packge names to the argument set -# here, and add the same name to the `buildInputs` list below. -# -# To add buildtime dependencies, add packge names to the argument set -# here, and add the same name to the `nativeBuildInputs` list below. -# -# To add environment variables add attributes to `buildArgs`. -# -# To set Cargo options, or other configuration see the Crane documentation, -# https://crane.dev/API.html#cranelibbuildpackage -# -{ craneLib -, staticallyLinked -, lib -, openssl -, libiconv -, pkg-config -, protobuf -, stdenv -, pkgsStatic -, binary-name -}: - -let - src = - let - isJsonFile = path: _type: builtins.match ".*json" path != null; - isSqlFile = path: _type: builtins.match ".*sql" path != null; - isSourceFile = path: type: - isJsonFile path type - || isSqlFile path type - || craneLib.filterCargoSources path type; - in - lib.cleanSourceWith { src = craneLib.path ./..; filter = isSourceFile; }; - - buildArgs = { - inherit src; - - pname = binary-name; - - buildInputs = [ - openssl - ] ++ lib.optionals stdenv.hostPlatform.isDarwin [ - libiconv - pkgsStatic.darwin.apple_sdk.frameworks.Security - pkgsStatic.darwin.apple_sdk.frameworks.SystemConfiguration - ]; - - nativeBuildInputs = [ - pkg-config # required for non-static builds - protobuf # required by opentelemetry-proto, a dependency of axum-tracing-opentelemetry - ]; - - } // lib.optionalAttrs staticallyLinked { - # Configure openssl-sys for static linking. The build script for the - # openssl-sys crate requires openssl lib and include locations to be - # specified explicitly for this case. - # - # `pkgsStatic` provides versions of nixpkgs that are compiled with musl - OPENSSL_STATIC = "1"; - OPENSSL_LIB_DIR = "${pkgsStatic.openssl.out}/lib"; - OPENSSL_INCLUDE_DIR = "${pkgsStatic.openssl.dev}/include"; - }; - - cargoArtifacts = craneLib.buildDepsOnly buildArgs; - - crate = craneLib.buildPackage - (buildArgs // { - inherit cargoArtifacts; - doCheck = false; - cargoExtraArgs = "--locked --bin ${binary-name}"; - }); -in -crate.overrideAttrs (prev: { - # Add buildArgs to the returned derivation so that we can access it from the - # caller. cargoArtifacts is included automatically. - passthru.buildArgs = buildArgs; -}) diff --git a/nix/rust.nix b/nix/rust.nix new file mode 100644 index 0000000..cba7ccd --- /dev/null +++ b/nix/rust.nix @@ -0,0 +1,59 @@ +# Sets up our Rust toolchain and Crane for cross-compilation. +# This is mostly a copy of the example provided at: +# https://crane.dev/examples/cross-rust-overlay.html +{ nixpkgs +, rust-overlay +, crane +, localSystem +, crossSystem ? localSystem +}: +let + pkgs = import nixpkgs { + inherit crossSystem localSystem; + overlays = [ rust-overlay.overlays.default ]; + }; + + lib = pkgs.pkgsBuildHost.lib; + + # Converts host system string for use in environment variable names + envCase = triple: lib.strings.toUpper (builtins.replaceStrings [ "-" ] [ "_" ] triple); + + # `hostPlatform` is the cross-compilation output platform; + # `buildPlatform` is the platform we are compiling on + buildPlatform = pkgs.stdenv.buildPlatform; + hostPlatform = pkgs.stdenv.hostPlatform; + + # When possibly cross-compiling we get several versions of nixpkgs of the + # form, `pkgs.pkgs`. We use + # `pkgs.pkgsBuildHost` to get packages that run at build time (so run on the + # build platform), and that produce outputs for the host platform which is the + # cross-compilation target. + rustBin = pkgs.pkgsBuildHost.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml; + rustToolchain = rustBin.override { targets = [ hostPlatform.config ]; }; + craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain; + + buildEnv = { + CARGO_BUILD_TARGET = hostPlatform.config; + "CARGO_TARGET_${envCase hostPlatform.config}_LINKER" = "${pkgs.stdenv.cc.targetPrefix}cc"; + + # This environment variable may be necessary if any of your dependencies use + # a build-script which invokes the `cc` crate to build some other code. The + # `cc` crate should automatically pick up on our target-specific linker + # above, but this may be necessary if the build script needs to compile and + # run some extra code on the build system. + HOST_CC = "${pkgs.stdenv.cc.nativePrefix}cc"; + }; +in +{ + inherit rustToolchain; + + callPackage = (package: args: + # Call the package, providing `craneLib` as an extra. + let crate = pkgs.callPackage package (args // { inherit craneLib; }); + in + # Override the derivation to add cross-compilation environment variables. + crate.overrideAttrs (previous: buildEnv // { + # We also have to override the `cargoArtifacts` derivation with the same changes. + cargoArtifacts = previous.cargoArtifacts.overrideAttrs (previous: buildEnv); + })); +}