Skip to content

Commit

Permalink
fix: jvm inject in container; feat: support set env from target process
Browse files Browse the repository at this point in the history
  • Loading branch information
KingsonKai committed Sep 27, 2023
1 parent 08a7b9b commit b71e61f
Show file tree
Hide file tree
Showing 19 changed files with 97 additions and 22 deletions.
2 changes: 1 addition & 1 deletion chaosmeta-deploy/templates/chaosmeta-daemon-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ spec:
# chaos-role.chaosmeta.io: chaosmeta-daemon
containers:
- name: chaosmeta-daemon
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-daemon:v0.3.0
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-daemon:v0.3.2
securityContext:
privileged: true
volumeMounts:
Expand Down
4 changes: 2 additions & 2 deletions chaosmeta-deploy/templates/chaosmeta-inject-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ spec:
- --leader-elect
command:
- /manager
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-inject-controller:v0.1.0
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-inject-controller:v0.1.1
livenessProbe:
httpGet:
path: /healthz
Expand Down Expand Up @@ -507,7 +507,7 @@ data:
"executor": {
"mode": "daemonset",
"executor": "chaosmetad",
"version": "0.3.0",
"version": "0.3.2",
"agentConfig": {
"agentPort": 29595
},
Expand Down
2 changes: 1 addition & 1 deletion chaosmeta-inject-operator/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

# Image URL to use all building/pushing image targets
IMG ?= registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-inject-controller:v0.1.0
IMG ?= registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-inject-controller:v0.1.1
# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary.
ENVTEST_K8S_VERSION = 1.25.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ spec:
# chaos-role.chaosmeta.io: chaosmeta-daemon
containers:
- name: chaosmeta-daemon
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-daemon:v0.1.1
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-daemon:v0.3.2
securityContext:
privileged: true
volumeMounts:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ spec:
- --leader-elect
command:
- /manager
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-inject-controller:v0.1.0
image: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-inject-controller:v0.1.1
livenessProbe:
httpGet:
path: /healthz
Expand Down
2 changes: 1 addition & 1 deletion chaosmeta-inject-operator/config/chaosmeta-inject.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"executor": {
"mode": "daemonset",
"executor": "chaosmetad",
"version": "0.3.0",
"version": "0.3.2",
"agentConfig": {
"agentPort": 29595
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ kind: Kustomization
images:
- name: controller
newName: registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-inject-controller
newTag: v0.1.0
newTag: v0.1.1
4 changes: 2 additions & 2 deletions chaosmetad/build/chaosmeta-daemonset.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# docker build -t registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-daemon:v0.3.0 -f chaosmeta-daemonset.Dockerfile .
# docker build -t registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmeta-daemon:v0.3.2 -f chaosmeta-daemonset.Dockerfile .
From centos:centos7
ENV CHAOSMETAD_VERSION=0.3.0
ENV CHAOSMETAD_VERSION=0.3.2
ADD ./chaosmetad-$CHAOSMETAD_VERSION.tar.gz /opt/chaosmeta
CMD while true; do if [ ! -d "/tmp/chaosmetad-$CHAOSMETAD_VERSION" ]; then cp -r /opt/chaosmeta/chaosmetad-$CHAOSMETAD_VERSION /tmp/chaosmetad-$CHAOSMETAD_VERSION; fi; sleep 600; done
9 changes: 6 additions & 3 deletions chaosmetad/build/chaosmetad-demo.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# docker build -t registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmetad-demo:v0.3.0 -f chaosmetad-demo.Dockerfile .
# docker build -t registry.cn-hangzhou.aliyuncs.com/chaosmeta/chaosmetad-demo:v0.3.2 -f chaosmetad-demo.Dockerfile .
From centos:centos7
ADD ./jdk-8u361-linux-x64.tar.gz /usr/local
RUN yum install -y iproute && yum clean all
ENV CHAOSMETAD_VERSION=0.3.0
ENV CHAOSMETAD_VERSION=0.3.2 \
JAVA_HOME=/usr/local/jdk1.8.0_361 \
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/chaosmeta/chaosmetad-0.3.2:/usr/local/jdk1.8.0_361/bin

ADD ./chaosmetad-$CHAOSMETAD_VERSION.tar.gz /opt/chaosmeta
RUN echo 'export JAVA_HOME=/usr/local/jdk1.8.0_361' >> /etc/profile && echo 'export PATH=$PATH:$JAVA_HOME/bin' >> /etc/profile && echo 'export PATH=$PATH:/opt/chaosmeta/chaosmetad-'${CHAOSMETAD_VERSION} >> /etc/profile
#RUN echo 'export JAVA_HOME=/usr/local/jdk1.8.0_361' >> /etc/profile && echo 'export PATH=$PATH:$JAVA_HOME/bin' >> /etc/profile && echo 'export PATH=$PATH:/opt/chaosmeta/chaosmetad-'${CHAOSMETAD_VERSION} >> /etc/profile
2 changes: 1 addition & 1 deletion chaosmetad/build/ci/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fi

# base info
BUILD_NAME="chaosmetad"
VERSION="0.3.0"
VERSION="0.3.2"
BUILD_DATE=$(date "+%Y-%m-%d %H:%M:%S")

# env var
Expand Down
45 changes: 44 additions & 1 deletion chaosmetad/pkg/exec/execns/chaosmeta_execns.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,38 @@
#include <getopt.h>
#include <signal.h>

int set_env(int pid) {
char cmd[64];
snprintf(cmd, sizeof(cmd), "cat /proc/%d/environ | tr '\\0' '\\t'", pid);

FILE* pipe = popen(cmd, "r");
if (pipe == NULL) {
fprintf(stderr, "Failed to execute command: %s\n", cmd);
return -1;
}

char env_data[4096];
fgets(env_data, sizeof(env_data), pipe);
pclose(pipe);

char* tmp;
int length = strlen(env_data);
tmp = (char*)malloc(length + 1);
strcpy(tmp, env_data);

char* env_var;
env_var = strtok(tmp, "\t");
while (env_var != NULL) {
if (putenv(env_var) != 0) {
fprintf(stderr, "failed to set environment variable[%s].\n", env_var);
return -1;
}
env_var = strtok(NULL, "\t");
}

return 0;
}

int enter_ns(int pid, const char* type) {
char path[64], selfpath[64];
snprintf(path, sizeof(path), "/proc/%d/ns/%s", pid, type);
Expand Down Expand Up @@ -76,7 +108,8 @@ int main(int argc, char *argv[]) {
int netns = 0;
int pidns = 0;
int mntns = 0;
char *string = "c:t:mpuni";
int envns = 0;
char *string = "c:t:mpunie";

while((opt =getopt(argc, argv, string))!= -1) {
switch (opt) {
Expand All @@ -101,6 +134,9 @@ int main(int argc, char *argv[]) {
case 'i':
ipcns = 1;
break;
case 'e':
envns = 1;
break;
default:
break;
}
Expand All @@ -116,6 +152,13 @@ int main(int argc, char *argv[]) {
return 1;
}

if(envns) {
int re = set_env(target);
if (re != 0) {
return re;
}
}

if(ipcns) {
int re = enter_ns(target, "ipc");
if (re != 0) {
Expand Down
13 changes: 12 additions & 1 deletion chaosmetad/pkg/injector/jvm/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ func writeRule(ctx context.Context, cId string, pid int, ruleBytes []byte) error
return nil
}

// TODO: It is currently impossible to determine accurately because the ExecContainer function does not completely determine whether it is successful based on the return code.
func checkJavaCmd(ctx context.Context, cr, cId string) error {
cmd := "java -help"
if cr != "" {
_, err := cmdexec.ExecContainer(ctx, cr, cId, []string{namespace.MNT, namespace.ENV}, cmd, cmdexec.ExecRun)
return err
} else {
return cmdexec.RunBashCmdWithoutOutput(ctx, cmd)
}
}

func doInject(ctx context.Context, cr, cId string, pidList []int, ruleBytes []byte) error {
// create rule file
for _, pid := range pidList {
Expand Down Expand Up @@ -143,7 +154,7 @@ func doInject(ctx context.Context, cr, cId string, pidList []int, ruleBytes []by
for _, pid := range pidList {
cmd := fmt.Sprintf("cd %s && java -cp .:tools.jar %s %d %s %s", JVMContainerDir, AttacherTool, pid,
fmt.Sprintf("%s/%s", JVMContainerDir, JVMAgentTool), getContainerRuleFile(pid))
if _, err := cmdexec.ExecContainer(ctx, cr, cId, []string{namespace.MNT, namespace.PID, namespace.MNT}, cmd, cmdexec.ExecStart); err != nil {
if _, err := cmdexec.ExecContainer(ctx, cr, cId, []string{namespace.MNT, namespace.PID, namespace.IPC, namespace.ENV}, cmd, cmdexec.ExecStart); err != nil {
return fmt.Errorf("execute fault for process[%d] error: %s", pid, err.Error())
}
}
Expand Down
4 changes: 4 additions & 0 deletions chaosmetad/pkg/injector/jvm/methoddelay.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ func (i *MethodDelayInjector) Validator(ctx context.Context) error {
return fmt.Errorf("\"method\" is invalid: %s", err.Error())
}

if err := checkJavaCmd(ctx, i.Info.ContainerRuntime, i.Info.ContainerId); err != nil {
return fmt.Errorf("check java exec error: %s", err.Error())
}

return nil
}

Expand Down
4 changes: 4 additions & 0 deletions chaosmetad/pkg/injector/jvm/methodexception.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ func (i *MethodExceptionInjector) Validator(ctx context.Context) error {
return fmt.Errorf("\"method\" is invalid: %s", err.Error())
}

if err := checkJavaCmd(ctx, i.Info.ContainerRuntime, i.Info.ContainerId); err != nil {
return fmt.Errorf("check java exec error: %s", err.Error())
}

return nil
}

Expand Down
4 changes: 4 additions & 0 deletions chaosmetad/pkg/injector/jvm/methodreturn.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ func (i *MethodReturnInjector) Validator(ctx context.Context) error {
return fmt.Errorf("\"method\" is invalid: %s", err.Error())
}

if err := checkJavaCmd(ctx, i.Info.ContainerRuntime, i.Info.ContainerId); err != nil {
return fmt.Errorf("check java exec error: %s", err.Error())
}

return nil
}

Expand Down
11 changes: 7 additions & 4 deletions chaosmetad/pkg/utils/cmdexec/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,16 +186,17 @@ func RunBashCmdWithOutput(ctx context.Context, cmd string) (string, error) {

reByte, err := c.CombinedOutput()
re := string(reByte)
log.GetLogger(ctx).Debugf("output: %s, err: %v", re, err)
if err != nil {
if c.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() == errutil.ExpectedErr {
return "", fmt.Errorf(re)
return "", fmt.Errorf("output: %s, error: %s", re, err.Error())
}

if c.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() == errutil.TestFileErr {
return "", fmt.Errorf("exit code: %d, error: %s", errutil.TestFileErr, re)
return "", fmt.Errorf("exit code: %d, output: %s, error: %s", errutil.TestFileErr, re, err.Error())
}

return "", fmt.Errorf("%s, output: %s", err.Error(), re)
return "", fmt.Errorf("error: %s, output: %s", err.Error(), re)
}

return re, nil
Expand Down Expand Up @@ -329,7 +330,9 @@ func ExecContainerRaw(ctx context.Context, cr, cId, cmd string) (string, error)
}

log.GetLogger(ctx).Debugf("container: %s, exec cmd: %s", cId, cmd)
return client.Exec(ctx, cId, cmd)
re, err := client.Exec(ctx, cId, cmd)
log.GetLogger(ctx).Debugf("container: %s, output: %s, err: %v", cId, re, err)
return re, err
}

func ExecCommon(ctx context.Context, cr, cId, cmd string) (string, error) {
Expand Down
4 changes: 3 additions & 1 deletion chaosmetad/pkg/utils/namespace/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ func GetNsOption(namespaces []string) string {
nsOptionStr += " -n"
case IPC:
nsOptionStr += " -i"
case ENV:
nsOptionStr += " -e"
}
}

return nsOptionStr
}
}
1 change: 1 addition & 0 deletions chaosmetad/pkg/utils/namespace/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ const (
NET = "net"
PID = "pid"
UTS = "uts"
ENV = "env"
)
2 changes: 1 addition & 1 deletion chaosmetad/test/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func main() {
path = filepath.Dir(path)
pathArr := strings.Split(path, "/")
rootPath := strings.Join(pathArr[:len(pathArr)-1], "/")
tool := fmt.Sprintf("%s/build/chaosmetad-0.3.0/chaosmetad", rootPath)
tool := fmt.Sprintf("%s/build/chaosmetad-0.3.2/chaosmetad", rootPath)
fmt.Println(tool)

var testCases = getTestCases()
Expand Down

0 comments on commit b71e61f

Please sign in to comment.