The image creates SWW_STATE_DIR when it is missing (closes #337) #351
No files matched your search
+2
-2
@@ -222,8 +222,8 @@ RUN groupadd --system --gid 65532 sww \
|
|||||||
sww
|
sww
|
||||||
|
|
||||||
# The state files' directory, SWW_STATE_DIR by default, where a volume
|
# The state files' directory, SWW_STATE_DIR by default, where a volume
|
||||||
# is mounted to keep them across deploys. The run script gives it to the
|
# is mounted to keep them across deploys. At each start of waf, the run
|
||||||
# sww user at each start of waf.
|
# script makes SWW_STATE_DIR if it is missing and gives it to the sww user.
|
||||||
RUN mkdir /var/lib/sww
|
RUN mkdir /var/lib/sww
|
||||||
|
|
||||||
# The default rule file, in SWW_RULES_DIR by default, where a Dockerfile
|
# The default rule file, in SWW_RULES_DIR by default, where a Dockerfile
|
||||||
|
|||||||
@@ -2507,11 +2507,11 @@ It sets no `ENTRYPOINT` or `USER` of its own. The container must start
|
|||||||
- The image's `run` script is `/etc/service/sww/run`. It starts `waf` when
|
- The image's `run` script is `/etc/service/sww/run`. It starts `waf` when
|
||||||
`SWW_COMMAND` is `waf`, and `rproxy` when it is `rproxy`, unset or empty. It
|
`SWW_COMMAND` is `waf`, and `rproxy` when it is `rproxy`, unset or empty. It
|
||||||
runs either as the `sww` user (uid and gid 65532), with runit's `chpst`. For
|
runs either as the `sww` user (uid and gid 65532), with runit's `chpst`. For
|
||||||
`waf`, it first makes `SWW_STATE_DIR` and every file in it belong to that
|
`waf`, it first makes `SWW_STATE_DIR` if it is missing, gives it and every
|
||||||
user. It also makes `SWW_CACHE_DIR` if it is missing, and gives it and every
|
file in it to that user, and sets its mode to `0700`. It also makes
|
||||||
file in it to that user. For `rproxy` it changes no owner. With any other
|
`SWW_CACHE_DIR` if it is missing, and gives it and every file in it to that
|
||||||
value, it starts nothing, and stops with a message naming `SWW_COMMAND` and
|
user. For `rproxy` it changes no owner. With any other value, it starts
|
||||||
its value.
|
nothing, and stops with a message naming `SWW_COMMAND` and its value.
|
||||||
|
|
||||||
Every `run` script, the app's included, is a bash script. It starts with
|
Every `run` script, the app's included, is a bash script. It starts with
|
||||||
`#!/usr/bin/env bash` and `set -euo pipefail`, and puts its code in a `main`
|
`#!/usr/bin/env bash` and `set -euo pipefail`, and puts its code in a `main`
|
||||||
|
|||||||
+2
-1
@@ -19,7 +19,8 @@ way.
|
|||||||
- The service directory `/etc/service/sww`, with the `run` script
|
- The service directory `/etc/service/sww`, with the `run` script
|
||||||
`share/sww.run`.
|
`share/sww.run`.
|
||||||
- `/var/lib/sww` for `waf`'s state files, and `/etc/sww/rules.d` with the
|
- `/var/lib/sww` for `waf`'s state files, and `/etc/sww/rules.d` with the
|
||||||
default rule file `share/rules.d/00-default.rules`.
|
default rule file `share/rules.d/00-default.rules`. The `run` script makes
|
||||||
|
`SWW_STATE_DIR` when it is missing.
|
||||||
- `EXPOSE 8080`, and the `HEALTHCHECK` that runs `sww healthcheck`.
|
- `EXPOSE 8080`, and the `HEALTHCHECK` that runs `sww healthcheck`.
|
||||||
|
|
||||||
## Pins
|
## Pins
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ the two (see "The image's command" below).
|
|||||||
## State and cache files
|
## State and cache files
|
||||||
|
|
||||||
- `SWW_STATE_DIR` (default `/var/lib/sww`): the directory of the state files, an
|
- `SWW_STATE_DIR` (default `/var/lib/sww`): the directory of the state files, an
|
||||||
absolute path that exists and can be written.
|
absolute path that can be written. The image's `run` script makes it.
|
||||||
- `SWW_STATE_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
|
- `SWW_STATE_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
|
||||||
written after a ban is made, lifted or made permanent. A duration.
|
written after a ban is made, lifted or made permanent. A duration.
|
||||||
- `SWW_STATE_COUNTER_INTERVAL` (default `15m`): how often every state and cache
|
- `SWW_STATE_COUNTER_INTERVAL` (default `15m`): how often every state and cache
|
||||||
|
|||||||
+13
-5
@@ -18,8 +18,8 @@
|
|||||||
# client;
|
# client;
|
||||||
# - that a waf container with its state files on a new volume mounted at
|
# - that a waf container with its state files on a new volume mounted at
|
||||||
# the directory SWW_STATE_DIR_FILE names becomes healthy;
|
# the directory SWW_STATE_DIR_FILE names becomes healthy;
|
||||||
# - that one whose SWW_STATE_DIR does not exist logs waf's message
|
# - that the run script makes a SWW_STATE_DIR that does not exist, owned
|
||||||
# about it.
|
# by sww with mode 0700, and that waf then becomes healthy.
|
||||||
# waf runs with SWW_LOOKUP_SOURCE=off, so that no address is sent to
|
# waf runs with SWW_LOOKUP_SOURCE=off, so that no address is sent to
|
||||||
# GeoJS. The containers, the network, the volumes and both images are removed
|
# GeoJS. The containers, the network, the volumes and both images are removed
|
||||||
# however the script ends. Building the app needs network access, for nixpkgs'
|
# however the script ends. Building the app needs network access, for nixpkgs'
|
||||||
@@ -159,6 +159,12 @@ owner_of() {
|
|||||||
docker exec "$1" stat --format '%U' "$2"
|
docker exec "$1" stat --format '%U' "$2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# owner_and_mode_of <container> <dir>: print who owns dir there, and its
|
||||||
|
# mode in octal.
|
||||||
|
owner_and_mode_of() {
|
||||||
|
docker exec "$1" stat --format '%U %a' "$2"
|
||||||
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
cd "$ROOT"
|
cd "$ROOT"
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
@@ -251,9 +257,11 @@ main() {
|
|||||||
--env SWW_STATE_DIR=/srv/missing \
|
--env SWW_STATE_DIR=/srv/missing \
|
||||||
--env SWW_LOOKUP_SOURCE=off \
|
--env SWW_LOOKUP_SOURCE=off \
|
||||||
"$IMAGE" >/dev/null
|
"$IMAGE" >/dev/null
|
||||||
wait_for "waf did not report the missing state directory" \
|
wait_for "waf's health check did not pass" healthy "$WAF"
|
||||||
logged "$WAF" "SWW_STATE_DIR cannot be written"
|
[ "$(owner_and_mode_of "$WAF" /srv/missing)" = "sww 700" ] ||
|
||||||
echo "example-app: waf reports a state directory that does not exist"
|
fail "the run script did not make SWW_STATE_DIR for sww with mode 0700"
|
||||||
|
echo "example-app: the run script makes a missing SWW_STATE_DIR for sww" \
|
||||||
|
"with mode 0700"
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
+17
-18
@@ -12,7 +12,7 @@ main() {
|
|||||||
case "$command" in
|
case "$command" in
|
||||||
rproxy) ;;
|
rproxy) ;;
|
||||||
waf)
|
waf)
|
||||||
give_state_dir_to_sww
|
make_state_dir_for_sww
|
||||||
make_cache_dir_for_sww
|
make_cache_dir_for_sww
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
@@ -24,28 +24,27 @@ main() {
|
|||||||
exec chpst -u sww:sww /usr/local/bin/sww "$command"
|
exec chpst -u sww:sww /usr/local/bin/sww "$command"
|
||||||
}
|
}
|
||||||
|
|
||||||
# give_state_dir_to_sww gives the state directory and every file in
|
# make_state_dir_for_sww makes the state directory, SWW_STATE_DIR in
|
||||||
# it to the sww user, so that a volume mounted there needs no change
|
# either form, when it is missing, gives it and every file in it to the
|
||||||
# of owner; chown -R changes a symbolic link itself, never what it points
|
# sww user, and sets its mode to 0700. So a volume mounted there needs no
|
||||||
# to. When SWW_STATE_DIR, in either form, cannot be read or is not the
|
# change of owner; chown -R changes a symbolic link itself, never what it
|
||||||
# absolute path of a directory, no owner is changed, and waf starts and
|
# points to. When the setting cannot be read or is not an absolute path,
|
||||||
# stops with a message naming the setting. A change of owner that fails, as
|
# nothing is changed, and waf starts and stops with a message naming the
|
||||||
# on a volume mounted read-only, does not end the script either: waf
|
# setting. A step that fails, as on a volume mounted read-only, does not
|
||||||
# reports a directory it cannot write.
|
# end the script either: waf reports a directory it cannot write.
|
||||||
give_state_dir_to_sww() {
|
make_state_dir_for_sww() {
|
||||||
local dir
|
local dir
|
||||||
if dir="$(setting SWW_STATE_DIR /var/lib/sww)" &&
|
if dir="$(setting SWW_STATE_DIR /var/lib/sww)" && [[ "$dir" == /* ]]; then
|
||||||
[[ "$dir" == /* && -d "$dir" ]]; then
|
{ mkdir -p -- "$dir" && chown -R sww:sww "$dir" &&
|
||||||
chown -R sww:sww "$dir" || true
|
chmod 0700 "$dir"; } || true
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# make_cache_dir_for_sww makes the cache directory, SWW_CACHE_DIR in
|
# make_cache_dir_for_sww makes the cache directory, SWW_CACHE_DIR in
|
||||||
# either form, and gives it and every file in it to the sww user, as
|
# either form, when it is missing, and gives it and every file in it to
|
||||||
# give_state_dir_to_sww does the state directory. Unlike that one, it is
|
# the sww user. As for the state directory, a setting that cannot be read
|
||||||
# made when it is missing, since the cache files need no volume. As there,
|
# or is not an absolute path changes nothing, and a failure does not end
|
||||||
# a setting that cannot be read or is not an absolute path changes
|
# the script.
|
||||||
# nothing, and a failure does not end the script.
|
|
||||||
make_cache_dir_for_sww() {
|
make_cache_dir_for_sww() {
|
||||||
local dir
|
local dir
|
||||||
if dir="$(setting SWW_CACHE_DIR /var/cache/sww)" && [[ "$dir" == /* ]]; then
|
if dir="$(setting SWW_CACHE_DIR /var/cache/sww)" && [[ "$dir" == /* ]]; then
|
||||||
|
|||||||
Reference in new issue
Block a user