From 86289655214ba92f059f573b7722caa7bf4fa15e Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Tue, 7 Jan 2020 16:21:45 +0300 Subject: [PATCH 1/3] Add signal action --- COOKBOOK.md | 32 +++++++++++ action/system.go | 113 +++++++++++++++++++++++++++++++++------ cli/executor/executor.go | 2 + recipe/tokens.go | 2 + 4 files changed, 132 insertions(+), 17 deletions(-) diff --git a/COOKBOOK.md b/COOKBOOK.md index f7c88181..58f9f5a0 100644 --- a/COOKBOOK.md +++ b/COOKBOOK.md @@ -49,6 +49,7 @@ * [`wait-fs`](#wait-fs) * [`connect`](#connect) * [`app`](#app) + * [`signal`](#signal) * [`env`](#env) * [`env-set`](#env-set) * [Users/Groups](#users-groups) @@ -1065,6 +1066,37 @@ command "-" "Check environment"
+##### `signal` + +Sends signal to process. + +If `pid-file` not defined signal will be sent to current process. + +**Syntax:** `signal ` + +**Arguments:** + +* `sig` - Signal name or code (_String_ or _Number_) +* `pid-file` - Path to PID file (_String_) [Optional] + +**Negative form:** No + +**Example:** + +```yang +command "myapp --daemon" "Check my app" + signal HUP + +``` + +```yang +command "myapp --daemon" "Check my app" + signal 16 + +``` + +
+ ##### `env` Checks environment variable value. diff --git a/action/system.go b/action/system.go index 197d331e..654ac527 100644 --- a/action/system.go +++ b/action/system.go @@ -9,21 +9,30 @@ package action import ( "fmt" - "io/ioutil" "net" "os" + "os/exec" + "strconv" "strings" + "syscall" "time" "pkg.re/essentialkaos/ek.v11/env" "pkg.re/essentialkaos/ek.v11/fsutil" "pkg.re/essentialkaos/ek.v11/mathutil" + "pkg.re/essentialkaos/ek.v11/pid" + "pkg.re/essentialkaos/ek.v11/signal" "github.com/essentialkaos/bibop/recipe" ) // ////////////////////////////////////////////////////////////////////////////////// // +// ErrCantReadPIDFile is returned if PID can't be read +var ErrCantReadPIDFile = fmt.Errorf("Can't read PID from PID file") + +// ////////////////////////////////////////////////////////////////////////////////// // + // ProcessWorks is action processor for "process-works" func ProcessWorks(action *recipe.Action) error { pidFile, err := action.GetS(0) @@ -32,19 +41,19 @@ func ProcessWorks(action *recipe.Action) error { return err } - pid, err := readPID(pidFile) + ppid := pid.Read(pidFile) - if err != nil { - return err + if ppid == -1 { + return ErrCantReadPIDFile } - isWorks := fsutil.IsExist("/proc/" + pid) + isWorks := fsutil.IsExist("/proc/" + strconv.Itoa(ppid)) switch { case !action.Negative && !isWorks: - return fmt.Errorf("Process with PID %s from PID file %s doesn't exist", pid, pidFile) + return fmt.Errorf("Process with PID %d from PID file %s doesn't exist", ppid, pidFile) case action.Negative && isWorks: - return fmt.Errorf("Process with PID %s from PID file %s exists", pid, pidFile) + return fmt.Errorf("Process with PID %d from PID file %s exists", ppid, pidFile) } return err @@ -77,13 +86,13 @@ func WaitPID(action *recipe.Action) error { for range time.NewTicker(25 * time.Millisecond).C { switch { case !action.Negative && fsutil.IsExist(pidFile): - pid, err := readPID(pidFile) + ppid := pid.Read(pidFile) - if err != nil { - return err + if ppid == -1 { + return ErrCantReadPIDFile } - if fsutil.IsExist("/proc/" + pid) { + if fsutil.IsExist("/proc/" + strconv.Itoa(ppid)) { return nil } case action.Negative && !fsutil.IsExist(pidFile): @@ -196,6 +205,39 @@ func App(action *recipe.Action) error { return nil } +// Signal is action processor for "signal" +func Signal(action *recipe.Action, cmd *exec.Cmd) error { + var sig syscall.Signal + var sigVal, pidFile string + var err error + + sigVal, err = action.GetS(0) + + if err != nil { + return err + } + + if action.Has(1) { + pidFile, err = action.GetS(1) + + if err != nil { + return err + } + } + + sig, err = parseSignal(sigVal) + + if err != nil { + return err + } + + if pidFile != "" { + return sendSignalToPID(sig, pidFile) + } + + return sendSignalToCmd(sig, cmd) +} + // Env is action processor for "env" func Env(action *recipe.Action) error { name, err := action.GetS(0) @@ -247,13 +289,50 @@ func EnvSet(action *recipe.Action) error { // ////////////////////////////////////////////////////////////////////////////////// // -// readPID reads PID from PID file -func readPID(file string) (string, error) { - pidFileData, err := ioutil.ReadFile(file) +// isNumber returns true if given value is number +func isNumber(v string) bool { + if len(v) != 0 && strings.Trim(v, "0123456789") == "" { + return true + } - if err != nil { - return "", fmt.Errorf("Can't read PID file %s: %v", file, err) + return false +} + +// parseSignal parses signal definition +func parseSignal(v string) (syscall.Signal, error) { + if isNumber(v) { + sigCode, err := strconv.Atoi(v) + + if err != nil { + return syscall.Signal(-1), err + } + + return signal.GetByCode(sigCode) + } + + return signal.GetByName(v) +} + +// sendSignalToCmd sends signal to PID from command +func sendSignalToCmd(sig syscall.Signal, cmd *exec.Cmd) error { + if cmd.Process == nil { + return fmt.Errorf("Can't find process PID (process already dead?)") + } + + if cmd.ProcessState.Exited() { + return fmt.Errorf("Can't send signal - process already dead") + } + + return signal.Send(cmd.ProcessState.Pid(), sig) +} + +// sendSignalToPID sends signal to PID from PID file +func sendSignalToPID(sig syscall.Signal, pidFile string) error { + ppid := pid.Read(pidFile) + + if ppid == -1 { + return ErrCantReadPIDFile } - return strings.TrimRight(string(pidFileData), " \n\r"), nil + return signal.Send(ppid, sig) } diff --git a/cli/executor/executor.go b/cli/executor/executor.go index 99eed65d..bf3cfc01 100644 --- a/cli/executor/executor.go +++ b/cli/executor/executor.go @@ -417,6 +417,8 @@ func runAction(a *recipe.Action, cmd *exec.Cmd, input io.Writer, outputStore *ou return action.Backup(a, tmpDir) case recipe.ACTION_BACKUP_RESTORE: return action.BackupRestore(a, tmpDir) + case recipe.ACTION_SIGNAL: + return action.Signal(a, cmd) } handler, ok := handlers[a.Name] diff --git a/recipe/tokens.go b/recipe/tokens.go index 8000b018..99c5523d 100644 --- a/recipe/tokens.go +++ b/recipe/tokens.go @@ -57,6 +57,7 @@ const ( ACTION_WAIT_FS = "wait-fs" ACTION_CONNECT = "connect" ACTION_APP = "app" + ACTION_SIGNAL = "signal" ACTION_ENV = "env" ACTION_ENV_SET = "env-set" @@ -151,6 +152,7 @@ var Tokens = []TokenInfo{ {ACTION_WAIT_FS, 1, 2, false, true}, {ACTION_CONNECT, 2, 2, false, true}, {ACTION_APP, 1, 1, false, true}, + {ACTION_SIGNAL, 1, 2, false, false}, {ACTION_ENV, 2, 2, false, true}, {ACTION_ENV_SET, 2, 2, false, false}, From 249790d783d7f945326d99fe35493dadb50e4a2a Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Tue, 7 Jan 2020 16:23:38 +0300 Subject: [PATCH 2/3] Version bump --- cli/cli.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cli.go b/cli/cli.go index fe0bc5a4..590c2a99 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -33,7 +33,7 @@ import ( // Application info const ( APP = "bibop" - VER = "1.7.0" + VER = "1.8.0" DESC = "Utility for testing command-line tools" ) From 8461200cbef88379ce8242cedc9557c5486d72e5 Mon Sep 17 00:00:00 2001 From: Anton Novojilov Date: Tue, 7 Jan 2020 16:23:52 +0300 Subject: [PATCH 3/3] Update copyright header --- action/auxi.go | 2 +- action/backup.go | 2 +- action/common.go | 2 +- action/fs.go | 2 +- action/http.go | 2 +- action/io.go | 2 +- action/libs.go | 2 +- action/python.go | 2 +- action/service.go | 2 +- action/system.go | 2 +- action/users.go | 2 +- bibop.go | 2 +- cli/cli.go | 2 +- cli/executor/executor.go | 2 +- cli/executor/validators.go | 2 +- output/output_store.go | 2 +- parser/fuzz.go | 2 +- parser/parser.go | 2 +- parser/parser_test.go | 2 +- recipe/recipe.go | 2 +- recipe/recipe_test.go | 2 +- recipe/runtime_variables.go | 2 +- recipe/tokens.go | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/action/auxi.go b/action/auxi.go index 649f49bb..1dcc1747 100644 --- a/action/auxi.go +++ b/action/auxi.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/backup.go b/action/backup.go index e36b9b60..b01230ab 100644 --- a/action/backup.go +++ b/action/backup.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/common.go b/action/common.go index df760f1b..7b411463 100644 --- a/action/common.go +++ b/action/common.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/fs.go b/action/fs.go index 74b82ff4..7c353b35 100644 --- a/action/fs.go +++ b/action/fs.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/http.go b/action/http.go index 96c31365..66f6c6e4 100644 --- a/action/http.go +++ b/action/http.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/io.go b/action/io.go index 090e2afa..9bc4e855 100644 --- a/action/io.go +++ b/action/io.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/libs.go b/action/libs.go index 0dbfcc93..2176880a 100644 --- a/action/libs.go +++ b/action/libs.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/python.go b/action/python.go index 77ca1234..7637ece5 100644 --- a/action/python.go +++ b/action/python.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/service.go b/action/service.go index 08c57096..593778c0 100644 --- a/action/service.go +++ b/action/service.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/system.go b/action/system.go index 654ac527..e22d0c39 100644 --- a/action/system.go +++ b/action/system.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/action/users.go b/action/users.go index bee2e084..ae8f0c2e 100644 --- a/action/users.go +++ b/action/users.go @@ -2,7 +2,7 @@ package action // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/bibop.go b/bibop.go index a0e660a4..b44c98a3 100644 --- a/bibop.go +++ b/bibop.go @@ -4,7 +4,7 @@ package main // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/cli/cli.go b/cli/cli.go index 590c2a99..bf655a95 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -2,7 +2,7 @@ package cli // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/cli/executor/executor.go b/cli/executor/executor.go index bf3cfc01..fbd5e73d 100644 --- a/cli/executor/executor.go +++ b/cli/executor/executor.go @@ -2,7 +2,7 @@ package executor // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/cli/executor/validators.go b/cli/executor/validators.go index 2f789bd5..ae5c2302 100644 --- a/cli/executor/validators.go +++ b/cli/executor/validators.go @@ -2,7 +2,7 @@ package executor // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/output/output_store.go b/output/output_store.go index c185a524..d6ac99a9 100644 --- a/output/output_store.go +++ b/output/output_store.go @@ -2,7 +2,7 @@ package output // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/parser/fuzz.go b/parser/fuzz.go index 85fb0591..a8f7fc14 100644 --- a/parser/fuzz.go +++ b/parser/fuzz.go @@ -4,7 +4,7 @@ package parser // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/parser/parser.go b/parser/parser.go index 42946fb3..00c6eb89 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -2,7 +2,7 @@ package parser // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/parser/parser_test.go b/parser/parser_test.go index 350863ab..28c369c1 100644 --- a/parser/parser_test.go +++ b/parser/parser_test.go @@ -2,7 +2,7 @@ package parser // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/recipe/recipe.go b/recipe/recipe.go index 5c9c726c..800ffc3f 100644 --- a/recipe/recipe.go +++ b/recipe/recipe.go @@ -2,7 +2,7 @@ package recipe // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/recipe/recipe_test.go b/recipe/recipe_test.go index 7e9b68be..e94666ee 100644 --- a/recipe/recipe_test.go +++ b/recipe/recipe_test.go @@ -2,7 +2,7 @@ package recipe // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/recipe/runtime_variables.go b/recipe/runtime_variables.go index 41a14440..d91a1fa7 100644 --- a/recipe/runtime_variables.go +++ b/recipe/runtime_variables.go @@ -2,7 +2,7 @@ package recipe // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/recipe/tokens.go b/recipe/tokens.go index 99c5523d..dee264b5 100644 --- a/recipe/tokens.go +++ b/recipe/tokens.go @@ -2,7 +2,7 @@ package recipe // ////////////////////////////////////////////////////////////////////////////////// // // // -// Copyright (c) 2009-2019 ESSENTIAL KAOS // +// Copyright (c) 2009-2020 ESSENTIAL KAOS // // Essential Kaos Open Source License // // // // ////////////////////////////////////////////////////////////////////////////////// //