Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change node-agent to golang version to adapt for glibc 2.17 #490

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion cmd/kubenest/node-agent/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@ COPY . .

RUN apt-get update && \
apt-get install -y --no-install-recommends build-essential gcc && \
pip install --no-cache-dir -r requirements.txt
pip install --no-cache-dir -r requirements.txt && \
apt-get install -y pwgen && \
WEB_USER=agent && \
WEB_PASS=$(pwgen -y 12 1) && \
sed -i "s/{{WEB_USER}}/$WEB_USER/g" agent.env && \
sed -i "s/{{WEB_PASS}}/$WEB_PASS/g" agent.env


RUN pip install pyinstaller && \
pyinstaller --onefile app.py

FROM golang:latest AS build-go
WORKDIR /app
COPY go/* .

RUN go mod tidy && \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o node-agent app.go

RUN openssl req -x509 -sha256 -new -nodes -days 3650 -newkey rsa:2048 -keyout key.pem -out cert.pem -subj "/C=CN/ST=JiangSu/L=SuZhou/O=Kosmos/OU=Kosmos/CN=kosmos.io"


FROM ubuntu:latest as release-env
WORKDIR /app

Expand All @@ -20,6 +36,10 @@ RUN apt-get update && apt-get install -y rsync
# copy install file to container
COPY . .
COPY --from=build-env /app/dist/app /app
COPY --from=build-env /app/agent.env /app
COPY --from=build-go /app/node-agent /app
COPY --from=build-go /app/cert.pem /app
COPY --from=build-go /app/key.pem /app

# install command
CMD ["bash", "/app/install.sh", "/app"]
2 changes: 2 additions & 0 deletions cmd/kubenest/node-agent/agent.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
WEB_USER={{WEB_USER}}
WEB_PASS={{WEB_PASS}}
10 changes: 9 additions & 1 deletion cmd/kubenest/node-agent/daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ spec:
image: cis-hub-huabei-3.cmecloud.cn/node-agent/node-agent:latest
securityContext:
privileged: true
command: [ "/bin/bash", "-c", "rsync -avz /app/ /host-path/ && cp /app/node-agent.service /host-systemd/node-agent.service" ]
env:
- name: WEB_USER
value: {{update when you deploy}}
- name: WEB_PASS
value: {{update when you deploy}}
command: ["/bin/bash"]
args:
- "-c"
- "sed -i 's/^WEB_USER=.*/WEB_USER=$(WEB_USER)/' /app/agent.env && sed -i 's/^WEB_PASS=.*/WEB_PASS=$(WEB_PASS)/' /app/agent.env && rsync -avz /app/ /host-path/ && cp /app/node-agent.service /host-systemd/node-agent.service "
volumeMounts:
- mountPath: /host-path
name: node-agent
Expand Down
91 changes: 56 additions & 35 deletions cmd/kubenest/node-agent/go/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"errors"
"flag"
"fmt"
"log"
"net/http"
"net/url"
"os"
Expand All @@ -19,6 +18,7 @@ import (
"time"

"github.com/gorilla/websocket"
"github.com/sirupsen/logrus"
)

var (
Expand All @@ -27,21 +27,42 @@ var (
keyFile = flag.String("key", "key.pem", "SSL key file")
user = flag.String("user", "", "Username for authentication")
password = flag.String("password", "", "Password for authentication")
log = logrus.New()
)

var upgrader = websocket.Upgrader{} // use default options

func init() {
log.Out = os.Stdout

file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
log.Out = file
} else {
log.Info("Failed to log to file, using default stderr")
}
log.SetLevel(logrus.InfoLevel)
}
func main() {
flag.Parse()
log.SetFlags(log.LstdFlags | log.Lshortfile)
if len(*user) == 0 || len(*password) == 0 {
*user = os.Getenv("WEB_USER")
*password = os.Getenv("WEB_PASS")
if len(*user) == 0 || len(*password) == 0 {
flag.Usage()
log.Fatal("-user and -password are required")
if *user == "" {
_user := os.Getenv("WEB_USER")
if _user != "" {
*user = _user
}
}

if *password == "" {
_password := os.Getenv("WEB_PASS")
if _password != "" {
*password = _password
}
}
if len(*user) == 0 || len(*password) == 0 {
flag.Usage()
log.Errorf("-user and -password are required %s %s", *user, *password)
return
}
start(*addr, *certFile, *keyFile, *user, *password)
}

Expand Down Expand Up @@ -77,14 +98,14 @@ func start(addr, certFile, keyFile, user, password string) {

conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Print("upgrade:", err)
log.Errorf("http upgrade to websocket failed : %v", err)
return
}
defer conn.Close()

u, err := url.Parse(r.RequestURI)
if err != nil {
log.Print("parse uri:", err)
log.Errorf("parse uri: %s, %v", r.RequestURI, err)
return
}
queryParams := u.Query()
Expand All @@ -103,7 +124,7 @@ func start(addr, certFile, keyFile, user, password string) {
}
})

log.Printf("Starting server on %s", addr)
log.Infof("Starting server on %s", addr)
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS12,
}
Expand All @@ -115,39 +136,39 @@ func start(addr, certFile, keyFile, user, password string) {
ReadHeaderTimeout: 10 * time.Second,
}

log.Fatal(server.ListenAndServeTLS("", ""))
log.Errorf("failed to start server %v", server.ListenAndServeTLS("", ""))
}

func handleUpload(conn *websocket.Conn, params url.Values) {
fileName := params.Get("file_name")
filePath := params.Get("file_path")
log.Printf("Uploading file name %s, file path %s", fileName, filePath)
log.Infof("Uploading file name %s, file path %s", fileName, filePath)
defer conn.Close()
if len(fileName) != 0 && len(filePath) != 0 {
// mkdir
err := os.MkdirAll(filePath, 0775)
if err != nil {
log.Print("mkdir:", err)
log.Errorf("mkdir: %s %v", filePath, err)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseInternalServerErr, fmt.Sprintf("failed to make directory: %v", err)))
return
}
file := filepath.Join(filePath, fileName)
// check if the file already exists
if _, err := os.Stat(file); err == nil {
log.Printf("File %s already exists", file)
log.Infof("File %s already exists", file)
timestamp := time.Now().Format("2006-01-02-150405000")
bakFilePath := fmt.Sprintf("%s_%s_bak", file, timestamp)
err = os.Rename(file, bakFilePath)
if err != nil {
log.Printf("failed to rename file: %v", err)
log.Errorf("failed to rename file: %v", err)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseInternalServerErr, fmt.Sprintf("failed to rename file: %v", err)))
return
}
}
// create file with append
fp, err := os.OpenFile(file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Printf("failed to open file: %v", err)
log.Errorf("failed to open file: %v", err)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseInternalServerErr, fmt.Sprintf("failed to open file: %v", err)))
return
}
Expand All @@ -156,20 +177,20 @@ func handleUpload(conn *websocket.Conn, params url.Values) {
for {
_, data, err := conn.ReadMessage()
if err != nil {
log.Printf("failed to read message : %s", err)
log.Errorf("failed to read message : %s", err)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseInternalServerErr, fmt.Sprintf("failed to read message: %v", err)))
return
}
// check if the file end
if string(data) == "EOF" {
log.Printf("finish file data transfer %s", file)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, fmt.Sprintf("finish file data transfer: %v", "EOF")))
log.Infof("finish file data transfer %s", file)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, fmt.Sprintf("%d", 0)))
return
}
// data to file
_, err = fp.Write(data)
if err != nil {
log.Printf("failed to write data to file : %s", err)
log.Errorf("failed to write data to file : %s", err)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseInternalServerErr, fmt.Sprintf("failed write data to file: %v", err)))
return
}
Expand All @@ -181,22 +202,22 @@ func handleUpload(conn *websocket.Conn, params url.Values) {
func handleCmd(conn *websocket.Conn, params url.Values) {
command := params.Get("command")
if command == "" {
log.Printf("No command specified %v", params)
log.Warnf("No command specified %v", params)
_ = conn.WriteMessage(websocket.TextMessage, []byte("No command specified"))
return
}

cmd := exec.Command("sh", "-c", command)
out, err := cmd.CombinedOutput()
if err != nil {
log.Printf("failed to execute command : %v", err)
log.Warnf("failed to execute command : %v", err)
_ = conn.WriteMessage(websocket.TextMessage, []byte(err.Error()))
} else {
_ = conn.WriteMessage(websocket.TextMessage, out)
}
exitCode := cmd.ProcessState.ExitCode()
log.Printf("Command finished with exit code %d", exitCode)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, fmt.Sprintf("Exit Code: %d", exitCode)))
log.Infof("Command finished with exit code %d", exitCode)
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, fmt.Sprintf("%d", exitCode)))
}

func handleScript(conn *websocket.Conn, params url.Values, command []string) {
Expand All @@ -208,30 +229,30 @@ func handleScript(conn *websocket.Conn, params url.Values, command []string) {
// Write data to a temporary file
tempFile, err := os.CreateTemp("", "script_*")
if err != nil {
log.Printf("Error creating temporary file: %v", err)
log.Errorf("Error creating temporary file: %v", err)
return
}
defer os.Remove(tempFile.Name()) // Clean up temporary file
defer tempFile.Close()
tempFilefp, err := os.OpenFile(tempFile.Name(), os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
log.Printf("Error opening temporary file: %v", err)
log.Errorf("Error opening temporary file: %v", err)
}
for {
// Read message from WebSocket client
_, data, err := conn.ReadMessage()
if err != nil {
log.Printf("failed to read message : %s", err)
log.Errorf("failed to read message : %s", err)
break
}
if string(data) == "EOF" {
log.Printf("finish file data transfer %s", tempFile.Name())
log.Infof("finish file data transfer %s", tempFile.Name())
break
}

// Write received data to the temporary file
if _, err := tempFilefp.Write(data); err != nil {
log.Printf("Error writing data to temporary file: %v", err)
log.Errorf("Error writing data to temporary file: %v", err)
continue
}
}
Expand All @@ -243,20 +264,20 @@ func handleScript(conn *websocket.Conn, params url.Values, command []string) {
cmd := exec.Command(executeCmd[0], executeCmd[1:]...)
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Printf("Error obtaining command output pipe: %v", err)
log.Warnf("Error obtaining command output pipe: %v", err)
}
defer stdout.Close()

if err := cmd.Start(); err != nil {
log.Printf("Error starting command: %v", err)
log.Warnf("Error starting command: %v", err)
}

// processOutput
go func() {
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
data := scanner.Bytes()
log.Printf("%s", data)
log.Warnf("%s", data)
_ = conn.WriteMessage(websocket.TextMessage, data)
}
}()
Expand All @@ -265,9 +286,9 @@ func handleScript(conn *websocket.Conn, params url.Values, command []string) {
if err := cmd.Wait(); err != nil {
var exitError *exec.ExitError
if errors.As(err, &exitError) {
log.Printf("Command exited with non-zero status: %v", exitError)
log.Warnf("Command exited with non-zero status: %v", exitError)
}
}
exitCode := cmd.ProcessState.ExitCode()
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, fmt.Sprintf("Exit Code: %d", exitCode)))
_ = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, fmt.Sprintf("%d", exitCode)))
}
5 changes: 2 additions & 3 deletions cmd/kubenest/node-agent/go/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"crypto/tls"
"encoding/base64"
"fmt"
"log"
"net/http"
"net/url"
"os"
Expand Down Expand Up @@ -33,8 +32,8 @@ func init() {
_, filename, _, _ := runtime.Caller(0)
currentDir = filepath.Dir(filename)
parentDir = filepath.Dir(currentDir)
_ = os.Setenv("WEB_USER", "admin")
_ = os.Setenv("WEB_PASS", "eiqu&ahr3sohW5ee")
_ = os.Setenv("WEB_USER", "")
_ = os.Setenv("WEB_PASS", "")
username = os.Getenv("WEB_USER")
pass = os.Getenv("WEB_PASS")
testAddr = "127.0.0.1:5678"
Expand Down
13 changes: 13 additions & 0 deletions cmd/kubenest/node-agent/go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/kosmos.io/kubenest/node-agent

go 1.22.1

require (
github.com/gorilla/websocket v1.5.1
github.com/sirupsen/logrus v1.9.3
)

require (
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
)
20 changes: 20 additions & 0 deletions cmd/kubenest/node-agent/go/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6 changes: 3 additions & 3 deletions cmd/kubenest/node-agent/node-agent.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ After=network.target
User=root
Group=root
WorkingDirectory=/srv/node-agent
Environment="WEB_USER=admin"
Environment="WEB_PASS=bich_oosh2zoh6Oh"
EnvironmentFile=-/srv/node-agent/agent.env
#./app: error while loading shared libraries: libz.so.1: failed to map segment from shared object
Environment="TMPDIR=/srv/node-agent"
#ExecStartPre=-/usr/bin/pip3 install -r /srv/node-agent/requirements.txt
#ExecStart=/usr/bin/env python3 /srv/node-agent/app.py
ExecStart=/srv/node-agent/app --user admin --password 'bich_oosh2zoh6Oh'
#ExecStart=/srv/node-agent/app
ExecStart=/srv/node-agent/node-agent
Restart=on-failure
RestartSec=5

Expand Down
Loading
Loading