Skip to content

Commit f5065a7

Browse files
committed
devcontainer: update for 20.04 & Codespaces
1 parent bf4f7c8 commit f5065a7

File tree

6 files changed

+373
-14
lines changed

6 files changed

+373
-14
lines changed

.devcontainer/devcontainer.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
// Protobuf language support.
3939
"zxh404.vscode-proto3",
4040
// Formatting support (eg, protobuf).
41-
"xaver.clang-format"
41+
"xaver.clang-format",
4242
// Spell checking.
4343
"streetsidesoftware.code-spell-checker"
4444
],
@@ -53,6 +53,7 @@
5353
// We're using a base image which is compatible with our CI runner,
5454
// and thus use the same make target.
5555
"postCreateCommand": "make extra-ci-runner-setup && go mod download",
56-
// Uncomment to run as a non-root user.
57-
// "remoteUser": "vscode"
56+
// This user matches the user that's created inside the flow image
57+
"remoteUser": "flow",
58+
"overrideCommand": false
5859
}

.devcontainer/docker-compose.yaml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
1-
version: "3"
1+
version: "3.7"
22

33
services:
44
develop:
55
build:
66
context: .
7-
dockerfile: github-ubuntu-1804.Dockerfile
7+
dockerfile: github-ubuntu-2004.Dockerfile
88

99
volumes:
10-
# Forwards the local Docker socket to the container.
11-
- /var/run/docker.sock:/var/run/docker.sock
1210
- ..:/workspace:cached
13-
# Overrides default command so things don't shut down after the process ends.
14-
command: sleep infinity
11+
# Map the host docker socket into the container.
12+
- /var/run/docker.sock:/var/run/docker-host.sock
13+
# Map /var/tmp of the host into the container, such that files staged into
14+
# /var/tmp are accessible on the host, and from there through started docker
15+
# invocations which pass files via bind-mounts.
16+
#
17+
# TODO(johnny): For reasons I don't understand, doing this with /tmp doesn't
18+
# work on Github Codespaces (but works fine in VSCode Remote Containers).
19+
- /var/tmp:/var/tmp
20+
21+
# Use /var/tmp as the default temporary directory, rather than /tmp.
22+
environment:
23+
TMPDIR: /var/tmp
24+
1525
# Wrap in an init process that reaps defunct child processes.
1626
init: true
1727
# Run app on the same network as the database container; allows "forwardPorts" in devcontainer.json function.

.devcontainer/docker-debian.sh

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
#!/usr/bin/env bash
2+
#-------------------------------------------------------------------------------------------------------------
3+
# Copyright (c) Microsoft Corporation. All rights reserved.
4+
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
5+
#-------------------------------------------------------------------------------------------------------------
6+
#
7+
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md
8+
# Maintainer: The VS Code and Codespaces Teams
9+
#
10+
# Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] [use moby]
11+
12+
ENABLE_NONROOT_DOCKER=${1:-"true"}
13+
SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
14+
TARGET_SOCKET=${3:-"/var/run/docker.sock"}
15+
USERNAME=${4:-"automatic"}
16+
USE_MOBY=${5:-"true"}
17+
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
18+
19+
set -e
20+
21+
if [ "$(id -u)" -ne 0 ]; then
22+
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
23+
exit 1
24+
fi
25+
26+
# Determine the appropriate non-root user
27+
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
28+
USERNAME=""
29+
POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)")
30+
for CURRENT_USER in ${POSSIBLE_USERS[@]}; do
31+
if id -u ${CURRENT_USER} > /dev/null 2>&1; then
32+
USERNAME=${CURRENT_USER}
33+
break
34+
fi
35+
done
36+
if [ "${USERNAME}" = "" ]; then
37+
USERNAME=root
38+
fi
39+
elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
40+
USERNAME=root
41+
fi
42+
43+
# Get central common setting
44+
get_common_setting() {
45+
if [ "${common_settings_file_loaded}" != "true" ]; then
46+
curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping."
47+
common_settings_file_loaded=true
48+
fi
49+
if [ -f "/tmp/vsdc-settings.env" ]; then
50+
local multi_line=""
51+
if [ "$2" = "true" ]; then multi_line="-z"; fi
52+
local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')"
53+
if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi
54+
fi
55+
echo "$1=${!1}"
56+
}
57+
58+
# Function to run apt-get if needed
59+
apt_get_update_if_needed()
60+
{
61+
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
62+
echo "Running apt-get update..."
63+
apt-get update
64+
else
65+
echo "Skipping apt-get update."
66+
fi
67+
}
68+
69+
# Checks if packages are installed and installs them if not
70+
check_packages() {
71+
if ! dpkg -s "$@" > /dev/null 2>&1; then
72+
apt_get_update_if_needed
73+
apt-get -y install --no-install-recommends "$@"
74+
fi
75+
}
76+
77+
# Ensure apt is in non-interactive to avoid prompts
78+
export DEBIAN_FRONTEND=noninteractive
79+
80+
# Install dependencies
81+
check_packages apt-transport-https curl ca-certificates gnupg2
82+
83+
# Install Docker / Moby CLI if not already installed
84+
if type docker > /dev/null 2>&1; then
85+
echo "Docker / Moby CLI already installed."
86+
else
87+
# Source /etc/os-release to get OS info
88+
. /etc/os-release
89+
if [ "${USE_MOBY}" = "true" ]; then
90+
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
91+
get_common_setting MICROSOFT_GPG_KEYS_URI
92+
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
93+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
94+
apt-get update
95+
apt-get -y install --no-install-recommends moby-cli moby-buildx moby-compose
96+
else
97+
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
98+
curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg
99+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
100+
apt-get update
101+
apt-get -y install --no-install-recommends docker-ce-cli
102+
fi
103+
fi
104+
105+
# Install Docker Compose if not already installed and is on a supported architecture
106+
if type docker-compose > /dev/null 2>&1; then
107+
echo "Docker Compose already installed."
108+
else
109+
TARGET_COMPOSE_ARCH="$(uname -m)"
110+
if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then
111+
TARGET_COMPOSE_ARCH="x86_64"
112+
fi
113+
if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then
114+
# Use pip to get a version that runns on this architecture
115+
if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv pipx > /dev/null 2>&1; then
116+
apt_get_update_if_needed
117+
apt-get -y install python3-minimal python3-pip libffi-dev python3-venv pipx
118+
fi
119+
export PIPX_HOME=/usr/local/pipx
120+
mkdir -p ${PIPX_HOME}
121+
export PIPX_BIN_DIR=/usr/local/bin
122+
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
123+
pipx install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' docker-compose
124+
rm -rf /tmp/pip-tmp
125+
else
126+
LATEST_COMPOSE_VERSION=$(basename "$(curl -fsSL -o /dev/null -w "%{url_effective}" https://github.com/docker/compose/releases/latest)")
127+
curl -fsSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-${TARGET_COMPOSE_ARCH}" -o /usr/local/bin/docker-compose
128+
chmod +x /usr/local/bin/docker-compose
129+
fi
130+
fi
131+
132+
# If init file already exists, exit
133+
if [ -f "/usr/local/share/docker-init.sh" ]; then
134+
exit 0
135+
fi
136+
137+
# By default, make the source and target sockets the same
138+
if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then
139+
touch "${SOURCE_SOCKET}"
140+
ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}"
141+
fi
142+
143+
# Add a stub if not adding non-root user access, user is root
144+
if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ]; then
145+
echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh
146+
chmod +x /usr/local/share/docker-init.sh
147+
exit 0
148+
fi
149+
150+
# If enabling non-root access and specified user is found, setup socat and add script
151+
chown -h "${USERNAME}":root "${TARGET_SOCKET}"
152+
if ! dpkg -s socat > /dev/null 2>&1; then
153+
apt_get_update_if_needed
154+
apt-get -y install socat
155+
fi
156+
tee /usr/local/share/docker-init.sh > /dev/null \
157+
<< EOF
158+
#!/usr/bin/env bash
159+
#-------------------------------------------------------------------------------------------------------------
160+
# Copyright (c) Microsoft Corporation. All rights reserved.
161+
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
162+
#-------------------------------------------------------------------------------------------------------------
163+
164+
set -e
165+
166+
SOCAT_PATH_BASE=/tmp/vscr-docker-from-docker
167+
SOCAT_LOG=\${SOCAT_PATH_BASE}.log
168+
SOCAT_PID=\${SOCAT_PATH_BASE}.pid
169+
170+
# Wrapper function to only use sudo if not already root
171+
sudoIf()
172+
{
173+
if [ "\$(id -u)" -ne 0 ]; then
174+
sudo "\$@"
175+
else
176+
"\$@"
177+
fi
178+
}
179+
180+
# Log messages
181+
log()
182+
{
183+
echo -e "[\$(date)] \$@" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
184+
}
185+
186+
echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null
187+
log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}"
188+
189+
# If enabled, try to add a docker group with the right GID. If the group is root,
190+
# fall back on using socat to forward the docker socket to another unix socket so
191+
# that we can set permissions on it without affecting the host.
192+
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then
193+
SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET})
194+
if [ "\${SOCKET_GID}" != "0" ]; then
195+
log "Adding user to group with GID \${SOCKET_GID}."
196+
if [ "\$(cat /etc/group | grep :\${SOCKET_GID}:)" = "" ]; then
197+
sudoIf groupadd --gid \${SOCKET_GID} docker-host
198+
fi
199+
# Add user to group if not already in it
200+
if [ "\$(id ${USERNAME} | grep -E "groups.*(=|,)\${SOCKET_GID}\(")" = "" ]; then
201+
sudoIf usermod -aG \${SOCKET_GID} ${USERNAME}
202+
fi
203+
else
204+
# Enable proxy if not already running
205+
if [ ! -f "\${SOCAT_PID}" ] || ! ps -p \$(cat \${SOCAT_PID}) > /dev/null; then
206+
log "Enabling socket proxy."
207+
log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode"
208+
sudoIf rm -rf ${TARGET_SOCKET}
209+
(sudoIf socat -t 3600 UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${USERNAME} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null)
210+
else
211+
log "Socket proxy already running."
212+
fi
213+
fi
214+
log "Success"
215+
fi
216+
217+
# Execute whatever commands were passed in (if any). This allows us
218+
# to set this script to ENTRYPOINT while still executing the default CMD.
219+
set +e
220+
exec "\$@"
221+
EOF
222+
chmod +x /usr/local/share/docker-init.sh
223+
chown ${USERNAME}:root /usr/local/share/docker-init.sh
224+
echo "Done!"

0 commit comments

Comments
 (0)