Skip to content

Commit

Permalink
Merge pull request #1049 from chaosblade-io/1.7.4-fix-jvm-cannot-exec…
Browse files Browse the repository at this point in the history
…-by-username

Enhancement : attach appliction but cannt get userName
  • Loading branch information
MandssS committed Jul 3, 2024
2 parents 3ed768a + ffa6d94 commit 5e9228e
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 78 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: build clean

export BLADE_VERSION=1.7.3
export BLADE_VERSION=1.7.4

ALLOWGITVERSION=1.8.5
GITVERSION:=$(shell git --version | grep ^git | sed 's/^.* //g')
Expand Down
2 changes: 1 addition & 1 deletion build/spec/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/chaosblade-io/chaosblade/cli/cmd"
)

var version = "1.7.3"
var version = "1.7.4"

func main() {

Expand Down
39 changes: 20 additions & 19 deletions cli/cmd/prepare_jvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/chaosblade-io/chaosblade-spec-go/log"
"path"
"strconv"
"strings"
"time"

"github.com/chaosblade-io/chaosblade-spec-go/log"

"github.com/chaosblade-io/chaosblade-spec-go/channel"
"github.com/chaosblade-io/chaosblade-spec-go/spec"
"github.com/chaosblade-io/chaosblade-spec-go/util"
Expand Down Expand Up @@ -145,13 +146,13 @@ func (pc *PrepareJvmCommand) reportAttachedResult(ctx context.Context, response

// attachAgent
func (pc *PrepareJvmCommand) attachAgent(ctx context.Context) *spec.Response {
response, username := jvm.Attach(ctx, strconv.Itoa(pc.port), pc.javaHome, pc.processId)
if !response.Success && username != "" && strings.Contains(response.Err, "connection refused") {
response, username, userid := jvm.Attach(ctx, strconv.Itoa(pc.port), pc.javaHome, pc.processId)
if !response.Success && (username != "" || userid != "") && strings.Contains(response.Err, "connection refused") {
// if attach failed, search port from ~/.sandbox.token
port, err := jvm.CheckPortFromSandboxToken(ctx, username)
if err == nil {
log.Infof(ctx, "use %s port to retry", port)
response, username = jvm.Attach(ctx, port, pc.javaHome, pc.processId)
response, username, userid = jvm.Attach(ctx, port, pc.javaHome, pc.processId)
if response.Success {
// update port
err := updatePreparationPort(pc.uid, port)
Expand Down Expand Up @@ -228,21 +229,21 @@ func (pc *PrepareJvmCommand) invokeAttaching(ctx context.Context, port string, u
}

/*
{
"data":{ #PreparestatusBean
"createTime":"",
"error":"",
"pid":"",
"port":"",
"process":"sss",
"running":false,
"status":"",
"type":"",
"uid":"",
"updateTime":""
},
"type":"JAVA_AGENT_PREPARE"
}
{
"data":{ #PreparestatusBean
"createTime":"",
"error":"",
"pid":"",
"port":"",
"process":"sss",
"running":false,
"status":"",
"type":"",
"uid":"",
"updateTime":""
},
"type":"JAVA_AGENT_PREPARE"
}
*/
func createPostBody(ctx context.Context) ([]byte, error) {
preparationRecord, err := GetDS().QueryPreparationByUid(uid)
Expand Down
11 changes: 6 additions & 5 deletions exec/jvm/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/chaosblade-io/chaosblade-spec-go/log"
"strconv"
"strings"
"time"

"github.com/chaosblade-io/chaosblade-spec-go/log"

"github.com/chaosblade-io/chaosblade-spec-go/channel"
"github.com/chaosblade-io/chaosblade-spec-go/spec"
"github.com/chaosblade-io/chaosblade-spec-go/util"
Expand Down Expand Up @@ -378,15 +379,15 @@ func Prepare(ctx context.Context, processName, processId, javaHome string) (resp
return spec.ResponseFailWithFlags(spec.DatabaseError, "insert", err), port
}
}
var username string
var username, userid string
port = record.Port
response, username = Attach(ctx, port, javaHome, processId)
if !response.Success && username != "" && strings.Contains(response.Err, "connection refused") {
response, username, userid = Attach(ctx, port, javaHome, processId)
if !response.Success && (username != "" || userid != "") && strings.Contains(response.Err, "connection refused") {
// if attach failed, search port from ~/.sandbox.token
port, err = CheckPortFromSandboxToken(ctx, username)
if err == nil {
log.Infof(ctx, "use %s port to retry", port)
response, username = Attach(ctx, port, "", processId)
response, username, userid = Attach(ctx, port, "", processId)
if response.Success {
// update port
err := db.UpdatePreparationPortByUid(record.Uid, port)
Expand Down
75 changes: 57 additions & 18 deletions exec/jvm/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"os"
osuser "os/user"
"path"
"regexp"
"strconv"
"strings"
"time"
Expand All @@ -38,20 +39,20 @@ var cl = channel.NewLocalChannel()

const DefaultNamespace = "chaosblade"

func Attach(ctx context.Context, port, javaHome, pid string) (*spec.Response, string) {
func Attach(ctx context.Context, port, javaHome, pid string) (*spec.Response, string, string) {
// refresh
response, username := attach(ctx, pid, port, javaHome)
response, username, userid := attach(ctx, pid, port, javaHome)
if !response.Success {
return response, username
return response, username, userid
}
time.Sleep(5 * time.Second)
// active
response = active(ctx, port)
if !response.Success {
return response, username
return response, username, userid
}
// check
return check(ctx, port), username
return check(ctx, port), username, userid
}

// curl -s http://localhost:$2/sandbox/default/module/http/chaosblade/status 2>&1
Expand Down Expand Up @@ -85,52 +86,72 @@ func active(ctx context.Context, port string) *spec.Response {
}

// attach java agent to application process
func attach(ctx context.Context, pid, port string, javaHome string) (*spec.Response, string) {
func attach(ctx context.Context, pid, port string, javaHome string) (*spec.Response, string, string) {
username, err := getUsername(pid)
userid := ""
if err != nil {
log.Errorf(ctx, spec.ProcessGetUsernameFailed.Sprintf(pid, err))
return spec.ResponseFailWithFlags(spec.ProcessGetUsernameFailed, pid, err), ""
userid, err = getUserid(ctx, pid)
if err != nil {
log.Errorf(ctx, spec.ProcessGetUsernameFailed.Sprintf(pid, err))
return spec.ResponseFailWithFlags(spec.ProcessGetUsernameFailed, pid, err), "", ""
}
}
javaBin, javaHome := getJavaBinAndJavaHome(ctx, javaHome, pid, getJavaCommandLine)
toolsJar := getToolJar(ctx, javaHome)
log.Infof(ctx, "javaBin: %s, javaHome: %s, toolsJar: %s", javaBin, javaHome, toolsJar)
log.Infof(ctx, "javaBin: %s, javaHome: %s, toolsJar: %s, username: %s, userid: %s", javaBin, javaHome, toolsJar, username, userid)
token, err := getSandboxToken(ctx)
if err != nil {
log.Errorf(ctx, spec.SandboxCreateTokenFailed.Sprintf(err))
return spec.ResponseFailWithFlags(spec.SandboxCreateTokenFailed, err), username
return spec.ResponseFailWithFlags(spec.SandboxCreateTokenFailed, err), username, userid
}
javaArgs := getAttachJvmOpts(toolsJar, token, port, pid)
currUser, err := osuser.Current()
if err != nil {
log.Warnf(ctx, "get current user info failed, %v", err)
log.Warnf(ctx, "get current user info failed, curr user: %v, %v", currUser, err)
if strings.Contains(err.Error(), "unknown userid") {
reg, e := regexp.Compile(`\d+`)
if e == nil {
uid := reg.FindString(err.Error())
currUser = &osuser.User{
Uid: uid,
}
}
}

}

var command string
if currUser != nil && (currUser.Username == username) {
if currUser != nil && (currUser.Username == username || currUser.Uid == userid) {
command = fmt.Sprintf("%s %s", javaBin, javaArgs)
} else {
if currUser != nil {
log.Infof(ctx, "current user name is %s, not equal %s, so use sudo command to execute",
currUser.Username, username)
log.Infof(ctx, "current user name is %s, not equal %s|%s, so use sudo command to execute",
currUser.Username, username, userid)
}
if username != "" {
command = fmt.Sprintf("sudo -u %s %s %s", username, javaBin, javaArgs)
} else if userid != "" {
command = fmt.Sprintf("su - #%s -c '%s %s'", userid, javaBin, javaArgs)
}
command = fmt.Sprintf("sudo -u %s %s %s", username, javaBin, javaArgs)

}
javaToolOptions := os.Getenv("JAVA_TOOL_OPTIONS")
if javaToolOptions != "" {
command = fmt.Sprintf("export JAVA_TOOL_OPTIONS='' && %s", command)
}
response := cl.Run(ctx, "", command)
if !response.Success {
return response, username
return response, username, userid
}
osCmd := fmt.Sprintf("grep %s", fmt.Sprintf(`%s %s | grep %s | tail -1 | awk -F ";" '{print $3";"$4}'`,
token, getSandboxTokenFile(username), DefaultNamespace))
response = cl.Run(ctx, "", osCmd)
// if attach successfully, the sandbox-agent.jar will write token to local file
if !response.Success {
log.Errorf(ctx, spec.OsCmdExecFailed.Sprintf(osCmd, response.Err))
return spec.ResponseFailWithFlags(spec.OsCmdExecFailed, osCmd, response.Err), username
return spec.ResponseFailWithFlags(spec.OsCmdExecFailed, osCmd, response.Err), username, userid
}
return response, username
return response, username, userid
}

func getAttachJvmOpts(toolsJar string, token string, port string, pid string) string {
Expand Down Expand Up @@ -177,6 +198,24 @@ func getUsername(pid string) (string, error) {
return javaProcess.Username()
}

func getUserid(ctx context.Context, pid string) (string, error) {
p, err := strconv.Atoi(pid)
if err != nil {
return "", err
}
javaProcess, err := process.NewProcess(int32(p))
if err != nil {
return "", err
}

userIds, err := javaProcess.Uids()
if err == nil && cap(userIds) > 0 {
userid := strconv.Itoa(int(userIds[0]))
return userid, err
}
return "", err
}

func getJavaBinAndJavaHome(ctx context.Context, javaHome string, pid string,
getJavaCommandLineFunc func(ctx context.Context, pid string) (commandSlice []string, err error)) (string, string) {
javaBin := "java"
Expand Down
22 changes: 11 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ module github.com/chaosblade-io/chaosblade
go 1.20

require (
github.com/chaosblade-io/chaosblade-exec-cloud v1.7.3
github.com/chaosblade-io/chaosblade-exec-cri v1.7.3
github.com/chaosblade-io/chaosblade-exec-middleware v1.7.3
github.com/chaosblade-io/chaosblade-exec-os v1.7.3
github.com/chaosblade-io/chaosblade-operator v1.7.3
github.com/chaosblade-io/chaosblade-spec-go v1.7.3
github.com/chaosblade-io/chaosblade-exec-cloud v1.7.4
github.com/chaosblade-io/chaosblade-exec-cri v1.7.4
github.com/chaosblade-io/chaosblade-exec-middleware v1.7.4
github.com/chaosblade-io/chaosblade-exec-os v1.7.4
github.com/chaosblade-io/chaosblade-operator v1.7.4
github.com/chaosblade-io/chaosblade-spec-go v1.7.4
github.com/mattn/go-sqlite3 v1.10.1-0.20190217174029-ad30583d8387
github.com/olekukonko/tablewriter v0.0.5-0.20201029120751-42e21c7531a3
github.com/shirou/gopsutil v3.21.8-0.20210816101416-f86a04298073+incompatible
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
golang.org/x/crypto v0.1.0
Expand All @@ -25,7 +25,6 @@ require (
github.com/Microsoft/hcsshim v0.8.21 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.2.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
Expand All @@ -46,7 +45,7 @@ require (
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
github.com/evanphx/json-patch v4.9.0+incompatible // indirect
github.com/go-logr/logr v0.2.1 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.19.3 // indirect
github.com/go-openapi/jsonreference v0.19.3 // indirect
github.com/go-openapi/spec v0.19.4 // indirect
Expand Down Expand Up @@ -85,8 +84,9 @@ require (
github.com/prometheus/common v0.10.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/tklauser/go-sysconf v0.3.7 // indirect
github.com/tklauser/numcpus v0.2.3 // indirect
github.com/tklauser/go-sysconf v0.3.9 // indirect
github.com/tklauser/numcpus v0.3.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opencensus.io v0.22.3 // indirect
go.uber.org/automaxprocs v1.3.0 // indirect
golang.org/x/net v0.1.0 // indirect
Expand Down
Loading

0 comments on commit 5e9228e

Please sign in to comment.