This repository has been archived by the owner on May 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
104 lines (82 loc) · 2.35 KB
/
main.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
package main
import (
"context"
"errors"
"io"
"log"
"os"
"os/exec"
"github.com/darwinia-network/kubevali/config"
"github.com/darwinia-network/kubevali/node"
"github.com/darwinia-network/kubevali/nodesvc"
"github.com/darwinia-network/kubevali/watchlog"
"github.com/fsnotify/fsnotify"
flags "github.com/jessevdk/go-flags"
"github.com/spf13/viper"
)
var opts struct {
Config string `long:"config" short:"c" description:"Path to the config file" value-name:"<PATH>" default:"kubevali.yaml"`
WatchConfig bool `long:"watch-config" short:"w" description:"Watch config file changes and restart node with new config"`
DryRun bool `long:"dry-run" description:"Print the final rendered command line and exit"`
}
var (
buildVersion = "dev"
buildCommit = "none"
buildDate = "unknown"
)
func main() {
if _, err := flags.Parse(&opts); err != nil {
os.Exit(0)
}
viper.SetConfigFile(opts.Config)
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Unable to load config file: %s", err)
}
if opts.WatchConfig {
viper.WatchConfig()
}
var configChanged bool
for {
configChanged = false
ctx, cancel := context.WithCancel(context.Background())
viper.OnConfigChange(func(e fsnotify.Event) {
configChanged = true
cancel()
})
conf := config.Unmarshal()
defer conf.Logger.Sync()
conf.Logger.Infof("Kubevali %v-%v (built %v)", buildVersion, buildCommit, buildDate)
status := kubevali(conf, ctx)
if !configChanged || status != 0 {
os.Exit(status)
}
}
}
func kubevali(conf *config.Config, ctx context.Context) int {
nodesvc.CreateOrUpdate(conf)
node := node.NewNode(conf)
if conf.Watchlog.Enabled {
logWatcher := watchlog.NewWatcher(conf)
go logWatcher.Watch(io.TeeReader(node.Stdout, conf.Node.Stdout), "stdout")
go logWatcher.Watch(io.TeeReader(node.Stderr, conf.Node.Stderr), "stderr")
} else {
go io.Copy(conf.Node.Stdout, node.Stdout)
go io.Copy(conf.Node.Stderr, node.Stderr)
}
conf.Logger.Infof("Starting node: %s", node.ShellCommand())
if opts.DryRun {
conf.Logger.Debugf("Exit because --dry-run is specified")
os.Exit(0)
}
err := node.Run(ctx)
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
conf.Logger.Debugf("Node exits: %s", exitErr)
return exitErr.ExitCode()
}
if err != nil {
conf.Logger.Fatalf("Node exits: %s", err)
}
conf.Logger.Debug("Node exits: OK")
return 0
}