Skip to content
This repository was archived by the owner on Dec 16, 2021. It is now read-only.
/ docker Public archive
Closed
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
18 changes: 18 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: CI

on:
pull_request:
push:
paths-ignore:
- '**.md'

jobs:
nix-build:
runs-on: ubuntu-latest
env:
NIX_PATH: "nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-20.09.tar.gz"
steps:
- uses: cachix/install-nix-action@v12
- uses: actions/checkout@v1
- name: Check format
run: nix-build --no-out-link ./.
15 changes: 0 additions & 15 deletions .travis.yml

This file was deleted.

264 changes: 264 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
{ pkgs ? import <nixpkgs> { }
, lib ? pkgs.lib
, name ? "nix"
, tag ? "latest"
, crossSystem ? null
, channelName ? "nixpkgs"
, channelURL ? "https://nixos.org/channels/nixpkgs-unstable"
}:
let
buildPkgs = pkgs;
targetPkgs =
if crossSystem != null && crossSystem != pkgs.system
then {
aarch64-linux = pkgs.pkgsCross.aarch64-multiplatform;
armv7l-linux = pkgs.pkgsCross.armv7l-hf-multiplatform.system;
x86_64-linux = pkgs.pkgsCross.gnu64;
powerpc64le-linux = pkgs.pkgsCross.musl-power;
i686-linux = pkgs.pkgsCross.gnu32;
}.${crossSystem}
else pkgs;

defaultPkgs = [
targetPkgs.nix
targetPkgs.bashInteractive
targetPkgs.coreutils-full
targetPkgs.gnutar
targetPkgs.gzip
targetPkgs.gnugrep
targetPkgs.which
targetPkgs.curl
targetPkgs.less
targetPkgs.wget
targetPkgs.man
targetPkgs.cacert.out
targetPkgs.findutils
];

users = {

root = {
uid = 0;
shell = "/bin/bash";
home = "/root";
gid = 0;
};

} // lib.listToAttrs (
map
(
n: {
name = "nixbld${toString n}";
value = {
uid = 30000 + n;
gid = 30000;
groups = [ "nixbld" ];
description = "Nix build user ${toString n}";
};
}
)
(lib.lists.range 1 32)
);

groups = {
root.gid = 0;
nixbld.gid = 30000;
};

userToPasswd = (
k:
{ uid
, gid ? 65534
, home ? "/var/empty"
, description ? ""
, shell ? "/bin/false"
, groups ? [ ]
}: "${k}:x:${toString uid}:${toString gid}:${description}:${home}:${shell}"
);
passwdContents = (
lib.concatStringsSep "\n"
(lib.attrValues (lib.mapAttrs userToPasswd users))
);

userToShadow = k: { ... }: "${k}:!:1::::::";
shadowContents = (
lib.concatStringsSep "\n"
(lib.attrValues (lib.mapAttrs userToShadow users))
);

# Map groups to members
# {
# group = [ "user1" "user2" ];
# }
groupMemberMap = (
let
# Create a flat list of user/group mappings
mappings = (
builtins.foldl'
(
acc: user:
let
groups = users.${user}.groups or [ ];
in
acc ++ map
(group: {
inherit user group;
})
groups
)
[ ]
(lib.attrNames users)
);
in
(
builtins.foldl'
(
acc: v: acc // {
${v.group} = acc.${v.group} or [ ] ++ [ v.user ];
}
)
{ }
mappings)
);

groupToGroup = k: { gid }:
let
members = groupMemberMap.${k} or [ ];
in
"${k}:x:${toString gid}:${lib.concatStringsSep "," members}";
groupContents = (
lib.concatStringsSep "\n"
(lib.attrValues (lib.mapAttrs groupToGroup groups))
);

nixConf = {
sandbox = "false";
build-users-group = "nixbld";
trusted-public-keys = "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=";
};
nixConfContents = (lib.concatStringsSep "\n" (lib.mapAttrsFlatten (n: v: "${n} = ${v}") nixConf)) + "\n";

baseSystem =
let
nixpkgs = targetPkgs.path;
channel = targetPkgs.runCommand "channel-nixos" { } ''
mkdir $out
ln -s ${nixpkgs} $out/nixpkgs
echo "[]" > $out/manifest.nix
'';
rootEnv = pkgs.buildEnv {
name = "root-profile-env";
paths = defaultPkgs;
};
profile = targetPkgs.runCommand "user-environment" { } ''
mkdir $out
cp -a ${rootEnv}/* $out/

cat > $out/manifest.nix <<EOF
[
${lib.concatStringsSep "\n" (builtins.map (drv: let
outputs = drv.outputsToInstall or [ "out" ];
in ''
{
${lib.concatStringsSep "\n" (builtins.map (output: ''
${output} = { outPath = "${lib.getOutput output drv}"; };
'') outputs)}
outputs = [ ${lib.concatStringsSep " " (builtins.map (x: "\"${x}\"") outputs)} ];
name = "${drv.name}";
outPath = "${drv}";
system = "${drv.system}";
type = "derivation";
meta = { };
}
'') defaultPkgs)}
]
EOF
'';
in
targetPkgs.runCommand "base-system"
{
inherit passwdContents groupContents shadowContents nixConfContents;
passAsFile = [
"passwdContents"
"groupContents"
"shadowContents"
"nixConfContents"
];
allowSubstitutes = false;
preferLocalBuild = true;
} ''
env
set -x
mkdir -p $out/etc

cat $passwdContentsPath > $out/etc/passwd
echo "" >> $out/etc/passwd

cat $groupContentsPath > $out/etc/group
echo "" >> $out/etc/group

cat $shadowContentsPath > $out/etc/shadow
echo "" >> $out/etc/shadow

mkdir -p $out/usr
ln -s /nix/var/nix/profiles/share $out/usr/

mkdir -p $out/nix/var/nix/gcroots

mkdir $out/tmp

mkdir -p $out/etc/nix
cat $nixConfContentsPath > $out/etc/nix/nix.conf

mkdir -p $out/root
mkdir -p $out/nix/var/nix/profiles/per-user/root

ln -s ${profile} $out/nix/var/nix/profiles/default-1-link
ln -s $out/nix/var/nix/profiles/default-1-link $out/nix/var/nix/profiles/default
ln -s /nix/var/nix/profiles/default $out/root/.nix-profile

ln -s ${channel} $out/nix/var/nix/profiles/per-user/root/channels-1-link
ln -s $out/nix/var/nix/profiles/per-user/root/channels-1-link $out/nix/var/nix/profiles/per-user/root/channels

mkdir -p $out/root/.nix-defexpr
ln -s $out/nix/var/nix/profiles/per-user/root/channels $out/root/.nix-defexpr/channels
echo "${channelURL} ${channelName}" > $out/root/.nix-channels

mkdir -p $out/bin $out/usr/bin
ln -s ${targetPkgs.coreutils}/bin/env $out/usr/bin/env
ln -s ${targetPkgs.bashInteractive}/bin/bash $out/bin/sh
'';

in
targetPkgs.dockerTools.buildLayeredImageWithNixDb {

inherit name tag;

contents = [ baseSystem ];

extraCommands = ''
rm -rf nix-support
ln -s /nix/var/nix/profiles nix/var/nix/gcroots/profiles
'';

config = {
Cmd = [ "/root/.nix-profile/bin/bash" ];
Env = [
"USER=root"
"PATH=${lib.concatStringsSep ":" [
"/root/.nix-profile/bin"
"/nix/var/nix/profiles/default/bin"
"/nix/var/nix/profiles/default/sbin"
]}"
"MANPATH=${lib.concatStringsSep ":" [
"/root/.nix-profile/share/man"
"/nix/var/nix/profiles/default/share/man"
]}"
"SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"GIT_SSL_CAINFO=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_SSL_CERT_FILE=/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"
"NIX_PATH=/nix/var/nix/profiles/per-user/root/channels:/root/.nix-defexpr/channels"
];
};

}
3 changes: 3 additions & 0 deletions dockerhub/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Dummy Dockerfile to make Docker Hub automated builds happy
# The actual build steps are overriden in hooks/
FROM localhost/nix:latest
14 changes: 8 additions & 6 deletions Dockerfile → dockerhub/bootstrap/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Dockerfile to create an environment that contains the Nix package manager.
# This is based on the old Alpine based Docker image and is used for bootstraping the Docker hub build

FROM alpine

Expand All @@ -7,16 +8,16 @@ RUN apk add --no-cache --update openssl \
&& echo hosts: dns files > /etc/nsswitch.conf

# Download Nix and install it into the system.
ARG NIX_VERSION=2.3.10
RUN wget https://nixos.org/releases/nix/nix-${NIX_VERSION}/nix-${NIX_VERSION}-$(uname -m)-linux.tar.xz \
&& tar xf nix-${NIX_VERSION}-$(uname -m)-linux.tar.xz \
ARG NIX_VERSION=2.3.6
RUN wget https://nixos.org/releases/nix/nix-${NIX_VERSION}/nix-${NIX_VERSION}-x86_64-linux.tar.xz \
&& tar xf nix-${NIX_VERSION}-x86_64-linux.tar.xz \
&& addgroup -g 30000 -S nixbld \
&& for i in $(seq 1 30); do adduser -S -D -h /var/empty -g "Nix build user $i" -u $((30000 + i)) -G nixbld nixbld$i ; done \
&& mkdir -m 0755 /etc/nix \
&& echo 'sandbox = false' > /etc/nix/nix.conf \
&& mkdir -m 0755 /nix && USER=root sh nix-${NIX_VERSION}-$(uname -m)-linux/install \
&& mkdir -m 0755 /nix && USER=root sh nix-${NIX_VERSION}-x86_64-linux/install \
&& ln -s /nix/var/nix/profiles/default/etc/profile.d/nix.sh /etc/profile.d/ \
&& rm -r /nix-${NIX_VERSION}-$(uname -m)-linux* \
&& rm -r /nix-${NIX_VERSION}-x86_64-linux* \
&& rm -rf /var/cache/apk/* \
&& /nix/var/nix/profiles/default/bin/nix-collect-garbage --delete-old \
&& /nix/var/nix/profiles/default/bin/nix-store --optimise \
Expand All @@ -27,7 +28,8 @@ ONBUILD ENV \
USER=root \
PATH=/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/bin:/sbin:/usr/bin:/usr/sbin \
GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt \
NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
NIX_SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz

ENV \
ENV=/etc/profile \
Expand Down
49 changes: 49 additions & 0 deletions dockerhub/hooks/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python3
from concurrent import futures
import subprocess
import os.path
import json
import os


def gen_cmds(systems, channels):
for system in systems:
for name, channel in channels.items():
yield "env NIX_PATH=nixpkgs={url} nix-build --no-out-link --argstr name {docker_repo} --argstr tag {tag} --argstr channelName {channel_name} --argstr channelURL {channel_url} --argstr crossSystem {system} /build/default.nix".format(
channel_name=channel["name"],
channel_url=channel["url"],
docker_repo=docker_repo,
tag=name + "-" + system,
system=system,
url=channel["url"]+"/nixexprs.tar.xz",
)


def run(buildcmd: str):
cmd = [
"docker",
"run",
"-i",
"--privileged",
"-v", "{}:/build".format(os.path.abspath("..")),
"-v", "/var/run/docker.sock:/var/run/docker.sock",
"nix-bootstrap",
] + [
"nix-shell", "-p", "docker", "--run", "docker load < `{}`".format(buildcmd)
]

subprocess.run(cmd, check=True)


if __name__ == "__main__":
docker_repo = os.environ["DOCKER_REPO"]

matrix_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "matrix.json")
with open(matrix_path) as f:
data = json.load(f)

subprocess.run("docker build -f bootstrap/Dockerfile -t nix-bootstrap:latest bootstrap", check=True, shell=True)

with futures.ThreadPoolExecutor() as e:
for future in futures.as_completed(e.submit(run, cmd) for cmd in gen_cmds(data["systems"], data["channels"])):
future.result()
Loading