diff options
author | Ryan Trinkle <ryan.trinkle@gmail.com> | 2017-11-03 10:53:00 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-03 10:53:00 -0400 |
commit | ded1281f4519bfdeea6c79eb6857f00619d9859d (patch) | |
tree | 0562858f7368f6e9ae65a730d2e4ea750d40f31e /pkgs/build-support/docker/default.nix | |
parent | dce2c258ac33ee1cd3b3e852b36e1d8fa11f33a1 (diff) | |
parent | 74260a4922e678348eac91f4aa5767a3f5a039a4 (diff) | |
download | nixpkgs-ded1281f4519bfdeea6c79eb6857f00619d9859d.tar nixpkgs-ded1281f4519bfdeea6c79eb6857f00619d9859d.tar.gz nixpkgs-ded1281f4519bfdeea6c79eb6857f00619d9859d.tar.bz2 nixpkgs-ded1281f4519bfdeea6c79eb6857f00619d9859d.tar.lz nixpkgs-ded1281f4519bfdeea6c79eb6857f00619d9859d.tar.xz nixpkgs-ded1281f4519bfdeea6c79eb6857f00619d9859d.tar.zst nixpkgs-ded1281f4519bfdeea6c79eb6857f00619d9859d.zip |
Merge branch 'master' into docker-dirlinks
Diffstat (limited to 'pkgs/build-support/docker/default.nix')
-rw-r--r-- | pkgs/build-support/docker/default.nix | 103 |
1 files changed, 89 insertions, 14 deletions
diff --git a/pkgs/build-support/docker/default.nix b/pkgs/build-support/docker/default.nix index 8230eb69c29..b9d9fd2a54c 100644 --- a/pkgs/build-support/docker/default.nix +++ b/pkgs/build-support/docker/default.nix @@ -6,9 +6,12 @@ findutils, go, jshon, + jq, lib, pkgs, pigz, + nixUnstable, + perl, runCommand, rsync, shadow, @@ -26,7 +29,7 @@ rec { examples = import ./examples.nix { - inherit pkgs buildImage pullImage shadowSetup; + inherit pkgs buildImage pullImage shadowSetup buildImageWithNixDb; }; pullImage = callPackage ./pull.nix {}; @@ -42,7 +45,7 @@ rec { cp ${./tarsum.go} tarsum.go export GOPATH=$(pwd) mkdir src - ln -sT ${docker.src}/pkg/tarsum src/tarsum + ln -sT ${docker.src}/components/engine/pkg/tarsum src/tarsum go build cp tarsum $out @@ -82,7 +85,7 @@ rec { export PATH=${shadow}/bin:$PATH mkdir -p /etc/pam.d if [[ ! -f /etc/passwd ]]; then - echo "root:x:0:0::/root:/bin/sh" > /etc/passwd + echo "root:x:0:0::/root:${stdenv.shell}" > /etc/passwd echo "root:!x:::::::" > /etc/shadow fi if [[ ! -f /etc/group ]]; then @@ -225,6 +228,19 @@ rec { ${text} ''; + nixRegistration = contents: runCommand "nix-registration" { + buildInputs = [ nixUnstable perl ]; + # For obtaining the closure of `contents'. + exportReferencesGraph = + let contentsList = if builtins.isList contents then contents else [ contents ]; + in map (x: [("closure-" + baseNameOf x) x]) contentsList; + } + '' + mkdir $out + printRegistration=1 perl ${pkgs.pathsFromGraph} closure-* > $out/db.dump + perl ${pkgs.pathsFromGraph} closure-* > $out/storePaths + ''; + # Create a "layer" (set of files). mkPureLayer = { # Name of the layer @@ -238,11 +254,10 @@ rec { # into directories. keepContentsDirlinks ? false, # Additional commands to run on the layer before it is tar'd up. - extraCommands ? "" + extraCommands ? "", uid ? 0, gid ? 0 }: runCommand "docker-layer-${name}" { inherit baseJson contents extraCommands; - buildInputs = [ jshon rsync ]; } '' @@ -257,6 +272,8 @@ rec { echo "No contents to add to layer." fi + chmod ug+w layer + if [[ -n $extraCommands ]]; then (cd layer; eval "$extraCommands") fi @@ -264,7 +281,7 @@ rec { # Tar up the layer and throw it into 'layer.tar'. echo "Packing layer..." mkdir $out - tar -C layer --mtime="@$SOURCE_DATE_EPOCH" -cf $out/layer.tar . + tar -C layer --mtime="@$SOURCE_DATE_EPOCH" --owner=${toString uid} --group=${toString gid} -cf $out/layer.tar . # Compute a checksum of the tarball. echo "Computing layer checksum..." @@ -320,6 +337,8 @@ rec { echo "Adding $item..." rsync -a${if keepContentsDirlinks then "K" else "k"} --chown=0:0 $item/ layer/ done + + chmod ug+w layer ''; postMount = '' @@ -387,11 +406,13 @@ rec { # Docker config; e.g. what command to run on the container. config ? null, # Optional bash script to run on the files prior to fixturizing the layer. - extraCommands ? "", + extraCommands ? "", uid ? 0, gid ? 0, # Optional bash script to run as root on the image when provisioning. runAsRoot ? null, # Size of the virtual machine disk to provision when building the image. diskSize ? 1024, + # Time of creation of the image. + created ? "1970-01-01T00:00:01Z", }: let @@ -399,17 +420,16 @@ rec { # Create a JSON blob of the configuration. Set the date to unix zero. baseJson = writeText "${baseName}-config.json" (builtins.toJSON { - created = "1970-01-01T00:00:01Z"; + inherit created config; architecture = "amd64"; os = "linux"; - config = config; }); layer = if runAsRoot == null then mkPureLayer { name = baseName; - inherit baseJson contents keepContentsDirlinks extraCommands; + inherit baseJson contents keepContentsDirlinks extraCommands uid gid; } else mkRootLayer { name = baseName; inherit baseJson fromImage fromImageName fromImageTag @@ -417,9 +437,10 @@ rec { extraCommands; }; result = runCommand "docker-image-${baseName}.tar.gz" { - buildInputs = [ jshon pigz coreutils findutils ]; - imageName = name; - imageTag = tag; + buildInputs = [ jshon pigz coreutils findutils jq ]; + # Image name and tag must be lowercase + imageName = lib.toLower name; + imageTag = lib.toLower tag; inherit fromImage baseJson; layerClosure = writeReferencesToFile layer; passthru.buildArgs = args; @@ -443,6 +464,9 @@ rec { if [[ -n "$fromImage" ]]; then echo "Unpacking base image..." tar -C image -xpf "$fromImage" + # Do not import the base image configuration and manifest + chmod a+w image image/*.json + rm -f image/*.json if [[ -z "$fromImageName" ]]; then fromImageName=$(jshon -k < image/repositories|head -n1) @@ -501,6 +525,24 @@ rec { # Use the temp folder we've been working on to create a new image. mv temp image/$layerID + # Create image json and image manifest + imageJson=$(cat ${baseJson} | jq ". + {\"rootfs\": {\"diff_ids\": [], \"type\": \"layers\"}}") + manifestJson=$(jq -n "[{\"RepoTags\":[\"$imageName:$imageTag\"]}]") + currentID=$layerID + while [[ -n "$currentID" ]]; do + layerChecksum=$(sha256sum image/$currentID/layer.tar | cut -d ' ' -f1) + imageJson=$(echo "$imageJson" | jq ".history |= [{\"created\": \"${created}\"}] + .") + imageJson=$(echo "$imageJson" | jq ".rootfs.diff_ids |= [\"sha256:$layerChecksum\"] + .") + manifestJson=$(echo "$manifestJson" | jq ".[0].Layers |= [\"$currentID/layer.tar\"] + .") + + currentID=$(cat image/$currentID/json | (jshon -e parent -u 2>/dev/null || true)) + done + + imageJsonChecksum=$(echo "$imageJson" | sha256sum | cut -d ' ' -f1) + echo "$imageJson" > "image/$imageJsonChecksum.json" + manifestJson=$(echo "$manifestJson" | jq ".[0].Config = \"$imageJsonChecksum.json\"") + echo "$manifestJson" > image/manifest.json + # Store the json under the name image/repositories. jshon -n object \ -n object -s "$layerID" -i "$imageTag" \ @@ -510,11 +552,44 @@ rec { chmod -R a-w image echo "Cooking the image..." - tar -C image --mtime="@$SOURCE_DATE_EPOCH" -c . | pigz -nT > $out + tar -C image --mtime="@$SOURCE_DATE_EPOCH" --owner=0 --group=0 --xform s:'./':: -c . | pigz -nT > $out echo "Finished." ''; in result; + + # Build an image and populate its nix database with the provided + # contents. The main purpose is to be able to use nix commands in + # the container. + # Be careful since this doesn't work well with multilayer. + buildImageWithNixDb = args@{ contents ? null, extraCommands ? "", ... }: + buildImage (args // { + extraCommands = '' + echo "Generating the nix database..." + echo "Warning: only the database of the deepest Nix layer is loaded." + echo " If you want to use nix commands in the container, it would" + echo " be better to only have one layer that contains a nix store." + # This requires Nix 1.12 or higher + export NIX_REMOTE=local?root=$PWD + ${nixUnstable}/bin/nix-store --load-db < ${nixRegistration contents}/db.dump + + # We fill the store in order to run the 'verify' command that + # generates hash and size of output paths. + # Note when Nix 1.12 is be the stable one, the database dump + # generated by the exportReferencesGraph function will + # contains sha and size. See + # https://github.com/NixOS/nix/commit/c2b0d8749f7e77afc1c4b3e8dd36b7ee9720af4a + storePaths=$(cat ${nixRegistration contents}/storePaths) + echo "Copying everything to /nix/store (will take a while)..." + cp -prd $storePaths nix/store/ + ${nixUnstable}/bin/nix-store --verify --check-contents + + mkdir -p nix/var/nix/gcroots/docker/ + for i in ${lib.concatStringsSep " " contents}; do + ln -s $i nix/var/nix/gcroots/docker/$(basename $i) + done; + '' + extraCommands; + }); } |