-
Notifications
You must be signed in to change notification settings - Fork 329
/
init.go
129 lines (109 loc) · 3.61 KB
/
init.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Tetragon
package main
import (
"encoding/json"
"fmt"
"os"
"time"
"github.com/cilium/tetragon/pkg/vmtests"
"golang.org/x/sys/unix"
)
// NB(kkourt): this is meant for running this program as init. It kinda works,
// but I think creates more trouble that being useful at this point. I'll leave
// the code for now, just in case we want to actually use it at some point. If
// it keeping the code creates issues, let's just delete it.
func doPID0() {
// mount proc and other filesystems that we need
if err := unix.Mount("none", "/proc", "proc", 0, ""); err != nil {
fmt.Printf("failed to mount proc: %v\n", err)
}
if err := unix.Mount("none", "/sys", "sysfs", 0, ""); err != nil {
fmt.Printf("failed to mount sysfs: %v\n", err)
}
if err := unix.Mount("none", "/sys/kernel/debug", "debugfs", 0, ""); err != nil {
fmt.Printf("failed to mount debugfs: %v\n", err)
}
if err := unix.Mount("none", "/sys/kernel/debug", "debugfs", 0, ""); err != nil {
fmt.Printf("failed to mount debugfs: %v\n", err)
}
if err := unix.Mount("/dev/root", "/", "", unix.MS_REMOUNT, ""); err != nil {
fmt.Printf("failed to remount /: %v\n", err)
}
// TODO: do mount -a, to mount everything in /etc/fstab
}
// https://github.com/aisola/go-coreutils/blob/6eb4c2d5305ac4795a562573fbd9b39d6cbdfc10/uname/uname.go#L98
// utsnameToString converts the utsname to a string and returns it.
func utsnameToString(unameArray [65]byte) string {
var byteString [65]byte
var indexLength int
for ; unameArray[indexLength] != 0; indexLength++ {
byteString[indexLength] = uint8(unameArray[indexLength])
}
return string(byteString[:indexLength])
}
// printInfo prints a short message similar to unmame
func printInfo() {
var uname unix.Utsname
if err := unix.Uname(&uname); err != nil {
fmt.Printf("failed to execute Uname: %v", err)
}
fmt.Printf("%s %s %s %s\n", utsnameToString(uname.Sysname), utsnameToString(uname.Nodename), utsnameToString(uname.Release), utsnameToString(uname.Version))
}
// tester performs the following
// - reads the configuration from the configuration file
// - runs the tests
// - marshalls the results in results.json
func tester() int {
var err error
var data []byte
var conf vmtests.Conf
if data, err = os.ReadFile(vmtests.ConfFile); err == nil {
if err = json.Unmarshal(data, &conf); err != nil {
fmt.Printf("failed to load config file %s: %v", vmtests.ConfFile, err)
return 1
}
} else {
// TODO: add proper parameters to handle local execution use-case
tetragonDir := "."
resultsDir, err := os.MkdirTemp(tetragonDir, "tetragon-tester-")
if err != nil {
fmt.Printf("failed to create results directory: %v\n", err)
return 1
}
conf = vmtests.Conf{
NoPowerOff: true,
TetragonDir: tetragonDir,
ResultsDir: resultsDir,
}
fmt.Printf("no configuration found: %v. Using default configuration for local execution (resultsdir:%s)\n", err, resultsDir)
}
if !conf.NoPowerOff {
defer func() {
fmt.Println("tetragon-tester shutting down the machine...")
os.Stdout.Sync()
time.Sleep(100 * time.Millisecond)
if err := os.WriteFile("/proc/sysrq-trigger", []byte("o"), 0777); err != nil {
fmt.Printf("failed to use syseq-trigger to shutdown machine")
return
}
// wait for the powerdown before init is killed to avoid confusing messages from the kernel
for {
time.Sleep(1 * time.Second)
}
}()
}
if os.Getpid() == 1 {
doPID0()
}
printInfo()
err = vmtests.Run(&conf)
if err != nil {
fmt.Printf("tetragon-tester: error running vmtests: %v\n", err)
return 1
}
return 0
}
func main() {
os.Exit(tester())
}