forked from balena-os/balena-supervisor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dindctl
executable file
·256 lines (234 loc) · 7.47 KB
/
dindctl
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#!/bin/bash
#
# This script can be used to facilitate supervisor development. Its core feature is allowing
# faster development iterations by bind-mounting the local './dist' directly into the running
# supervisor container.
#
# Setting the '--mount-nm' flag in either 'run' or 'buildrun' action will bind-mount
# './node_modules/' into the running supervisor. In this case, it's up to the developer
# to make sure that the correct dependencies are installed.
#
# Usage: dindctl action [options]
#
# Actions:
# build build local supervisor image. By default it will be balena/<arch>-supervisor:master, you can override the tag with --tag.
# run [options] build dind host container, run it (with name balena_supervisor_1), which will include the specified supervisor image and run it.
# buildrun [options] run 'build' and then immediately 'run' the built container.
# refresh recompile sources in './src' and restart supervisor container on dind host - requires --mount-dist in order to work properly.
# logs [-f] print out supervisor log files - use '-f' to follow instead, or any other arguments you'd send to journalctl.
# stop stop dind supervisor host container.
# Options:
# --arch | -a [arch] architecture of the supervisor to build (default: same as host )
# --image | -i [image] image name for supervisor image to build/use ( default: balena/$ARCH-supervisor:master )
# --dind-image [image] image to use for the resinos-in-container host (default: resin/resinos:2.12.5_rev1-intel-nuc)
# --dind-container [name] container name suffix for the dind host container ( default: "supervisor", which will produce a container named resinos-in-container-supervisor)
# --mount-dist bind-mount './dist/' (where webpack stores the built js) from local development environment into supervisor container.
# --mount-nm bind-mount './node_modules/' from local development environment into supervisor container.
# --mount-backup bind-mount './tools/dind/backup.tgz' to simulate a migration backup.
# --preload | -p use tools/dind/apps.json to preload an application image into the dind host.
# --config | -c [file] path to config.json, relative to tools/dind ( default: config.json )
# --tag | -t [tag] for the "build" action, specify the tag to build (default: master)
# --no-clean for the "stop" action, skip removing the data, boot and state volumes
#
# See README.md for examples.
#
# The script requires make and docker.
#
THIS_FILE=$0
set -o errexit
set -o pipefail
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
SUPERVISOR_BASE_DIR="${DIR}"
ARCH="auto"
SUPERVISOR_IMAGE="balena/%ARCH%-supervisor:master"
declare -A DEFAULT_DIND_IMAGES=()
DEFAULT_DIND_IMAGES["amd64"]="resin/resinos:2.44.0_rev1.dev-intel-nuc"
DEFAULT_DIND_IMAGES["arm64"]="resin/resinos:2.43.0_rev1.dev-jetson-nano"
DIND_IMAGE="auto"
MOUNT_DIST="false"
MOUNT_NODE_MODULES="false"
CONTAINER_NAME="supervisor"
PRELOADED_IMAGE=""
OPTIMIZE="true"
CONFIG_FILENAME="config.json"
TAG="master"
CLEAN_VOLUMES="true"
MOUNT_BACKUP="false"
function showHelp {
cat $THIS_FILE | awk '{if(/^#/)print;else exit}' | tail -n +2 | sed 's/\#//' | sed 's|dindctl|'$THIS_FILE'|'
}
function parseOptions {
while [[ $# -ge 1 ]]
do
case $1 in
--mount-dist)
MOUNT_DIST="true"
;;
--mount-nm)
MOUNT_NODE_MODULES="true"
;;
--mount-backup)
MOUNT_BACKUP="true"
;;
-p|--preload)
PRELOADED_IMAGE="true"
;;
-i|--image)
SUPERVISOR_IMAGE="$2"
shift || { echo "--image provided not specified" && exit 1; }
;;
-c|--config)
CONFIG_FILENAME="$2"
shift || { echo "--config provided not specified" && exit 1; }
;;
--dind-image)
DIND_IMAGE="$2"
shift || { echo "--dind-image provided not specified" && exit 1; }
;;
--dind-container)
CONTAINER_NAME="$2"
shift || { echo "--dind-container provided not specified" && exit 1; }
;;
-a|--arch)
ARCH="$2"
shift || { echo "--arch provided not specified" && exit 1; }
;;
-t|--tag)
TAG="$2"
shift || { echo "--tag provided not specified" && exit 1; }
;;
-n|--no-optimize)
OPTIMIZE="false"
;;
--no-clean)
CLEAN_VOLUMES="false"
;;
*)
echo "Warning: unknown argument: $arg"
;;
esac
shift
done
if [ "$ARCH" == "auto" ]; then
HOSTARCH="$(uname -m)"
case "$HOSTARCH" in
armv7l) # Raspberry pi 32 bit
ARCH="rpi"
;;
aarch64)
ARCH="arm64"
;;
x86_64)
ARCH="amd64"
;;
*)
echo "Supervisor architecture for host architecture $HOSTARCH is unknown; please specify with --arch."
exit 1
;;
esac
fi
SUPERVISOR_IMAGE="${SUPERVISOR_IMAGE//%ARCH%/$ARCH}"
if [ "$DIND_IMAGE" == "auto" ]; then
DIND_IMAGE="${DEFAULT_DIND_IMAGES["$ARCH"]}"
if [ -z "$DIND_IMAGE" ]; then
echo "Default BalenaOS image for $ARCH is unknown; please specify with --dind-image."
exit 1
fi
fi
}
function buildSupervisor {
echo "Building supervisor image for architecture $ARCH and tagging as $TAG"
ARCH="$ARCH" TAG="$TAG" bash automation/build.sh
}
function buildSupervisorSrc {
if [ "$OPTIMIZE" = "true" ]; then
echo "Rebuilding supervisor source"
( cd "$SUPERVISOR_BASE_DIR" && npm install && npm run build )
else
echo "Rebuilding supervisor source without optimizations"
( cd "$SUPERVISOR_BASE_DIR" && npm install && npm run build -- --env.noOptimize )
fi
}
function refreshSupervisorSrc {
buildSupervisorSrc
echo "Restarting the supervisor container"
docker exec -ti resinos-in-container-$CONTAINER_NAME systemctl restart resin-supervisor
}
function runDind {
if [ ! -f "tools/dind/resinos-in-container/resinos-in-container.sh" ]; then
git submodule update --init
fi
if [ "$MOUNT_DIST" = "true" ]; then
buildSupervisorSrc
echo "Running with mounted dist folder"
fi
if [ "$PRELOADED_IMAGE" = "true" ]; then
echo "Running with preloaded apps"
fi
if ! ( docker inspect $SUPERVISOR_IMAGE &> /dev/null ); then
echo "$SUPERVISOR_IMAGE not available locally, pulling"
docker pull $SUPERVISOR_IMAGE
fi
echo "Starting dind supervisor"
make -C "$SUPERVISOR_BASE_DIR" \
ARCH="$ARCH" \
SUPERVISOR_IMAGE="$SUPERVISOR_IMAGE" \
MOUNT_DIST="$MOUNT_DIST" \
MOUNT_NODE_MODULES="$MOUNT_NODE_MODULES" \
MOUNT_BACKUP="$MOUNT_BACKUP" \
PRELOADED_IMAGE="$PRELOADED_IMAGE" \
CONTAINER_NAME="$CONTAINER_NAME" \
CONFIG_FILENAME="$CONFIG_FILENAME" \
DIND_IMAGE="$DIND_IMAGE" \
run-supervisor
}
function stopDind {
echo "Stopping dind supervisor"
make -C "$SUPERVISOR_BASE_DIR" CONTAINER_NAME="$CONTAINER_NAME" stop-supervisor
if [ "$CLEAN_VOLUMES" = "true" ]; then
cleanDind
fi
}
function cleanDind {
echo "Cleaning dind supervisor volumes"
docker volume rm "resin-boot-$CONTAINER_NAME" "resin-state-$CONTAINER_NAME" "resin-data-$CONTAINER_NAME" &> /dev/null || true
}
function logs {
docker exec -ti resinos-in-container-$CONTAINER_NAME journalctl $@
}
function dumpVars {
for VNAME in ARCH SUPERVISOR_IMAGE MOUNT_DIST MOUNT_NODE_MODULES MOUNT_BACKUP PRELOADED_IMAGE CONTAINER_NAME CONFIG_FILENAME DIND_IMAGE; do
echo "$VNAME=$(printf "%q" "${!VNAME}")"
done
}
action="$1"
shift || true
if [ "$action" = "logs" ]; then
logs "$@"
else
parseOptions "$@"
case $action in
build)
buildSupervisor
;;
run)
stopDind
runDind
;;
buildrun)
buildSupervisor && runDind
;;
refresh)
refreshSupervisorSrc
;;
stop)
stopDind
;;
vars)
dumpVars
;;
*)
showHelp
;;
esac
fi