Initial implementation of a buildImage function with configurable build steps, and an implementation of a mutable image building function
This commit is contained in:
parent
c69248bb7c
commit
d347c04fd6
|
@ -935,9 +935,8 @@ To construct such as an image, we can evaluate a Nix expression (e.g.
|
|||
}:
|
||||
|
||||
let
|
||||
createMultiProcessImage = import ../../nixproc/create-multi-process-image/create-multi-process-image.nix {
|
||||
inherit pkgs system;
|
||||
inherit (pkgs) dockerTools stdenv;
|
||||
createMultiProcessImage = import ../../nixproc/create-image-from-steps/create-multi-process-image-universal.nix {
|
||||
inherit pkgs;
|
||||
};
|
||||
in
|
||||
createMultiProcessImage {
|
||||
|
@ -946,6 +945,7 @@ createMultiProcessImage {
|
|||
exprFile = ../webapps-agnostic/processes.nix;
|
||||
processManager = "supervisord"; # sysvinit, disnix, s6-rc are also valid options
|
||||
interactive = true; # the default option
|
||||
manpages = false; # the default option
|
||||
forceDisableUserChange = false; # the default option
|
||||
}
|
||||
```
|
||||
|
@ -964,6 +964,8 @@ with the following parameters:
|
|||
this setting has been enabled, a `.bashrc` will be configured to make
|
||||
the bash shell usable, and a number of additional packages will be installed
|
||||
for file and process management operations.
|
||||
* We can also optionally install `man` in the container so that you can access
|
||||
manual pages. By default, it is disabled
|
||||
* It is also possible to adjust the state settings in the processes model.
|
||||
With `forceDisableUserChange` we can disable user creation and user
|
||||
switching. It is also possible to control the other state variables, such
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
}:
|
||||
|
||||
let
|
||||
createMultiProcessImage = import ../../nixproc/create-multi-process-image/create-multi-process-image-universal.nix {
|
||||
inherit pkgs system;
|
||||
inherit (pkgs) dockerTools stdenv;
|
||||
createMultiProcessImage = import ../../nixproc/create-image-from-steps/create-multi-process-image-universal.nix {
|
||||
inherit pkgs;
|
||||
};
|
||||
in
|
||||
createMultiProcessImage {
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
{pkgs, system, exprFile, stateDir, runtimeDir, forceDisableUserChange, extraParams}:
|
||||
|
||||
let
|
||||
sysvinitTools = (import ../../../tools {
|
||||
inherit pkgs system;
|
||||
}).sysvinit;
|
||||
|
||||
generateCompoundProxy = import ../util/generate-compound-proxy.nix {
|
||||
inherit (pkgs) stdenv writeTextFile;
|
||||
};
|
||||
|
||||
disnixDataDir = "${pkgs.disnix}/share/disnix";
|
||||
|
||||
profile = import ./build-disnix-env.nix {
|
||||
inherit pkgs system exprFile stateDir runtimeDir forceDisableUserChange extraParams disnixDataDir;
|
||||
};
|
||||
|
||||
emptyProfile = import ./build-disnix-env.nix {
|
||||
inherit pkgs system stateDir runtimeDir forceDisableUserChange extraParams disnixDataDir;
|
||||
exprFile = null;
|
||||
};
|
||||
|
||||
script = generateCompoundProxy {
|
||||
path = [ pkgs.dysnomia pkgs.disnix ];
|
||||
startCommand = "disnix-activate ${profile}";
|
||||
stopCommand = "disnix-activate -o ${profile} ${emptyProfile}";
|
||||
};
|
||||
in
|
||||
{
|
||||
runAsRoot = pkgs.lib.optionalString (!forceDisableUserChange) ''
|
||||
${pkgs.gnused}/bin/sed -i -e "s/CREATE_MAIL_SPOOL=yes/CREATE_MAIL_SPOOL=no/" /etc/default/useradd
|
||||
|
||||
mkdir -p /etc/pam.d
|
||||
cat > /etc/pam.d/su <<EOF
|
||||
account required pam_unix.so
|
||||
auth sufficient pam_rootok.so
|
||||
auth required pam_tally.so
|
||||
auth sufficient pam_unix.so likeauth try_first_pass
|
||||
auth required pam_deny.so
|
||||
password sufficient pam_unix.so nullok sha512
|
||||
EOF
|
||||
'';
|
||||
contents = [ pkgs.shadow pkgs.su pkgs.disnix pkgs.dysnomia ];
|
||||
cmd = [ script ];
|
||||
credentialsSpec = null;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
disnixTools = (import ../../../../tools {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
}).disnix;
|
||||
|
||||
generateCompoundProxy = import ../../util/generate-compound-proxy.nix {
|
||||
inherit (pkgs) stdenv writeTextFile;
|
||||
};
|
||||
|
||||
disnixDataDir = "${pkgs.disnix}/share/disnix";
|
||||
|
||||
emptyProfile = import ../build-disnix-env.nix {
|
||||
inherit pkgs disnixDataDir;
|
||||
inherit (common) system;
|
||||
inherit (input) stateDir runtimeDir forceDisableUserChange extraParams;
|
||||
exprFile = null;
|
||||
};
|
||||
|
||||
profilePath = "/nix/var/nix/profiles/per-user/root/disnix-coordinator/default";
|
||||
|
||||
script = generateCompoundProxy {
|
||||
path = [ pkgs.dysnomia pkgs.disnix ];
|
||||
startCommand = "disnix-activate -o ${emptyProfile} ${profilePath}";
|
||||
stopCommand = "disnix-activate -o ${profilePath} ${emptyProfile}";
|
||||
};
|
||||
in
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
mkdir -p "$(dirname ${profilePath})"
|
||||
ln -s ${emptyProfile} ${profilePath}
|
||||
'';
|
||||
|
||||
contents = result.contents or [] ++ [ disnixTools ];
|
||||
config = result.config or {} // {
|
||||
Cmd = [ script ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
generateCompoundProxy = import ../../util/generate-compound-proxy.nix {
|
||||
inherit (pkgs) stdenv writeTextFile;
|
||||
};
|
||||
|
||||
disnixDataDir = "${pkgs.disnix}/share/disnix";
|
||||
|
||||
profile = import ../build-disnix-env.nix {
|
||||
inherit pkgs disnixDataDir;
|
||||
inherit (common) system;
|
||||
inherit (input) exprFile stateDir runtimeDir forceDisableUserChange extraParams;
|
||||
};
|
||||
|
||||
emptyProfile = import ../build-disnix-env.nix {
|
||||
inherit pkgs disnixDataDir;
|
||||
inherit (common) system;
|
||||
inherit (input) stateDir runtimeDir forceDisableUserChange extraParams;
|
||||
exprFile = null;
|
||||
};
|
||||
|
||||
script = generateCompoundProxy {
|
||||
path = [ pkgs.dysnomia pkgs.disnix ];
|
||||
startCommand = "disnix-activate ${profile}";
|
||||
stopCommand = "disnix-activate -o ${profile} ${emptyProfile}";
|
||||
};
|
||||
in
|
||||
result // {
|
||||
config = result.config or {} // {
|
||||
Cmd = [ script ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
result // {
|
||||
contents = result.contents or [] ++ [ pkgs.disnix pkgs.dysnomia ];
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
../../../create-image-from-steps/steps/su-pam.nix
|
||||
./disnix.nix
|
||||
./disnix-dynamic.nix
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
../../../create-image-from-steps/steps/su-pam.nix
|
||||
./disnix.nix
|
||||
./disnix-static.nix
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
./s6-rc.nix
|
||||
./s6-rc-dynamic.nix
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
s6-rcTools = (import ../../../../tools {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
}).s6-rc;
|
||||
in
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
# Create empty service directory
|
||||
mkdir -p /etc/s6/sv
|
||||
|
||||
# Initialize s6-rc with a compiled database
|
||||
mkdir -p /etc/s6/rc
|
||||
s6-rc-compile /etc/s6/rc/compiled /etc/s6/sv
|
||||
'';
|
||||
contents = result.contents or [] ++ [ s6-rcTools ];
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
profile = import ../build-s6-rc-env.nix {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
inherit (input) exprFile extraParams stateDir runtimeDir forceDisableUserChange;
|
||||
};
|
||||
in
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
# Initialize s6-rc with a compiled database
|
||||
mkdir -p /etc/s6/rc
|
||||
s6-rc-compile /etc/s6/rc/compiled ${profile}/etc/s6/sv
|
||||
|
||||
${pkgs.lib.optionalString (!input.forceDisableUserChange) ''
|
||||
export PATH=$PATH:${pkgs.findutils}/bin:${pkgs.glibc.bin}/bin
|
||||
${pkgs.dysnomia}/bin/dysnomia-addgroups ${profile}
|
||||
${pkgs.dysnomia}/bin/dysnomia-addusers ${profile}
|
||||
''}
|
||||
'';
|
||||
}
|
|
@ -1,10 +1,6 @@
|
|||
{pkgs, system, exprFile, stateDir, runtimeDir, forceDisableUserChange, extraParams}:
|
||||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
profile = import ./build-s6-rc-env.nix {
|
||||
inherit pkgs system exprFile extraParams stateDir runtimeDir forceDisableUserChange;
|
||||
};
|
||||
|
||||
skelDir = pkgs.stdenv.mkDerivation {
|
||||
name = "s6-skel-dir";
|
||||
buildCommand = ''
|
||||
|
@ -38,8 +34,8 @@ let
|
|||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
runAsRoot = ''
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
# Run s6-linux-init-maker to configure s6-linux-init as an init system
|
||||
mkdir -p /etc/s6
|
||||
s6-linux-init-maker -c /etc/s6/current -p /bin -m 0022 -f ${skelDir} -N -C -B /etc/s6/current
|
||||
|
@ -49,12 +45,11 @@ in
|
|||
# Create s6-log user and group
|
||||
groupadd -g 2 s6-log
|
||||
useradd -u 2 -d /dev/null -g s6-log s6-log
|
||||
|
||||
# Initialize s6-rc with a compiled database
|
||||
mkdir -p /etc/s6/rc
|
||||
s6-rc-compile /etc/s6/rc/compiled ${profile}/etc/s6/sv
|
||||
'';
|
||||
contents = [ pkgs.s6-linux-init pkgs.s6 pkgs.s6-rc pkgs.execline ];
|
||||
cmd = [ "/bin/init" ];
|
||||
credentialsSpec = profile;
|
||||
|
||||
contents = result.contents or [] ++ [ pkgs.s6-linux-init pkgs.s6 pkgs.s6-rc pkgs.execline ];
|
||||
|
||||
config = result.config or {} // {
|
||||
cmd = [ "/bin/init" ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
./s6-rc.nix
|
||||
./s6-rc-static.nix
|
||||
]
|
|
@ -1,15 +0,0 @@
|
|||
{pkgs, system, exprFile, stateDir, runtimeDir, forceDisableUserChange, extraParams}:
|
||||
|
||||
let
|
||||
profile = import ./build-supervisord-env.nix {
|
||||
inherit pkgs system exprFile extraParams stateDir runtimeDir forceDisableUserChange;
|
||||
};
|
||||
in
|
||||
{
|
||||
runAsRoot = ''
|
||||
ln -s ${profile} /etc/supervisor
|
||||
'';
|
||||
contents = [ pkgs.pythonPackages.supervisor ];
|
||||
cmd = [ "${pkgs.pythonPackages.supervisor}/bin/supervisord" "--nodaemon" "--configuration" "/etc/supervisor/supervisord.conf" "--logfile" "/var/log/supervisord.log" "--pidfile" "/var/run/supervisord.pid" ];
|
||||
credentialsSpec = profile;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
./supervisord.nix
|
||||
./supervisord-dynamic.nix
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
./supervisord.nix
|
||||
./supervisord-static.nix
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
supervisordTools = (import ../../../../tools {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
}).supervisord;
|
||||
in
|
||||
result // {
|
||||
contents = result.contents or [] ++ [ supervisordTools ];
|
||||
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
mkdir -p /etc/supervisor/conf.d
|
||||
cp ${../supervisord.conf} /etc/supervisor/supervisord.conf
|
||||
'';
|
||||
|
||||
config = result.config or {} // {
|
||||
Env = result.config.Env or []
|
||||
++ [ "SUPERVISORD_CONF_DIR=/etc/supervisor" ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
profile = import ../build-supervisord-env.nix {
|
||||
inherit pkgs;
|
||||
inherit (input) exprFile extraParams stateDir runtimeDir forceDisableUserChange;
|
||||
inherit (common) system;
|
||||
};
|
||||
in
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
ln -s ${profile} /etc/supervisor
|
||||
|
||||
${pkgs.lib.optionalString (!input.forceDisableUserChange) ''
|
||||
export PATH=$PATH:${pkgs.findutils}/bin:${pkgs.glibc.bin}/bin
|
||||
${pkgs.dysnomia}/bin/dysnomia-addgroups ${profile}
|
||||
${pkgs.dysnomia}/bin/dysnomia-addusers ${profile}
|
||||
''}
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
result // {
|
||||
contents = result.contents or [] ++ [ pkgs.pythonPackages.supervisor ];
|
||||
config = result.config or {} // {
|
||||
Cmd = [ "${pkgs.pythonPackages.supervisor}/bin/supervisord" "--nodaemon" "--configuration" "/etc/supervisor/supervisord.conf" "--logfile" "/var/log/supervisord.log" "--pidfile" "/var/run/supervisord.pid" ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
../../../create-image-from-steps/steps/su-pam.nix
|
||||
./sysvinit.nix
|
||||
./sysvinit-dynamic.nix
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
../../../create-image-from-steps/steps/su-pam.nix
|
||||
./sysvinit.nix
|
||||
./sysvinit-static.nix
|
||||
]
|
|
@ -0,0 +1,29 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
sysvinitTools = (import ../../../../tools {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
}).sysvinit;
|
||||
|
||||
generateCompoundProxy = import ../../util/generate-compound-proxy.nix {
|
||||
inherit (pkgs) stdenv writeTextFile;
|
||||
};
|
||||
|
||||
runlevel = "3";
|
||||
|
||||
script = generateCompoundProxy {
|
||||
startCommand = "${sysvinitTools}/bin/nixproc-sysvinit-runactivity --runlevel ${runlevel} start /";
|
||||
stopCommand = "${sysvinitTools}/bin/nixproc-sysvinit-runactivity --runlevel ${runlevel} -r stop /";
|
||||
};
|
||||
in
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
# Make symlink to processes profile
|
||||
ln -s /nix/var/nix/profiles/processes/etc/rc.d /etc/rc.d
|
||||
'';
|
||||
config = result.config or {} // {
|
||||
Cmd = [ script ];
|
||||
};
|
||||
contents = result.contents or [] ++ [ sysvinitTools ];
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
sysvinitTools = (import ../../../../tools {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
}).sysvinit;
|
||||
|
||||
generateCompoundProxy = import ../../util/generate-compound-proxy.nix {
|
||||
inherit (pkgs) stdenv writeTextFile;
|
||||
};
|
||||
|
||||
runlevel = "3";
|
||||
|
||||
script = generateCompoundProxy {
|
||||
startCommand = "${sysvinitTools}/bin/nixproc-sysvinit-runactivity start ${profile}";
|
||||
stopCommand = "${sysvinitTools}/bin/nixproc-sysvinit-runactivity -r stop ${profile}";
|
||||
};
|
||||
|
||||
profile = import ../build-sysvinit-env.nix {
|
||||
inherit (input) exprFile stateDir runtimeDir forceDisableUserChange extraParams;
|
||||
};
|
||||
in
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
ln -s ${profile}/etc/rc.d /etc/rc.d
|
||||
|
||||
${pkgs.lib.optionalString (!input.forceDisableUserChange) ''
|
||||
export PATH=$PATH:${pkgs.findutils}/bin:${pkgs.glibc.bin}/bin
|
||||
${pkgs.dysnomia}/bin/dysnomia-addgroups ${profile}
|
||||
${pkgs.dysnomia}/bin/dysnomia-addusers ${profile}
|
||||
''}
|
||||
'';
|
||||
config = result.config or {} // {
|
||||
Cmd = [ script ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
result // {
|
||||
contents = result.contents or [] ++ [ pkgs.sysvinit pkgs.gnugrep pkgs.coreutils ];
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{pkgs, steps, common ? {}, input}:
|
||||
|
||||
let
|
||||
generatedConfig = import ./generate-config-from-steps.nix {
|
||||
inherit pkgs common input steps;
|
||||
};
|
||||
in
|
||||
pkgs.dockerTools.buildImage generatedConfig
|
|
@ -0,0 +1,13 @@
|
|||
{pkgs}:
|
||||
input:
|
||||
|
||||
import ./create-multi-process-image.nix {
|
||||
inherit pkgs;
|
||||
} (input // {
|
||||
steps = {
|
||||
disnix = ../backends/disnix/image-steps/static-steps.nix;
|
||||
s6-rc = ../backends/s6-rc/image-steps/static-steps.nix;
|
||||
supervisord = ../backends/supervisord/image-steps/static-steps.nix;
|
||||
sysvinit = ../backends/sysvinit/image-steps/static-steps.nix;
|
||||
};
|
||||
})
|
|
@ -0,0 +1,30 @@
|
|||
{pkgs}:
|
||||
{processManager, steps, ...}@input:
|
||||
|
||||
let
|
||||
_input = rec {
|
||||
stateDir = "/var";
|
||||
runtimeDir = "${stateDir}/run";
|
||||
forceDisableUserChange = false;
|
||||
extraParams = {};
|
||||
} // input;
|
||||
|
||||
processManagerSpecificStepsFile = builtins.getAttr processManager steps;
|
||||
in
|
||||
import ./create-image-from-steps.nix {
|
||||
inherit pkgs;
|
||||
input = _input;
|
||||
|
||||
common = {
|
||||
system = builtins.currentSystem;
|
||||
};
|
||||
|
||||
steps = [
|
||||
./steps/init.nix
|
||||
./steps/basic.nix
|
||||
./steps/interactive.nix
|
||||
./steps/man.nix
|
||||
./steps/nix-processmgmt-static.nix
|
||||
]
|
||||
++ import processManagerSpecificStepsFile;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{pkgs}:
|
||||
input:
|
||||
|
||||
import ./create-mutable-multi-process-image.nix {
|
||||
inherit pkgs;
|
||||
} (input // {
|
||||
steps = {
|
||||
disnix = ../backends/disnix/image-steps/dynamic-steps.nix;
|
||||
s6-rc = ../backends/s6-rc/image-steps/dynamic-steps.nix;
|
||||
supervisord = ../backends/supervisord/image-steps/dynamic-steps.nix;
|
||||
sysvinit = ../backends/sysvinit/image-steps/dynamic-steps.nix;
|
||||
};
|
||||
})
|
|
@ -0,0 +1,31 @@
|
|||
{pkgs}:
|
||||
{processManager, steps, ...}@input:
|
||||
|
||||
let
|
||||
_input = rec {
|
||||
stateDir = "/var";
|
||||
runtimeDir = "${stateDir}/run";
|
||||
} // input;
|
||||
|
||||
processManagerSpecificStepsFile = builtins.getAttr processManager steps;
|
||||
in
|
||||
import ./create-image-from-steps.nix {
|
||||
inherit pkgs;
|
||||
common = {
|
||||
system = builtins.currentSystem;
|
||||
};
|
||||
input = _input;
|
||||
|
||||
steps = [
|
||||
./steps/init.nix
|
||||
./steps/basic.nix
|
||||
./steps/interactive.nix
|
||||
./steps/man.nix
|
||||
./steps/nix-processmgmt-dynamic.nix
|
||||
]
|
||||
++ import processManagerSpecificStepsFile
|
||||
++ [
|
||||
./steps/bootstrap-init.nix
|
||||
./steps/nix-support.nix
|
||||
];
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{pkgs}:
|
||||
input:
|
||||
|
||||
import ./create-image-from-steps.nix {
|
||||
inherit pkgs input;
|
||||
|
||||
common = {
|
||||
system = builtins.currentSystem;
|
||||
};
|
||||
|
||||
steps = [
|
||||
./steps/init.nix
|
||||
./steps/basic.nix
|
||||
./steps/interactive.nix
|
||||
./steps/man.nix
|
||||
./steps/nix-support.nix
|
||||
];
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{pkgs, common ? {}, input, steps}:
|
||||
|
||||
pkgs.lib.foldl (result: moduleFile:
|
||||
import moduleFile {
|
||||
inherit pkgs common input result;
|
||||
}
|
||||
) {} steps
|
|
@ -0,0 +1,18 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
${pkgs.dockerTools.shadowSetup}
|
||||
|
||||
# Always create these global state directories, because they are needed quite often
|
||||
mkdir -p /run /tmp
|
||||
chmod 1777 /tmp
|
||||
|
||||
mkdir -p /var/empty
|
||||
ln -s ../run /var/run
|
||||
|
||||
# Always create nobody/nogroup
|
||||
groupadd -g 65534 -r nogroup
|
||||
useradd -u 65534 -r nobody -g nogroup -d /dev/null
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
cmd = pkgs.lib.escapeShellArgs result.config.Cmd;
|
||||
in
|
||||
result // pkgs.lib.optionalAttrs (!(input ? bootstrap) || input.bootstrap) {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
cat > /bin/bootstrap <<EOF
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
|
||||
# Add nix channel configuration
|
||||
nix-channel --add https://nixos.org/channels/nixpkgs-unstable
|
||||
nix-channel --update
|
||||
nixproc-${input.processManager}-switch &
|
||||
|
||||
# Overwrite the bootstrap script, so that it simply just starts the process manager
|
||||
cat > /bin/bootstrap <<EOR
|
||||
#! ${pkgs.stdenv.shell} -e
|
||||
exec ${cmd}
|
||||
EOR
|
||||
|
||||
# Chain load the actual process manager
|
||||
exec ${cmd}
|
||||
EOF
|
||||
chmod 755 /bin/bootstrap
|
||||
'';
|
||||
|
||||
config = result.config or {} // {
|
||||
Cmd = "/bin/bootstrap";
|
||||
};
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
buildImageFormalArgs = builtins.functionArgs pkgs.dockerTools.buildImage;
|
||||
buildImageArgs = builtins.intersectAttrs buildImageFormalArgs input;
|
||||
in
|
||||
buildImageArgs
|
|
@ -0,0 +1,37 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
result // pkgs.lib.optionalAttrs (!(input ? interactive) || input.interactive) {
|
||||
contents = result.contents or [] ++ (with pkgs; [
|
||||
# An interactive bash shell
|
||||
bashInteractive
|
||||
# Basic shell utilities for file management, text manipulation, user management, process management
|
||||
coreutils diffutils findutils gnugrep gnused glibc.bin less utillinux procps shadow
|
||||
]);
|
||||
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
mkdir -p /root
|
||||
cat > /root/.bashrc << "EOF"
|
||||
alias ls='ls --color=auto'
|
||||
|
||||
if [ -n "$PS1" ]
|
||||
then
|
||||
if [ "$TERM" != "dumb" -o -n "$INSIDE_EMACS" ]
|
||||
then
|
||||
PROMPT_COLOR="1;31m"
|
||||
let $UID && PROMPT_COLOR="1;32m"
|
||||
if [ -n "$INSIDE_EMACS" -o "$TERM" == "eterm" -o "$TERM" == "eterm-color" ]
|
||||
then
|
||||
# Emacs term mode doesn't support xterm title escape sequence (\e]0;)
|
||||
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
|
||||
else
|
||||
PS1="\n\[\033[$PROMPT_COLOR\][\[\e]0;\u@\h: \w\a\]\u@\h:\w]\\$\[\033[0m\] "
|
||||
fi
|
||||
if test "$TERM" = "xterm"
|
||||
then
|
||||
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
EOF
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
result // pkgs.lib.optionalAttrs (input ? manpages && input.manpages) {
|
||||
contents = result.contents ++ (with pkgs; [
|
||||
man groff gzip
|
||||
]);
|
||||
|
||||
config = result.config or {} // {
|
||||
Env = result.config.Env or [] ++ [ "MANPATH=/share/man:/nix/var/nix/profiles/default/share/man" ];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
commonTools = (import ../../../tools {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
}).common;
|
||||
|
||||
# If no processes.nix parameter was provided, generate a template
|
||||
templateFile = pkgs.writeTextFile {
|
||||
name = "processes.nix";
|
||||
text = ''
|
||||
{ pkgs ? import <nixpkgs> { inherit system; }
|
||||
, system ? builtins.currentSystem
|
||||
, stateDir ? "/var"
|
||||
, runtimeDir ? "''${stateDir}/run"
|
||||
, logDir ? "''${stateDir}/log"
|
||||
, cacheDir ? "''${stateDir}/cache"
|
||||
, tmpDir ? (if stateDir == "/var" then "/tmp" else "''${stateDir}/tmp")
|
||||
, forceDisableUserChange ? false
|
||||
, processManager
|
||||
}:
|
||||
|
||||
let
|
||||
nix-processmgmt-services = builtins.fetchGit {
|
||||
url = https://github.com/svanderburg/nix-processmgmt-services.git;
|
||||
ref = "master";
|
||||
};
|
||||
|
||||
sharedConstructors = import "''${nix-processmgmt-services}/examples/services-agnostic/constructors.nix" {
|
||||
inherit pkgs stateDir runtimeDir logDir cacheDir tmpDir forceDisableUserChange processManager;
|
||||
};
|
||||
in
|
||||
rec {
|
||||
/*nginx = rec {
|
||||
port = 8080;
|
||||
|
||||
pkg = sharedConstructors.nginxReverseProxyHostBased {
|
||||
webapps = [];
|
||||
inherit port;
|
||||
} {};
|
||||
};*/
|
||||
}
|
||||
'';
|
||||
};
|
||||
in
|
||||
result // {
|
||||
contents = result.contents or []
|
||||
++ [ pkgs.dysnomia commonTools ];
|
||||
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
nixproc-init-state --state-dir ${input.stateDir} --runtime-dir ${input.runtimeDir}
|
||||
|
||||
# Provide a processes.nix expression
|
||||
mkdir -p /etc/nixproc
|
||||
'' + (if input ? exprFile then ''
|
||||
cp ${input.exprFile} /etc/nixproc/processes.nix
|
||||
'' else ''
|
||||
cp ${templateFile} /etc/nixproc/processes.nix
|
||||
'')
|
||||
+ ''
|
||||
chmod 644 /etc/nixproc/processes.nix
|
||||
'';
|
||||
|
||||
config = result.config or {} // {
|
||||
Env = result.config.Env or [] ++ [
|
||||
"NIXPROC_PROCESSES=/etc/nixproc/processes.nix"
|
||||
];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
commonTools = (import ../../../tools {
|
||||
inherit pkgs;
|
||||
inherit (common) system;
|
||||
}).common;
|
||||
in
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
# Initialize common state directories
|
||||
${commonTools}/bin/nixproc-init-state --state-dir ${input.stateDir} --runtime-dir ${input.runtimeDir}
|
||||
'';
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
let
|
||||
mkDbExtraCommand = contents: let
|
||||
contentsList = if builtins.isList contents then pkgs.lib.unique contents else [ contents ]; in
|
||||
''
|
||||
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."
|
||||
|
||||
export NIX_REMOTE=local?root=$PWD
|
||||
# A user is required by nix
|
||||
# https://github.com/NixOS/nix/blob/9348f9291e5d9e4ba3c4347ea1b235640f54fd79/src/libutil/util.cc#L478
|
||||
export USER=nobody
|
||||
${pkgs.nix}/bin/nix-store --load-db < ${pkgs.closureInfo {rootPaths = contentsList;}}/registration
|
||||
|
||||
mkdir -p nix/var/nix/gcroots/docker/
|
||||
for i in ${pkgs.lib.concatStringsSep " " contentsList}
|
||||
do
|
||||
ln -s $i nix/var/nix/gcroots/docker/$(basename $i)
|
||||
done;
|
||||
'';
|
||||
in
|
||||
result // rec {
|
||||
contents = result.contents or [] ++ (with pkgs; [
|
||||
# Nix
|
||||
nix.out
|
||||
# Needed for SSL authentication
|
||||
cacert
|
||||
# Needed for fetchgit
|
||||
git
|
||||
# Needed for downloading compressed tarballs
|
||||
gnutar gzip bzip2 xz
|
||||
]);
|
||||
|
||||
extraCommands = result.extraCommands or ""
|
||||
+ mkDbExtraCommand contents;
|
||||
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
# Initialize groups for Nix
|
||||
groupadd -g 30000 nixbld
|
||||
for i in $(seq 1 30)
|
||||
do
|
||||
groupadd -g $((30000 + i)) nixbld$i
|
||||
useradd -d /var/empty -c "Nix build user $i" -u $((30000 + i)) -g nixbld$i -G nixbld nixbld$i
|
||||
done
|
||||
'';
|
||||
|
||||
config = result.config or {} // {
|
||||
Env = result.config.Env or [] ++ [
|
||||
"NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt"
|
||||
"GIT_SSL_CAINFO=/etc/ssl/certs/ca-bundle.crt"
|
||||
"NIX_PATH=/nix/var/nix/profiles/per-user/root/channels"
|
||||
"USER=root"
|
||||
"PATH=/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin"
|
||||
];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{pkgs, common, input, result}:
|
||||
|
||||
result // {
|
||||
runAsRoot = result.runAsRoot or "" + ''
|
||||
${pkgs.gnused}/bin/sed -i -e "s/CREATE_MAIL_SPOOL=yes/CREATE_MAIL_SPOOL=no/" /etc/default/useradd
|
||||
|
||||
mkdir -p /etc/pam.d
|
||||
cat > /etc/pam.d/su <<EOF
|
||||
account required pam_unix.so
|
||||
auth sufficient pam_rootok.so
|
||||
auth required pam_tally.so
|
||||
auth sufficient pam_unix.so likeauth try_first_pass
|
||||
auth required pam_deny.so
|
||||
password sufficient pam_unix.so nullok sha512
|
||||
EOF
|
||||
'';
|
||||
|
||||
contents = result.contents or [] ++ [ pkgs.su pkgs.shadow ];
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
''
|
||||
mkdir -p /root
|
||||
cat > /root/.bashrc << "EOF"
|
||||
alias ls='ls --color=auto'
|
||||
|
||||
if [ -n "$PS1" ]
|
||||
then
|
||||
if [ "$TERM" != "dumb" -o -n "$INSIDE_EMACS" ]
|
||||
then
|
||||
PROMPT_COLOR="1;31m"
|
||||
let $UID && PROMPT_COLOR="1;32m"
|
||||
if [ -n "$INSIDE_EMACS" -o "$TERM" == "eterm" -o "$TERM" == "eterm-color" ]
|
||||
then
|
||||
# Emacs term mode doesn't support xterm title escape sequence (\e]0;)
|
||||
PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] "
|
||||
else
|
||||
PS1="\n\[\033[$PROMPT_COLOR\][\[\e]0;\u@\h: \w\a\]\u@\h:\w]\\$\[\033[0m\] "
|
||||
fi
|
||||
if test "$TERM" = "xterm"
|
||||
then
|
||||
PS1="\[\033]2;\h:\u:\w\007\]$PS1"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
EOF
|
||||
''
|
|
@ -1,11 +0,0 @@
|
|||
{dockerTools, stdenv, pkgs, system}:
|
||||
|
||||
import ./create-multi-process-image.nix {
|
||||
inherit dockerTools stdenv pkgs system;
|
||||
generators = {
|
||||
disnix = ../backends/disnix/generate-disnix-image-args.nix;
|
||||
s6-rc = ../backends/s6-rc/generate-s6-rc-image-args.nix;
|
||||
supervisord = ../backends/supervisord/generate-supervisord-image-args.nix;
|
||||
sysvinit = ../backends/sysvinit/generate-sysvinit-image-args.nix;
|
||||
};
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
{dockerTools, stdenv, pkgs, system, generators}:
|
||||
|
||||
{ interactive ? true
|
||||
, exprFile
|
||||
, extraParams ? {}
|
||||
, contents ? []
|
||||
, runAsRoot ? ""
|
||||
, config ? {}
|
||||
, processManager
|
||||
, stateDir ? "/var"
|
||||
, runtimeDir ? "${stateDir}/run"
|
||||
, forceDisableUserChange ? false
|
||||
, ...
|
||||
}@args:
|
||||
|
||||
let
|
||||
# Determine which parameters can be propagated to buildImage and which are customizations
|
||||
buildImageFormalArgs = builtins.functionArgs dockerTools.buildImage;
|
||||
buildImageArgs = removeAttrs (builtins.intersectAttrs buildImageFormalArgs args) [ "contents" "runAsRoot" "config" ];
|
||||
|
||||
commonTools = (import ../../tools { inherit pkgs; }).common;
|
||||
|
||||
generateImageArgsModule = if builtins.hasAttr processManager generators
|
||||
then builtins.getAttr processManager generators
|
||||
else throw "Cannot use process manager: ${processManager} in a multi-process container!";
|
||||
|
||||
processManagerArgs = import generateImageArgsModule {
|
||||
inherit exprFile stateDir runtimeDir forceDisableUserChange extraParams pkgs system;
|
||||
};
|
||||
|
||||
setupProcessManagement = import ../backends/docker/setup.nix {
|
||||
inherit (pkgs) dockerTools stdenv dysnomia findutils glibc;
|
||||
inherit (processManagerArgs) credentialsSpec;
|
||||
inherit commonTools stateDir runtimeDir forceDisableUserChange;
|
||||
};
|
||||
in
|
||||
dockerTools.buildImage ({
|
||||
contents = stdenv.lib.optionals interactive [ pkgs.glibc.bin pkgs.bashInteractive pkgs.coreutils pkgs.gnugrep pkgs.findutils pkgs.procps pkgs.utillinux pkgs.less ]
|
||||
++ processManagerArgs.contents
|
||||
++ contents;
|
||||
|
||||
runAsRoot =
|
||||
setupProcessManagement
|
||||
+ processManagerArgs.runAsRoot
|
||||
+ stdenv.lib.optionalString interactive import ./configure-bashrc.nix
|
||||
+
|
||||
''
|
||||
|
||||
${runAsRoot}
|
||||
'';
|
||||
|
||||
config = stdenv.lib.recursiveUpdate {
|
||||
Cmd = processManagerArgs.cmd;
|
||||
} config;
|
||||
} // buildImageArgs)
|
Loading…
Reference in New Issue