-
Notifications
You must be signed in to change notification settings - Fork 80
/
main.go
102 lines (92 loc) · 2.08 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
package main
import (
"context"
"flag"
"fmt"
"log"
"os"
"os/signal"
"sync"
"syscall"
)
var cleanup sync.WaitGroup
type commonConfig struct {
cleanup *sync.WaitGroup
}
type subcmd func(context.Context, *commonConfig, []string) error
func main() {
var exit int
defer func() {
if exit != 0 {
os.Exit(exit)
}
}()
ctx, done := context.WithCancel(context.Background())
go func() {
ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGTERM, syscall.SIGINT)
<-ch
done()
}()
var cfg commonConfig = commonConfig{
cleanup: &cleanup,
}
fs := flag.NewFlagSet("main", flag.ExitOnError)
fs.Usage = func() {
out := fs.Output()
fmt.Fprintf(out, "Usage of %s:\n", os.Args[0])
fs.PrintDefaults()
fmt.Fprintf(out, "\nSubcommands\n\n")
fmt.Fprintln(out, "report")
fmt.Fprintln(out, "\tgenerate reports for containers provided as arguments or on stdin")
fmt.Fprintln(out, "manifest")
fmt.Fprintln(out, "\tgenerate manifests for containers provided as arguments or on stdin")
fmt.Fprintln(out, "unpack")
fmt.Fprintln(out, "\textracts each container's layers content for inspection")
fmt.Fprintln(out, "run-updaters")
fmt.Fprintln(out, "\trun default updaters and produce an artifact for later importing")
fmt.Fprintln(out, "load-updates")
fmt.Fprintln(out, "\tload an artifact from `run-updaters` into a database")
fmt.Fprintln(out)
}
if err := fs.Parse(os.Args[1:]); err != nil {
log.Fatal(err)
}
var cmd subcmd
switch n := fs.Arg(0); n {
case "report":
cmd = Report
case "manifest":
cmd = Manifest
case "unpack":
cmd = Unpack
case "run-updaters":
cmd = RunUpdaters
case "load-updates":
cmd = LoadUpdates
case "":
fs.Usage()
os.Exit(99)
default:
fs.Usage()
fmt.Fprintf(os.Stderr, "\nunknown subcommand %q\n", n)
os.Exit(99)
}
var cmdErr error
cmdctx, cmddone := context.WithCancel(ctx)
go func() {
defer cmddone()
cmdErr = cmd(cmdctx, &cfg, fs.Args()[1:])
}()
select {
case <-ctx.Done():
log.Print(ctx.Err())
exit = 1
case <-cmdctx.Done():
if cmdErr != nil {
log.Print(cmdErr)
exit = 2
}
}
cleanup.Wait()
}