-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcontainer.nix
More file actions
135 lines (120 loc) · 4.06 KB
/
container.nix
File metadata and controls
135 lines (120 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
{ system ? builtins.currentSystem
, pkgs ? import <nixpkgs> { inherit system; }
, lxcExtraConfig ? ""
, name
, configuration
}:
with pkgs;
with pkgs.lib;
let
container_root = "/var/lib/containers/${name}";
switchScript = writeScript "${name}-switch" ''
#!${pkgs.bash}/bin/bash
old_gen="$(readlink -f /old_config)"
new_gen="$(readlink -f /new_config)"
[ "x$old_gen" != "x$new_gen" ] || exit 0
$new_gen/bin/switch-to-configuration switch
rm /old_config && ln -fs $new_gen /old_config
'';
container = (import <nixpkgs/nixos/lib/eval-config.nix> {
modules =
let extraConfig = {
nixpkgs.system = system;
boot.isContainer = true;
networking.hostName = mkDefault name;
security.pam.services.sshd.startSession = mkOverride 50 false;
services.cron.systemCronJobs = [
"* * * * * root ${switchScript} > /var/log/switch-config.log 2>&1"
];
};
in [ extraConfig ] ++ configuration;
prefix = [ "systemd" "containers" name ];
}).config.system.build.toplevel;
containerConfig = ''
lxc.utsname = ${name}
lxc.arch = ${if system == "x86_64-linux" then "x86_64" else "i686"}
lxc.tty = 6
lxc.pts = 1024
## Capabilities
lxc.cap.drop = audit_control audit_write mac_admin mac_override mknod setfcap
lxc.cap.drop = sys_boot sys_module sys_pacct sys_rawio sys_time
## Devices
lxc.cgroup.devices.deny = a # Deny access to all devices
# Allow to mknod all devices (but not using them)
lxc.cgroup.devices.allow = c *:* m
lxc.cgroup.devices.allow = b *:* m
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
lxc.cgroup.devices.allow = c 4:2 rwm
lxc.cgroup.devices.allow = c 4:3 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:2 rwm
lxc.cgroup.devices.allow = c 10:229 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 254:0 rwm
## Mounts
lxc.mount.entry = /nix/store nix/store none defaults,bind.ro 0.0
lxc.autodev = 1
${lxcExtraConfig}
## Network
lxc.network.type = veth
lxc.network.name = eth0
lxc.network.flags = up
'';
startContainer = writeTextFile {
name = "${name}-container-start";
text = ''
#!${pkgs.bash}/bin/bash
if [ -z "$CONTAINER_ROOT" ]; then
export CONTAINER_ROOT="/var/lib/containers/${name}"
fi
echo "Using $CONTAINER_ROOT as rootfs"
mkdir -p $CONTAINER_ROOT/{proc,sys,dev,nix/store,etc}
mkdir -p /var/lib/lxc/rootfs
chmod 0755 $CONTAINER_ROOT/etc
if ! [ -e $CONTAINER_ROOT/etc/os-release ]; then
touch $CONTAINER_ROOT/etc/os-release
fi
rm $CONTAINER_ROOT/old_config
ln -fs "${container}" $CONTAINER_ROOT/old_config
rm $CONTAINER_ROOT/new_config
ln -fs "${container}" $CONTAINER_ROOT/new_config
${pkgs.lxc}/bin/lxc-start -n "${name}" \
-f "${pkgs.writeText "container.conf" containerConfig}" \
-s lxc.rootfs=$CONTAINER_ROOT \
"$@" "${container}/init"
'';
executable = true;
destination = "/bin/${name}-container-start";
};
stopContainer = writeTextFile {
name = "${name}-container-stop";
text = ''
#!${pkgs.bash}/bin/bash
${pkgs.lxc}/bin/lxc-stop -n "${name}" "$@"
'';
executable = true;
destination = "/bin/${name}-container-stop";
};
updateContainer = writeTextFile {
name = "${name}-container-update";
text = ''
#!${pkgs.bash}/bin/bash
if [ -z "$CONTAINER_ROOT" ]; then
export CONTAINER_ROOT="/var/lib/containers/${name}"
fi
rm $CONTAINER_ROOT/new_config
ln -fs ${container} $CONTAINER_ROOT/new_config
'';
executable = true;
destination = "/bin/${name}-container-update";
};
in buildEnv {
name = "${name}-container";
paths = [ startContainer stopContainer updateContainer ];
}