@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 10, 22:30 UTC

master
go 87 lines 3.08 KB
Raw
1 // Copyright 2015 Matthew Holt and The Caddy Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //go:build !windows && !plan9 && !nacl && !js
16
17 package caddy
18
19 import (
20 "context"
21 "errors"
22 "os"
23 "os/signal"
24 "syscall"
25
26 "github.com/caddyserver/certmagic"
27 "go.uber.org/zap"
28 )
29
30 // trapSignalsPosix captures POSIX-only signals.
31 func trapSignalsPosix() {
32 // Ignore all SIGPIPE signals to prevent weird issues with systemd: https://github.com/dunglas/frankenphp/issues/1020
33 // Docker/Moby has a similar hack: https://github.com/moby/moby/blob/d828b032a87606ae34267e349bf7f7ccb1f6495a/cmd/dockerd/docker.go#L87-L90
34 signal.Ignore(syscall.SIGPIPE)
35
36 go func() {
37 sigchan := make(chan os.Signal, 1)
38 signal.Notify(sigchan, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGUSR1, syscall.SIGUSR2)
39
40 for sig := range sigchan {
41 switch sig {
42 case syscall.SIGQUIT:
43 Log().Info("quitting process immediately", zap.String("signal", "SIGQUIT"))
44 certmagic.CleanUpOwnLocks(context.TODO(), Log()) // try to clean up locks anyway, it's important
45 os.Exit(ExitCodeForceQuit)
46
47 case syscall.SIGTERM:
48 Log().Info("shutting down apps, then terminating", zap.String("signal", "SIGTERM"))
49 exitProcessFromSignal("SIGTERM")
50
51 case syscall.SIGUSR1:
52 logger := Log().With(zap.String("signal", "SIGUSR1"))
53 // If we know the last source config file/adapter (set when starting
54 // via `caddy run --config <file> --adapter <adapter>`), attempt
55 // to reload from that source. Otherwise, ignore the signal.
56 file, adapter, reloadCallback := getLastConfig()
57 if file == "" {
58 logger.Info("last config unknown, ignored SIGUSR1")
59 break
60 }
61 logger = logger.With(
62 zap.String("file", file),
63 zap.String("adapter", adapter))
64 if reloadCallback == nil {
65 logger.Warn("no reload helper available, ignored SIGUSR1")
66 break
67 }
68 logger.Info("reloading config from last-known source")
69 if err := reloadCallback(file, adapter); errors.Is(err, errReloadFromSourceUnavailable) {
70 // No reload helper available (likely not started via caddy run).
71 logger.Warn("reload from source unavailable in this process; ignored SIGUSR1")
72 } else if err != nil {
73 logger.Error("failed to reload config from file", zap.Error(err))
74 } else {
75 logger.Info("successfully reloaded config from file")
76 }
77
78 case syscall.SIGUSR2:
79 Log().Info("not implemented", zap.String("signal", "SIGUSR2"))
80
81 case syscall.SIGHUP:
82 // ignore; this signal is sometimes sent outside of the user's control
83 Log().Info("not implemented", zap.String("signal", "SIGHUP"))
84 }
85 }
86 }()
87 }