Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dockerTools: add nix-prefetch-docker script #58360

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 29 additions & 12 deletions doc/functions/dockertools.xml
Original file line number Diff line number Diff line change
Expand Up @@ -436,18 +436,7 @@ pullImage {
<callout arearefs='ex-dockerTools-pullImage-2'>
<para>
<varname>imageDigest</varname> specifies the digest of the image to be
downloaded. Skopeo can be used to get the digest of an image, with its
<varname>inspect</varname> subcommand. Since a given
<varname>imageName</varname> may transparently refer to a manifest list of
images which support multiple architectures and/or operating systems,
supply the `--override-os` and `--override-arch` arguments to specify
exactly which image you want. By default it will match the OS and
architecture of the host the command is run on.
<programlisting>
$ nix-shell --packages skopeo jq --command "skopeo --override-os linux --override-arch x86_64 inspect docker://docker.io/nixos/nix:1.11 | jq -r '.Digest'"
sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b
</programlisting>
This argument is required.
downloaded. This argument is required.
</para>
</callout>
<callout arearefs='ex-dockerTools-pullImage-3'>
Expand Down Expand Up @@ -477,6 +466,34 @@ sha256:20d9485b25ecfd89204e843a962c1bd70e9cc6858d65d7f5fadc340246e2116b
</para>
</callout>
</calloutlist>

<para>
<literal>nix-prefetch-docker</literal> command can be used to get required
image parameters:

<programlisting>
$ nix run nixpkgs.nix-prefetch-docker -c nix-prefetch-docker --image-name mysql --image-tag 5
</programlisting>

Since a given <varname>imageName</varname> may transparently refer to a
manifest list of images which support multiple architectures and/or
operating systems, you can supply the <option>--os</option> and
<option>--arch</option> arguments to specify exactly which image you want.
By default it will match the OS and architecture of the host the command is
run on.

<programlisting>
$ nix-prefetch-docker --image-name mysql --image-tag 5 --arch x86_64 --os linux
</programlisting>

Desired image name and tag can be set using
<option>--final-image-name</option> and <option>--final-image-tag</option>
arguments:

<programlisting>
$ nix-prefetch-docker --image-name mysql --image-tag 5 --final-image-name eu.gcr.io/my-project/mysql --final-image-tag prod
</programlisting>
</para>
</section>

<section xml:id="ssec-pkgs-dockerTools-exportImage">
Expand Down
173 changes: 173 additions & 0 deletions pkgs/build-support/docker/nix-prefetch-docker
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
#! /usr/bin/env bash

set -e -o pipefail

os=
arch=
imageName=
imageTag=
imageDigest=
finalImageName=
finalImageTag=
hashType=$NIX_HASH_ALGO
hashFormat=$hashFormat
format=nix

usage(){
echo >&2 "syntax: nix-prefetch-docker [options] [IMAGE_NAME [IMAGE_TAG|IMAGE_DIGEST]]

Options:
--os os OS to fetch image for
--arch linux Arch to fetch image for
--image-name name Name of the image to fetch
--image-tag tag Image tag
--image-digest digest Image digest
--final-image-name name Desired name of the image
--final-image-tag tag Desired image tag
--json Output result in json format instead of nix
--quiet Only print the final result
"
exit 1
}

get_image_digest(){
local imageName=$1
local imageTag=$2

if test -z "$imageTag"; then
imageTag="latest"
fi

skopeo inspect "docker://$imageName:$imageTag" | jq '.Digest' -r
}

get_name() {
local imageName=$1
local imageTag=$2

echo "docker-image-$(echo "$imageName:$imageTag" | tr '/:' '-').tar"
}

argi=0
argfun=""
for arg; do
if test -z "$argfun"; then
case $arg in
--os) argfun=set_os;;
--arch) argfun=set_arch;;
--image-name) argfun=set_imageName;;
--image-tag) argfun=set_imageTag;;
--image-digest) argfun=set_imageDigest;;
--final-image-name) argfun=set_finalImageName;;
--final-image-tag) argfun=set_finalImageTag;;
--quiet) QUIET=true;;
--json) format=json;;
--help) usage; exit;;
*)
: $((++argi))
case $argi in
1) imageName=$arg;;
2) [[ $arg == *"sha256"* ]] && imageDigest=$arg || imageTag=$arg;;
*) exit 1;;
esac
;;
esac
else
case $argfun in
set_*)
var=${argfun#set_}
eval $var=$arg
;;
esac
argfun=""
fi
done

if test -z "$imageName"; then
usage
fi

if test -z "$os"; then
os=linux
fi

if test -z "$arch"; then
arch=amd64
fi

if test -z "$hashType"; then
hashType=sha256
fi

if test -z "$hashFormat"; then
hashFormat=base32
fi

if test -z "$finalImageName"; then
finalImageName="$imageName"
fi

if test -z "$finalImageTag"; then
if test -z "$imageTag"; then
finalImageTag="latest"
else
finalImageTag="$imageTag"
fi
fi

if test -z "$imageDigest"; then
imageDigest=$(get_image_digest $imageName $imageTag)
fi

sourceUrl="docker://$imageName@$imageDigest"

tmpPath="$(mktemp -d "${TMPDIR:-/tmp}/skopeo-copy-tmp-XXXXXXXX")"
trap "rm -rf \"$tmpPath\"" EXIT

tmpFile="$tmpPath/$(get_name $finalImageName $finalImageTag)"

if test -z "$QUIET"; then
skopeo --override-os ${os} --override-arch ${arch} copy "$sourceUrl" "docker-archive://$tmpFile:$finalImageName:$finalImageTag"
else
skopeo --override-os ${os} --override-arch ${arch} copy "$sourceUrl" "docker-archive://$tmpFile:$finalImageName:$finalImageTag" > /dev/null
fi

# Compute the hash.
imageHash=$(nix-hash --flat --type $hashType --base32 "$tmpFile")

# Add the downloaded file to Nix store.
finalPath=$(nix-store --add-fixed "$hashType" "$tmpFile")

if test -z "$QUIET"; then
echo "-> ImageName: $imageName"
echo "-> ImageDigest: $imageDigest"
echo "-> FinalImageName: $finalImageName"
echo "-> FinalImageTag: $finalImageTag"
echo "-> ImagePath: $finalPath"
echo "-> ImageHash: $imageHash"
fi

if [ "$format" == "nix" ]; then
cat <<EOF
{
imageName = "$imageName";
imageDigest = "$imageDigest";
sha256 = "$imageHash";
finalImageName = "$finalImageName";
finalImageTag = "$finalImageTag";
}
EOF

else

cat <<EOF
{
"imageName": "$imageName",
"imageDigest": "$imageDigest",
"sha256": "$imageHash",
"finalImageName": "$finalImageName",
"finalImageTag": "$finalImageTag"
}
EOF

fi
26 changes: 26 additions & 0 deletions pkgs/build-support/docker/nix-prefetch-docker.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{ stdenv, makeWrapper, nix, skopeo }:

with stdenv.lib;

stdenv.mkDerivation {
name = "nix-prefetch-docker";

nativeBuildInputs = [ makeWrapper ];

unpackPhase = ":";

installPhase = ''
install -vD ${./nix-prefetch-docker} $out/bin/$name;
wrapProgram $out/bin/$name \
--prefix PATH : ${makeBinPath [ nix skopeo ]} \
--set HOME /homeless-shelter
'';

preferLocalBuild = true;

meta = {
description = "Script used to obtain source hashes for dockerTools.pullImage";
maintainers = with maintainers; [ offline ];
platforms = platforms.unix;
};
}
2 changes: 2 additions & 0 deletions pkgs/top-level/all-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ in

dockerTools = callPackage ../build-support/docker { };

nix-prefetch-docker = callPackage ../build-support/docker/nix-prefetch-docker.nix { };

docker-compose = python3Packages.callPackage ../applications/virtualization/docker-compose {};

docker-ls = callPackage ../tools/misc/docker-ls { };
Expand Down