Skip to content

Commit 0553641

Browse files
committed
Add dockerfile and local management script for local development
1 parent 3781d84 commit 0553641

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

Dockerfile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
FROM ubuntu:24.04
2+
ARG IMAGE_FINGERPRINT
3+
LABEL dev.fingerprint="${IMAGE_FINGERPRINT}"
4+
5+
ENV DEBIAN_FRONTEND=noninteractive
6+
RUN apt-get update && apt-get install -y \
7+
--no-install-recommends \
8+
build-essential \
9+
clang \
10+
clang-tools \
11+
cmake \
12+
ninja-build \
13+
pkg-config \
14+
git \
15+
ca-certificates \
16+
curl \
17+
gdb \
18+
lldb \
19+
&& rm -rf /var/lib/apt/lists/*
20+
21+
ENV CC=clang CXX=clang++
22+
CMD ["/bin/bash", "-l"]

container.sh

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/bin/sh
2+
set -e
3+
4+
container_name="libkqueue-dev"
5+
dev_image="libkqueue-clang-cmake-dev:latest"
6+
platform="linux/amd64"
7+
8+
# Verbosity
9+
verbose=0
10+
11+
debug() {
12+
if [ "$verbose" -eq 1 ]; then
13+
echo "$@"
14+
fi
15+
}
16+
17+
error() {
18+
echo "$@" >&2;
19+
}
20+
21+
# Parse flags
22+
while [ $# -gt 0 ]; do
23+
case "$1" in
24+
-v)
25+
verbose=1
26+
shift
27+
;;
28+
start|stop|restart|status)
29+
cmd="$1"
30+
shift
31+
;;
32+
*)
33+
echo "Usage: $0 [-v] {start|stop|restart|status}"
34+
exit 1
35+
;;
36+
esac
37+
done
38+
39+
[ -z "$cmd" ] && cmd="start"
40+
41+
hash_file() {
42+
# portable sha256
43+
if command -v sha256sum >/dev/null 2>&1; then
44+
sha256sum "$1" | awk '{print $1}'
45+
elif command -v shasum >/dev/null 2>&1; then
46+
shasum -a 256 "$1" | awk '{print $1}'
47+
else
48+
# macOS has openssl by default
49+
openssl dgst -sha256 "$1" | awk '{print $NF}'
50+
fi
51+
}
52+
53+
image_build() {
54+
[ -f Dockerfile ] || { error "no Dockerfile in $(pwd)"; exit 1; }
55+
hash=$(hash_file Dockerfile)
56+
debug "(re-)building image with $platform -t $dev_image --build-arg IMAGE_FINGERPRINT=$hash ."
57+
docker build --platform=$platform -t "$dev_image" --build-arg "IMAGE_FINGERPRINT=$hash" .
58+
}
59+
60+
run_container() {
61+
debug "Starting container '$container_name' with image '$dev_image'"
62+
docker run --rm -it \
63+
--platform=${platform} \
64+
--name "$container_name" \
65+
--hostname "$container_name" \
66+
-u "$(id -u)":"$(id -g)" \
67+
-e HOME=/home/dev \
68+
-w /home/dev \
69+
-v "$PWD":/home/dev \
70+
"$dev_image"
71+
}
72+
73+
start_container() {
74+
expected=$(hash_file Dockerfile)
75+
current=$(docker image inspect "$dev_image" \
76+
--format '{{ index .Config.Labels "dev.fingerprint" }}' 2>/dev/null || true)
77+
78+
if [ -z "$current" ]; then
79+
debug "Image missing or unlabeled, building"
80+
image_build
81+
run_container
82+
fi
83+
84+
if [ "$current" != "$expected" ]; then
85+
debug "fingerprint changed ($current -> $expected), rebuilding"
86+
image_build
87+
docker rm -f "$container_name"
88+
start_container
89+
fi
90+
91+
if ! docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then
92+
run_container
93+
else
94+
debug "Getting shell on existing container '$container_name'"
95+
docker exec -it ${container_name} /bin/bash
96+
fi
97+
}
98+
99+
stop_container() {
100+
if docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then
101+
debug "Stopping and removing container '$container_name'"
102+
docker rm -f "$container_name" > /dev/null
103+
else
104+
debug "Container '$container_name' is not running"
105+
fi
106+
}
107+
108+
status_container() {
109+
if docker ps --format '{{.Names}}' | grep -q "^${container_name}$"; then
110+
echo "Container '$container_name' is running"
111+
else
112+
echo "Container '$container_name' is not running"
113+
exit 1
114+
fi
115+
}
116+
117+
case "$cmd" in
118+
start)
119+
start_container
120+
;;
121+
stop)
122+
stop_container
123+
;;
124+
restart)
125+
stop_container
126+
start_container
127+
;;
128+
status)
129+
status_container
130+
;;
131+
esac

0 commit comments

Comments
 (0)