diff --git a/Dockerfile b/Dockerfile index 17bf01a19..244678b63 100644 --- a/Dockerfile +++ b/Dockerfile @@ -192,22 +192,10 @@ RUN ldconfig EXPOSE 5000 EXPOSE 1935 EXPOSE 8554 -EXPOSE 8555 +EXPOSE 8555/tcp 8555/udp -# Fails if cont-init.d fails -ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2 -# Wait indefinitely for cont-init.d to finish before starting services -ENV S6_CMD_WAIT_FOR_SERVICES=1 -ENV S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 -# Give services (including Frigate) 30 seconds to stop before killing them -# But this is not working currently because of: -# https://github.com/just-containers/s6-overlay/issues/503 -ENV S6_SERVICES_GRACETIME=30000 # Configure logging to prepend timestamps, log to stdout, keep 0 archives and rotate on 10MB ENV S6_LOGGING_SCRIPT="T 1 n0 s10000000 T" -# TODO: remove after a new version of s6-overlay is released. See: -# https://github.com/just-containers/s6-overlay/issues/460#issuecomment-1327127006 -ENV S6_SERVICES_READYTIME=50 ENTRYPOINT ["/init"] CMD [] @@ -217,7 +205,7 @@ FROM deps AS devcontainer # Do not start the actual Frigate service on devcontainer as it will be started by VSCode # But start a fake service for simulating the logs -COPY docker/fake_frigate_run /etc/services.d/frigate/run +COPY docker/fake_frigate_run /etc/s6-overlay/s6-rc.d/frigate/run # Install Node 16 RUN apt-get update \ diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/consumer-for b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/consumer-for new file mode 100644 index 000000000..5e9301778 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/consumer-for @@ -0,0 +1 @@ +frigate diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/dependencies.d/log-prepare b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/dependencies.d/log-prepare new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/pipeline-name b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/pipeline-name new file mode 100644 index 000000000..01f465e4e --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/pipeline-name @@ -0,0 +1 @@ +frigate-pipeline diff --git a/docker/rootfs/etc/services.d/frigate/log/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/run similarity index 100% rename from docker/rootfs/etc/services.d/frigate/log/run rename to docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/run diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/type new file mode 100644 index 000000000..5883cff0c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate-log/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/dependencies.d/go2rtc b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/dependencies.d/go2rtc new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/finish b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/finish new file mode 100755 index 000000000..d83c1a6e6 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/finish @@ -0,0 +1,30 @@ +#!/command/with-contenv bash +# shellcheck shell=bash +# Take down the S6 supervision tree when the service exits + +set -o errexit -o nounset -o pipefail + +declare exit_code_container +exit_code_container=$(cat /run/s6-linux-init-container-results/exitcode) +readonly exit_code_container +readonly exit_code_service="${1}" +readonly exit_code_signal="${2}" +readonly service="Frigate" + +echo "Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})" >&2 + +if [[ "${exit_code_service}" -eq 256 ]]; then + if [[ "${exit_code_container}" -eq 0 ]]; then + echo $((128 + exit_code_signal)) > /run/s6-linux-init-container-results/exitcode + fi +elif [[ "${exit_code_service}" -ne 0 ]]; then + if [[ "${exit_code_container}" -eq 0 ]]; then + echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode + fi +else + # Exit code 0 is expected when Frigate is restarted by the user. In this case, + # we create a signal for the go2rtc finish script to tolerate the restart. + touch /dev/shm/restarting-frigate +fi + +exec /run/s6/basedir/bin/halt diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/producer-for b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/producer-for new file mode 100644 index 000000000..65f1316a4 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/producer-for @@ -0,0 +1 @@ +frigate-log diff --git a/docker/rootfs/etc/services.d/frigate/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run similarity index 81% rename from docker/rootfs/etc/services.d/frigate/run rename to docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run index c543ff0ff..905f4b670 100755 --- a/docker/rootfs/etc/services.d/frigate/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run @@ -4,6 +4,9 @@ set -o errexit -o nounset -o pipefail +# Tell S6-Overlay not to restart this service +s6-svc -O . + cd /opt/frigate # Replace the bash process with the Frigate process, redirecting stderr to stdout diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/type new file mode 100644 index 000000000..5883cff0c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/consumer-for b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/consumer-for new file mode 100644 index 000000000..02b16a879 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/consumer-for @@ -0,0 +1 @@ +go2rtc diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/dependencies.d/log-prepare b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/dependencies.d/log-prepare new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/pipeline-name b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/pipeline-name new file mode 100644 index 000000000..1fe545297 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/pipeline-name @@ -0,0 +1 @@ +go2rtc-pipeline diff --git a/docker/rootfs/etc/services.d/go2rtc/log/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/run similarity index 100% rename from docker/rootfs/etc/services.d/go2rtc/log/run rename to docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/run diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/type new file mode 100644 index 000000000..5883cff0c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-log/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/dependencies.d/base b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/dependencies.d/base new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/finish b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/finish new file mode 100755 index 000000000..26b34294a --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/finish @@ -0,0 +1,32 @@ +#!/command/with-contenv bash +# shellcheck shell=bash +# Take down the S6 supervision tree when the service exits + +set -o errexit -o nounset -o pipefail + +declare exit_code_container +exit_code_container=$(cat /run/s6-linux-init-container-results/exitcode) +readonly exit_code_container +readonly exit_code_service="${1}" +readonly exit_code_signal="${2}" +readonly service="go2rtc" + +echo "Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})" >&2 + +if [[ "${exit_code_service}" -eq 256 ]]; then + if [[ "${exit_code_container}" -eq 0 ]]; then + echo $((128 + exit_code_signal)) > /run/s6-linux-init-container-results/exitcode + fi +elif [[ "${exit_code_service}" -ne 0 ]]; then + if [[ "${exit_code_container}" -eq 0 ]]; then + echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode + fi +else + # go2rtc is not supposed to exit, so even when it exits with 0 we make the + # container with 1. We only tolerate it when Frigate is restarting. + if [[ "${exit_code_container}" -eq 0 && ! -f /dev/shm/restarting-frigate ]]; then + echo "1" > /run/s6-linux-init-container-results/exitcode + fi +fi + +exec /run/s6/basedir/bin/halt diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/producer-for b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/producer-for new file mode 100644 index 000000000..20fbc45f8 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/producer-for @@ -0,0 +1 @@ +go2rtc-log diff --git a/docker/rootfs/etc/services.d/go2rtc/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run similarity index 83% rename from docker/rootfs/etc/services.d/go2rtc/run rename to docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run index db5c2a869..aa753bd12 100755 --- a/docker/rootfs/etc/services.d/go2rtc/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run @@ -4,6 +4,9 @@ set -o errexit -o nounset -o pipefail +# Tell S6-Overlay not to restart this service +s6-svc -O . + raw_config=$(python3 /usr/local/go2rtc/create_config.py) # Replace the bash process with the go2rtc process, redirecting stderr to stdout diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/type new file mode 100644 index 000000000..5883cff0c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/dependencies.d/base b/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/dependencies.d/base new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/cont-init.d/prepare-logs.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/run similarity index 100% rename from docker/rootfs/etc/cont-init.d/prepare-logs.sh rename to docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/run diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/type new file mode 100644 index 000000000..bdd22a185 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/up b/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/up new file mode 100644 index 000000000..f90be02e8 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/up @@ -0,0 +1 @@ +/etc/s6-overlay/s6-rc.d/log-prepare/run diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/consumer-for b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/consumer-for new file mode 100644 index 000000000..68b7d12d4 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/consumer-for @@ -0,0 +1 @@ +nginx diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/dependencies.d/log-prepare b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/dependencies.d/log-prepare new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/pipeline-name b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/pipeline-name new file mode 100644 index 000000000..e22259a61 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/pipeline-name @@ -0,0 +1 @@ +nginx-pipeline diff --git a/docker/rootfs/etc/services.d/nginx/log/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/run similarity index 100% rename from docker/rootfs/etc/services.d/nginx/log/run rename to docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/run diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/type new file mode 100644 index 000000000..5883cff0c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx-log/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/dependencies.d/frigate b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/dependencies.d/frigate new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/finish b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/finish new file mode 100755 index 000000000..01c37d192 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/finish @@ -0,0 +1,28 @@ +#!/command/with-contenv bash +# shellcheck shell=bash +# Take down the S6 supervision tree when the service fails + +set -o errexit -o nounset -o pipefail + +declare exit_code_container +exit_code_container=$(cat /run/s6-linux-init-container-results/exitcode) +readonly exit_code_container +readonly exit_code_service="${1}" +readonly exit_code_signal="${2}" +readonly service="NGINX" + +echo "Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})" >&2 + +if [[ "${exit_code_service}" -eq 256 ]]; then + if [[ "${exit_code_container}" -eq 0 ]]; then + echo $((128 + exit_code_signal)) > /run/s6-linux-init-container-results/exitcode + fi + if [[ "${exit_code_signal}" -eq 15 ]]; then + exec /run/s6/basedir/bin/halt + fi +elif [[ "${exit_code_service}" -ne 0 ]]; then + if [[ "${exit_code_container}" -eq 0 ]]; then + echo "${exit_code_service}" > /run/s6-linux-init-container-results/exitcode + fi + exec /run/s6/basedir/bin/halt +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/producer-for b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/producer-for new file mode 100644 index 000000000..307d7404c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/producer-for @@ -0,0 +1 @@ +nginx-log diff --git a/docker/rootfs/etc/services.d/nginx/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run similarity index 100% rename from docker/rootfs/etc/services.d/nginx/run rename to docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/type new file mode 100644 index 000000000..5883cff0c --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/type @@ -0,0 +1 @@ +longrun diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/frigate-pipeline b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/frigate-pipeline new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/go2rtc-pipeline b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/go2rtc-pipeline new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/nginx-pipeline b/docker/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/nginx-pipeline new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/services.d/frigate/finish b/docker/rootfs/etc/services.d/frigate/finish deleted file mode 100755 index e219ed8b4..000000000 --- a/docker/rootfs/etc/services.d/frigate/finish +++ /dev/null @@ -1,16 +0,0 @@ -#!/command/with-contenv bash -# shellcheck shell=bash -# Take down the S6 supervision tree when the service exits - -set -o errexit -o nounset -o pipefail - -# Prepare exit code -if [[ "${1}" -eq 256 ]]; then - exit_code="$((128 + ${2}))" -else - exit_code="${1}" -fi - -# Make the container exit with the same exit code as the service -echo "${exit_code}" > /run/s6-linux-init-container-results/exitcode -exec /run/s6/basedir/bin/halt diff --git a/docker/rootfs/etc/services.d/go2rtc/finish b/docker/rootfs/etc/services.d/go2rtc/finish deleted file mode 100755 index c1b77fccc..000000000 --- a/docker/rootfs/etc/services.d/go2rtc/finish +++ /dev/null @@ -1,8 +0,0 @@ -#!/command/with-contenv bash -# shellcheck shell=bash -# Take down the S6 supervision tree when the service fails, or restart it -# otherwise - -if [[ "${1}" -ne 0 && "${1}" -ne 256 ]]; then - exec /run/s6/basedir/bin/halt -fi diff --git a/docker/rootfs/etc/services.d/nginx/finish b/docker/rootfs/etc/services.d/nginx/finish deleted file mode 100755 index c1b77fccc..000000000 --- a/docker/rootfs/etc/services.d/nginx/finish +++ /dev/null @@ -1,8 +0,0 @@ -#!/command/with-contenv bash -# shellcheck shell=bash -# Take down the S6 supervision tree when the service fails, or restart it -# otherwise - -if [[ "${1}" -ne 0 && "${1}" -ne 256 ]]; then - exec /run/s6/basedir/bin/halt -fi diff --git a/frigate/http.py b/frigate/http.py index a83b94751..581635d5e 100644 --- a/frigate/http.py +++ b/frigate/http.py @@ -769,7 +769,10 @@ def config_save(): logging.error(f"Error restarting Frigate: {e}") return "Config successfully saved, unable to restart Frigate", 200 - return "Config successfully saved, restarting...", 200 + return ( + "Config successfully saved, restarting (this can take up to one minute)...", + 200, + ) else: return "Config successfully saved.", 200 diff --git a/frigate/util.py b/frigate/util.py index 69ead2a7a..2987099e8 100755 --- a/frigate/util.py +++ b/frigate/util.py @@ -628,13 +628,8 @@ def clipped(obj, frame_shape): def restart_frigate(): - proc = psutil.Process(1) - # if this is running via s6, sigterm pid 1 - if proc.name() == "s6-svscan": - proc.terminate() - # otherwise, just try and exit frigate - else: - os.kill(os.getpid(), signal.SIGTERM) + # S6 overlay is configured to exit once the Frigate process exits + os.kill(os.getpid(), signal.SIGTERM) class EventsPerSecond: diff --git a/web/src/AppBar.jsx b/web/src/AppBar.jsx index 95a6bfbf2..b5bb16c0f 100644 --- a/web/src/AppBar.jsx +++ b/web/src/AppBar.jsx @@ -78,7 +78,7 @@ export default function AppBar() { {showDialogWait ? ( ) : null}