aboutsummaryrefslogtreecommitdiff
path: root/tcwg-base/tcwg-host/start.sh
blob: 96095def0ba136018610c2c8c2d74efb5b92f376 (plain)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/bash

set -e

usage ()
{
    cat <<EOF
$0 [OPTIONS] -- IMAGE [GROUP [NODE]]

Options:
  --verbose true/false
	Whether to run in verbose mode

  IMAGE
	Docker tcwg-host image

  GROUP
	User group to configure access to; or "all"

  NODE
	Jenkins node ID to connect as; or "host"
EOF
    exit 1
}

group="all"
node="host"
verbose=false
additional_options=""

while [ $# -gt 0 ]; do
    case $1 in
	--verbose) verbose="$2"; shift ;;
	--additional_options) additional_options="$2"; shift ;;
	--) shift; break ;;
	*) echo "ERROR: Wrong option: $1"; usage ;;
    esac
    shift
done

image="$1"
group="${2-$group}"
node="${3-$node}"

if $verbose; then
    set -x
fi

if [ x"$image" = x"" ]; then
  echo "ERROR: image name not provided"
  usage
fi

if [ x"$(id -u)" = x"0" ] || groups 2>/dev/null | grep -q docker; then
    # Run docker straight up if $USER is root or in "docker" group.
    DOCKER="docker"
elif groups tcwg-buildslave 2>/dev/null | grep -q docker; then
    # If tcwg-buildslave user is present, use it to start the container
    # to have [sudo] log record of container startups.
    DOCKER="sudo -u tcwg-buildslave docker"
else
    # Fallback to sudo otherwise.
    DOCKER="sudo docker"
fi

mounts=""
# Bind-mount user HOMEs.
mounts="$mounts -v /home:/home"
# Bind-mount root's home so that run.sh can grant $root_users access
# to bare machine.
mounts="$mounts -v /root:/root"
# Bind-mount docker socket and binary to give access to docker.
mounts="$mounts -v /var/run/docker.sock:/var/run/docker.sock"
mounts="$mounts -v /usr/bin/docker:/usr/bin/docker"
# Bind-mount ssh host keys.
for key in /etc/ssh/ssh_host_*_key{,.pub}; do
    mounts="$mounts -v $key:$key:ro"
done

# Use at most half of all available RAM.
memlimit=$(free -m | awk '/^Mem/ { print $2 }')
memlimit=$(($memlimit / 2))m

case "$(uname -m):$($DOCKER --version | cut -d" " -f3)" in
    armv7l:18*)
	# Somewhere between docker-ce 19.03.5 and 19.03.6 docker bridge network
	# got broken on, at least, armhf with 3.10 kernel (aka TK1s).
	# At the same time to run ubuntu:focal we need docker-ce 19.03.9-ish
	# due to seccomp not supporting some of the syscalls.
	# We have two options:
	# 1. Use old docker and workaround ubuntu:focal's seccomp problem by
	# disabling it via --privileged option.
	# 2. Use new docker and workaround broken bridge network by using
	# --network host.
	# In the case of tcwg-tk1-* boards, which are used for jenkins CI, we
	# need the bridge network, so we choose (1).
	workaround="--privileged"
	;;
esac

# Since we're starting a host container, take the opportunity to ensure that GDB
# can attach to test programs when running the testsuite, and that core files
# are being correctly stored in the filesystem.
(
    # Use "sudo sysctl" because there's no guarantee that this script is
    # running as root. And there's no guarantee that "sudo sysctl" will
    # actually work but, at least, it will get the attention of
    # the developer.
    set +e
    ptrace_scope=$(sudo sysctl -n kernel.yama.ptrace_scope)
    res=$?
    ptrace_scope_config=""
    # If sysctl above failed (e.g., because this is a non-privileged
    # jenkins container), then do not attempt to change system configuration.
    if [ $res = 0 ] && [ "$ptrace_scope" != 0 ]; then
	set -e
	sudo sysctl -we kernel.yama.ptrace_scope=0
	ptrace_scope_config="kernel.yama.ptrace_scope = 0"
    fi

    core_pattern=$(sudo sysctl -n kernel.core_pattern)
    res=$?
    core_pattern_config=""
    # If sysctl above failed (e.g., because this is a non-privileged
    # jenkins container), then do not attempt to change system configuration.
    if [ $res = 0 ] && echo "$core_pattern" | grep -q -v -e '^core'; then
	set -e
	sudo sysctl -we kernel.core_pattern=core.%e.%p.%h.%t
	core_pattern_config="
# %e: executable filename
# %p: PID
# %h: hostname
# %t: UNIX time of dump
kernel.core_pattern = core.%e.%p.%h.%t"
    fi

    # If any sysctl change was made, persist it in a configuration file.
    if [ -n "$ptrace_scope_config" ] || [ -n "$core_pattern_config" ]; then
	sudo tee /etc/sysctl.d/90-tcwg.conf > /dev/null <<EOF
$ptrace_scope_config
$core_pattern_config
EOF
	sudo chmod 644 /etc/sysctl.d/90-tcwg.conf
    fi
)

$DOCKER run -dt --name=$node --network host --restart=unless-stopped $mounts \
	--memory=$memlimit --pids-limit=5000 $workaround $additional_options \
	$image "$group" "$node"