Skip to content

Commit bceb2e1

Browse files
Revert "chore: cover supervisor package with unit tests" (#14)
Revert "chore: cover supervisor package with unit tests (#12)" This reverts commit a11f921.
1 parent 6bb1e63 commit bceb2e1

File tree

8 files changed

+463
-430
lines changed

8 files changed

+463
-430
lines changed

pkg/controller/k0scontroller.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"encoding/csv"
77
"fmt"
8+
"io"
89
"os"
910
"os/user"
1011
"path/filepath"
@@ -27,7 +28,8 @@ import (
2728
type K0sController struct {
2829
Options config.K0sControllerOptions
2930

30-
supervisor *supervisor.Supervisor
31+
supervisor supervisor.Supervisor
32+
Output io.Writer
3133
uid int
3234
gid int
3335
}
@@ -66,9 +68,16 @@ func (k *K0sController) Init(_ context.Context) error {
6668
if k.Options.CmdLogLevels != nil {
6769
args = append(args, fmt.Sprintf("--logging=%s", createS2SFlag(k.Options.CmdLogLevels)))
6870
}
69-
k0spath := assets.BinPath("k0s", k.Options.BinDir())
70-
if k.supervisor, err = supervisor.New(k0spath, args); err != nil {
71-
return fmt.Errorf("failed to create supervisor: %w", err)
71+
k.supervisor = supervisor.Supervisor{
72+
Name: "k0s",
73+
UID: k.uid,
74+
GID: k.gid,
75+
BinPath: assets.BinPath("k0s", k.Options.BinDir()),
76+
Output: k.Output,
77+
RunDir: k.Options.RunDir(),
78+
DataDir: k.Options.DataDir,
79+
KeepEnvPrefix: true,
80+
Args: args,
7281
}
7382
return nil
7483
}

pkg/supervisor/detachattr.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//go:build !windows
2+
// +build !windows
3+
4+
package supervisor
5+
6+
import (
7+
"os"
8+
"syscall"
9+
)
10+
11+
// DetachAttr creates the proper syscall attributes to run the managed processes
12+
func DetachAttr(uid, gid int) *syscall.SysProcAttr {
13+
var creds *syscall.Credential
14+
15+
if os.Geteuid() == 0 {
16+
creds = &syscall.Credential{
17+
Uid: uint32(uid),
18+
Gid: uint32(gid),
19+
}
20+
}
21+
22+
return &syscall.SysProcAttr{
23+
Setpgid: true,
24+
Pgid: 0,
25+
Credential: creds,
26+
}
27+
}

pkg/supervisor/logwriter.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package supervisor
2+
3+
import (
4+
"bytes"
5+
"unicode/utf8"
6+
7+
"github.com/sirupsen/logrus"
8+
)
9+
10+
// logWriter implements [io.Writer] by forwarding whole lines to log. In case
11+
// the lines get too long, it logs them in multiple chunks.
12+
//
13+
// This is in contrast to logrus's implementation of io.Writer, which simply
14+
// errors out if the log line gets longer than 64k.
15+
type logWriter struct {
16+
log logrus.FieldLogger // receives (possibly chunked) log lines
17+
buf []byte // buffer in which to accumulate chunks; len(buf) determines the chunk length
18+
len int // current buffer length
19+
chunkNo uint // current chunk number; 0 means "no chunk"
20+
}
21+
22+
// Write implements [io.Writer].
23+
func (w *logWriter) Write(in []byte) (int, error) {
24+
w.writeBytes(in)
25+
return len(in), nil
26+
}
27+
28+
func (w *logWriter) writeBytes(in []byte) {
29+
// Fill and drain buffer with available data until everything has been consumed.
30+
for rest := in; len(rest) > 0; {
31+
32+
n := copy(w.buf[w.len:], rest) // fill buffer with new input data
33+
rest = rest[n:] // strip copied input data
34+
w.len += n // increase buffer length accordingly
35+
36+
// Loop over buffer as long as there are newlines in it
37+
for off := 0; ; {
38+
idx := bytes.IndexRune(w.buf[off:w.len], '\n')
39+
40+
// Discard already logged chunks and break if no newline left
41+
if idx < 0 {
42+
if off > 0 {
43+
w.len = copy(w.buf, w.buf[off:w.len])
44+
}
45+
break
46+
}
47+
48+
// Strip trailing carriage returns
49+
line := bytes.TrimRight(w.buf[off:off+idx], "\r")
50+
51+
if w.chunkNo == 0 {
52+
w.log.Infof("%s", line)
53+
} else {
54+
if len(line) > 0 {
55+
w.log.WithField("chunk", w.chunkNo+1).Infof("%s", line)
56+
}
57+
w.chunkNo = 0
58+
}
59+
60+
off += idx + 1 // advance read offset behind the newline
61+
}
62+
63+
// Issue a chunked log entry in case the buffer is full
64+
if w.len == len(w.buf) {
65+
// Try to chunk at UTF-8 rune boundaries
66+
length := w.len
67+
for i := 0; i < utf8.MaxRune && i < w.len; i++ {
68+
if r, _ := utf8.DecodeLastRune(w.buf[:w.len-i]); r != utf8.RuneError {
69+
length = length - i
70+
break
71+
}
72+
}
73+
74+
// Strip trailing carriage returns
75+
line := bytes.TrimRight(w.buf[:length], "\r")
76+
77+
w.log.WithField("chunk", w.chunkNo+1).Infof("%s", line)
78+
w.chunkNo++ // increase chunk number
79+
w.len = copy(w.buf, w.buf[length:]) // discard logged bytes
80+
}
81+
}
82+
}

pkg/supervisor/options.go

Lines changed: 0 additions & 53 deletions
This file was deleted.

pkg/supervisor/options_test.go

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)