docker: format
This commit is contained in:
parent
daa36171c0
commit
ceb417aaf1
|
@ -1,49 +1,47 @@
|
||||||
{
|
{ bashInteractive
|
||||||
bashInteractive,
|
, buildPackages
|
||||||
buildPackages,
|
, cacert
|
||||||
cacert,
|
, callPackage
|
||||||
callPackage,
|
, closureInfo
|
||||||
closureInfo,
|
, coreutils
|
||||||
coreutils,
|
, e2fsprogs
|
||||||
e2fsprogs,
|
, fakeroot
|
||||||
fakeroot,
|
, findutils
|
||||||
findutils,
|
, go
|
||||||
go,
|
, jq
|
||||||
jq,
|
, jshon
|
||||||
jshon,
|
, lib
|
||||||
lib,
|
, makeWrapper
|
||||||
makeWrapper,
|
, moreutils
|
||||||
moreutils,
|
, nix
|
||||||
nix,
|
, pigz
|
||||||
pigz,
|
, pkgs
|
||||||
pkgs,
|
, rsync
|
||||||
rsync,
|
, runCommand
|
||||||
runCommand,
|
, runtimeShell
|
||||||
runtimeShell,
|
, shadow
|
||||||
shadow,
|
, skopeo
|
||||||
skopeo,
|
, storeDir ? builtins.storeDir
|
||||||
storeDir ? builtins.storeDir,
|
, substituteAll
|
||||||
substituteAll,
|
, symlinkJoin
|
||||||
symlinkJoin,
|
, util-linux
|
||||||
util-linux,
|
, vmTools
|
||||||
vmTools,
|
, writeReferencesToFile
|
||||||
writeReferencesToFile,
|
, writeScript
|
||||||
writeScript,
|
, writeText
|
||||||
writeText,
|
, writeTextDir
|
||||||
writeTextDir,
|
, writePython3
|
||||||
writePython3,
|
, system
|
||||||
system, # Note: This is the cross system we're compiling for
|
, # Note: This is the cross system we're compiling for
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
inherit (lib)
|
mkDbExtraCommand = contents:
|
||||||
optionals
|
let
|
||||||
;
|
|
||||||
|
|
||||||
mkDbExtraCommand = contents: let
|
|
||||||
contentsList = if builtins.isList contents then contents else [ contents ];
|
contentsList = if builtins.isList contents then contents else [ contents ];
|
||||||
in ''
|
in
|
||||||
|
''
|
||||||
echo "Generating the nix database..."
|
echo "Generating the nix database..."
|
||||||
echo "Warning: only the database of the deepest Nix layer is loaded."
|
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 " If you want to use nix commands in the container, it would"
|
||||||
|
@ -70,12 +68,12 @@ let
|
||||||
|
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
examples = callPackage ./examples.nix {
|
examples = callPackage ./examples.nix {
|
||||||
inherit buildImage buildLayeredImage fakeNss pullImage shadowSetup buildImageWithNixDb;
|
inherit buildImage buildLayeredImage fakeNss pullImage shadowSetup buildImageWithNixDb;
|
||||||
};
|
};
|
||||||
|
|
||||||
pullImage = let
|
pullImage =
|
||||||
|
let
|
||||||
fixName = name: builtins.replaceStrings [ "/" ":" ] [ "-" "-" ] name;
|
fixName = name: builtins.replaceStrings [ "/" ":" ] [ "-" "-" ] name;
|
||||||
in
|
in
|
||||||
{ imageName
|
{ imageName
|
||||||
|
@ -96,7 +94,8 @@ rec {
|
||||||
, name ? fixName "docker-image-${finalImageName}-${finalImageTag}.tar"
|
, name ? fixName "docker-image-${finalImageName}-${finalImageTag}.tar"
|
||||||
}:
|
}:
|
||||||
|
|
||||||
runCommand name {
|
runCommand name
|
||||||
|
{
|
||||||
inherit imageDigest;
|
inherit imageDigest;
|
||||||
imageName = finalImageName;
|
imageName = finalImageName;
|
||||||
imageTag = finalImageTag;
|
imageTag = finalImageTag;
|
||||||
|
@ -126,11 +125,12 @@ rec {
|
||||||
tarsum = pkgs.tarsum;
|
tarsum = pkgs.tarsum;
|
||||||
|
|
||||||
# buildEnv creates symlinks to dirs, which is hard to edit inside the overlay VM
|
# buildEnv creates symlinks to dirs, which is hard to edit inside the overlay VM
|
||||||
mergeDrvs = {
|
mergeDrvs =
|
||||||
derivations,
|
{ derivations
|
||||||
onlyDeps ? false
|
, onlyDeps ? false
|
||||||
}:
|
}:
|
||||||
runCommand "merge-drvs" {
|
runCommand "merge-drvs"
|
||||||
|
{
|
||||||
inherit derivations onlyDeps;
|
inherit derivations onlyDeps;
|
||||||
} ''
|
} ''
|
||||||
if [[ -n "$onlyDeps" ]]; then
|
if [[ -n "$onlyDeps" ]]; then
|
||||||
|
@ -180,19 +180,20 @@ rec {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Run commands in a virtual machine.
|
# Run commands in a virtual machine.
|
||||||
runWithOverlay = {
|
runWithOverlay =
|
||||||
name,
|
{ name
|
||||||
fromImage ? null,
|
, fromImage ? null
|
||||||
fromImageName ? null,
|
, fromImageName ? null
|
||||||
fromImageTag ? null,
|
, fromImageTag ? null
|
||||||
diskSize ? 1024,
|
, diskSize ? 1024
|
||||||
preMount ? "",
|
, preMount ? ""
|
||||||
postMount ? "",
|
, postMount ? ""
|
||||||
postUmount ? ""
|
, postUmount ? ""
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
result = vmTools.runInLinuxVM (
|
result = vmTools.runInLinuxVM (
|
||||||
runCommand name {
|
runCommand name
|
||||||
|
{
|
||||||
preVM = vmTools.createEmptyImage {
|
preVM = vmTools.createEmptyImage {
|
||||||
size = diskSize;
|
size = diskSize;
|
||||||
fullName = "docker-run-disk";
|
fullName = "docker-run-disk";
|
||||||
|
@ -293,7 +294,6 @@ rec {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
# Create an executable shell script which has the coreutils in its
|
# Create an executable shell script which has the coreutils in its
|
||||||
# PATH. Since root scripts are executed in a blank environment, even
|
# PATH. Since root scripts are executed in a blank environment, even
|
||||||
# things like `ls` or `echo` will be missing.
|
# things like `ls` or `echo` will be missing.
|
||||||
|
@ -306,21 +306,25 @@ rec {
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Create a "layer" (set of files).
|
# Create a "layer" (set of files).
|
||||||
mkPureLayer = {
|
mkPureLayer =
|
||||||
|
{
|
||||||
# Name of the layer
|
# Name of the layer
|
||||||
name,
|
name
|
||||||
# JSON containing configuration and metadata for this layer.
|
, # JSON containing configuration and metadata for this layer.
|
||||||
baseJson,
|
baseJson
|
||||||
# Files to add to the layer.
|
, # Files to add to the layer.
|
||||||
contents ? null,
|
contents ? null
|
||||||
# When copying the contents into the image, preserve symlinks to
|
, # When copying the contents into the image, preserve symlinks to
|
||||||
# directories (see `rsync -K`). Otherwise, transform those symlinks
|
# directories (see `rsync -K`). Otherwise, transform those symlinks
|
||||||
# into directories.
|
# into directories.
|
||||||
keepContentsDirlinks ? false,
|
keepContentsDirlinks ? false
|
||||||
# Additional commands to run on the layer before it is tar'd up.
|
, # Additional commands to run on the layer before it is tar'd up.
|
||||||
extraCommands ? "", uid ? 0, gid ? 0
|
extraCommands ? ""
|
||||||
|
, uid ? 0
|
||||||
|
, gid ? 0
|
||||||
}:
|
}:
|
||||||
runCommand "docker-layer-${name}" {
|
runCommand "docker-layer-${name}"
|
||||||
|
{
|
||||||
inherit baseJson contents extraCommands;
|
inherit baseJson contents extraCommands;
|
||||||
nativeBuildInputs = [ jshon rsync tarsum ];
|
nativeBuildInputs = [ jshon rsync tarsum ];
|
||||||
}
|
}
|
||||||
|
@ -360,35 +364,37 @@ rec {
|
||||||
# Make a "root" layer; required if we need to execute commands as a
|
# Make a "root" layer; required if we need to execute commands as a
|
||||||
# privileged user on the image. The commands themselves will be
|
# privileged user on the image. The commands themselves will be
|
||||||
# performed in a virtual machine sandbox.
|
# performed in a virtual machine sandbox.
|
||||||
mkRootLayer = {
|
mkRootLayer =
|
||||||
|
{
|
||||||
# Name of the image.
|
# Name of the image.
|
||||||
name,
|
name
|
||||||
# Script to run as root. Bash.
|
, # Script to run as root. Bash.
|
||||||
runAsRoot,
|
runAsRoot
|
||||||
# Files to add to the layer. If null, an empty layer will be created.
|
, # Files to add to the layer. If null, an empty layer will be created.
|
||||||
contents ? null,
|
contents ? null
|
||||||
# When copying the contents into the image, preserve symlinks to
|
, # When copying the contents into the image, preserve symlinks to
|
||||||
# directories (see `rsync -K`). Otherwise, transform those symlinks
|
# directories (see `rsync -K`). Otherwise, transform those symlinks
|
||||||
# into directories.
|
# into directories.
|
||||||
keepContentsDirlinks ? false,
|
keepContentsDirlinks ? false
|
||||||
# JSON containing configuration and metadata for this layer.
|
, # JSON containing configuration and metadata for this layer.
|
||||||
baseJson,
|
baseJson
|
||||||
# Existing image onto which to append the new layer.
|
, # Existing image onto which to append the new layer.
|
||||||
fromImage ? null,
|
fromImage ? null
|
||||||
# Name of the image we're appending onto.
|
, # Name of the image we're appending onto.
|
||||||
fromImageName ? null,
|
fromImageName ? null
|
||||||
# Tag of the image we're appending onto.
|
, # Tag of the image we're appending onto.
|
||||||
fromImageTag ? null,
|
fromImageTag ? null
|
||||||
# How much disk to allocate for the temporary virtual machine.
|
, # How much disk to allocate for the temporary virtual machine.
|
||||||
diskSize ? 1024,
|
diskSize ? 1024
|
||||||
# Commands (bash) to run on the layer; these do not require sudo.
|
, # Commands (bash) to run on the layer; these do not require sudo.
|
||||||
extraCommands ? ""
|
extraCommands ? ""
|
||||||
}:
|
}:
|
||||||
# Generate an executable script from the `runAsRoot` text.
|
# Generate an executable script from the `runAsRoot` text.
|
||||||
let
|
let
|
||||||
runAsRootScript = shellScript "run-as-root.sh" runAsRoot;
|
runAsRootScript = shellScript "run-as-root.sh" runAsRoot;
|
||||||
extraCommandsScript = shellScript "extra-commands.sh" extraCommands;
|
extraCommandsScript = shellScript "extra-commands.sh" extraCommands;
|
||||||
in runWithOverlay {
|
in
|
||||||
|
runWithOverlay {
|
||||||
name = "docker-layer-${name}";
|
name = "docker-layer-${name}";
|
||||||
|
|
||||||
inherit fromImage fromImageName fromImageTag diskSize;
|
inherit fromImage fromImageName fromImageTag diskSize;
|
||||||
|
@ -449,7 +455,8 @@ rec {
|
||||||
let
|
let
|
||||||
stream = streamLayeredImage args;
|
stream = streamLayeredImage args;
|
||||||
in
|
in
|
||||||
runCommand "${baseNameOf name}.tar.gz" {
|
runCommand "${baseNameOf name}.tar.gz"
|
||||||
|
{
|
||||||
inherit (stream) imageName;
|
inherit (stream) imageName;
|
||||||
passthru = { inherit (stream) imageTag; };
|
passthru = { inherit (stream) imageTag; };
|
||||||
nativeBuildInputs = [ pigz ];
|
nativeBuildInputs = [ pigz ];
|
||||||
|
@ -461,40 +468,45 @@ rec {
|
||||||
# 4. compute the layer id
|
# 4. compute the layer id
|
||||||
# 5. put the layer in the image
|
# 5. put the layer in the image
|
||||||
# 6. repack the image
|
# 6. repack the image
|
||||||
buildImage = args@{
|
buildImage =
|
||||||
|
args@{
|
||||||
# Image name.
|
# Image name.
|
||||||
name,
|
name
|
||||||
# Image tag, when null then the nix output hash will be used.
|
, # Image tag, when null then the nix output hash will be used.
|
||||||
tag ? null,
|
tag ? null
|
||||||
# Parent image, to append to.
|
, # Parent image, to append to.
|
||||||
fromImage ? null,
|
fromImage ? null
|
||||||
# Name of the parent image; will be read from the image otherwise.
|
, # Name of the parent image; will be read from the image otherwise.
|
||||||
fromImageName ? null,
|
fromImageName ? null
|
||||||
# Tag of the parent image; will be read from the image otherwise.
|
, # Tag of the parent image; will be read from the image otherwise.
|
||||||
fromImageTag ? null,
|
fromImageTag ? null
|
||||||
# Files to put on the image (a nix store path or list of paths).
|
, # Files to put on the image (a nix store path or list of paths).
|
||||||
contents ? null,
|
contents ? null
|
||||||
# When copying the contents into the image, preserve symlinks to
|
, # When copying the contents into the image, preserve symlinks to
|
||||||
# directories (see `rsync -K`). Otherwise, transform those symlinks
|
# directories (see `rsync -K`). Otherwise, transform those symlinks
|
||||||
# into directories.
|
# into directories.
|
||||||
keepContentsDirlinks ? false,
|
keepContentsDirlinks ? false
|
||||||
# Docker config; e.g. what command to run on the container.
|
, # Docker config; e.g. what command to run on the container.
|
||||||
config ? null,
|
config ? null
|
||||||
# Optional bash script to run on the files prior to fixturizing the layer.
|
, # Optional bash script to run on the files prior to fixturizing the layer.
|
||||||
extraCommands ? "", uid ? 0, gid ? 0,
|
extraCommands ? ""
|
||||||
# Optional bash script to run as root on the image when provisioning.
|
, uid ? 0
|
||||||
runAsRoot ? null,
|
, gid ? 0
|
||||||
# Size of the virtual machine disk to provision when building the image.
|
, # Optional bash script to run as root on the image when provisioning.
|
||||||
diskSize ? 1024,
|
runAsRoot ? null
|
||||||
# Time of creation of the image.
|
, # Size of the virtual machine disk to provision when building the image.
|
||||||
created ? "1970-01-01T00:00:01Z",
|
diskSize ? 1024
|
||||||
|
, # Time of creation of the image.
|
||||||
|
created ? "1970-01-01T00:00:01Z"
|
||||||
|
,
|
||||||
}:
|
}:
|
||||||
|
|
||||||
let
|
let
|
||||||
baseName = baseNameOf name;
|
baseName = baseNameOf name;
|
||||||
|
|
||||||
# Create a JSON blob of the configuration. Set the date to unix zero.
|
# Create a JSON blob of the configuration. Set the date to unix zero.
|
||||||
baseJson = let
|
baseJson =
|
||||||
|
let
|
||||||
pure = writeText "${baseName}-config.json" (builtins.toJSON {
|
pure = writeText "${baseName}-config.json" (builtins.toJSON {
|
||||||
inherit created config;
|
inherit created config;
|
||||||
architecture = defaultArch;
|
architecture = defaultArch;
|
||||||
|
@ -505,20 +517,25 @@ rec {
|
||||||
''
|
''
|
||||||
jq ".created = \"$(TZ=utc date --iso-8601="seconds")\"" ${pure} > $out
|
jq ".created = \"$(TZ=utc date --iso-8601="seconds")\"" ${pure} > $out
|
||||||
'';
|
'';
|
||||||
in if created == "now" then impure else pure;
|
in
|
||||||
|
if created == "now" then impure else pure;
|
||||||
|
|
||||||
layer =
|
layer =
|
||||||
if runAsRoot == null
|
if runAsRoot == null
|
||||||
then mkPureLayer {
|
then
|
||||||
|
mkPureLayer
|
||||||
|
{
|
||||||
name = baseName;
|
name = baseName;
|
||||||
inherit baseJson contents keepContentsDirlinks extraCommands uid gid;
|
inherit baseJson contents keepContentsDirlinks extraCommands uid gid;
|
||||||
} else mkRootLayer {
|
} else
|
||||||
|
mkRootLayer {
|
||||||
name = baseName;
|
name = baseName;
|
||||||
inherit baseJson fromImage fromImageName fromImageTag
|
inherit baseJson fromImage fromImageName fromImageTag
|
||||||
contents keepContentsDirlinks runAsRoot diskSize
|
contents keepContentsDirlinks runAsRoot diskSize
|
||||||
extraCommands;
|
extraCommands;
|
||||||
};
|
};
|
||||||
result = runCommand "docker-image-${baseName}.tar.gz" {
|
result = runCommand "docker-image-${baseName}.tar.gz"
|
||||||
|
{
|
||||||
nativeBuildInputs = [ jshon pigz coreutils findutils jq moreutils ];
|
nativeBuildInputs = [ jshon pigz coreutils findutils jq moreutils ];
|
||||||
# Image name must be lowercase
|
# Image name must be lowercase
|
||||||
imageName = lib.toLower name;
|
imageName = lib.toLower name;
|
||||||
|
@ -760,32 +777,34 @@ rec {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
streamLayeredImage = {
|
streamLayeredImage =
|
||||||
|
{
|
||||||
# Image Name
|
# Image Name
|
||||||
name,
|
name
|
||||||
# Image tag, the Nix's output hash will be used if null
|
, # Image tag, the Nix's output hash will be used if null
|
||||||
tag ? null,
|
tag ? null
|
||||||
# Parent image, to append to.
|
, # Parent image, to append to.
|
||||||
fromImage ? null,
|
fromImage ? null
|
||||||
# Files to put on the image (a nix store path or list of paths).
|
, # Files to put on the image (a nix store path or list of paths).
|
||||||
contents ? [],
|
contents ? [ ]
|
||||||
# Docker config; e.g. what command to run on the container.
|
, # Docker config; e.g. what command to run on the container.
|
||||||
config ? {},
|
config ? { }
|
||||||
# Time of creation of the image. Passing "now" will make the
|
, # Time of creation of the image. Passing "now" will make the
|
||||||
# created date be the time of building.
|
# created date be the time of building.
|
||||||
created ? "1970-01-01T00:00:01Z",
|
created ? "1970-01-01T00:00:01Z"
|
||||||
# Optional bash script to run on the files prior to fixturizing the layer.
|
, # Optional bash script to run on the files prior to fixturizing the layer.
|
||||||
extraCommands ? "",
|
extraCommands ? ""
|
||||||
# Optional bash script to run inside fakeroot environment.
|
, # Optional bash script to run inside fakeroot environment.
|
||||||
# Could be used for changing ownership of files in customisation layer.
|
# Could be used for changing ownership of files in customisation layer.
|
||||||
fakeRootCommands ? "",
|
fakeRootCommands ? ""
|
||||||
# We pick 100 to ensure there is plenty of room for extension. I
|
, # We pick 100 to ensure there is plenty of room for extension. I
|
||||||
# believe the actual maximum is 128.
|
# believe the actual maximum is 128.
|
||||||
maxLayers ? 100,
|
maxLayers ? 100
|
||||||
# Whether to include store paths in the image. You generally want to leave
|
, # Whether to include store paths in the image. You generally want to leave
|
||||||
# this on, but tooling may disable this to insert the store paths more
|
# this on, but tooling may disable this to insert the store paths more
|
||||||
# efficiently via other means, such as bind mounting the host store.
|
# efficiently via other means, such as bind mounting the host store.
|
||||||
includeStorePaths ? true,
|
includeStorePaths ? true
|
||||||
|
,
|
||||||
}:
|
}:
|
||||||
assert
|
assert
|
||||||
(lib.assertMsg (maxLayers > 1)
|
(lib.assertMsg (maxLayers > 1)
|
||||||
|
@ -833,7 +852,7 @@ rec {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
closureRoots = optionals includeStorePaths /* normally true */ (
|
closureRoots = lib.optionals includeStorePaths /* normally true */ (
|
||||||
[ baseJson ] ++ contentsList
|
[ baseJson ] ++ contentsList
|
||||||
);
|
);
|
||||||
overallClosure = writeText "closure" (lib.concatStringsSep " " closureRoots);
|
overallClosure = writeText "closure" (lib.concatStringsSep " " closureRoots);
|
||||||
|
@ -842,7 +861,8 @@ rec {
|
||||||
# so they'll be excluded from the created images.
|
# so they'll be excluded from the created images.
|
||||||
unnecessaryDrvs = [ baseJson overallClosure ];
|
unnecessaryDrvs = [ baseJson overallClosure ];
|
||||||
|
|
||||||
conf = runCommand "${baseName}-conf.json" {
|
conf = runCommand "${baseName}-conf.json"
|
||||||
|
{
|
||||||
inherit fromImage maxLayers created;
|
inherit fromImage maxLayers created;
|
||||||
imageName = lib.toLower name;
|
imageName = lib.toLower name;
|
||||||
passthru.imageTag =
|
passthru.imageTag =
|
||||||
|
@ -931,7 +951,8 @@ rec {
|
||||||
--arg created "$created" |
|
--arg created "$created" |
|
||||||
tee $out
|
tee $out
|
||||||
'';
|
'';
|
||||||
result = runCommand "stream-${baseName}" {
|
result = runCommand "stream-${baseName}"
|
||||||
|
{
|
||||||
inherit (conf) imageName;
|
inherit (conf) imageName;
|
||||||
passthru = {
|
passthru = {
|
||||||
inherit (conf) imageTag;
|
inherit (conf) imageTag;
|
||||||
|
@ -944,5 +965,6 @@ rec {
|
||||||
} ''
|
} ''
|
||||||
makeWrapper ${streamScript} $out --add-flags ${conf}
|
makeWrapper ${streamScript} $out --add-flags ${conf}
|
||||||
'';
|
'';
|
||||||
in result;
|
in
|
||||||
|
result;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue