From 1cfc867059d82c5ad26ec82a2531027f02bbb9c8 Mon Sep 17 00:00:00 2001 From: Jonas Falck Date: Mon, 28 Apr 2025 16:51:30 +0200 Subject: [PATCH] Fix multiple stuff * set correct file owner if file already exists * stream ssh stdout back to command line * 1 sec backoff if reconnecting * reconnect without token if we get 401 --- pkg/admin/bootstrap.go | 17 +++++++++-------- pkg/agent/agent.go | 12 ++++++++++++ pkg/agent/reconciliation/files.go | 15 +++++++++------ pkg/api/v1/types/types.go | 2 +- pkg/master/webserver/webserver.go | 8 +++++++- pkg/websocket/websocketclient.go | 19 +++++++++++++++++-- 6 files changed, 55 insertions(+), 18 deletions(-) diff --git a/pkg/admin/bootstrap.go b/pkg/admin/bootstrap.go index 590cea7..69b82f2 100644 --- a/pkg/admin/bootstrap.go +++ b/pkg/admin/bootstrap.go @@ -61,7 +61,6 @@ func (a *Admin) Bootstrap(ctx context.Context, hosts []string) error { if err != nil { return err } - } return nil } @@ -125,14 +124,15 @@ func runOverSSH(ctx context.Context, client *ssh.Client, cmd string) error { } // session.Stdout = os.Stdout defer session.Close() - buf := &bytes.Buffer{} - buf2 := &bytes.Buffer{} - session.Stdout = buf - session.Stderr = buf2 + // buf := &bytes.Buffer{} // TODO do we want io.MultiWriter aswell? + // buf2 := &bytes.Buffer{} + session.Stdout = os.Stdout + session.Stderr = os.Stderr session.Stdin = os.Stdin err = session.Start(cmd) if err != nil { - return fmt.Errorf("%w stdout: %s stderr: %s", err, buf.String(), buf2.String()) + return fmt.Errorf("ssh: error running command %s error: %w", cmd, err) + // return fmt.Errorf("%w stdout: %s stderr: %s", err, buf.String(), buf2.String()) } exit := make(chan struct{}, 1) @@ -144,7 +144,7 @@ func runOverSSH(ctx context.Context, client *ssh.Client, cmd string) error { select { case <-ctx.Done(): if ctx.Err() != nil { - fmt.Println("stdout", buf.String(), "stderr", buf2.String()) + // fmt.Println("stdout", buf.String(), "stderr", buf2.String()) session.Signal(ssh.SIGINT) session.Close() } @@ -154,7 +154,8 @@ func runOverSSH(ctx context.Context, client *ssh.Client, cmd string) error { err = session.Wait() if err != nil { - return fmt.Errorf("%w stdout: %s stderr: %s", err, buf.String(), buf2.String()) + // return fmt.Errorf("%w stdout: %s stderr: %s", err, buf.String(), buf2.String()) + return fmt.Errorf("ssh: error waiting for command %s error: %w", cmd, err) } return nil diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 773a112..2528ee3 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" "encoding/json" + "errors" "net/http" "os" "path/filepath" @@ -130,6 +131,7 @@ func (a *Agent) run(pCtx context.Context) error { if err != nil { logrus.Error(err) cancel() + time.Sleep(1 * time.Second) continue } @@ -137,6 +139,16 @@ func (a *Agent) run(pCtx context.Context) error { if err != nil { logrus.Error(err) cancel() + + if errors.Is(err, websocket.ErrUnauthorized) { + logrus.Errorf("error asdf") + + // remove token in runtime if we get auth error. Then the machine will have to be accepted again. + a.mutex.Lock() + a.config.Token = "" + a.mutex.Unlock() + } + time.Sleep(1 * time.Second) continue } diff --git a/pkg/agent/reconciliation/files.go b/pkg/agent/reconciliation/files.go index 0aa41bf..736b56f 100644 --- a/pkg/agent/reconciliation/files.go +++ b/pkg/agent/reconciliation/files.go @@ -62,14 +62,14 @@ func assertSameOwner(file os.FileInfo, fileSpec *types.File) (bool, error) { if fileSpec.User == "" && fileSpec.Group == "" { return false, nil } - var fileUid string - var fileGid string + var existingFileUid int + var existingFileGid int stat, ok := file.Sys().(*syscall.Stat_t) if !ok { return false, fmt.Errorf("not syscall.Stat_t") } - fileUid = strconv.Itoa(int(stat.Uid)) - fileGid = strconv.Itoa(int(stat.Gid)) + existingFileUid = (int(stat.Uid)) + existingFileGid = (int(stat.Gid)) u, err := user.Lookup(fileSpec.User) if err != nil { return false, err @@ -79,11 +79,14 @@ func assertSameOwner(file os.FileInfo, fileSpec *types.File) (bool, error) { return false, err } - if fileUid == u.Uid && fileGid == g.Gid { + newUid, _ := strconv.Atoi(u.Uid) + newGid, _ := strconv.Atoi(g.Gid) + + if existingFileUid == newUid && existingFileGid == newGid { return false, nil } - return true, os.Chown(file.Name(), int(stat.Uid), int(stat.Gid)) + return true, os.Chown(fileSpec.Path, newUid, newGid) } func chown(file *os.File, userName, group string) error { if userName == "" && group == "" { diff --git a/pkg/api/v1/types/types.go b/pkg/api/v1/types/types.go index 14d1e63..512819d 100644 --- a/pkg/api/v1/types/types.go +++ b/pkg/api/v1/types/types.go @@ -105,7 +105,7 @@ type File struct { func (f File) FileMode() (os.FileMode, error) { if f.Mode == "" { - return os.FileMode(0700), nil // default to this + return os.FileMode(0600), nil // default to this } u, err := strconv.ParseUint(f.Mode, 8, 32) return os.FileMode(u), err diff --git a/pkg/master/webserver/webserver.go b/pkg/master/webserver/webserver.go index 8b4038e..3601fc0 100644 --- a/pkg/master/webserver/webserver.go +++ b/pkg/master/webserver/webserver.go @@ -179,6 +179,12 @@ func (ws *Webserver) approveMachine(c *gin.Context) error { func (ws *Webserver) listPendingMachines(c *gin.Context) error { t := ` + + +