mirror of
https://github.com/systemd/systemd.git
synced 2025-01-09 01:18:19 +03:00
Merge pull request #27651 from mrc0mmand/more-nspawn-tests
nspawn: OCI related fixes & tests
This commit is contained in:
commit
a5a4d5a18e
@ -605,7 +605,7 @@ static int oci_namespace_type(const char *name, JsonVariant *v, JsonDispatchFlag
|
||||
*nsflags = CLONE_NEWCGROUP;
|
||||
else
|
||||
return json_log(v, flags, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Unknown cgroup type, refusing: %s", n);
|
||||
"Unknown namespace type, refusing: %s", n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -663,7 +663,7 @@ static int oci_namespaces(const char *name, JsonVariant *v, JsonDispatchFlags fl
|
||||
|
||||
if (!FLAGS_SET(n, CLONE_NEWNS))
|
||||
return json_log(v, flags, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Containers without file system namespace aren't supported.");
|
||||
"Containers without a mount namespace aren't supported.");
|
||||
|
||||
s->private_network = FLAGS_SET(n, CLONE_NEWNET);
|
||||
s->userns_mode = FLAGS_SET(n, CLONE_NEWUSER) ? USER_NAMESPACE_FIXED : USER_NAMESPACE_NO;
|
||||
@ -819,7 +819,7 @@ static int oci_device_file_mode(const char *name, JsonVariant *v, JsonDispatchFl
|
||||
return json_log(v, flags, SYNTHETIC_ERRNO(ERANGE),
|
||||
"fileMode out of range, refusing.");
|
||||
|
||||
*mode = m;
|
||||
*mode = (*mode & ~07777) | m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -874,7 +874,7 @@ static int oci_devices(const char *name, JsonVariant *v, JsonDispatchFlags flags
|
||||
/* Suppress a couple of implicit device nodes */
|
||||
r = devname_from_devnum(node->mode, makedev(node->major, node->minor), &path);
|
||||
if (r < 0)
|
||||
json_log(e, flags|JSON_DEBUG, 0, "Failed to resolve device node %u:%u, ignoring: %m", node->major, node->minor);
|
||||
json_log(e, flags|JSON_DEBUG, r, "Failed to resolve device node %u:%u, ignoring: %m", node->major, node->minor);
|
||||
else {
|
||||
if (PATH_IN_SET(path,
|
||||
"/dev/null",
|
||||
@ -1177,13 +1177,13 @@ static int oci_cgroup_memory(const char *name, JsonVariant *v, JsonDispatchFlags
|
||||
};
|
||||
|
||||
static const JsonDispatch table[] = {
|
||||
{ "limit", JSON_VARIANT_NUMBER, oci_cgroup_memory_limit, offsetof(struct memory_data, limit), 0 },
|
||||
{ "reservation", JSON_VARIANT_NUMBER, oci_cgroup_memory_limit, offsetof(struct memory_data, reservation), 0 },
|
||||
{ "swap", JSON_VARIANT_NUMBER, oci_cgroup_memory_limit, offsetof(struct memory_data, swap), 0 },
|
||||
{ "kernel", JSON_VARIANT_NUMBER, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{ "kernelTCP", JSON_VARIANT_NUMBER, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{ "swapiness", JSON_VARIANT_NUMBER, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{ "disableOOMKiller", JSON_VARIANT_NUMBER, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{ "limit", JSON_VARIANT_NUMBER, oci_cgroup_memory_limit, offsetof(struct memory_data, limit), 0 },
|
||||
{ "reservation", JSON_VARIANT_NUMBER, oci_cgroup_memory_limit, offsetof(struct memory_data, reservation), 0 },
|
||||
{ "swap", JSON_VARIANT_NUMBER, oci_cgroup_memory_limit, offsetof(struct memory_data, swap), 0 },
|
||||
{ "kernel", JSON_VARIANT_NUMBER, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{ "kernelTCP", JSON_VARIANT_NUMBER, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{ "swapiness", JSON_VARIANT_NUMBER, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{ "disableOOMKiller", JSON_VARIANT_BOOLEAN, oci_unsupported, 0, JSON_PERMISSIVE },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -1589,7 +1589,7 @@ static int oci_sysctl(const char *name, JsonVariant *v, JsonDispatchFlags flags,
|
||||
|
||||
assert_se(m = json_variant_string(w));
|
||||
|
||||
if (sysctl_key_valid(k))
|
||||
if (!sysctl_key_valid(k))
|
||||
return json_log(v, flags, SYNTHETIC_ERRNO(EINVAL),
|
||||
"sysctl key invalid, refusing: %s", k);
|
||||
|
||||
@ -1829,6 +1829,7 @@ static int oci_seccomp_syscalls(const char *name, JsonVariant *v, JsonDispatchFl
|
||||
{ "names", JSON_VARIANT_ARRAY, json_dispatch_strv, offsetof(struct syscall_rule, names), JSON_MANDATORY },
|
||||
{ "action", JSON_VARIANT_STRING, oci_seccomp_action, offsetof(struct syscall_rule, action), JSON_MANDATORY },
|
||||
{ "args", JSON_VARIANT_ARRAY, oci_seccomp_args, 0, 0 },
|
||||
{}
|
||||
};
|
||||
struct syscall_rule rule = {
|
||||
.action = UINT32_MAX,
|
||||
@ -2083,7 +2084,7 @@ static int oci_hooks_array(const char *name, JsonVariant *v, JsonDispatchFlags f
|
||||
.timeout = USEC_INFINITY,
|
||||
};
|
||||
|
||||
r = json_dispatch(e, table, oci_unexpected, flags, userdata);
|
||||
r = json_dispatch(e, table, oci_unexpected, flags, new_item);
|
||||
if (r < 0) {
|
||||
free(new_item->path);
|
||||
strv_free(new_item->args);
|
||||
@ -2100,9 +2101,9 @@ static int oci_hooks_array(const char *name, JsonVariant *v, JsonDispatchFlags f
|
||||
static int oci_hooks(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
|
||||
|
||||
static const JsonDispatch table[] = {
|
||||
{ "prestart", JSON_VARIANT_OBJECT, oci_hooks_array, 0, 0 },
|
||||
{ "poststart", JSON_VARIANT_OBJECT, oci_hooks_array, 0, 0 },
|
||||
{ "poststop", JSON_VARIANT_OBJECT, oci_hooks_array, 0, 0 },
|
||||
{ "prestart", JSON_VARIANT_ARRAY, oci_hooks_array, 0, 0 },
|
||||
{ "poststart", JSON_VARIANT_ARRAY, oci_hooks_array, 0, 0 },
|
||||
{ "poststop", JSON_VARIANT_ARRAY, oci_hooks_array, 0, 0 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -97,27 +97,25 @@ int settings_load(FILE *f, const char *path, Settings **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_oci_hooks(OciHook *h, size_t n) {
|
||||
size_t i;
|
||||
static void free_oci_hooks(OciHook *hooks, size_t n) {
|
||||
assert(hooks || n == 0);
|
||||
|
||||
assert(h || n == 0);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
free(h[i].path);
|
||||
strv_free(h[i].args);
|
||||
strv_free(h[i].env);
|
||||
FOREACH_ARRAY(hook, hooks, n) {
|
||||
free(hook->path);
|
||||
strv_free(hook->args);
|
||||
strv_free(hook->env);
|
||||
}
|
||||
|
||||
free(h);
|
||||
free(hooks);
|
||||
}
|
||||
|
||||
void device_node_array_free(DeviceNode *node, size_t n) {
|
||||
size_t i;
|
||||
void device_node_array_free(DeviceNode *nodes, size_t n) {
|
||||
assert(nodes || n == 0);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
free(node[i].path);
|
||||
FOREACH_ARRAY(node, nodes, n)
|
||||
free(node->path);
|
||||
|
||||
free(node);
|
||||
free(nodes);
|
||||
}
|
||||
|
||||
Settings* settings_free(Settings *s) {
|
||||
|
@ -4651,6 +4651,7 @@ static int merge_settings(Settings *settings, const char *path) {
|
||||
device_node_array_free(arg_extra_nodes, arg_n_extra_nodes);
|
||||
arg_extra_nodes = TAKE_PTR(settings->extra_nodes);
|
||||
arg_n_extra_nodes = settings->n_extra_nodes;
|
||||
settings->n_extra_nodes = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
{
|
||||
"ociVersion": "1.0.0",
|
||||
|
||||
"hostname" : "foo",
|
||||
|
||||
"root": {
|
||||
"path": "rootfs",
|
||||
"readonly": true
|
||||
@ -33,11 +35,42 @@
|
||||
|
||||
"cwd": "/tmp/src",
|
||||
|
||||
"rlimits": [
|
||||
"noNewPrivileges" : true,
|
||||
"oomScoreAdj" : 20,
|
||||
"capabilities" : {
|
||||
"bounding" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"permitted" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"inheritable" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"effective" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL"
|
||||
],
|
||||
"ambient" : [
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
]
|
||||
},
|
||||
"rlimits" : [
|
||||
{
|
||||
"type": "RLIMIT_NOFILE",
|
||||
"hard": 1020,
|
||||
"soft": 1020
|
||||
"type" : "RLIMIT_NOFILE",
|
||||
"soft" : 1024,
|
||||
"hard" : 1024
|
||||
},
|
||||
{
|
||||
"type" : "RLIMIT_RTPRIO",
|
||||
"soft" : 5,
|
||||
"hard" : 10
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -110,32 +143,206 @@
|
||||
}
|
||||
],
|
||||
|
||||
"hooks": {},
|
||||
|
||||
"linux": {
|
||||
"resources": {
|
||||
"devices": [
|
||||
"linux" : {
|
||||
"namespaces" : [
|
||||
{
|
||||
"type" : "mount"
|
||||
},
|
||||
{
|
||||
"type" : "network",
|
||||
"path" : "$NETNS"
|
||||
},
|
||||
{
|
||||
"type" : "pid"
|
||||
},
|
||||
{
|
||||
"type" : "uts"
|
||||
}
|
||||
],
|
||||
"uidMappings" : [
|
||||
{
|
||||
"containerID" : 0,
|
||||
"hostID" : 1000,
|
||||
"size" : 100
|
||||
}
|
||||
],
|
||||
"gidMappings" : [
|
||||
{
|
||||
"containerID" : 0,
|
||||
"hostID" : 1000,
|
||||
"size" : 100
|
||||
}
|
||||
],
|
||||
"devices" : [
|
||||
{
|
||||
"type" : "c",
|
||||
"path" : "/dev/zero",
|
||||
"major" : 1,
|
||||
"minor" : 5,
|
||||
"fileMode" : 444
|
||||
},
|
||||
{
|
||||
"type" : "b",
|
||||
"path" : "$DEV",
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"fileMode" : 666,
|
||||
"uid" : 0,
|
||||
"gid" : 0
|
||||
}
|
||||
],
|
||||
"resources" : {
|
||||
"devices" : [
|
||||
{
|
||||
"allow": false,
|
||||
"access": "rwm"
|
||||
"allow" : false,
|
||||
"access" : "m"
|
||||
},
|
||||
{
|
||||
"allow" : true,
|
||||
"type" : "b",
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"access" : "rwm"
|
||||
}
|
||||
],
|
||||
"memory" : {
|
||||
"limit" : 134217728,
|
||||
"reservation" : 33554432,
|
||||
"swap" : 268435456
|
||||
},
|
||||
"cpu" : {
|
||||
"shares" : 1024,
|
||||
"quota" : 1000000,
|
||||
"period" : 500000,
|
||||
"cpus" : "0-7"
|
||||
},
|
||||
"blockIO" : {
|
||||
"weight" : 10,
|
||||
"weightDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"weight" : 500
|
||||
}
|
||||
],
|
||||
"throttleReadBpsDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
],
|
||||
"throttleWriteBpsDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
],
|
||||
"throttleReadIOPSDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
],
|
||||
"throttleWriteIOPSDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
]
|
||||
},
|
||||
"pids" : {
|
||||
"limit" : 1024
|
||||
}
|
||||
},
|
||||
"sysctl" : {
|
||||
"kernel.domainname" : "foo.bar",
|
||||
"vm.swappiness" : "60"
|
||||
},
|
||||
"seccomp" : {
|
||||
"defaultAction" : "SCMP_ACT_ALLOW",
|
||||
"architectures" : [
|
||||
"SCMP_ARCH_ARM",
|
||||
"SCMP_ARCH_X86_64"
|
||||
],
|
||||
"syscalls" : [
|
||||
{
|
||||
"names" : [
|
||||
"lchown",
|
||||
"chmod"
|
||||
],
|
||||
"action" : "SCMP_ACT_ERRNO",
|
||||
"args" : [
|
||||
{
|
||||
"index" : 0,
|
||||
"value" : 1,
|
||||
"op" : "SCMP_CMP_NE"
|
||||
},
|
||||
{
|
||||
"index" : 1,
|
||||
"value" : 2,
|
||||
"valueTwo" : 3,
|
||||
"op" : "SCMP_CMP_MASKED_EQ"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"namespaces": [
|
||||
"rootfsPropagation" : "shared",
|
||||
"maskedPaths" : [
|
||||
"/proc/kcore",
|
||||
"/root/nonexistent"
|
||||
],
|
||||
"readonlyPaths" : [
|
||||
"/proc/sys",
|
||||
"/opt/readonly"
|
||||
]
|
||||
},
|
||||
"hooks" : {
|
||||
"prestart" : [
|
||||
{
|
||||
"type": "pid"
|
||||
"path" : "/bin/sh",
|
||||
"args" : [
|
||||
"-xec",
|
||||
"echo $PRESTART_FOO >/prestart"
|
||||
],
|
||||
"env" : [
|
||||
"PRESTART_FOO=prestart_bar",
|
||||
"ALSO_FOO=also_bar"
|
||||
],
|
||||
"timeout" : 666
|
||||
},
|
||||
{
|
||||
"type": "ipc"
|
||||
},
|
||||
"path" : "/bin/touch",
|
||||
"args" : [
|
||||
"/tmp/also-prestart"
|
||||
]
|
||||
}
|
||||
],
|
||||
"poststart" : [
|
||||
{
|
||||
"type": "mount"
|
||||
"path" : "/bin/sh",
|
||||
"args" : [
|
||||
"touch",
|
||||
"/poststart"
|
||||
]
|
||||
}
|
||||
],
|
||||
"poststop" : [
|
||||
{
|
||||
"path" : "/bin/sh",
|
||||
"args" : [
|
||||
"touch",
|
||||
"/poststop"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"annotations": {
|
||||
"com.example.key1": "value1",
|
||||
"com.example.key2": "value2"
|
||||
"annotations" : {
|
||||
"hello.world" : "1",
|
||||
"foo" : "bar"
|
||||
}
|
||||
}
|
||||
|
383
test/units/testsuite-13.nspawn-oci.sh
Executable file
383
test/units/testsuite-13.nspawn-oci.sh
Executable file
@ -0,0 +1,383 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
# shellcheck disable=SC2016
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
export SYSTEMD_LOG_LEVEL=debug
|
||||
export SYSTEMD_LOG_TARGET=journal
|
||||
CREATE_BB_CONTAINER="/usr/lib/systemd/tests/testdata/create-busybox-container"
|
||||
|
||||
# shellcheck disable=SC2317
|
||||
at_exit() {
|
||||
set +e
|
||||
|
||||
mountpoint -q /var/lib/machines && umount /var/lib/machines
|
||||
[[ -n "${DEV:-}" ]] && rm -f "$DEV"
|
||||
[[ -n "${NETNS:-}" ]] && umount "$NETNS" && rm -f "$NETNS"
|
||||
[[ -n "${TMPDIR:-}" ]] && rm -fr "$TMPDIR"
|
||||
}
|
||||
|
||||
trap at_exit EXIT
|
||||
|
||||
# Mount tmpfs over /var/lib/machines to not pollute the image
|
||||
mkdir -p /var/lib/machines
|
||||
mount -t tmpfs tmpfs /var/lib/machines
|
||||
|
||||
# Setup a couple of dirs/devices for the OCI containers
|
||||
DEV="$(mktemp -u /dev/oci-dev-XXX)"
|
||||
mknod -m 666 "$DEV" b 42 42
|
||||
NETNS="$(mktemp /var/tmp/netns.XXX)"
|
||||
mount --bind /proc/self/ns/net "$NETNS"
|
||||
TMPDIR="$(mktemp -d)"
|
||||
touch "$TMPDIR/hello"
|
||||
OCI="$(mktemp -d /var/lib/machines/testsuite-13.oci-bundle.XXX)"
|
||||
"$CREATE_BB_CONTAINER" "$OCI/rootfs"
|
||||
mkdir -p "$OCI/rootfs/opt/var"
|
||||
mkdir -p "$OCI/rootfs/opt/readonly"
|
||||
|
||||
# Let's start with a simple config
|
||||
cat >"$OCI/config.json" <<EOF
|
||||
{
|
||||
"ociVersion" : "1.0.0",
|
||||
"root" : {
|
||||
"path" : "rootfs"
|
||||
},
|
||||
"mounts" : [
|
||||
{
|
||||
"destination" : "/root",
|
||||
"type" : "tmpfs",
|
||||
"source" : "tmpfs"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
systemd-nspawn --oci-bundle="$OCI" sh -xec 'mountpoint /root'
|
||||
|
||||
# And now for something a bit more involved
|
||||
# Notes:
|
||||
# - the hooks are parsed & processed, but never executed
|
||||
# - set sysctl's are parsed but never used?
|
||||
# - same goes for arg_sysctl in nspawn.c
|
||||
cat >"$OCI/config.json" <<EOF
|
||||
{
|
||||
"ociVersion" : "1.0.0",
|
||||
"hostname" : "my-oci-container",
|
||||
"root" : {
|
||||
"path" : "rootfs",
|
||||
"readonly" : false
|
||||
},
|
||||
"mounts" : [
|
||||
{
|
||||
"destination" : "/root",
|
||||
"type" : "tmpfs",
|
||||
"source" : "tmpfs"
|
||||
},
|
||||
{
|
||||
"destination" : "/var",
|
||||
"type" : "none",
|
||||
"source" : "$TMPDIR",
|
||||
"options" : ["rbind", "rw"]
|
||||
}
|
||||
],
|
||||
"process" : {
|
||||
"terminal" : false,
|
||||
"consoleSize" : {
|
||||
"height" : 25,
|
||||
"width" : 80
|
||||
},
|
||||
"user" : {
|
||||
"uid" : 0,
|
||||
"gid" : 0,
|
||||
"additionalGids" : [5, 6]
|
||||
},
|
||||
"env" : [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"FOO=bar"
|
||||
],
|
||||
"cwd" : "/root",
|
||||
"args" : [
|
||||
"sh",
|
||||
"-xe",
|
||||
"/entrypoint.sh"
|
||||
],
|
||||
"noNewPrivileges" : true,
|
||||
"oomScoreAdj" : 20,
|
||||
"capabilities" : {
|
||||
"bounding" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"permitted" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"inheritable" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL",
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
],
|
||||
"effective" : [
|
||||
"CAP_AUDIT_WRITE",
|
||||
"CAP_KILL"
|
||||
],
|
||||
"ambient" : [
|
||||
"CAP_NET_BIND_SERVICE"
|
||||
]
|
||||
},
|
||||
"rlimits" : [
|
||||
{
|
||||
"type" : "RLIMIT_NOFILE",
|
||||
"soft" : 1024,
|
||||
"hard" : 1024
|
||||
},
|
||||
{
|
||||
"type" : "RLIMIT_RTPRIO",
|
||||
"soft" : 5,
|
||||
"hard" : 10
|
||||
}
|
||||
]
|
||||
},
|
||||
"linux" : {
|
||||
"namespaces" : [
|
||||
{
|
||||
"type" : "mount"
|
||||
},
|
||||
{
|
||||
"type" : "network",
|
||||
"path" : "$NETNS"
|
||||
},
|
||||
{
|
||||
"type" : "pid"
|
||||
},
|
||||
{
|
||||
"type" : "uts"
|
||||
}
|
||||
],
|
||||
"uidMappings" : [
|
||||
{
|
||||
"containerID" : 0,
|
||||
"hostID" : 1000,
|
||||
"size" : 100
|
||||
}
|
||||
],
|
||||
"gidMappings" : [
|
||||
{
|
||||
"containerID" : 0,
|
||||
"hostID" : 1000,
|
||||
"size" : 100
|
||||
}
|
||||
],
|
||||
"devices" : [
|
||||
{
|
||||
"type" : "c",
|
||||
"path" : "/dev/zero",
|
||||
"major" : 1,
|
||||
"minor" : 5,
|
||||
"fileMode" : 444
|
||||
},
|
||||
{
|
||||
"type" : "b",
|
||||
"path" : "$DEV",
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"fileMode" : 666,
|
||||
"uid" : 0,
|
||||
"gid" : 0
|
||||
}
|
||||
],
|
||||
"resources" : {
|
||||
"devices" : [
|
||||
{
|
||||
"allow" : false,
|
||||
"access" : "m"
|
||||
},
|
||||
{
|
||||
"allow" : true,
|
||||
"type" : "b",
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"access" : "rwm"
|
||||
}
|
||||
],
|
||||
"memory" : {
|
||||
"limit" : 134217728,
|
||||
"reservation" : 33554432,
|
||||
"swap" : 268435456
|
||||
},
|
||||
"cpu" : {
|
||||
"shares" : 1024,
|
||||
"quota" : 1000000,
|
||||
"period" : 500000,
|
||||
"cpus" : "0-7"
|
||||
},
|
||||
"blockIO" : {
|
||||
"weight" : 10,
|
||||
"weightDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"weight" : 500
|
||||
}
|
||||
],
|
||||
"throttleReadBpsDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
],
|
||||
"throttleWriteBpsDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
],
|
||||
"throttleReadIOPSDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
],
|
||||
"throttleWriteIOPSDevice" : [
|
||||
{
|
||||
"major" : 4,
|
||||
"minor" : 2,
|
||||
"rate" : 500
|
||||
}
|
||||
]
|
||||
},
|
||||
"pids" : {
|
||||
"limit" : 1024
|
||||
}
|
||||
},
|
||||
"sysctl" : {
|
||||
"kernel.domainname" : "foo.bar",
|
||||
"vm.swappiness" : "60"
|
||||
},
|
||||
"seccomp" : {
|
||||
"defaultAction" : "SCMP_ACT_ALLOW",
|
||||
"architectures" : [
|
||||
"SCMP_ARCH_ARM",
|
||||
"SCMP_ARCH_X86_64"
|
||||
],
|
||||
"syscalls" : [
|
||||
{
|
||||
"names" : [
|
||||
"lchown",
|
||||
"chmod"
|
||||
],
|
||||
"action" : "SCMP_ACT_ERRNO",
|
||||
"args" : [
|
||||
{
|
||||
"index" : 0,
|
||||
"value" : 1,
|
||||
"op" : "SCMP_CMP_NE"
|
||||
},
|
||||
{
|
||||
"index" : 1,
|
||||
"value" : 2,
|
||||
"valueTwo" : 3,
|
||||
"op" : "SCMP_CMP_MASKED_EQ"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"rootfsPropagation" : "shared",
|
||||
"maskedPaths" : [
|
||||
"/proc/kcore",
|
||||
"/root/nonexistent"
|
||||
],
|
||||
"readonlyPaths" : [
|
||||
"/proc/sys",
|
||||
"/opt/readonly"
|
||||
]
|
||||
},
|
||||
"hooks" : {
|
||||
"prestart" : [
|
||||
{
|
||||
"path" : "/bin/sh",
|
||||
"args" : [
|
||||
"-xec",
|
||||
"echo \$PRESTART_FOO >/prestart"
|
||||
],
|
||||
"env" : [
|
||||
"PRESTART_FOO=prestart_bar",
|
||||
"ALSO_FOO=also_bar"
|
||||
],
|
||||
"timeout" : 666
|
||||
},
|
||||
{
|
||||
"path" : "/bin/touch",
|
||||
"args" : [
|
||||
"/tmp/also-prestart"
|
||||
]
|
||||
}
|
||||
],
|
||||
"poststart" : [
|
||||
{
|
||||
"path" : "/bin/sh",
|
||||
"args" : [
|
||||
"touch",
|
||||
"/poststart"
|
||||
]
|
||||
}
|
||||
],
|
||||
"poststop" : [
|
||||
{
|
||||
"path" : "/bin/sh",
|
||||
"args" : [
|
||||
"touch",
|
||||
"/poststop"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"annotations" : {
|
||||
"hello.world" : "1",
|
||||
"foo" : "bar"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
# Create a simple "entrypoint" script that validates that the container
|
||||
# is created correctly according to the OCI config
|
||||
cat >"$OCI/rootfs/entrypoint.sh" <<EOF
|
||||
#!/bin/sh -e
|
||||
|
||||
# Mounts
|
||||
mountpoint /root
|
||||
mountpoint /var
|
||||
test -e /var/hello
|
||||
|
||||
# Process
|
||||
[[ "\$PWD" == /root ]]
|
||||
[[ "\$FOO" == bar ]]
|
||||
|
||||
# Process - rlimits
|
||||
[[ "\$(ulimit -S -n)" -eq 1024 ]]
|
||||
[[ "\$(ulimit -H -n)" -eq 1024 ]]
|
||||
[[ "\$(ulimit -S -r)" -eq 5 ]]
|
||||
[[ "\$(ulimit -H -r)" -eq 10 ]]
|
||||
[[ "\$(hostname)" == my-oci-container ]]
|
||||
|
||||
# Linux - devices
|
||||
test -c /dev/zero
|
||||
test -b "$DEV"
|
||||
[[ "\$(stat -c '%t:%T' "$DEV")" == 4:2 ]]
|
||||
|
||||
# Linux - maskedPaths
|
||||
test -e /proc/kcore
|
||||
cat /proc/kcore && exit 1
|
||||
test ! -e /root/nonexistent
|
||||
|
||||
# Linux - readonlyPaths
|
||||
touch /opt/readonly/foo && exit 1
|
||||
|
||||
exit 0
|
||||
EOF
|
||||
systemd-nspawn --oci-bundle="$OCI"
|
@ -46,7 +46,7 @@ mkdir -p /var/lib/machines
|
||||
mount -t tmpfs tmpfs /var/lib/machines
|
||||
|
||||
testcase_sanity_check() {
|
||||
local template root image oci uuid tmpdir
|
||||
local template root image uuid tmpdir
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
template="$(mktemp -d /tmp/nspawn-template.XXX)"
|
||||
@ -59,24 +59,6 @@ testcase_sanity_check() {
|
||||
mount -o loop "$image" /mnt
|
||||
cp -r "$template"/* /mnt/
|
||||
umount /mnt
|
||||
# Create a simple OCI bundle
|
||||
oci="$(mktemp -d /var/lib/machines/testsuite-13.oci-bundle.XXX)"
|
||||
"$CREATE_BB_CONTAINER" "$oci/rootfs"
|
||||
cat >"$oci/config.json" <<EOF
|
||||
{
|
||||
"ociVersion" : "1.0.0",
|
||||
"root" : {
|
||||
"path" : "rootfs"
|
||||
},
|
||||
"mounts" : [
|
||||
{
|
||||
"destination" : "/root",
|
||||
"type" : "tmpfs",
|
||||
"source" : "tmpfs"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
systemd-nspawn --help --no-pager
|
||||
systemd-nspawn --version
|
||||
@ -101,7 +83,6 @@ EOF
|
||||
sh -xec 'touch /nope')
|
||||
test ! -e "$root/nope"
|
||||
systemd-nspawn --image="$image" sh -xec 'echo hello'
|
||||
systemd-nspawn --oci-bundle="$oci" sh -xec 'mountpoint /root'
|
||||
|
||||
# --volatile=
|
||||
touch "$root/usr/has-usr"
|
||||
|
Loading…
Reference in New Issue
Block a user