-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathmagefile.go
150 lines (118 loc) · 3.23 KB
/
magefile.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// +build mage
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/magefile/mage/sh"
"github.com/magefile/mage/target"
)
const (
app = "conntracct"
buildPath = "build/conntracct"
)
var (
buildEnv = map[string]string{
"CGO_ENABLED": "0",
}
build = func() error {
return sh.RunWith(buildEnv, "go", "build", "-o", buildPath)
}
goreleaser = sh.RunCmd("goreleaser", "release", "--rm-dist")
)
// Build builds the application.
func Build() error {
// Watch for files newer than the app in these directories.
mod, err := target.Dir(buildPath, "bpf", "pkg", "cmd", "internal")
if err != nil {
return err
}
if mod {
realPath := realPath(buildPath)
// Unlink the existing binary so it can be replaced without stopping the daemon first.
if err := sh.Rm(realPath); err != nil {
return err
}
// Build the application.
if err := build(); err != nil {
return err
}
// 'Minimal' capability set to run without being uid 0.
// cap_sys_admin for calling bpf().
// cap_ipc_lock for locking memory for the ring buffer.
// cap_dac_override for opening /sys/kernel/debug/tracing/*
// cap_net_admin for managing sysctl net.netfilter.nf_conntrack_acct
if err := sh.Run("sudo", "setcap", "cap_sys_admin,cap_ipc_lock,cap_net_admin,cap_dac_override,cap_sys_resource+eip", realPath); err != nil {
return err
}
fmt.Printf("Successfully built %s!\n", buildPath)
return nil
}
fmt.Println(buildPath, "already up to date.")
return nil
}
// Dev brings up a docker-compose stack and runs the application with modd for live reloading.
func Dev() error {
if err := sh.Run("docker-compose", "-f", "test/docker-compose.yml", "-p", app, "up", "-d"); err != nil {
return err
}
fmt.Println("Starting live-reload with modd..")
if err := sh.RunV("modd"); err != nil {
return err
}
return nil
}
// Generate runs `go generate` on all packages.
func Generate() error {
if err := sh.RunV("go", "generate", "-x", "./..."); err != nil {
return err
}
fmt.Println("Successfully ran go generate.")
return nil
}
// Lint runs golangci-lint with the project's configuration.
func Lint() error {
return sh.RunV("golangci-lint", "run")
}
// Release builds and publishes the release to GitHub.
func Release() error {
if err := envGoVersion(); err != nil {
return err
}
return goreleaser()
}
// Snapshot creates a local snapshot release without publishing to GitHub.
func Snapshot() error {
if err := envGoVersion(); err != nil {
return err
}
return goreleaser("--snapshot")
}
// realPath resolves (nested) symlinks. If the target of a nested symlink does
// not exist, falls back to the target of the first symlink.
func realPath(path string) string {
fi, err := os.Lstat(path)
if err != nil {
// Return the input string if the path doesn't exist (yet), there's nothing to resolve.
return path
}
if (fi.Mode() & os.ModeSymlink) != 0 {
// Try to recursive symlinks.
realPath, err := filepath.EvalSymlinks(path)
if err != nil {
// Return the symlink target path if target file doesn't exist.
ret, _ := os.Readlink(path)
return ret
}
return realPath
}
return path
}
func envGoVersion() error {
v, err := sh.Output("go", "version")
if err != nil {
return err
}
os.Setenv("GOVERSION", v)
return nil
}