From 6d3d90b0e26e2f820fdb6cc96e72711f976fd6c8 Mon Sep 17 00:00:00 2001 From: Alexander Baryshnikov Date: Fri, 9 Oct 2020 19:37:41 +0800 Subject: [PATCH] add graceful shutdown for bin mode --- _docs/modes.md | 18 +++++++++++ server/mode_bin.go | 34 ++++++++++++++++++--- server/runner/embedded/templates/bindata.go | 2 +- server/unit.go | 34 +++++++++++---------- templates/unit-info.html | 27 +++++++++++----- 5 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 _docs/modes.md diff --git a/_docs/modes.md b/_docs/modes.md new file mode 100644 index 0000000..0c80981 --- /dev/null +++ b/_docs/modes.md @@ -0,0 +1,18 @@ +## BIN + +Binary modes just executes any script in shell (`/bin/sh` by default). You can override shell per-unit +by `shell: /path/to/shell` configuration param. + +To handle a graceful timeout, child should be able to forward signal: basically, use `exec` before last command. + +Danger (but will work), signals may not be handled by foo + +```yaml +command: "V=1 RAIL=2 foo bar -c -y -z" +``` + +Good + +```yaml +command: "V=1 RAIL=2 exec foo bar -c -y -z" +``` \ No newline at end of file diff --git a/server/mode_bin.go b/server/mode_bin.go index 90a1d35..c318fee 100644 --- a/server/mode_bin.go +++ b/server/mode_bin.go @@ -3,6 +3,7 @@ package server import ( "context" "io/ioutil" + "log" "net/http" "os" "os/exec" @@ -33,11 +34,12 @@ func (m *markerResponse) WriteHeader(statusCode int) { } type binHandler struct { - command string - workDir string - shell string - environment []string - timeout time.Duration + command string + workDir string + shell string + environment []string + timeout time.Duration + gracefulTimeout time.Duration } func (bh *binHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) { @@ -75,7 +77,29 @@ func (bh *binHandler) ServeHTTP(writer http.ResponseWriter, request *http.Reques cmd.Stdout = marker cmd.Env = env api.SetBinFlags(cmd) + + var done bool + + if bh.gracefulTimeout > 0 { + graceCtx, graceCancel := context.WithTimeout(ctx, bh.gracefulTimeout) + defer graceCancel() + go func() { + <-graceCtx.Done() + proc := cmd.Process + if proc == nil || done { + return + } + err := proc.Signal(os.Interrupt) + if err != nil { + log.Println("failed send signal to process:", err) + } else { + log.Println("sent graceful shutdown to proces") + } + }() + } + err := cmd.Run() + done = true if codeReset, ok := writer.(interface{ Status(status int) }); ok && err != nil { codeReset.Status(http.StatusBadGateway) diff --git a/server/runner/embedded/templates/bindata.go b/server/runner/embedded/templates/bindata.go index 4942ba6..dabc750 100644 --- a/server/runner/embedded/templates/bindata.go +++ b/server/runner/embedded/templates/bindata.go @@ -102,7 +102,7 @@ func loginHtml() (*asset, error) { return a, nil } -var _unitInfoHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x5a\xef\x8e\xe3\xb6\x11\xff\x7e\x4f\x41\x10\xfb\xe1\x16\x58\x49\x4e\xda\x3d\xb4\x5b\x59\xc0\xf6\x2e\x4d\xee\x70\x17\xa4\x77\x9b\xde\x67\x5a\x1c\x5b\xec\x52\xa4\x42\x8e\xec\x75\x54\x7f\xef\x53\xf4\xe1\xfa\x24\x05\x25\xff\x91\x6d\xc9\xa6\x7c\x9b\xa4\x68\x8d\x05\x56\x7f\x86\xbf\xf9\xc7\x21\x87\x33\x8a\x33\xcc\x25\x91\x4c\xcd\xc6\x14\x14\x4d\x5e\xc4\x19\x30\x9e\xbc\x20\x84\x90\x38\x07\x64\x24\xcd\x98\xb1\x80\x63\x5a\xe2\x34\xf8\x03\x6d\xbf\x52\x2c\x87\x31\x9d\x0b\x58\x14\xda\x20\x25\xa9\x56\x08\x0a\xc7\x74\x21\x38\x66\x63\x0e\x73\x91\x42\x50\xdf\xdc\x10\xa1\x04\x0a\x26\x03\x9b\x32\x09\xe3\xaf\x6e\x88\xcd\x8c\x50\x8f\x01\xea\x60\x2a\x70\xac\xb4\x63\x1e\x35\xdc\xe3\x89\xe6\xcb\xe4\x45\xcc\xc5\x9c\xa4\x92\x59\x3b\xa6\x0e\x9b\x09\x05\x66\x23\x81\x62\xdb\x77\x8a\xcd\x27\xcc\x90\xe6\x5f\x00\x4f\x05\x53\x3c\xb0\xf9\xe6\x81\x14\xb3\x0c\xc9\x64\xd6\x5c\xac\xc7\xd7\x18\x6c\x1f\x21\x98\x18\xa6\x38\x25\x99\x81\xe9\x98\x56\x55\xf8\x11\x24\xa1\x11\x5d\xad\x68\xf2\x3d\x53\x3a\xf8\x58\xaa\x38\x62\x2d\x80\x3d\x01\xa5\x64\x85\x85\x0d\xd7\xcd\x7d\x8b\x5f\x3d\xa4\x94\x07\x4c\x9d\x22\xb9\x09\x58\x89\xfa\x80\xb6\xa6\x97\xa2\x45\x1f\x08\x84\xbc\x83\xea\x48\x9b\x40\x0a\xf5\x78\xa4\x49\xa9\x04\x36\xea\xdc\x4b\x49\xdc\x9d\xdd\xd3\x67\x0b\x15\x49\x71\xfc\xb4\xaa\xc4\x94\x84\xf7\x25\x66\xda\x88\x9f\x81\xaf\x56\xdd\x72\x78\x4b\xec\x29\x35\x2b\x31\x8b\xa4\x9e\xe9\x12\x6b\xd9\xdf\xd7\x97\x9d\x82\x9f\x12\x1e\xd4\xa1\xc4\x71\x54\xca\x96\x33\x23\x2e\xe6\xad\x5b\x5b\x30\x75\xe0\x2a\x84\x27\xa4\x49\x55\x85\xef\xf5\x4c\xa8\xd5\x2a\x8e\x1c\xd1\x7a\x42\x46\x8a\xcd\x5b\x73\x93\x19\xc1\x02\xc9\x26\x20\xc7\x74\x62\x80\xf1\xd4\x94\xf9\xa4\x3d\xfb\xf4\x76\x26\x74\xbe\x3f\xb0\xe5\x8e\x66\x6d\xd2\x98\xf5\xba\x97\xa0\x40\x09\x63\xca\x36\x5e\xa6\xc9\xd6\xd9\xc7\xe6\xe9\x67\x42\x58\x8a\x62\x0e\x5b\x3c\x07\x52\xeb\xff\xa3\x12\x18\x7e\xcf\x72\x70\x36\x68\xe3\xc5\x91\x96\xc7\xf6\x68\x85\x89\xd1\x0b\xda\x1b\x40\x87\xda\xb7\xdf\x32\xc3\xbb\xc2\xe3\x80\x24\x70\x2b\x47\x5f\x80\x64\xb7\x7b\xa4\xb5\x52\x34\x71\xba\x90\x43\x9d\xb2\xdb\x3e\x8c\x57\x7b\x18\xb6\x9c\xd4\x30\x24\x9f\x04\x5f\x13\x37\x3f\x82\xbc\x44\xe0\x34\x79\xad\xd5\x54\xcc\x4a\xc3\x50\x68\x15\x47\xd9\xab\x1e\xc0\x43\x05\x9a\x39\xd6\x1f\x2f\x5c\x76\x9b\xb2\x9b\x18\x5b\xd6\x0d\x6c\x1e\xfc\x8e\x26\xf7\x3f\xbc\x25\xa0\x78\xa1\x85\xc2\x38\xe2\x78\x0e\x82\x1f\x40\xfc\xf1\x0c\xd3\x7a\x54\xaa\x39\x9c\x27\xab\x49\x95\xb6\xa9\x11\x05\x26\xef\x3e\x11\x03\x3f\x95\xc2\x00\x27\xa8\x09\x07\x84\x14\x89\x13\xb7\x34\x32\x8e\xb6\x74\x7e\xb0\x6b\x62\xae\xd3\x32\x07\x85\xe1\xc2\x08\x84\x97\x2f\x15\x2c\xc8\x8f\x1f\xdf\xbf\xa4\x61\x18\x35\x7f\xac\x10\xd1\xbe\xfb\x23\x7a\x43\x16\x42\x71\xbd\x08\xa5\x4e\x6b\x07\x5e\x87\x2e\xd6\xae\xaf\xe3\xc8\x57\x88\x38\x3a\x6f\x83\x38\xe2\xfc\x02\x0f\x7e\xd0\x1c\x2e\xf4\xdc\x46\x51\x07\xe1\xe6\xf9\x45\xfc\x5f\x6b\x95\x96\xc6\x80\x4a\x97\x5f\x28\xc6\x67\x6d\x1e\xc1\xd8\x8b\x25\xb9\x47\x84\xbc\x70\x0b\xdb\x17\x89\xb1\x81\xb9\x58\x8e\xb7\x0a\xc1\xcc\x99\xfc\x42\x39\x36\x30\x17\xcb\xf1\x20\x72\xa8\xf7\xc6\x5f\x26\xac\xab\x6a\x21\x30\x23\x8d\xb0\x6b\x5e\x3d\x59\xc0\xf1\xd0\xd0\x83\xb2\xaa\x40\x5a\xf0\x84\xfc\xf7\x3f\xff\xe5\x03\x78\xb4\xed\x1f\xfe\x2e\x8d\x42\xf6\x54\xaf\x57\x60\x91\x58\xf1\xf3\xa5\x11\x39\xcc\xe8\x1f\xd8\xd3\xc7\x86\xe7\xff\xad\xdd\xdd\x9a\x21\xd4\x8c\x70\x61\x20\x45\x6d\x2e\x5d\x83\x86\x19\xde\x71\x7d\x23\x8c\xa7\x89\x62\x5b\x16\x89\x45\x86\x22\x8d\x23\x77\xed\x39\xca\xa5\x9c\x16\x97\x2e\xd7\xd2\x73\x30\x53\xa9\x17\xc1\xd3\x1d\x71\x67\x83\x3f\x91\x85\x76\xf9\x8d\x01\xf6\x78\x47\xea\x7f\x01\x93\xb2\x5e\x3c\xf6\x33\xd1\xd3\x3a\x0d\x70\x74\x2c\x12\xbe\x54\x2c\x77\x4a\x74\xa4\xd4\x1d\xd8\xcf\xe0\xf3\xfa\x94\xa1\x0d\x79\x09\x3f\x91\xdd\x5e\x45\xe8\x44\x28\x7a\x7d\xf4\x34\x9d\x09\x7a\xed\xa1\x4e\xcf\x3e\x96\xe7\x4c\xf1\xf3\xf3\x87\x9c\x5b\xb8\xd7\x48\x3e\xeb\x76\xaf\x34\x9f\x32\x90\x1e\x1b\xc8\x59\x59\x6a\x1c\x1f\x49\xce\xf9\x2b\x8e\xb8\xec\x3b\x62\xed\x1d\x95\xf6\x5e\x79\x27\xc8\xdf\xa8\xb9\x30\x5a\xb9\xe4\xec\xf9\xd2\xe3\xbd\x98\x6d\x71\x38\x37\x2d\x5b\x6c\x90\x4d\x24\x04\x06\x6c\xa1\x95\x75\xa7\x1f\x0f\x7f\xd4\x63\xf6\x00\x48\x03\x33\xd1\x86\x83\x91\x60\xed\xfa\x81\x45\x23\x0a\xe8\x3a\xca\x74\x03\xef\xca\x31\xe7\x69\x8d\x1f\xe1\x1a\x38\x71\xc9\x6e\x1c\x61\x36\x6c\xd4\xdf\x98\x2c\x07\x0c\x8b\x23\x5f\xb1\x1c\xe6\x00\x65\x9b\x12\x91\x0f\x6d\x55\x19\xa6\x66\x40\xae\x1e\x6f\xae\xe6\xe4\x6e\x4c\x7c\x76\xc4\x1d\xa3\x01\x56\x6d\x06\x78\xaa\xb0\x37\xa8\x30\x90\x54\xd5\xd5\xa3\x8b\x5b\x77\x3d\x8c\x65\x34\x94\xa7\x13\xb2\xaa\xae\xe6\x8e\xdd\x90\xb1\xfe\xde\xf4\xd9\x0c\x5a\xa8\x7e\xde\x8c\xa3\x3a\x88\xce\x1e\xaa\xfa\x16\x27\xe2\xbb\x03\x2a\x4d\xd2\xd2\xa2\xce\xc9\x9c\x19\xe1\x78\x5a\xc2\x61\x2a\x14\xf0\x53\xc0\xbd\x1a\x9f\x5a\x30\x27\x26\xfa\xd2\xa5\x74\x53\x93\x7b\xe6\x5a\x43\xbd\x15\x2b\x8d\xe4\x6a\xbd\xb3\x40\x5a\x9a\xde\xba\xdf\xe6\xa7\xb4\xcb\x57\x76\xf2\xf8\x18\xee\xbc\x47\xf6\x16\xf6\x3d\x7d\xbd\x76\xff\x01\x45\x93\x1d\x47\x31\x25\xe1\xbb\xcf\x0f\xe1\x37\xca\xcd\x80\x21\x8b\x46\xd7\xfe\xfe\xee\xf3\x83\xdf\xee\xbe\x43\xe9\xd8\xe5\x85\x1a\x16\xe8\x75\x11\xa2\xaa\x6a\x3d\xbe\x05\xfc\x0e\x18\x07\xe3\xc2\xde\xbf\x42\xb3\xf9\x65\xf5\xd8\x01\x6b\x85\x4f\x2a\x44\x06\xae\x15\x8d\x57\xfe\x5a\x82\x59\x3e\xe8\x47\x50\xcf\xe4\x9c\x1a\x90\xa0\x43\xfc\x0d\x9d\xd4\x52\xeb\x5b\xc0\x1f\x98\x61\xf9\x65\xae\x2a\xdc\xd0\xff\x0a\x4f\x35\x13\xee\x39\x5d\xd5\x20\xfe\xe6\xbe\x6a\x2b\xf6\xbf\x13\x58\x7f\x66\x56\xa4\xcf\xe4\xa8\x1a\xeb\x19\x3c\x54\x55\x6b\xb1\xea\xae\x8b\x25\xff\x20\x7f\xd7\x42\x11\x7a\x43\xa8\xef\x81\x8b\x0c\x30\x46\xff\xb1\xc7\x17\xe9\x82\x4c\xa0\xe3\xf1\x61\x3f\x6a\x77\xdb\xbe\xdc\x66\x0f\x17\x37\x59\xa6\xda\xe4\x24\x07\xcc\x34\x1f\xd3\x42\xdb\xae\x8c\xc0\xa3\x13\xd3\x45\x76\xaa\x1b\x43\xfa\x3b\x32\x0f\x66\xd9\xdf\x81\xe9\xe4\x73\x26\x91\xa9\xc7\x38\x1a\x66\x60\xdb\x6f\x74\x7a\x07\xa9\x56\x68\xb4\xa4\xeb\x5e\x76\x2d\x2f\x29\x24\x4b\x21\xd3\x92\x83\x19\xd3\x4d\x89\xaf\x60\x4b\xa9\x19\xa7\x49\x1c\x6d\x90\x4e\x08\x78\x3a\x07\xed\xcf\xf9\x9a\xb7\x25\xa2\xde\xf6\x1e\x27\xa8\xc8\x04\x55\x50\x18\x91\x33\xb3\xa4\x04\x97\x05\x8c\xa9\x2d\x27\xb9\x40\x9a\x58\x50\x3c\x8e\x9a\x21\x83\x4e\xeb\x9d\x53\xce\x19\xe5\x57\x98\x73\xbf\x4a\x63\xef\x3d\xb3\x48\x6e\x47\x9b\x22\xad\x3d\xd1\xd5\x1b\xdc\x84\xbb\xb8\x5c\xf0\x8b\x94\x0a\x7c\xcb\x04\xde\x87\x59\x77\xd0\x7f\xfb\x66\xc0\x29\x1f\xb3\xba\xf7\x30\x6c\xc4\x6b\x9d\x17\x12\x70\xe0\xa8\x5d\xcf\xc7\x67\x94\xdf\x89\xd5\xbb\xf6\xe0\x5b\x77\xd8\xd6\x1c\xc2\xef\x84\x45\x6d\x96\xe4\x76\xe4\x7b\x1a\x1e\x56\xc7\x19\x7a\xf2\xdf\x7c\x35\xb0\x8e\x8a\xa8\xaa\xc2\xb7\x6f\x56\xab\xa8\xde\x67\xdd\x55\xef\x87\x15\x9d\x70\xc3\xca\x07\x75\xd9\x21\xfc\x00\xc8\xc2\xd7\x06\x18\x02\xbf\xc7\xf0\x2f\xda\xe4\x0c\x09\x1d\x7d\x4d\xde\x31\x45\x46\xaf\xc8\x57\xb7\x77\xa3\xdf\xdf\x8d\x6e\xc3\xd1\x68\x44\x3e\x7c\x7a\xa0\x83\xeb\x14\x43\xcd\xd2\x64\x3f\x8d\x60\xeb\x59\x39\x20\xfd\xd9\xa1\xec\x43\xf8\x2a\x37\x50\xd4\x01\x25\xfc\xf6\x4f\x28\x52\x18\x3d\x33\x60\xed\x50\x86\xde\x59\x24\xb9\x70\x4e\x48\x50\x6b\xf3\xb7\x7b\xb1\xbe\x38\x7e\x41\xee\x9f\x00\x7a\x04\xf9\xd9\x52\xd4\xa9\x92\xcf\xf3\xe5\x80\x9b\x7f\x52\xa8\x47\x62\x40\x8e\x69\xdd\x3e\xb2\x19\x00\x1e\x7d\x48\xd5\x34\xa4\x28\xa1\xa9\xb5\x94\xd0\x89\xd6\x68\xd1\xb0\x22\xc8\x19\x82\x11\x4c\x06\x1c\xac\x98\xa9\x30\x17\x2a\x74\x34\xab\x15\x4d\x5e\xbc\x88\xa3\xf5\xe7\x78\x51\x86\xb9\x4c\xfe\x13\x00\x00\xff\xff\x8e\x1b\xc0\x5a\x33\x28\x00\x00") +var _unitInfoHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xe4\x5a\x6d\x8f\xdb\xb8\xf1\x7f\x9f\x4f\x31\x20\xf2\x22\x01\x22\x69\xef\xfe\xff\x0d\xda\x54\x16\xb0\xdd\x5c\x73\x1b\x24\xc1\x35\xd9\x6b\x5e\xd3\xd2\xd8\x62\x97\x22\x75\xe4\xc8\x5e\x9f\xea\xf7\xfd\x14\xfd\x70\xfd\x24\x05\x25\xcb\x4f\x2b\xdb\x94\x77\x9b\x2b\x5a\x63\x81\xd5\xc3\xcc\x6f\x66\x38\x24\xe7\x81\x8a\x73\x2a\x24\x48\xae\xa6\x23\x86\x8a\x25\xcf\xe2\x1c\x79\x96\x3c\x03\x00\x88\x0b\x24\x0e\x69\xce\x8d\x45\x1a\xb1\x8a\x26\xc1\xef\xd8\xf6\x2b\xc5\x0b\x1c\xb1\x99\xc0\x79\xa9\x0d\x31\x48\xb5\x22\x54\x34\x62\x73\x91\x51\x3e\xca\x70\x26\x52\x0c\x9a\x9b\x57\x20\x94\x20\xc1\x65\x60\x53\x2e\x71\xf4\xdd\x2b\xb0\xb9\x11\xea\x2e\x20\x1d\x4c\x04\x8d\x94\x76\xc2\xa3\x56\x7a\x3c\xd6\xd9\x22\x79\x16\x67\x62\x06\xa9\xe4\xd6\x8e\x98\xc3\xe6\x42\xa1\xe9\x34\x50\x7c\xfd\x4e\xf1\xd9\x98\x1b\x68\xff\x05\x78\x5f\x72\x95\x05\xb6\xe8\x1e\x48\x31\xcd\x09\xc6\xd3\xf6\x62\xc5\xdf\x60\xf0\x5d\x84\x60\x6c\xb8\xca\x18\xe4\x06\x27\x23\x56\xd7\xe1\x67\x94\xc0\x22\xb6\x5c\xb2\xe4\x13\x57\x3a\xf8\x5c\xa9\x38\xe2\x5b\x00\x3b\x0a\x4a\xc9\x4b\x8b\x9d\xd4\xee\x7e\x4b\x5e\xc3\x52\xc9\x3d\xa1\xce\x90\xc2\x04\xbc\x22\xbd\x47\xdb\xd0\x4b\xb1\x45\x1f\x08\xc2\xa2\x87\xea\x81\x35\x81\x14\xea\xee\x81\x25\x95\x12\xd4\x9a\x73\x25\x25\xb8\x3b\xbb\x63\xcf\x1a\x2a\x92\xe2\xe1\xd3\xba\x16\x13\x08\xaf\x2a\xca\xb5\x11\xbf\x62\xb6\x5c\xf6\xeb\xe1\xad\xb1\xa7\xd6\xbc\xa2\x3c\x92\x7a\xaa\x2b\x6a\x74\xff\xd0\x5c\xf6\x2a\x7e\x4c\x79\x54\xfb\x1a\xc7\x51\x25\xb7\x9c\x19\x65\x62\xb6\x75\x6b\x4b\xae\xf6\x5c\x45\x78\x4f\x2c\xa9\xeb\xf0\x83\x9e\x0a\xb5\x5c\xc6\x91\x23\x5a\x4d\xc8\x48\xf1\xd9\xd6\xdc\xe4\x46\xf0\x40\xf2\x31\xca\x11\x1b\x1b\xe4\x59\x6a\xaa\x62\xbc\x3d\xfb\xf4\x7a\x26\xf4\xbe\xdf\x1b\xcb\x0d\xcd\x6a\x48\x63\x7e\xd0\xbd\x40\x82\x24\x8e\x18\xef\xbc\xcc\x92\xb5\xb3\x1f\x0e\xcf\x61\x21\xc0\x53\x12\x33\x5c\xe3\x39\x90\xc6\xfe\x9f\x95\xa0\xf0\x13\x2f\xd0\x8d\xc1\x36\x5e\x1c\x69\xf9\x70\x3c\xb6\x96\x89\xd1\x73\x76\x70\x01\xed\x5b\xbf\xfd\x96\x9b\xac\x6f\x79\xec\x91\x04\x6e\xe7\x38\xb4\x40\xf2\xcb\x1d\xd2\xc6\x28\x96\x38\x5b\x60\xdf\xa6\xfc\xf2\x10\xc6\xeb\x1d\x0c\x5b\x8d\x1b\x18\x28\xc6\xc1\xf7\xe0\xe6\x47\x50\x54\x84\x19\x4b\xae\xb5\x9a\x88\x69\x65\x38\x09\xad\xe2\x28\x7f\x7d\x00\x70\xdf\x80\x76\x8e\x1d\x5e\x2f\x99\xec\x1f\xca\x7e\x62\xda\x1a\xdd\xc0\x16\xc1\xff\xb1\xe4\xea\xa7\x1b\x40\x95\x95\x5a\x28\x8a\xa3\x8c\x4e\x41\x64\x7b\x10\xbf\x3f\x21\xb4\xe1\x4a\x75\x86\xa7\xc9\x1a\x52\xa5\x6d\x6a\x44\x49\xc9\xfb\x2f\x60\xf0\x97\x4a\x18\xcc\x80\x34\x64\x48\x98\x12\x38\x75\x2b\x23\xe3\x68\x4d\xe7\x07\xbb\x22\xce\x74\x5a\x15\xa8\x28\x9c\x1b\x41\xf8\xe2\x85\xc2\x39\xfc\xfc\xf9\xc3\x0b\x16\x86\x51\xfb\xc7\x4b\x11\xed\xba\x3f\x62\xaf\x60\x2e\x54\xa6\xe7\xa1\xd4\x69\xe3\xc0\x97\xa1\x5b\x6b\x2f\x5f\xc6\x91\xaf\x12\x71\x74\x7a\x0c\xe2\x28\xcb\xce\xf0\xe0\x47\x9d\xe1\x99\x9e\xeb\x0c\x75\x10\x6e\x9e\x9f\x25\xff\x5a\xab\xb4\x32\x06\x55\xba\x78\xa4\x1a\x5f\xb5\xb9\x43\x63\xcf\xd6\xe4\x8a\x08\x8b\xd2\x6d\x6c\x8f\x52\xa3\x83\x39\x5b\x8f\x1b\x45\x68\x66\x5c\x3e\x52\x8f\x0e\xc6\x47\x8f\x26\x1a\xe3\x2f\xb0\xf1\x27\xb0\xb1\x50\xec\x40\x54\x3e\x65\x42\xb7\xc5\xdf\x8a\x02\x75\x45\xc0\x27\x84\x06\xe6\xb9\x48\x73\x28\x8d\x4e\xd1\x5a\x98\x0b\x29\x61\x8c\x60\x51\x11\x4b\x56\x94\xa7\x4d\x3e\x68\xb6\xd7\x42\xae\xeb\xb9\xa0\x7c\x65\xe6\x4a\xa6\x87\x8d\x1b\xf6\xd0\x93\xba\xae\x51\x5a\x1c\x00\xfd\xcf\xbf\xff\xc3\x17\xf8\x41\xea\xd1\xf7\x3b\xed\x73\x38\xc3\x79\x5f\x6e\xde\xdd\x7c\xba\xdd\xf3\xdd\x3b\xc3\x53\x9c\x54\x12\xa8\xe5\xf0\xd1\xed\xdb\x79\xb9\xd3\xee\x7f\xdc\xdb\x3e\x48\xfd\xf1\x81\xdf\x37\x91\x14\x2d\x81\x15\xbf\x9e\x1b\x2b\x4e\x9a\xb0\xe3\xb4\x8f\xfc\xfe\x73\x2b\xd3\xdb\x03\x3e\xbe\x1a\xe4\x27\x1f\x1f\x79\x8d\xea\x79\x51\xc0\x45\x33\xa1\xa6\x90\x09\x83\x29\x69\x73\x6e\x74\x1c\x36\xf0\x4e\xea\x5b\x61\x3c\x87\x28\xb6\x55\x99\x58\xe2\x24\xd2\x38\x72\xd7\x9e\x5c\xae\x18\xb2\xb4\x70\xbb\x8c\x9e\xa1\x99\x48\x3d\x0f\xee\xdf\x80\xab\x5a\xff\x00\x73\xed\x32\x6f\x83\xfc\xee\x0d\x34\xff\x02\x2e\x65\x13\xd6\x76\x6b\xa4\xe3\x36\x0d\x70\x74\x2c\x92\x6c\xa1\x78\xe1\x8c\xe8\x29\xf6\x7a\xb0\x9f\xc0\xe7\x4d\xc4\xd5\x06\x5e\xf4\x44\xdd\x97\x0f\x9e\xa6\x53\xc1\x5e\x9e\x19\x8c\x93\x6b\x5d\x14\x5c\x65\x8f\xd8\x75\xbb\x94\x62\x85\xe4\x93\x51\x1c\xd4\xe6\x4b\x8e\xd2\x23\xb5\x39\xa9\x4b\x83\xe3\x97\xdb\x1c\xf7\x57\x1c\x65\xf2\x50\xf1\xbf\x53\xc4\xef\xbc\xf2\x2e\xdd\x7e\x50\x33\x61\xb4\x72\x65\xc3\xd3\x15\x6e\x3b\x6b\x76\x4b\xc2\xc9\x0d\x7e\x23\x86\xf8\x58\x62\x60\xd0\x96\x5a\x59\x57\x97\x7b\xf8\xa3\xe1\xd9\x01\x80\x16\x66\xac\x4d\x86\x46\xba\xbc\xae\x7d\x60\xc9\x88\x12\xfb\x8a\xec\x7e\xe0\x4d\xa3\xf0\x34\xad\xf1\x23\x5c\x01\x27\xae\x0c\x8b\x23\xca\x87\x71\xfd\x85\xcb\x6a\x00\x5b\x1c\xf9\xaa\xe5\x30\x07\x18\xdb\x36\x2f\x7d\x68\xeb\xda\x70\x35\x45\x78\x7e\xf7\xea\xf9\x0c\xde\x8c\xc0\x37\x7b\x81\xa1\xa3\xda\x32\x78\x9a\xb0\xc3\x54\x1a\x4c\xea\xfa\xf9\x9d\x5b\xb7\xee\x7a\x98\xc8\x68\xa8\x4c\xa7\x64\x5d\x3f\x9f\x39\x71\x43\x78\xfd\xbd\xe9\x9b\xa0\xad\x50\xfd\xbc\x19\x47\xcd\x22\x3a\x59\xee\x1f\xda\x9c\xc0\x37\x02\x2a\x0d\x69\x65\x49\x17\x30\xe3\x46\x38\x99\x16\x32\x9c\x08\x85\xd9\x31\xe0\x83\x16\x1f\xdb\x30\xc7\x26\x7a\xec\x56\xda\x75\x8b\x9f\xb8\x0b\xd6\x84\x62\xa5\x09\x9e\xaf\x22\x0b\xa6\x95\x39\xd8\x91\xee\x7e\x4a\xbb\x7c\x65\xa3\x8f\xcf\xc0\x9d\xf6\xc8\xce\xc6\xbe\x63\xaf\x57\xf4\x1f\xd0\xce\xdb\x48\x14\x13\x08\xdf\x7f\xbd\x0d\x7f\x50\x6e\x06\x0c\xd9\x34\xfa\xe2\xfb\xfb\xaf\xb7\x7e\xd1\x7d\x83\xd2\x13\xe5\x85\x1a\xb6\xd0\x9b\xf6\x58\x5d\x37\x76\xbc\x43\xfa\x11\x79\x86\xc6\x2d\x7b\xff\xde\x61\xf7\xcb\x1b\xde\x01\x7b\x85\x4f\x2a\x04\x03\xf7\x8a\xd6\x2b\x7f\xae\xd0\x2c\x6e\xf5\x1d\xaa\x27\x72\x4e\x03\x08\xe4\x10\x7f\x43\x27\x6d\x99\xf5\x0e\xe9\x27\x6e\x78\x71\x9e\xab\x4a\xc7\xfa\x1f\xe1\xa9\x76\xc2\x3d\xa5\xab\x5a\xc4\xdf\xdc\x57\xdb\x86\xfd\xf7\x2c\xac\x3f\x72\x2b\xd2\x27\x72\x54\x83\xf5\x04\x1e\xaa\xeb\x95\x5a\xcd\x79\xa0\x85\xbf\xc1\x5f\xb5\x50\xc0\x5e\x01\xf3\x2d\xb8\x60\x58\xcb\xe8\x40\xd9\xe3\x8b\x74\x46\x26\xd0\xf3\x78\xff\xa4\x74\x73\xbb\x7d\xb9\xce\x1e\xce\x3e\xfe\x9b\x68\x53\x40\x81\x94\xeb\x6c\xc4\x4a\x6d\xfb\x32\x02\x8f\x33\xc2\x3e\xb2\x63\xe7\x84\x70\xf8\xac\xf0\xd6\x2c\x0e\x9f\x0d\xf6\xca\x39\x91\xc8\x34\x3c\x8e\x86\x1b\x5c\x9f\x84\x3b\xbb\x83\x54\x2b\x32\x5a\xb2\xd5\x57\x16\x8d\xbe\x50\x4a\x9e\x62\xae\x65\x86\x66\xc4\xba\x16\x5f\xc9\x17\x52\xf3\x8c\x25\x71\xd4\x21\x1d\x51\xf0\x78\x0e\x7a\x38\xe7\x6b\xdf\x56\x44\x7a\x7d\x2a\x3e\x26\x05\x63\x52\x41\x69\x44\xc1\xcd\x82\x01\x2d\x4a\x1c\x31\x5b\x8d\x0b\x41\x2c\xb1\xa8\xb2\x38\x6a\x59\x06\x55\xeb\xbd\x53\xce\x0d\xca\x37\x98\x73\xdf\xe4\xc8\xf9\x03\xb7\x04\x97\x17\x5d\x93\xd6\x1e\x39\x6f\x1e\x7c\x3c\x7c\x76\xbb\xe0\xdf\xd2\x2a\xf0\x6d\x13\x78\x17\xb3\xae\xd0\xbf\x79\x3b\xa0\xca\xa7\xbc\x39\xa9\x1a\xc6\x71\xad\x8b\x52\x22\x0d\xe4\xda\x9c\x46\xfa\x70\xf9\x55\xac\xde\xbd\x07\xdf\xbe\xc3\xba\xe7\x10\xfe\x28\x2c\x69\xb3\x80\xcb\x0b\xdf\x6a\x78\x58\x1f\x67\x68\xe5\xdf\x7d\xcf\xb2\x5a\x15\x51\x5d\x87\x37\x6f\x97\xcb\xa8\x89\xb3\xee\xea\xe0\x27\x3f\xbd\x70\xc3\xda\x07\x4d\xdb\x21\xfc\x88\xc4\xc3\x6b\x83\x9c\x30\xbb\xa2\xf0\x4f\xda\x14\x9c\x80\x5d\x7c\x0f\xef\xb9\x82\x8b\xd7\xf0\xdd\xe5\x9b\x8b\xff\x7f\x73\x71\x19\x5e\x5c\x5c\xc0\xc7\x2f\xb7\x6c\x70\x9f\x62\xe8\xb0\xb4\xd9\x4f\xab\xd8\x6a\x56\x0e\x48\x7f\x36\x28\xbb\x10\xbe\xc6\x0d\x54\x75\xe0\x99\x5a\xf7\x13\x0a\x4a\xa3\xa7\x06\xad\x1d\x2a\xd0\x3b\x8b\x84\x33\xe7\x84\x44\xb5\x1a\xfe\xed\xaf\x04\x7c\x71\xfc\x16\xb9\x7f\x02\xe8\xb1\xc8\x4f\xb6\xa2\x8e\xb5\x7c\x9e\x2e\x07\xec\xfe\x49\xa1\xee\xc0\xa0\x1c\xb1\xe6\xf8\xc8\xe6\x88\xf4\xe0\x13\xbf\xf6\x40\x8a\x01\x4b\xad\x65\xc0\xc6\x5a\x93\x25\xc3\xcb\xa0\xe0\x84\x46\x70\x19\x64\x68\xc5\x54\x85\x85\x50\xa1\xa3\x59\x2e\x59\xf2\xec\x59\x1c\xad\x3e\x14\x8d\x72\x2a\x64\xf2\xaf\x00\x00\x00\xff\xff\x64\x50\x73\x17\xcd\x2a\x00\x00") func unitInfoHtmlBytes() ([]byte, error) { return bindataRead( diff --git a/server/unit.go b/server/unit.go index 26dcff6..6a22e20 100644 --- a/server/unit.go +++ b/server/unit.go @@ -26,17 +26,18 @@ import ( ) type Unit struct { - Interval time.Duration `yaml:"interval,omitempty"` // interval between attempts - Attempts int `yaml:"attempts,omitempty"` // maximum number of attempts - Workers int `yaml:"workers,omitempty"` // concurrency level - number of parallel requests - Mode string `yaml:"mode,omitempty"` // execution mode: bin, cgi or proxy - WorkDir string `yaml:"workdir,omitempty"` // working directory for the worker. if empty - temporary one will generated automatically - Command string `yaml:"command"` // command in a shell to execute - Timeout time.Duration `yaml:"timeout,omitempty"` // maximum execution timeout (enabled only for bin mode and only if positive) - Shell string `yaml:"shell,omitempty"` // shell to execute command in bin mode (default - /bin/sh) - Environment map[string]string `yaml:"environment,omitempty"` // custom environment for executable (in addition to system) - MaxRequest int64 `yaml:"max_request,omitempty"` // optional maximum HTTP body size (enabled if positive) - Authorization struct { + Interval time.Duration `yaml:"interval,omitempty"` // interval between attempts + Attempts int `yaml:"attempts,omitempty"` // maximum number of attempts + Workers int `yaml:"workers,omitempty"` // concurrency level - number of parallel requests + Mode string `yaml:"mode,omitempty"` // execution mode: bin, cgi or proxy + WorkDir string `yaml:"workdir,omitempty"` // working directory for the worker. if empty - temporary one will generated automatically + Command string `yaml:"command"` // command in a shell to execute + Timeout time.Duration `yaml:"timeout,omitempty"` // maximum execution timeout (enabled only for bin mode and only if positive) + GracefulTimeout time.Duration `yaml:"graceful_timeout,omitempty"` // maximum execution timeout after which SIGINT will be sent (enabled only for bin mode and only if positive) + Shell string `yaml:"shell,omitempty"` // shell to execute command in bin mode (default - /bin/sh) + Environment map[string]string `yaml:"environment,omitempty"` // custom environment for executable (in addition to system) + MaxRequest int64 `yaml:"max_request,omitempty"` // optional maximum HTTP body size (enabled if positive) + Authorization struct { JWT struct { Enable bool `yaml:"enable"` // enable JWT verification JWT `yaml:",inline"` @@ -242,11 +243,12 @@ func (cfg Unit) createRunner() (http.Handler, error) { switch cfg.Mode { case "bin": return &binHandler{ - command: cfg.Command, - workDir: cfg.WorkDir, - shell: cfg.Shell, - timeout: cfg.Timeout, - environment: append(os.Environ(), makeEnvList(cfg.Environment)...), + command: cfg.Command, + workDir: cfg.WorkDir, + shell: cfg.Shell, + timeout: cfg.Timeout, + gracefulTimeout: cfg.GracefulTimeout, + environment: append(os.Environ(), makeEnvList(cfg.Environment)...), }, nil case "cgi": return &cgi.Handler{ diff --git a/templates/unit-info.html b/templates/unit-info.html index 9760a83..c3c4a7f 100644 --- a/templates/unit-info.html +++ b/templates/unit-info.html @@ -50,14 +50,25 @@
{{.Unit.Attempts}}
Interval
{{.Unit.Interval}}
-
Timeout
-
- {{with .Unit.Timeout}} - {{.}} - {{else}} - ∞ - {{end}} -
+ {{if eq .Unit.Mode "bin"}} +
Timeout
+
+ {{with .Unit.Timeout}} + {{.}} + {{else}} + ∞ + {{end}} +
+
Graceful timeout +
+
+ {{with .Unit.GracefulTimeout}} + {{.}} + {{else}} + ∞ + {{end}} +
+ {{end}}
Max request size
{{with .Unit.MaxRequest}}