add parameter recover-cmd for process kill (#122)

* add parameter recover-cmd for process kill

Signed-off-by: FingerLeader <wanxfinger@gmail.com>

* add parameter recover-cmd for process kill

Signed-off-by: FingerLeader <wanxfinger@gmail.com>

* resolve confilct

Signed-off-by: FingerLeader <wanxfinger@gmail.com>

* add test for recover-cmd

Signed-off-by: FingerLeader <wanxfinger@gmail.com>

* fix some detail

Signed-off-by: FingerLeader <wanxfinger@gmail.com>

* modify details

Signed-off-by: FingerLeader <wanxfinger@gmail.com>

* modify details

Signed-off-by: FingerLeader <wanxfinger@gmail.com>

* modify details

Signed-off-by: FingerLeader <wanxfinger@gmail.com>
This commit is contained in:
FingerLeader 2022-01-12 17:27:43 +08:00 committed by GitHub
parent 22a8a7cfc9
commit fafc3eb912
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 11 deletions

View File

@ -62,6 +62,7 @@ func NewProcessKillCommand(dep fx.Option, options *core.ProcessCommand) *cobra.C
cmd.Flags().StringVarP(&options.Process, "process", "p", "", "The process name or the process ID")
cmd.Flags().IntVarP(&options.Signal, "signal", "s", 9, "The signal number to send")
cmd.Flags().StringVarP(&options.RecoverCmd, "recover-cmd", "r", "", "The command to be executed when recovering experiment")
return cmd
}

View File

@ -30,9 +30,10 @@ type ProcessCommand struct {
CommonAttackConfig
// Process defines the process name or the process ID.
Process string `json:"process,omitempty"`
Signal int `json:"signal,omitempty"`
PIDs []int
Process string `json:"process,omitempty"`
Signal int `json:"signal,omitempty"`
PIDs []int
RecoverCmd string `json:"recoverCmd,omitempty"`
// TODO: support these feature
// Newest bool
// Oldest bool

View File

@ -15,11 +15,15 @@ package chaosd
import (
"fmt"
"os/exec"
"strconv"
"syscall"
"github.com/mitchellh/go-ps"
"github.com/pingcap/errors"
"go.uber.org/zap"
"github.com/pingcap/log"
"github.com/chaos-mesh/chaosd/pkg/core"
)
@ -65,13 +69,23 @@ func (processAttack) Recover(exp core.Experiment, _ Environment) error {
}
pcmd := config.(*core.ProcessCommand)
if pcmd.Signal != int(syscall.SIGSTOP) {
return core.ErrNonRecoverableAttack.New("only SIGSTOP process attack is supported to recover")
}
if pcmd.RecoverCmd == "" {
return core.ErrNonRecoverableAttack.New("only SIGSTOP process attack and process attack with the recover-cmd are supported to recover")
}
for _, pid := range pcmd.PIDs {
if err := syscall.Kill(pid, syscall.SIGCONT); err != nil {
rcmd := exec.Command("bash", "-c", pcmd.RecoverCmd)
if err := rcmd.Start(); err != nil {
return errors.WithStack(err)
}
log.Info("Execute recover-cmd successfully", zap.String("recover-cmd", pcmd.RecoverCmd))
} else {
for _, pid := range pcmd.PIDs {
if err := syscall.Kill(pid, syscall.SIGCONT); err != nil {
return errors.WithStack(err)
}
}
}
return nil

View File

@ -58,23 +58,36 @@ if [[ ${stat} != "S" ]]; then
exit 1
fi
# test kill attack
${bin_path}/chaosd attack process kill -p ${pid} > proc.out
# test kill attack and recover-cmd
${bin_path}/chaosd attack process kill -p ${pid} -r "echo \"recover process\" >> proc.out" > proc.out
sleep 1
uid=$(cat proc.out | grep "Attack process ${pid} successfully" | awk -F: '{print $2}')
stat=$(ps axo pid | grep ${pid})
# test kill attack
if [[ -n ${stat} ]]; then
echo "target process is not killed by processed kill attack"
rm dummy.out
rm proc.out
kill ${pid}
exit 1
fi
# test recover-cmd
${bin_path}/chaosd recover ${uid}
recover_result=$(cat proc.out | awk 'END {print}')
if [[ ${recover_result} != "recover process" ]]; then
echo "target recover process is not executed"
rm dummy.out
rm proc.out
exit 1
fi
rm dummy.out
rm proc.out
kill ${pid}
exit 0