├── script
├── shell_check_process_duplicate.sh
├── shell_remove_process.sh
├── shell_check_process_id.sh
├── shell_initialization.sh
├── shell_break_and_return.sh
├── shell_modify_variable.sh
├── shell_response_delay.sh
├── shell_break_and_return_attach_parent.sh
├── shell_modify_variable_attach_parent.sh
├── shell_response_delay_attach_parent.sh
├── shell_break_and_return_attach.sh
├── shell_modify_variable_attach.sh
└── shell_response_delay_attach.sh
├── go.mod
├── .gitignore
├── module
├── common.go
├── module.go
├── linedelayed.go
├── errorreturned.go
└── variablemodified.go
├── controller
├── controller.go
├── status.go
├── remove.go
├── destroy.go
├── manager.go
└── create.go
├── common
├── signal.go
├── constants.go
└── utils.go
├── Makefile
├── README.md
├── pom.xml
├── go.sum
├── main.go
├── CODE_OF_CONDUCT.md
└── CONTRIBUTING.md
/script/shell_check_process_duplicate.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ps -ef|grep $1|grep 'gdb'
--------------------------------------------------------------------------------
/script/shell_remove_process.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | pkill -f gdb
4 |
5 | if [[ -n "$1" ]]; then
6 | kill -9 "$1"
7 | fi
--------------------------------------------------------------------------------
/script/shell_check_process_id.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ps -ef|grep $1|grep -v 'grep'|grep -v 'initParams'|grep -v 'shell_check_process_id'| awk '{print $2}'
--------------------------------------------------------------------------------
/script/shell_initialization.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Install gdb
4 | if ! [ -x "$(command -v gdb)" ]; then
5 | yes | yum install gdb
6 | echo 'Pass: gdb has been installed.'
7 | else
8 | echo 'Pass: gdb has been installed.'
9 | fi
10 |
11 | # Install expect
12 | if ! [ -x "$(command -v expect)" ]; then
13 | yes | yum install expect
14 | echo 'Pass: expect has been installed.'
15 | exit 1
16 | else
17 | echo 'Pass: expect already has been installed.'
18 | exit 1
19 | fi
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/wetcatacomb/chaosblade-exec-cplus
2 |
3 | go 1.20
4 |
5 | require github.com/chaosblade-io/chaosblade-spec-go v1.7.3
6 |
7 | require (
8 | github.com/go-ole/go-ole v1.2.6 // indirect
9 | github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
10 | github.com/shirou/gopsutil v3.21.11+incompatible // indirect
11 | github.com/sirupsen/logrus v1.4.2 // indirect
12 | github.com/tklauser/go-sysconf v0.3.9 // indirect
13 | github.com/tklauser/numcpus v0.3.0 // indirect
14 | github.com/yusufpapurcu/wmi v1.2.4 // indirect
15 | golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71 // indirect
16 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
17 | gopkg.in/yaml.v2 v2.2.8 // indirect
18 | )
19 |
--------------------------------------------------------------------------------
/script/shell_break_and_return.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb
5 | expect {
6 | \"gdb\" {send \"file $1\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"set pagination off\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $4\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"r $5\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"r $6\n\";}
37 | }
38 |
39 | interact
40 | "
--------------------------------------------------------------------------------
/script/shell_modify_variable.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb
5 | expect {
6 | \"gdb\" {send \"file $1\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"set pagination off\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $4\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"set $5=$6\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"r $7\n\";}
37 | }
38 |
39 | interact
40 | "
--------------------------------------------------------------------------------
/script/shell_response_delay.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb
5 | expect {
6 | \"gdb\" {send \"file $1\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"set pagination off\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $4\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"shell sleep $5\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"r $6\n\";}
37 | }
38 |
39 | interact
40 | "
--------------------------------------------------------------------------------
/script/shell_break_and_return_attach_parent.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb -q attach $1
5 | expect {
6 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set pagination off\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"$4\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $5\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"return $6\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"c\n\";}
37 | }
38 |
39 | interact
40 | "
--------------------------------------------------------------------------------
/script/shell_modify_variable_attach_parent.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb -q attach $1
5 | expect {
6 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set pagination off\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"$4\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $5\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"set $6 = $7\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"c\n\";}
37 | }
38 |
39 | interact
40 | "
--------------------------------------------------------------------------------
/script/shell_response_delay_attach_parent.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb -q attach $1
5 | expect {
6 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set pagination off\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"$4\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $5\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"shell sleep $6\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"c\n\";}
37 | }
38 |
39 | interact
40 | "
--------------------------------------------------------------------------------
/script/shell_break_and_return_attach.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb -q attach $1
5 | expect {
6 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set pagination off\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"$4\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $5\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"return $6\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"r $7\n\";}
37 | }
38 | expect {
39 | \"beginning\" {send \"y\n\";}
40 | }
41 |
42 | interact
43 | "
--------------------------------------------------------------------------------
/script/shell_modify_variable_attach.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb -q attach $1
5 | expect {
6 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set pagination off\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"$4\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $5\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"set $6 = $7\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"r $8\n\";}
37 | }
38 | expect {
39 | \"beginning\" {send \"y\n\";}
40 | }
41 |
42 | interact
43 | "
--------------------------------------------------------------------------------
/script/shell_response_delay_attach.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | expect -c "
4 | spawn gdb -q attach $1
5 | expect {
6 | \"gdb\" {send \"set follow-fork-mode $2\n\";}
7 | }
8 | expect {
9 | \"gdb\" {send \"set pagination off\n\";}
10 | }
11 | expect {
12 | \"gdb\" {send \"$3\n\";}
13 | }
14 | expect {
15 | \"gdb\" {send \"$4\n\";}
16 | }
17 | expect {
18 | \"gdb\" {send \"b $5\n\";}
19 | }
20 | expect {
21 | \"gdb\" {send \"commands\n\";}
22 | }
23 | expect {
24 | \">\" {send \"silent\n\"}
25 | }
26 | expect {
27 | \">\" {send \"shell sleep $6\n\"}
28 | }
29 | expect {
30 | \">\" {send \"cont\n\"}
31 | }
32 | expect {
33 | \">\" {send \"end\n\"}
34 | }
35 | expect {
36 | \"gdb\" {send \"r $7\n\";}
37 | }
38 | expect {
39 | \"beginning\" {send \"y\n\";}
40 | }
41 |
42 | interact
43 | "
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.exe
7 | *.o
8 | *.so
9 |
10 | # Packages #
11 | ############
12 | # it's better to unpack these files and commit the raw source
13 | # git has its own built in compression methods
14 | *.7z
15 | *.dmg
16 | *.gz
17 | *.iso
18 | *.jar
19 | *.rar
20 | *.tar
21 | *.zip
22 | *.classpath
23 | *.project
24 | diamond_config_data.log
25 | diamond_config_data.log.*
26 |
27 |
28 | #ignore these files
29 | */.settings/*
30 | .settings/*
31 | */bin/*
32 | */target/*
33 | bin/*
34 | target/*
35 | **/target/**
36 | */.idea/*
37 | .idea/*
38 | *.iml
39 | */*.iml
40 | build-target
41 | # Logs and databases #
42 | ######################
43 | *.log
44 | *.sql
45 | *.sqlite
46 |
47 | # OS generated files #
48 | ######################
49 | .DS_Store
50 | .DS_Store?
51 | ._*
52 | .Spotlight-V100
53 | .Trashes
54 | ehthumbs.db
55 | Thumbs.db
56 |
57 | # project
58 | /plugins
59 | /cp.sh
60 |
--------------------------------------------------------------------------------
/module/common.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package module
18 |
19 | import (
20 | "fmt"
21 | "strings"
22 | )
23 |
24 | func buildArgs(flags []string) string {
25 | args := ""
26 | for _, flag := range flags {
27 | if flag != "" {
28 | args = fmt.Sprintf(`%s %s`, args, flag)
29 | } else {
30 | args = fmt.Sprintf(`%s ''`, args)
31 | }
32 | }
33 | return strings.TrimSpace(args)
34 | }
35 |
--------------------------------------------------------------------------------
/controller/controller.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package controller
18 |
19 | import "net/http"
20 |
21 | type Controller interface {
22 | GetControllerName() string
23 | GetRequestHandler() func(writer http.ResponseWriter, request *http.Request)
24 | }
25 |
26 | var Controllers = []Controller{
27 | &CreateController{},
28 | &DestroyController{},
29 | &RemoveController{},
30 | &StatusController{},
31 | }
32 |
--------------------------------------------------------------------------------
/controller/status.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package controller
18 |
19 | import (
20 | "fmt"
21 | "net/http"
22 | )
23 |
24 | const StatusName = "status"
25 |
26 | type StatusController struct {
27 | }
28 |
29 | func (r *StatusController) GetControllerName() string {
30 | return StatusName
31 | }
32 |
33 | func (r *StatusController) GetRequestHandler() func(writer http.ResponseWriter, request *http.Request) {
34 | return func(writer http.ResponseWriter, request *http.Request) {
35 | fmt.Fprintf(writer, "success")
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/controller/remove.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package controller
18 |
19 | import (
20 | "context"
21 | "fmt"
22 | "net/http"
23 |
24 | "github.com/chaosblade-io/chaosblade-spec-go/channel"
25 | )
26 |
27 | const RemoveName = "remove"
28 |
29 | type RemoveController struct {
30 | }
31 |
32 | func (r *RemoveController) GetControllerName() string {
33 | return RemoveName
34 | }
35 |
36 | func (r *RemoveController) GetRequestHandler() func(writer http.ResponseWriter, request *http.Request) {
37 | return func(writer http.ResponseWriter, request *http.Request) {
38 | // TODO 暂时全部杀掉 gdb
39 | response := channel.NewLocalChannel().Run(context.Background(), "pkill", "-f gdb")
40 | fmt.Fprintf(writer, response.Print())
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/common/signal.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package common
18 |
19 | import (
20 | "context"
21 | "os"
22 | "os/signal"
23 | "runtime"
24 | "syscall"
25 |
26 | "github.com/chaosblade-io/chaosblade-spec-go/log"
27 | )
28 |
29 | type ShutdownHook interface {
30 | Shutdown() error
31 | }
32 |
33 | func Hold(hooks ...ShutdownHook) {
34 | sig := make(chan os.Signal, 1)
35 | signal.Notify(sig, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
36 | buf := make([]byte, 1<<10)
37 | for {
38 | switch <-sig {
39 | case syscall.SIGINT, syscall.SIGTERM:
40 | log.Warnf(context.TODO(), "received SIGINT/SIGTERM, exit")
41 | for _, hook := range hooks {
42 | hook.Shutdown()
43 | }
44 | return
45 | case syscall.SIGQUIT:
46 | for _, hook := range hooks {
47 | hook.Shutdown()
48 | }
49 | len := runtime.Stack(buf, true)
50 | log.Warnf(context.TODO(), "received SIGQUIT\n%s\n", buf[:len])
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: build clean
2 |
3 | BLADE_SRC_ROOT=$(shell pwd)
4 | UNAME := $(shell uname)
5 |
6 | ifeq ($(BLADE_VERSION), )
7 | BLADE_VERSION=1.7.3
8 | endif
9 |
10 | BUILD_TARGET=build-target
11 | BUILD_TARGET_DIR_NAME=chaosblade-$(BLADE_VERSION)
12 | BUILD_TARGET_PKG_DIR=$(BUILD_TARGET)/chaosblade-$(BLADE_VERSION)
13 | BUILD_TARGET_YAML=$(BUILD_TARGET_PKG_DIR)/yaml
14 | BUILD_TARGET_CPLUS_LIB=$(BUILD_TARGET_PKG_DIR)/lib/cplus
15 | BUILD_TARGET_CPLUS_SCRIPT=$(BUILD_TARGET_CPLUS_LIB)/script
16 | # yaml file name
17 | CPLUS_YAML_FILE=$(BUILD_TARGET_YAML)/chaosblade-cplus-spec.yaml
18 | # agent file name
19 | CPLUS_AGENT_FILE_NAME=chaosblade-exec-cplus
20 |
21 | GO_ENV=CGO_ENABLED=1
22 | GO_MODULE=GO111MODULE=on
23 | GO=env $(GO_ENV) $(GO_MODULE) go
24 | ifeq ($(GOOS), linux)
25 | GO_FLAGS=-ldflags="-linkmode external -extldflags -static"
26 | endif
27 |
28 | build: pre_build build_cplus build_yaml
29 | cp -R script/* $(BUILD_TARGET_CPLUS_SCRIPT)
30 | chmod -R 755 $(BUILD_TARGET_CPLUS_LIB)
31 |
32 | pre_build:
33 | rm -rf $(BUILD_TARGET_PKG_DIR)
34 | mkdir -p $(BUILD_TARGET_YAML) $(BUILD_TARGET_CPLUS_SCRIPT)
35 |
36 | build_yaml: build/spec.go
37 | $(GO) run $< $(CPLUS_YAML_FILE)
38 |
39 | build_cplus: main.go
40 | $(GO) build $(GO_FLAGS) -o $(BUILD_TARGET_CPLUS_LIB)/chaosblade-exec-cplus $<
41 |
42 | # build chaosblade linux version by docker image
43 | build_linux:
44 | docker build -f build/image/musl/Dockerfile -t chaosblade-cplus-build-musl:latest build/image/musl
45 | docker run --rm \
46 | -v $(shell echo -n ${GOPATH}):/go \
47 | -v $(BLADE_SRC_ROOT):/chaosblade-exec-cplus \
48 | -w /chaosblade-exec-cplus \
49 | chaosblade-cplus-build-musl:latest
50 |
51 | # test
52 | test:
53 | mvn clean test -U
54 | # clean all build result
55 | clean:
56 | $(GO) clean ./...
57 | rm -rf $(BUILD_TARGET)
58 |
59 | all: build test
60 |
--------------------------------------------------------------------------------
/common/constants.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package common
18 |
19 | const (
20 | TargetName = "cplus"
21 | DelayActionName = "delay"
22 | ReturnErrorDataActionName = "return"
23 | VariableModifyActionName = "modify"
24 | FileKeyword = "file "
25 | SetEnvLdLibraryPath = "set env LD_LIBRARY_PATH "
26 | SleepMilliseconds = 1000
27 | CorePoolSize = 1
28 | MaximumPoolSize = 1
29 | KeepAliveTime = 0
30 | BinName = "chaosblade-exec-cplus"
31 | )
32 |
33 | const (
34 | InitializationScript = "shell_initialization.sh"
35 | RemoveProcessScript = "shell_remove_process.sh"
36 | ResponseDelayScript = "shell_response_delay.sh"
37 | ResponseDelayAttachScript = "shell_response_delay_attach.sh"
38 | ResponseDelayAttachParentScript = "shell_response_delay_attach_parent.sh"
39 | BreakAndReturnScript = "shell_break_and_return.sh"
40 | BreakAndReturnAttachScript = "shell_break_and_return_attach.sh"
41 | BreakAndReturnAttachParentScript = "shell_break_and_return_attach_parent.sh"
42 | ModifyVariableScript = "shell_modify_variable.sh"
43 | ModifyVariableAttachScript = "shell_modify_variable_attach.sh"
44 | ModifyVariableAttachParentScript = "shell_modify_variable_attach_parent.sh"
45 | CheckProcessIdScript = "shell_check_process_id.sh"
46 | CheckProcessDuplicateScript = "shell_check_process_duplicate.sh"
47 | )
48 |
--------------------------------------------------------------------------------
/common/utils.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package common
18 |
19 | import (
20 | "log"
21 | "os"
22 | "os/exec"
23 | "path"
24 | "path/filepath"
25 |
26 | "github.com/chaosblade-io/chaosblade-spec-go/util"
27 | )
28 |
29 | var proPath string
30 |
31 | // GetProgramPath
32 | func GetProgramPath() string {
33 | if proPath != "" {
34 | return proPath
35 | }
36 | dir, err := exec.LookPath(os.Args[0])
37 | if err != nil {
38 | log.Fatalf("can not get the process path, %v", err)
39 | }
40 | if p, err := os.Readlink(dir); err == nil {
41 | dir = p
42 | }
43 | proPath, err = filepath.Abs(filepath.Dir(dir))
44 | if err != nil {
45 | log.Fatalf("can not get the full process path, %v", err)
46 | }
47 | return proPath
48 | }
49 |
50 | var scriptPath string
51 |
52 | func GetScriptPath() string {
53 | if scriptPath != "" {
54 | return scriptPath
55 | }
56 | scriptPath = path.Join(GetProgramPath(), "script")
57 | return scriptPath
58 | }
59 |
60 | var chaosbladeLogPath string
61 |
62 | // chaosblade-VERSION/lib/cplus
63 | func GetChaosBladeLogPath() string {
64 | if chaosbladeLogPath != "" {
65 | return chaosbladeLogPath
66 | }
67 | chaosbladeLogPath = path.Join(path.Dir(path.Dir(GetProgramPath())), "logs", "chaosblade.log")
68 |
69 | if util.IsExist(chaosbladeLogPath) {
70 | return chaosbladeLogPath
71 | }
72 | err := os.MkdirAll(path.Dir(chaosbladeLogPath), os.ModePerm)
73 | if err != nil {
74 | chaosbladeLogPath = path.Join(GetProgramPath(), "chaosblade.log")
75 | }
76 | return chaosbladeLogPath
77 | }
78 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Chaosblade-exec-cplus: Chaosblade executor for chaos experiments on c++ applications
4 |
5 |
6 | ## Introduction
7 | The project is a chaosblade executor based on [GDB] for chaos
8 | experiments on c++ applications. The drill can be implemented through the blade cli, see
9 | [chaosblade](https://github.com/chaosblade-io/chaosblade) project for details.
10 |
11 |
12 | ## Compiling
13 | In the project root directory, execute the following command to compile
14 | ```bash
15 | make
16 | ```
17 |
18 | The compilation result will be stored in the target directory.
19 |
20 |
21 | ## Deploying
22 | When deploying Chaosblade-exec-cplus, the shell script files under the source’s folders [/src/main/resources/script] should be deployed on the disk of server separately. Create a new folder in server, put all the shell script files under the new folder, and when you startup chaosblade-exec-cplus jar, you can use the command just like:
23 | ```bash
24 | nohup java -jar chaosblade-exec-cplus.jar --server.port=8908 --script.location=/home/admin/cplus/ &
25 | ```
26 | the value of parameter "script.location" can be set the location of the new created folder. So that the chaosblade-exec-cplus jar know where to get the script files.
27 |
28 |
29 | ## Restriction
30 | 1. If the C++ application doesn’t add '-g' when compiling, Chaosblade-exec-cplus can’t work.
31 | 2. If the linux system can’t support yum command to install software, the [GDB], and [expect] software should be manual installed, before use Chaosblade-exec-cplus.
32 |
33 |
34 | ## Contributing
35 | We welcome every contribution, even if it is just a punctuation. See details of [CONTRIBUTING](CONTRIBUTING.md)
36 |
37 |
38 | ## Bugs and Feedback
39 | For bug report, questions and discussions please submit [GitHub Issues](https://github.com/wetcatacomb/chaosblade-exec-cplus/issues).
40 |
41 | Contact us: chaosblade.io.01@gmail.com
42 |
43 | Gitter room: [chaosblade community](https://gitter.im/chaosblade-io/community)
44 |
45 |
46 | ## License
47 | Chaosblade-exec-cplus is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.
48 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
21 | 4.0.0
22 |
23 | com.alibaba.chaosblade
24 | chaosblade-exec-cplus
25 | 1.1-SNAPSHOT
26 |
27 |
28 | UTF-8
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter-parent
34 | 1.3.1.RELEASE
35 |
36 |
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-web
41 |
42 |
43 |
44 |
45 | org.apache.commons
46 | commons-lang3
47 | 3.8.1
48 |
49 |
50 |
51 |
52 | chaosblade-exec-cplus
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-maven-plugin
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/controller/destroy.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package controller
18 |
19 | import (
20 | "context"
21 | "fmt"
22 | "net/http"
23 | "path"
24 | "strings"
25 |
26 | "github.com/wetcatacomb/chaosblade-exec-cplus/common"
27 | "github.com/chaosblade-io/chaosblade-spec-go/channel"
28 | "github.com/chaosblade-io/chaosblade-spec-go/spec"
29 | )
30 |
31 | const DestroyName = "destroy"
32 |
33 | type DestroyController struct {
34 | }
35 |
36 | func (d *DestroyController) GetControllerName() string {
37 | return DestroyName
38 | }
39 |
40 | func (d *DestroyController) GetRequestHandler() func(writer http.ResponseWriter, request *http.Request) {
41 | return func(writer http.ResponseWriter, request *http.Request) {
42 | err := request.ParseForm()
43 | if err != nil {
44 | fmt.Fprintf(writer, spec.ResponseFailWithFlags(spec.CommandIllegal, err).Print())
45 | return
46 | }
47 | suid := request.Form.Get("suid")
48 | if suid == "" {
49 | fmt.Fprintf(writer, spec.ResponseFailWithFlags(spec.ParameterLess, "suid").Print())
50 | return
51 | }
52 | expModel := Manager.Experiments[suid]
53 | if expModel == nil {
54 | fmt.Fprintf(writer, spec.ReturnSuccess("the experiment not found").Print())
55 | return
56 | }
57 | processName := expModel.ActionFlags["processName"]
58 | if processName == "" {
59 | fmt.Fprintf(writer, spec.ReturnSuccess("success").Print())
60 | return
61 | }
62 | localChannel := channel.NewLocalChannel()
63 | pids, err := localChannel.GetPidsByProcessName(processName, context.Background())
64 | if err == nil && len(pids) == 0 {
65 | fmt.Fprintf(writer, spec.ReturnSuccess("success").Print())
66 | return
67 | }
68 | var pid string
69 | if len(pids) > 0 {
70 | pid = strings.Join(pids, ",")
71 | }
72 |
73 | response := localChannel.Run(context.Background(),
74 | path.Join(common.GetScriptPath(), common.RemoveProcessScript), pid)
75 | fmt.Fprintf(writer, response.Print())
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/module/module.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package module
18 |
19 | import (
20 | "github.com/chaosblade-io/chaosblade-spec-go/spec"
21 | )
22 |
23 | type CPlusExpModuleSpec struct {
24 | spec.BaseExpModelCommandSpec
25 | }
26 |
27 | func NewCPlusCommandModelSpec() spec.ExpModelCommandSpec {
28 | return &CPlusExpModuleSpec{
29 | spec.BaseExpModelCommandSpec{
30 | ExpScope: "host",
31 | ExpActions: []spec.ExpActionCommandSpec{
32 | NewErrorReturnedActionSpec(),
33 | NewLineDelayedActionSpec(),
34 | NewVariableModifiedActionSpec(),
35 | },
36 | ExpFlags: []spec.ExpFlagSpec{
37 | &spec.ExpFlag{
38 | Name: "breakLine",
39 | Desc: "Injection line in source code",
40 | Required: true,
41 | },
42 | &spec.ExpFlag{
43 | Name: "fileLocateAndName",
44 | Desc: "Startup file location and name",
45 | Required: true,
46 | },
47 | &spec.ExpFlag{
48 | Name: "initParams",
49 | Desc: "Initialization parameters for program startup (such as port number)",
50 | Required: false,
51 | },
52 | &spec.ExpFlag{
53 | Name: "forkMode",
54 | Desc: "Fault injection into child or parent processes (sub process:child ; main process:parent)",
55 | Required: true,
56 | },
57 | &spec.ExpFlag{
58 | Name: "processName",
59 | Desc: "Application process name",
60 | Required: true,
61 | },
62 | &spec.ExpFlag{
63 | Name: "libLoad",
64 | Desc: "If the class library needs to be loaded when the program starts, input the class library address",
65 | Required: false,
66 | },
67 | },
68 | },
69 | }
70 | }
71 |
72 | func (c *CPlusExpModuleSpec) Name() string {
73 | return "cplus"
74 | }
75 |
76 | func (c *CPlusExpModuleSpec) ShortDesc() string {
77 | return "C++ chaos experiments"
78 | }
79 |
80 | func (c *CPlusExpModuleSpec) LongDesc() string {
81 | return "C++ chaos experiments contain code line delayed, variable modified and err returned"
82 | }
83 |
84 | func (c *CPlusExpModuleSpec) Example() string {
85 | // TODO
86 | return ""
87 | }
88 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
2 | github.com/chaosblade-io/chaosblade-spec-go v1.7.3 h1:OhFFBCV4iNwOdKA7BPjtdSM5cJZrtZry7JBUyWEc83g=
3 | github.com/chaosblade-io/chaosblade-spec-go v1.7.3/go.mod h1:khF37h4B8tKfBlgqKGE/+2sWimvm+Mc1l3V8rY5rbOQ=
4 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6 | github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
7 | github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
8 | github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
9 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
10 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
11 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
12 | github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
13 | github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
14 | github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
15 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
16 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
17 | github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
18 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
19 | github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
20 | github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
21 | github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
22 | github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
23 | github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
24 | github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
25 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
26 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
27 | golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71 h1:ikCpsnYR+Ew0vu99XlDp55lGgDJdIMx3f4a18jfse/s=
28 | golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
29 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
30 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
31 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
32 | gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
33 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
34 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
35 |
--------------------------------------------------------------------------------
/controller/manager.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package controller
18 |
19 | import (
20 | "sync"
21 |
22 | "github.com/chaosblade-io/chaosblade-spec-go/spec"
23 |
24 | "github.com/wetcatacomb/chaosblade-exec-cplus/module"
25 | )
26 |
27 | type ExpManager struct {
28 | //
29 | Experiments map[string]*spec.ExpModel
30 | //
31 | Actions map[string]*spec.ActionModel
32 | }
33 |
34 | var Manager *ExpManager
35 | var once sync.Once
36 |
37 | func init() {
38 | once.Do(func() {
39 | Manager = &ExpManager{
40 | Experiments: make(map[string]*spec.ExpModel, 0),
41 | Actions: make(map[string]*spec.ActionModel, 0),
42 | }
43 |
44 | modelSpec := module.NewCPlusCommandModelSpec()
45 | actions := modelSpec.Actions()
46 | for _, action := range actions {
47 | actionModel := &spec.ActionModel{
48 | ActionName: action.Name(),
49 | ActionAliases: action.Aliases(),
50 | ActionShortDesc: action.ShortDesc(),
51 | ActionLongDesc: action.LongDesc(),
52 | ActionMatchers: func() []spec.ExpFlag {
53 | matchers := make([]spec.ExpFlag, 0)
54 | for _, m := range action.Matchers() {
55 | matchers = append(matchers, spec.ExpFlag{
56 | Name: m.FlagName(),
57 | Desc: m.FlagDesc(),
58 | NoArgs: m.FlagNoArgs(),
59 | Required: m.FlagRequired(),
60 | })
61 | }
62 | return matchers
63 | }(),
64 | ActionFlags: func() []spec.ExpFlag {
65 | flags := make([]spec.ExpFlag, 0)
66 | for _, m := range action.Flags() {
67 | flags = append(flags, spec.ExpFlag{
68 | Name: m.FlagName(),
69 | Desc: m.FlagDesc(),
70 | NoArgs: m.FlagNoArgs(),
71 | Required: m.FlagRequired(),
72 | })
73 | }
74 | for _, m := range modelSpec.Flags() {
75 | flags = append(flags, spec.ExpFlag{
76 | Name: m.FlagName(),
77 | Desc: m.FlagDesc(),
78 | NoArgs: m.FlagNoArgs(),
79 | Required: m.FlagRequired(),
80 | })
81 | }
82 | return flags
83 | }(),
84 | }
85 | actionModel.SetExecutor(action.Executor())
86 | Manager.Actions[action.Name()] = actionModel
87 | }
88 | })
89 | }
90 |
91 | func (e *ExpManager) Record(suid string, expModel *spec.ExpModel) error {
92 | // TODO
93 | e.Experiments[suid] = expModel
94 | return nil
95 | }
96 |
97 | func (e *ExpManager) Remove(suid string) error {
98 | // TODO
99 | delete(e.Experiments, suid)
100 | return nil
101 | }
102 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package main
18 |
19 | import (
20 | "context"
21 | "flag"
22 | "fmt"
23 | "log"
24 | "net/http"
25 | "os"
26 | "path"
27 | "time"
28 |
29 | "github.com/chaosblade-io/chaosblade-spec-go/channel"
30 | "github.com/chaosblade-io/chaosblade-spec-go/util"
31 |
32 | "github.com/wetcatacomb/chaosblade-exec-cplus/common"
33 | "github.com/wetcatacomb/chaosblade-exec-cplus/controller"
34 | )
35 |
36 | type Config struct {
37 | Port int
38 | IP string
39 | nohup bool
40 | }
41 |
42 | func main() {
43 | config := &Config{}
44 | flag.StringVar(&config.IP, "ip", "", "The ip bounds on the service")
45 | flag.IntVar(&config.Port, "port", 9525, "The port bounds one the service")
46 | flag.BoolVar(&config.nohup, "nohup", false, "used by internal")
47 |
48 | flag.Parse()
49 | util.InitLog(util.Custom)
50 | ctx := context.WithValue(context.Background(), channel.ProcessKey, "nohup")
51 | pids, err := channel.NewLocalChannel().GetPidsByProcessName(common.BinName, ctx)
52 | if err != nil {
53 | log.Fatalf("query process failed, %v", err)
54 | }
55 | if len(pids) > 0 {
56 | log.Fatalf("process has been started, %+v", pids)
57 | }
58 | if config.nohup {
59 | start0(config)
60 | os.Exit(0)
61 | }
62 | err = start(config)
63 | if err != nil {
64 | log.Fatalf("start failed, %v", err)
65 | }
66 | log.Printf("success")
67 | os.Exit(0)
68 | }
69 |
70 | func start(config *Config) error {
71 | args := fmt.Sprintf("%s --nohup --port %d", path.Join(common.GetProgramPath(), common.BinName), config.Port)
72 | if config.IP != "" {
73 | args = fmt.Sprintf("%s --ip %s", args, config.IP)
74 | }
75 | cl := channel.NewLocalChannel()
76 |
77 | response := cl.Run(context.TODO(), "nohup", fmt.Sprintf("%s > %s 2>&1 &", args, common.GetChaosBladeLogPath()))
78 | if !response.Success {
79 | return fmt.Errorf(response.Err)
80 | }
81 | time.Sleep(time.Second)
82 | ctx := context.WithValue(context.Background(), channel.ProcessKey, "nohup")
83 | pids, err := cl.GetPidsByProcessName(common.BinName, ctx)
84 | if err != nil {
85 | return err
86 | }
87 | if len(pids) == 0 {
88 | return fmt.Errorf("process not found")
89 | }
90 | return nil
91 | }
92 |
93 | func start0(config *Config) {
94 | go func() {
95 | err := http.ListenAndServe(fmt.Sprintf("%s:%d", config.IP, config.Port), nil)
96 | if err != nil {
97 | log.Fatalf("start chaosblade-exec-cplus failed, %v", err)
98 | }
99 | }()
100 |
101 | for _, c := range controller.Controllers {
102 | http.HandleFunc("/"+c.GetControllerName(), c.GetRequestHandler())
103 | }
104 | common.Hold()
105 | }
106 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of experience,
9 | education, socio-economic status, nationality, personal appearance, race,
10 | religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at chaosblade.io.01@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)
72 |
73 | [homepage]: https://www.contributor-covenant.org
--------------------------------------------------------------------------------
/module/linedelayed.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package module
18 |
19 | import (
20 | "context"
21 | "path"
22 |
23 | "github.com/wetcatacomb/chaosblade-exec-cplus/common"
24 | "github.com/chaosblade-io/chaosblade-spec-go/channel"
25 | "github.com/chaosblade-io/chaosblade-spec-go/log"
26 | "github.com/chaosblade-io/chaosblade-spec-go/spec"
27 | )
28 |
29 | type LineDelayedActionSpec struct {
30 | spec.BaseExpActionCommandSpec
31 | }
32 |
33 | func NewLineDelayedActionSpec() spec.ExpActionCommandSpec {
34 | return &LineDelayedActionSpec{
35 | spec.BaseExpActionCommandSpec{
36 | ActionMatchers: []spec.ExpFlagSpec{},
37 | ActionFlags: []spec.ExpFlagSpec{
38 | &spec.ExpFlag{
39 | Name: "delayDuration",
40 | Desc: "delay time, unit is second",
41 | Required: true,
42 | },
43 | },
44 | ActionExecutor: &LineDelayedExecutor{},
45 | },
46 | }
47 | }
48 |
49 | func (l LineDelayedActionSpec) Name() string {
50 | return "delay"
51 | }
52 |
53 | func (l LineDelayedActionSpec) Aliases() []string {
54 | return []string{}
55 | }
56 |
57 | func (l LineDelayedActionSpec) ShortDesc() string {
58 | return "Code line delayed"
59 | }
60 |
61 | func (l LineDelayedActionSpec) LongDesc() string {
62 | return "Code line delayed"
63 | }
64 |
65 | type LineDelayedExecutor struct {
66 | channel spec.Channel
67 | }
68 |
69 | func (l *LineDelayedExecutor) Name() string {
70 | return "delay"
71 | }
72 |
73 | func (l *LineDelayedExecutor) Exec(uid string, ctx context.Context, model *spec.ExpModel) *spec.Response {
74 | delayDuration := model.ActionFlags["delayDuration"]
75 | if delayDuration == "" {
76 | return spec.ResponseFailWithFlags(spec.ParameterLess, "delayDuration")
77 | }
78 | // search pid by process name
79 | processName := model.ActionFlags["processName"]
80 | if processName == "" {
81 | return spec.ResponseFailWithFlags(spec.ParameterLess, "processName")
82 | }
83 | processCtx := context.WithValue(context.Background(), channel.ExcludeProcessKey, "blade")
84 | pids, err := channel.NewLocalChannel().GetPidsByProcessName(processName, processCtx)
85 | if err != nil {
86 | log.Warnf(ctx, "get pids by %s process name err, %v", processName, err)
87 | }
88 | localChannel := channel.NewLocalChannel()
89 | if pids == nil || len(pids) == 0 {
90 | args := buildArgs([]string{
91 | model.ActionFlags["fileLocateAndName"],
92 | model.ActionFlags["forkMode"],
93 | model.ActionFlags["libLoad"],
94 | model.ActionFlags["breakLine"],
95 | delayDuration,
96 | model.ActionFlags["initParams"],
97 | })
98 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.ResponseDelayScript), args)
99 | } else {
100 | args := buildArgs([]string{
101 | pids[0],
102 | model.ActionFlags["forkMode"],
103 | "",
104 | "",
105 | model.ActionFlags["breakLine"],
106 | delayDuration,
107 | model.ActionFlags["initParams"],
108 | })
109 | if "child" == model.ActionFlags["forkMode"] {
110 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.ResponseDelayAttachScript), args)
111 | }
112 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.ResponseDelayAttachParentScript), args)
113 | }
114 | }
115 |
116 | func (l *LineDelayedExecutor) SetChannel(channel spec.Channel) {
117 | l.channel = channel
118 | }
119 |
--------------------------------------------------------------------------------
/module/errorreturned.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package module
18 |
19 | import (
20 | "context"
21 | "path"
22 |
23 | "github.com/wetcatacomb/chaosblade-exec-cplus/common"
24 | "github.com/chaosblade-io/chaosblade-spec-go/channel"
25 | "github.com/chaosblade-io/chaosblade-spec-go/log"
26 | "github.com/chaosblade-io/chaosblade-spec-go/spec"
27 | )
28 |
29 | type ErrorReturnedActionSpec struct {
30 | spec.BaseExpActionCommandSpec
31 | }
32 |
33 | func NewErrorReturnedActionSpec() spec.ExpActionCommandSpec {
34 | return &ErrorReturnedActionSpec{
35 | spec.BaseExpActionCommandSpec{
36 | ActionMatchers: []spec.ExpFlagSpec{},
37 | ActionFlags: []spec.ExpFlagSpec{
38 | &spec.ExpFlag{
39 | Name: "returnValue",
40 | Desc: "Value returned. If you want return null, set --returnValue null",
41 | Required: true,
42 | },
43 | },
44 | ActionExecutor: &ErrorReturnedExecutor{},
45 | },
46 | }
47 | }
48 |
49 | func (e ErrorReturnedActionSpec) Name() string {
50 | return "return"
51 | }
52 |
53 | func (e ErrorReturnedActionSpec) Aliases() []string {
54 | return []string{}
55 | }
56 |
57 | func (e ErrorReturnedActionSpec) ShortDesc() string {
58 | return "error returned"
59 | }
60 |
61 | func (e ErrorReturnedActionSpec) LongDesc() string {
62 | return "error returned"
63 | }
64 |
65 | type ErrorReturnedExecutor struct {
66 | channel spec.Channel
67 | }
68 |
69 | func (e *ErrorReturnedExecutor) Name() string {
70 | return "return"
71 | }
72 |
73 | func (e *ErrorReturnedExecutor) Exec(uid string, ctx context.Context, model *spec.ExpModel) *spec.Response {
74 | if _, ok := spec.IsDestroy(ctx); ok {
75 | return spec.ResponseFailWithFlags(spec.CommandIllegal, "destroy")
76 | }
77 | returnValue := model.ActionFlags["returnValue"]
78 | if returnValue == "" {
79 | return spec.ResponseFailWithFlags(spec.ParameterLess, "returnValue")
80 | }
81 | // search pid by process name
82 | processName := model.ActionFlags["processName"]
83 | if processName == "" {
84 | return spec.ResponseFailWithFlags(spec.ParameterLess, "processName")
85 | }
86 | processCtx := context.WithValue(context.Background(), channel.ExcludeProcessKey, "blade")
87 | pids, err := channel.NewLocalChannel().GetPidsByProcessName(processName, processCtx)
88 | if err != nil {
89 | log.Warnf(ctx, "get pids by %s process name err, %v", processName, err)
90 | }
91 | localChannel := channel.NewLocalChannel()
92 | if pids == nil || len(pids) == 0 {
93 | args := buildArgs([]string{
94 | model.ActionFlags["fileLocateAndName"],
95 | model.ActionFlags["forkMode"],
96 | model.ActionFlags["libLoad"],
97 | model.ActionFlags["breakLine"],
98 | returnValue,
99 | model.ActionFlags["initParams"],
100 | })
101 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.BreakAndReturnScript), args)
102 | } else {
103 | args := buildArgs([]string{
104 | pids[0],
105 | model.ActionFlags["forkMode"],
106 | "",
107 | "",
108 | model.ActionFlags["breakLine"],
109 | returnValue,
110 | model.ActionFlags["initParams"],
111 | })
112 | if "child" == model.ActionFlags["forkMode"] {
113 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.BreakAndReturnAttachScript), args)
114 | }
115 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.BreakAndReturnAttachParentScript), args)
116 | }
117 | }
118 |
119 | func (e *ErrorReturnedExecutor) SetChannel(channel spec.Channel) {
120 | e.channel = channel
121 | }
122 |
--------------------------------------------------------------------------------
/module/variablemodified.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package module
18 |
19 | import (
20 | "context"
21 | "path"
22 |
23 | "github.com/wetcatacomb/chaosblade-exec-cplus/common"
24 | "github.com/chaosblade-io/chaosblade-spec-go/channel"
25 | "github.com/chaosblade-io/chaosblade-spec-go/log"
26 | "github.com/chaosblade-io/chaosblade-spec-go/spec"
27 | )
28 |
29 | type VariableModifiedActionSpec struct {
30 | spec.BaseExpActionCommandSpec
31 | }
32 |
33 | func NewVariableModifiedActionSpec() spec.ExpActionCommandSpec {
34 | return &VariableModifiedActionSpec{
35 | spec.BaseExpActionCommandSpec{
36 | ActionMatchers: []spec.ExpFlagSpec{},
37 | ActionFlags: []spec.ExpFlagSpec{
38 | &spec.ExpFlag{
39 | Name: "variableName",
40 | Desc: "The name of the modified variable",
41 | Required: true,
42 | },
43 | &spec.ExpFlag{
44 | Name: "variableValue",
45 | Desc: "The value of the modified variable",
46 | Required: true,
47 | },
48 | },
49 | ActionExecutor: &VariableModifiedExecutor{},
50 | },
51 | }
52 | }
53 |
54 | func (v *VariableModifiedActionSpec) Name() string {
55 | return "modify"
56 | }
57 |
58 | func (v *VariableModifiedActionSpec) Aliases() []string {
59 | return []string{}
60 | }
61 |
62 | func (v *VariableModifiedActionSpec) ShortDesc() string {
63 | return "Modify value of the variable in source code when program running"
64 | }
65 |
66 | func (v *VariableModifiedActionSpec) LongDesc() string {
67 | return "Modify value of the variable in source code when program running"
68 | }
69 |
70 | type VariableModifiedExecutor struct {
71 | channel spec.Channel
72 | }
73 |
74 | func (v *VariableModifiedExecutor) Name() string {
75 | return "modify"
76 | }
77 |
78 | func (v *VariableModifiedExecutor) Exec(uid string, ctx context.Context, model *spec.ExpModel) *spec.Response {
79 | variableName := model.ActionFlags["variableName"]
80 | if variableName == "" {
81 | return spec.ResponseFailWithFlags(spec.ParameterLess, "variableName")
82 | }
83 | variableValue := model.ActionFlags["variableValue"]
84 | if variableValue == "" {
85 | return spec.ResponseFailWithFlags(spec.ParameterLess, "variableValue")
86 | }
87 | // search pid by process name
88 | processName := model.ActionFlags["processName"]
89 | if processName == "" {
90 | return spec.ResponseFailWithFlags(spec.ParameterLess, "processName")
91 | }
92 | processCtx := context.WithValue(context.Background(), channel.ExcludeProcessKey, "blade")
93 | pids, err := channel.NewLocalChannel().GetPidsByProcessName(processName, processCtx)
94 | if err != nil {
95 | log.Warnf(ctx, "get pids by %s process name err, %v", processName, err)
96 | }
97 | localChannel := channel.NewLocalChannel()
98 | if pids == nil || len(pids) == 0 {
99 | args := buildArgs([]string{
100 | model.ActionFlags["fileLocateAndName"],
101 | model.ActionFlags["forkMode"],
102 | model.ActionFlags["libLoad"],
103 | model.ActionFlags["breakLine"],
104 | variableName,
105 | variableValue,
106 | model.ActionFlags["initParams"],
107 | })
108 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.ModifyVariableScript), args)
109 | } else {
110 | args := buildArgs([]string{
111 | pids[0],
112 | model.ActionFlags["forkMode"],
113 | "",
114 | "",
115 | model.ActionFlags["breakLine"],
116 | variableName,
117 | variableValue,
118 | model.ActionFlags["initParams"],
119 | })
120 | if "child" == model.ActionFlags["forkMode"] {
121 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.ModifyVariableAttachScript), args)
122 | }
123 | return localChannel.Run(context.Background(), path.Join(common.GetScriptPath(), common.ModifyVariableAttachParentScript), args)
124 | }
125 | }
126 |
127 | func (v *VariableModifiedExecutor) SetChannel(channel spec.Channel) {
128 | v.channel = channel
129 | }
130 |
--------------------------------------------------------------------------------
/controller/create.go:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 1999-2020 Alibaba Group Holding Ltd.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package controller
18 |
19 | import (
20 | "context"
21 | "fmt"
22 | "net/http"
23 |
24 | "github.com/chaosblade-io/chaosblade-spec-go/spec"
25 |
26 | "github.com/wetcatacomb/chaosblade-exec-cplus/common"
27 | )
28 |
29 | const CreateName = "create"
30 |
31 | type CreateController struct {
32 | }
33 |
34 | func (c *CreateController) GetControllerName() string {
35 | return CreateName
36 | }
37 |
38 | func (c *CreateController) GetRequestHandler() func(writer http.ResponseWriter, request *http.Request) {
39 | return func(writer http.ResponseWriter, request *http.Request) {
40 | expModel, suid, err := convertRequestToExpModel(request)
41 | if err != nil {
42 | fmt.Fprintf(writer, spec.ResponseFailWithFlags(spec.CommandIllegal, err).Print())
43 | return
44 | }
45 | actionModel := Manager.Actions[expModel.ActionName]
46 | if actionModel == nil {
47 | fmt.Fprintf(writer, spec.ResponseFailWithFlags(spec.ActionNotSupport, expModel.ActionName).Print())
48 | return
49 | }
50 | // record
51 | err = Manager.Record(suid, expModel)
52 | if err != nil {
53 | fmt.Fprintf(writer, spec.ResponseFailWithFlags(spec.DatabaseError, "record", err).Print())
54 | return
55 | }
56 | response := actionModel.Executor().Exec(suid, context.Background(), expModel)
57 | if !response.Success {
58 | Manager.Remove(suid)
59 | }
60 | fmt.Fprintf(writer, response.Print())
61 | }
62 | }
63 |
64 | func convertRequestToExpModel(request *http.Request) (*spec.ExpModel, string, error) {
65 | err := request.ParseForm()
66 | if err != nil {
67 | return nil, "", err
68 | }
69 | flags := make(map[string]string, 0)
70 |
71 | suid := request.Form.Get("suid")
72 | if suid == "" {
73 | return nil, "", fmt.Errorf("illegal suid parameter")
74 | }
75 | target := request.Form.Get("target")
76 | if target != common.TargetName {
77 | return nil, suid, fmt.Errorf("the target not support")
78 | }
79 | action := request.Form.Get("action")
80 | if action == "" {
81 | return nil, suid, fmt.Errorf("less action parameter")
82 | }
83 | breakLine := request.Form.Get("breakLine")
84 | if breakLine == "" {
85 | return nil, suid, fmt.Errorf("less breakLine parameter")
86 | }
87 | flags["breakLine"] = breakLine
88 | fileLocateAndName := request.Form.Get("fileLocateAndName")
89 | if fileLocateAndName == "" {
90 | return nil, suid, fmt.Errorf("less fileLocateAndName parameter")
91 | }
92 | flags["fileLocateAndName"] = fileLocateAndName
93 | forkMode := request.Form.Get("forkMode")
94 | if forkMode == "" {
95 | return nil, suid, fmt.Errorf("less forkMode parameter")
96 | }
97 | flags["forkMode"] = forkMode
98 | processName := request.Form.Get("processName")
99 | if processName == "" {
100 | return nil, suid, fmt.Errorf("less processName parameter")
101 | }
102 | flags["processName"] = processName
103 | libLoad := request.Form.Get("libLoad")
104 | if libLoad != "" {
105 | libLoad = common.SetEnvLdLibraryPath + libLoad
106 | }
107 | flags["libLoad"] = libLoad
108 | initParams := request.Form.Get("initParams")
109 | if initParams != "" {
110 | flags["initParams"] = initParams
111 | }
112 |
113 | // TODO delay
114 | delayDuration := request.Form.Get("delayDuration")
115 | if delayDuration != "" {
116 | flags["delayDuration"] = delayDuration
117 | }
118 | // return
119 | returnValue := request.Form.Get("returnValue")
120 | if returnValue != "" {
121 | flags["returnValue"] = returnValue
122 | }
123 |
124 | // modify
125 | variableValue := request.Form.Get("variableValue")
126 | if variableValue != "" {
127 | flags["variableValue"] = variableValue
128 | }
129 | variableName := request.Form.Get("variableName")
130 | if variableName != "" {
131 | flags["variableName"] = variableName
132 | }
133 |
134 | return &spec.ExpModel{
135 | Target: common.TargetName,
136 | Scope: "",
137 | ActionName: action,
138 | ActionFlags: flags,
139 | }, suid, nil
140 | }
141 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to chaosblade-exec-cplus
2 |
3 | Welcome to ChaosBlade world, here is a list of contributing guide for you. If you find something incorrect or missing
4 | content in the page, please submit an issue or PR to fix it.
5 |
6 |
7 | ## What can you do
8 | Every action to make project better is encouraged. On GitHub, every improvement for the project could be via a PR
9 | (short
10 | for pull request).
11 |
12 | * If you find a typo, try to fix it!
13 | * If you find a bug, try to fix it!
14 | * If you find some redundant codes, try to remove them!
15 | * If you find some test cases missing, try to add them!
16 | * If you could enhance a feature, please **DO NOT** hesitate!
17 | * If you find code implicit, try to add comments to make it clear!
18 | * If you find code ugly, try to refactor that!
19 | * If you can help to improve documents, it could not be better!
20 | * If you find document incorrect, just do it and fix that!
21 | * ...
22 |
23 | Actually it is impossible to list them completely. Just remember one principle:
24 |
25 | **WE ARE LOOKING FORWARD TO ANY PR FROM YOU.**
26 |
27 |
28 | ## Contributing
29 | ### Preparation
30 | Before you contribute, you need to register a Github ID. Prepare the following environment:
31 | * JDK 1.8+
32 | * git
33 |
34 | ### Workflow
35 | We use the `master` branch as the development branch, which indicates that this is a unstable branch.
36 |
37 | Here are the workflow for contributors:
38 |
39 | 1. Fork to your own
40 | 2. Clone fork to local repository
41 | 3. Create a new branch and work on it
42 | 4. Keep your branch in sync
43 | 5. Commit your changes (make sure your commit message concise)
44 | 6. Push your commits to your forked repository
45 | 7. Create a pull request
46 |
47 | Please follow [the pull request template](./.github/PULL_REQUEST_TEMPLATE.md).
48 | Please make sure the PR has a corresponding issue.
49 |
50 | After creating a PR, one or more reviewers will be assigned to the pull request.
51 | The reviewers will review the code.
52 |
53 | Before merging a PR, squash any fix review feedback, typo, merged, and rebased sorts of commits.
54 | The final commit message should be clear and concise.
55 |
56 | ### Compile
57 | In the project root directory, execute the following command to compile
58 | ```bash
59 | Sh build.sh
60 | ```
61 |
62 | The compilation result will be stored in the target directory.
63 |
64 | ### Code Style
65 | We suggest that all contributors should install [p3c](https://github.com/alibaba/p3c) plugin to unify code style and
66 | analyze code quality.
67 |
68 | ### Commit Rules
69 | #### Commit Message
70 |
71 | Commit message could help reviewers better understand what is the purpose of submitted PR. It could help accelerate the code review procedure as well. We encourage contributors to use **EXPLICIT** commit message rather than ambiguous message. In general, we advocate the following commit message type:
72 |
73 | * feat: A new feature
74 | * fix: A bug fix
75 | * docs: Documentation only changes
76 | * style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
77 | * refactor: A code change that neither fixes a bug nor adds a feature
78 | * perf: A code change that improves performance
79 | * test: Adding missing or correcting existing tests
80 | * chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
81 |
82 | On the other side, we discourage contributors from committing message like the following ways:
83 |
84 | * ~~fix bug~~
85 | * ~~update~~
86 | * ~~add doc~~
87 |
88 | If you get lost, please see [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/) for a start.
89 |
90 | #### Commit Content
91 |
92 | Commit content represents all content changes included in one commit. We had better include things in one single commit which could support reviewer's complete review without any other commits' help. In another word, contents in one single commit can pass the CI to avoid code mess. In brief, there are two minor rules for us to keep in mind:
93 |
94 | * avoid very large change in a commit;
95 | * complete and reviewable for each commit.
96 |
97 | No matter commit message, or commit content, we do take more emphasis on code review.
98 |
99 |
100 | ### Pull Request
101 | We use [GitHub Issues](https://github.com/wetcatacomb/chaosblade-exec-cplus/issues) and [Pull Requests](https://github.com/wetcatacomb/chaosblade-exec-cplus/pulls) for trackers.
102 |
103 | If you find a typo in document, find a bug in code, or want new features, or want to give suggestions,
104 | you can [open an issue on GitHub](https://github.com/wetcatacomb/chaosblade-exec-cplus/issues/new) to report it.
105 | Please follow the guideline message in the issue template.
106 |
107 | If you want to contribute, please follow the [contribution workflow](#Workflow) and create a new pull request.
108 | If your PR contains large changes, e.g. component refactor or new components, please write detailed documents
109 | about its design and usage.
110 |
111 | Note that a single PR should not be too large. If heavy changes are required, it's better to separate the changes
112 | to a few individual PRs.
113 |
114 |
115 | ### Code Review
116 | All code should be well reviewed by one or more committers. Some principles:
117 |
118 | - Readability: Important code should be well-documented. Comply with our code style.
119 | - Elegance: New functions, classes or components should be well designed.
120 | - Testability: Important code should be well-tested (high unit test coverage).
121 |
122 | ## Community
123 | ### Contact Us
124 | #### Mailing list
125 | If you have any questions or advice, please contact chaosblade.io.01@gmail.com.
126 |
127 | #### DingDing
128 | You can also search the ID: `23177705` in dingding(钉钉) app to join the ChaosBlade group.
129 |
130 |
131 | ## Others
132 | ### Code of Conduct
133 | *"In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making
134 | participation in our project and our community a harassment-free experience for everyone, regardless of age, body
135 | size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education,
136 | socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation..."*
137 |
138 | See details of [CONTRIBUTOR COVENANT CODE OF CONDUCT](https://github.com/wetcatacomb/chaosblade-exec-cplus/blob/master/CODE_OF_CONDUCT.md)
139 |
140 | ### Sign your work
141 | The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an open-source patch.
142 | The rules are pretty simple: if you can certify the below (from [developercertificate.org](http://developercertificate.org/)):
143 |
144 | ```
145 | Developer Certificate of Origin
146 | Version 1.1
147 |
148 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
149 | 660 York Street, Suite 102,
150 | San Francisco, CA 94110 USA
151 |
152 | Everyone is permitted to copy and distribute verbatim copies of this
153 | license document, but changing it is not allowed.
154 |
155 | Developer's Certificate of Origin 1.1
156 |
157 | By making a contribution to this project, I certify that:
158 |
159 | (a) The contribution was created in whole or in part by me and I
160 | have the right to submit it under the open source license
161 | indicated in the file; or
162 |
163 | (b) The contribution is based upon previous work that, to the best
164 | of my knowledge, is covered under an appropriate open source
165 | license and I have the right under that license to submit that
166 | work with modifications, whether created in whole or in part
167 | by me, under the same open source license (unless I am
168 | permitted to submit under a different license), as indicated
169 | in the file; or
170 |
171 | (c) The contribution was provided directly to me by some other
172 | person who certified (a), (b) or (c) and I have not modified
173 | it.
174 |
175 | (d) I understand and agree that this project and the contribution
176 | are public and that a record of the contribution (including all
177 | personal information I submit with it, including my sign-off) is
178 | maintained indefinitely and may be redistributed consistent with
179 | this project or the open source license(s) involved.
180 | ```
181 |
182 | Then you just add a line to every git commit message:
183 |
184 | ```
185 | Signed-off-by: Joe Smith
186 | ```
187 |
188 | Use your real name (sorry, no pseudonyms or anonymous contributions.)
189 |
190 | If you set your `user.name` and `user.email` git configs, you can sign your commit automatically with `git commit -s`.
191 |
--------------------------------------------------------------------------------