-
Notifications
You must be signed in to change notification settings - Fork 686
/
envoy.go
118 lines (105 loc) · 3.11 KB
/
envoy.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
package entrypoint
import (
"context"
"errors"
"fmt"
"os"
"time"
"github.com/datawire/dlib/dcontext"
"github.com/datawire/dlib/dexec"
"github.com/datawire/dlib/dgroup"
"github.com/datawire/dlib/dlog"
)
func runEnvoy(ctx context.Context, envoyHUP chan os.Signal) error {
// Wait until we get a SIGHUP to start envoy.
//var bootstrap string
select {
case <-ctx.Done():
return nil
case <-envoyHUP:
}
// Try to run envoy directly, but fallback to running it inside docker if there is
// no envoy executable available.
if IsEnvoyAvailable() {
cmd := subcommand(ctx, "envoy", GetEnvoyFlags()...)
if envbool("DEV_SHUTUP_ENVOY") {
cmd.Stdout = nil
cmd.Stderr = nil
}
return cmd.Run()
} else {
// For some reason docker only sometimes passes the signal onto the process inside
// the container, so we setup this cleanup function so that in the docker case we
// can do a docker kill, just to be sure it is really dead and we don't leave an
// envoy lying around.
// Create a label unique to this invocation so we can use it to do a docker
// kill for cleanup.
label := fmt.Sprintf("amb-envoy-label-%d", os.Getpid())
snapdir := GetSnapshotDir()
group := dgroup.NewGroup(ctx, dgroup.GroupConfig{
ShutdownOnNonError: true,
})
group.Go("envoy", func(ctx context.Context) error {
// XXX: will host networking work on a mac? (probably not)
dockerArgs := []string{
"run", "-l", label, "--rm", "--network", "host",
"-v", fmt.Sprintf("%s:%s", snapdir, snapdir),
"-v", fmt.Sprintf("%s:%s", GetEnvoyBootstrapFile(), GetEnvoyBootstrapFile()),
}
if envbool("DEV_ENVOY_DOCKER_PRIVILEGED") {
dockerArgs = append(dockerArgs, "--privileged")
}
dockerArgs = append(dockerArgs, "--entrypoint", "envoy", "docker.io/datawire/aes:1.12.2")
cmd := subcommand(ctx, "docker", append(dockerArgs, GetEnvoyFlags()...)...)
if envbool("DEV_SHUTUP_ENVOY") {
cmd.Stdout = nil
cmd.Stderr = nil
}
return cmd.Run()
})
group.Go("cleanup", func(ctx context.Context) error {
<-ctx.Done()
ctx = dcontext.HardContext(ctx)
for {
cids, err := cidsForLabel(ctx, label)
if err != nil {
return err
}
if len(cids) == 0 {
return nil
}
// Give the container one second to exit
tctx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()
wait := subcommand(tctx, "docker", append([]string{"wait"}, cids...)...)
wait.Stdout = nil
if err := wait.Run(); err != nil {
var exitErr *dexec.ExitError
if errors.As(err, &exitErr) {
dlog.Errorf(ctx, "docker wait: %v\n%s", err, string(exitErr.Stderr))
} else {
return err
}
}
cids, err = cidsForLabel(ctx, label)
if err != nil {
return err
}
if len(cids) == 0 {
return nil
}
kill := subcommand(ctx, "docker", append([]string{"kill"}, cids...)...)
kill.Stdout = nil
if err := wait.Run(); err != nil {
var exitErr *dexec.ExitError
if errors.As(err, &exitErr) {
dlog.Errorf(ctx, "docker kill: %v\n%s", err, string(exitErr.Stderr))
} else {
return err
}
}
}
})
return group.Wait()
}
}