Skip to content

Instantly share code, notes, and snippets.

@andreabedini
Created April 6, 2023 07:46
Show Gist options
  • Save andreabedini/29c8ad72d9964d487151482db758a0da to your computer and use it in GitHub Desktop.
Save andreabedini/29c8ad72d9964d487151482db758a0da to your computer and use it in GitHub Desktop.
Upload a nix closure to a container registry
#/usr/bin/bash
set -e
USAGE="Usage: $0 repository installables..."
if [ "$#" == "0" ]; then # If zero arguments were supplied,
echo "Error: no repository or installables provided."
echo "$USAGE" # display a help message
exit 1 # and return an error.
fi
# The terminology seems to be registry/namespace/image:tag
# registry/namespace/image is also known as the image repository
# e.g. localhost:5000/test1
repository="$1"
shift 1
WORKDIR=$(mktemp -d)
trap cleanup SIGHUP SIGINT SIGQUIT SIGABRT
cleanup() {
rm -rf "$WORKDIR"
exit
}
unload_path() {
pp=$1
ph=$(nix-hash --type sha256 --to-base16 $(nix-store --query --hash $pp))
ps=$(nix-store --query --size $pp)
# The operation --dump produces a NAR (Nix ARchive) file containing the contents of the file system tree rooted at path.
nix-store --dump $pp >$WORKDIR/$ph
oras blob push \
--descriptor \
--media-type application/vnd.nixos.nar \
--size $ps \
$repository@sha256:$ph \
$WORKDIR/$ph
}
for p in $@; do
echo "Uploading installable $p"
# This is the nix store path
pp=$(nix-store --query $p)
for r in $(nix-store --query --requisites $pp); do
echo "Uploading $r"
references=$(nix-store --query --references $r | tr '\n' ' ')
unload_path $r | jq --compact-output --arg path $r --arg references "$references" \
'.annotations |= { "org.nixos.path": $path, "org.nixos.references": $references }' \
>>$WORKDIR/layers.json
done
# https://github.com/opencontainers/image-spec/blob/main/manifest.md#example-of-a-scratch-config-or-layer-descriptor
echo -n '{}' >$WORKDIR/config.json
config=$(
oras blob push \
--descriptor \
--media-type application/vnd.oci.image.config.v1+json \
--size 2 \
$repository@sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a \
$WORKDIR/config.json
)
bn=$(basename $pp)
# name=${bn#*-}
version=${bn%%-*}
jq --null-input --compact-output \
--arg path $pp \
--argjson config "$config" \
--slurpfile layers $WORKDIR/layers.json '
{
schemaVersion: 2,
config: $config,
layers: $layers,
annotations: { "org.nixos.path": $path }
}
' >$WORKDIR/manifest.json
oras manifest push \
--media-type 'application/vnd.oci.image.manifest.v1+json' \
$repository:$version,$bn \
$WORKDIR/manifest.json
done
cleanup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment