2024-05-02 00:46:19 +00:00
|
|
|
{
|
|
|
|
stdenv,
|
|
|
|
lib,
|
|
|
|
haskellPackages,
|
|
|
|
writeText,
|
|
|
|
gawk,
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
awk = "${gawk}/bin/awk";
|
|
|
|
dockerCredentialsFile = import ./credentials.nix { inherit lib; };
|
|
|
|
in
|
|
|
|
{
|
|
|
|
fetcher,
|
|
|
|
name,
|
|
|
|
registry ? "https://registry-1.docker.io/v2/",
|
|
|
|
repository ? "library",
|
|
|
|
imageName,
|
|
|
|
sha256,
|
|
|
|
tag ? "",
|
|
|
|
layerDigest ? "",
|
|
|
|
}:
|
|
|
|
|
|
|
|
# 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
|
|
|
|
assert null == lib.findFirst (c: "/" == c) null (lib.stringToCharacters repository);
|
|
|
|
assert null == lib.findFirst (c: "/" == c) null (lib.stringToCharacters imageName);
|
|
|
|
|
|
|
|
# Only allow hocker-config and hocker-layer as fetchers for now
|
|
|
|
assert (
|
|
|
|
builtins.elem fetcher [
|
|
|
|
"hocker-config"
|
|
|
|
"hocker-layer"
|
2024-06-30 08:12:46 +00:00
|
|
|
]
|
2024-05-02 00:46:19 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
# If layerDigest is non-empty then it must not have a 'sha256:' prefix!
|
|
|
|
assert (if layerDigest != "" then !lib.hasPrefix "sha256:" layerDigest else true);
|
|
|
|
|
|
|
|
let
|
|
|
|
layerDigestFlag = lib.optionalString (layerDigest != "") "--layer ${layerDigest}";
|
|
|
|
in
|
|
|
|
stdenv.mkDerivation {
|
|
|
|
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;
|
|
|
|
}
|