core/pkgs/build-support/fetchdocker/generic-fetcher.nix

87 lines
3 KiB
Nix
Raw Normal View History

2024-05-02 00:46:19 +00:00
{ stdenv, lib, haskellPackages, writeText, gawk }:
let
2024-05-13 21:24:10 +00:00
awk = "${gawk}/bin/awk";
2024-05-02 00:46:19 +00:00
dockerCredentialsFile = import ./credentials.nix { inherit lib; };
2024-05-13 21:24:10 +00:00
in { fetcher, name, registry ? "https://registry-1.docker.io/v2/"
, repository ? "library", imageName, sha256, tag ? "", layerDigest ? "" }:
2024-05-02 00:46:19 +00:00
# There must be no slashes in the repository or container names since
# we use these to make the output derivation name for the nix store
# path
2024-05-13 21:24:10 +00:00
assert null
== lib.findFirst (c: "/" == c) null (lib.stringToCharacters repository);
assert null
== lib.findFirst (c: "/" == c) null (lib.stringToCharacters imageName);
2024-05-02 00:46:19 +00:00
# Only allow hocker-config and hocker-layer as fetchers for now
2024-05-13 21:24:10 +00:00
assert (builtins.elem fetcher [ "hocker-config" "hocker-layer" ]);
2024-05-02 00:46:19 +00:00
# If layerDigest is non-empty then it must not have a 'sha256:' prefix!
2024-05-13 21:24:10 +00:00
assert (if layerDigest != "" then
!lib.hasPrefix "sha256:" layerDigest
else
true);
2024-05-02 00:46:19 +00:00
let
layerDigestFlag =
lib.optionalString (layerDigest != "") "--layer ${layerDigest}";
2024-05-13 21:24:10 +00:00
in stdenv.mkDerivation {
2024-05-02 00:46:19 +00:00
inherit name;
builder = writeText "${fetcher}-builder.sh" ''
source "$stdenv/setup"
echo "${fetcher} exporting to $out"
declare -A creds
# This is a hack for Hydra since we have no way of adding values
# to the NIX_PATH for Hydra jobsets!!
staticCredentialsFile="/etc/nix-docker-credentials.txt"
if [ ! -f "$dockerCredentialsFile" -a -f "$staticCredentialsFile" ]; then
echo "credentials file not set, falling back on static credentials file at: $staticCredentialsFile"
dockerCredentialsFile=$staticCredentialsFile
fi
if [ -f "$dockerCredentialsFile" ]; then
echo "using credentials from $dockerCredentialsFile"
CREDSFILE=$(cat "$dockerCredentialsFile")
creds[token]=$(${awk} -F'=' '/DOCKER_TOKEN/ {print $2}' <<< "$CREDSFILE" | head -n1)
# Prefer DOCKER_TOKEN over the username and password
# authentication method
if [ -z "''${creds[token]}" ]; then
creds[user]=$(${awk} -F'=' '/DOCKER_USER/ {print $2}' <<< "$CREDSFILE" | head -n1)
creds[pass]=$(${awk} -F'=' '/DOCKER_PASS/ {print $2}' <<< "$CREDSFILE" | head -n1)
fi
fi
# These variables will be filled in first by the impureEnvVars, if
# those variables are empty then they will default to the
# credentials that may have been read in from the 'DOCKER_CREDENTIALS'
DOCKER_USER="''${DOCKER_USER:-''${creds[user]}}"
DOCKER_PASS="''${DOCKER_PASS:-''${creds[pass]}}"
DOCKER_TOKEN="''${DOCKER_TOKEN:-''${creds[token]}}"
${fetcher} --out="$out" \
''${registry:+--registry "$registry"} \
''${DOCKER_USER:+--username "$DOCKER_USER"} \
''${DOCKER_PASS:+--password "$DOCKER_PASS"} \
''${DOCKER_TOKEN:+--token "$DOCKER_TOKEN"} \
${layerDigestFlag} \
"${repository}/${imageName}" \
"${tag}"
'';
buildInputs = [ haskellPackages.hocker ];
outputHashAlgo = "sha256";
outputHashMode = "flat";
outputHash = sha256;
preferLocalBuild = true;
impureEnvVars = [ "DOCKER_USER" "DOCKER_PASS" "DOCKER_TOKEN" ];
inherit registry dockerCredentialsFile;
}