From 0a4c136863dc97ccfd7fbae767df745c30fe9473 Mon Sep 17 00:00:00 2001 From: Franco Bruno Lavayen Date: Fri, 30 Sep 2022 16:17:52 -0300 Subject: [PATCH 01/24] [CONSUL-491] Support admin_access_log_path value for Windows (#71) --- command/connect/envoy/envoy.go | 44 ++-- command/connect/envoy/envoy_test.go | 46 +++- .../envoy/testdata/defaults-windows.golden | 210 ++++++++++++++++++ command/registry.go | 5 +- 4 files changed, 282 insertions(+), 23 deletions(-) create mode 100644 command/connect/envoy/testdata/defaults-windows.golden diff --git a/command/connect/envoy/envoy.go b/command/connect/envoy/envoy.go index bd5be872efcc..953c7d42d756 100644 --- a/command/connect/envoy/envoy.go +++ b/command/connect/envoy/envoy.go @@ -7,6 +7,7 @@ import ( "net" "os" "os/exec" + "runtime" "strings" "github.com/mitchellh/cli" @@ -22,13 +23,14 @@ import ( "github.com/hashicorp/consul/tlsutil" ) -func New(ui cli.Ui) *cmd { +func New(ui cli.Ui, osPlatform string) *cmd { c := &cmd{UI: ui} - c.init() + c.init(osPlatform) return c } -const DefaultAdminAccessLogPath = "/dev/null" +const DefaultUnixAdminAccessLogPath = "/dev/null" +const DefaultWindowsAdminAccessLogPath = "nul" type cmd struct { UI cli.Ui @@ -82,7 +84,7 @@ var supportedGateways = map[string]api.ServiceKind{ "ingress": api.ServiceKindIngressGateway, } -func (c *cmd) init() { +func (c *cmd) init(osPlatform string) { c.flags = flag.NewFlagSet("", flag.ContinueOnError) c.flags.StringVar(&c.proxyID, "proxy-id", os.Getenv("CONNECT_PROXY_ID"), @@ -108,10 +110,17 @@ func (c *cmd) init() { "The full path to the envoy binary to run. By default will just search "+ "$PATH. Ignored if -bootstrap is used.") - c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultAdminAccessLogPath, - fmt.Sprintf("The path to write the access log for the administration server. If no access "+ - "log is desired specify %q. By default it will use %q.", - DefaultAdminAccessLogPath, DefaultAdminAccessLogPath)) + if osPlatform == "windows" { + c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultWindowsAdminAccessLogPath, + fmt.Sprintf("The path to write the access log for the administration server. If no access "+ + "log is desired specify %q. By default it will use %q.", + DefaultWindowsAdminAccessLogPath, DefaultWindowsAdminAccessLogPath)) + } else { + c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultUnixAdminAccessLogPath, + fmt.Sprintf("The path to write the access log for the administration server. If no access "+ + "log is desired specify %q. By default it will use %q.", + DefaultUnixAdminAccessLogPath, DefaultUnixAdminAccessLogPath)) + } c.flags.StringVar(&c.adminBind, "admin-bind", "localhost:19000", "The address:port to start envoy's admin server on. Envoy requires this "+ @@ -259,10 +268,11 @@ func (c *cmd) Run(args []string) int { return 1 } // TODO: refactor - return c.run(c.flags.Args()) + osPlatform := runtime.GOOS + return c.run(c.flags.Args(), osPlatform) } -func (c *cmd) run(args []string) int { +func (c *cmd) run(args []string, osPlatform string) int { if c.nodeName != "" && c.proxyID == "" { c.UI.Error("'-node-name' requires '-proxy-id'") @@ -429,7 +439,7 @@ func (c *cmd) run(args []string) int { } // Generate config - bootstrapJson, err := c.generateConfig() + bootstrapJson, err := c.generateConfig(osPlatform) if err != nil { c.UI.Error(err.Error()) return 1 @@ -472,7 +482,7 @@ func (c *cmd) findBinary() (string, error) { return exec.LookPath("envoy") } -func (c *cmd) templateArgs() (*BootstrapTplArgs, error) { +func (c *cmd) templateArgs(osPlatform string) (*BootstrapTplArgs, error) { httpCfg := api.DefaultConfig() c.http.MergeOntoConfig(httpCfg) @@ -515,7 +525,11 @@ func (c *cmd) templateArgs() (*BootstrapTplArgs, error) { adminAccessLogPath := c.adminAccessLogPath if adminAccessLogPath == "" { - adminAccessLogPath = DefaultAdminAccessLogPath + if osPlatform == "windows" { + adminAccessLogPath = DefaultWindowsAdminAccessLogPath + } else { + adminAccessLogPath = DefaultUnixAdminAccessLogPath + } } // Fallback to the old certificate configuration, if none was defined. @@ -556,8 +570,8 @@ func (c *cmd) templateArgs() (*BootstrapTplArgs, error) { }, nil } -func (c *cmd) generateConfig() ([]byte, error) { - args, err := c.templateArgs() +func (c *cmd) generateConfig(osPlatform string) ([]byte, error) { + args, err := c.templateArgs(osPlatform) if err != nil { return nil, err } diff --git a/command/connect/envoy/envoy_test.go b/command/connect/envoy/envoy_test.go index 31c078dc9967..4bb2032da80d 100644 --- a/command/connect/envoy/envoy_test.go +++ b/command/connect/envoy/envoy_test.go @@ -24,9 +24,11 @@ import ( var update = flag.Bool("update", false, "update golden files") +const defaultOSPlatform = "linux" + func TestEnvoyCommand_noTabs(t *testing.T) { t.Parallel() - if strings.ContainsRune(New(nil).Help(), '\t') { + if strings.ContainsRune(New(nil, defaultOSPlatform).Help(), '\t') { t.Fatal("help has tabs") } } @@ -64,8 +66,8 @@ func TestEnvoyGateway_Validation(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { ui := cli.NewMockUi() - c := New(ui) - c.init() + c := New(ui, defaultOSPlatform) + c.init(defaultOSPlatform) code := c.Run(tc.args) if code == 0 { @@ -120,6 +122,7 @@ type generateConfigTestCase struct { AgentSelf110 bool // fake the agent API from versions v1.10 and earlier WantArgs BootstrapTplArgs WantErr string + OSPlatform string } // This tests the args we use to generate the template directly because they @@ -160,6 +163,28 @@ func TestGenerateConfig(t *testing.T) { PrometheusScrapePath: "/metrics", }, }, + { + Name: "defaults-windows", + Flags: []string{"-proxy-id", "test-proxy"}, + WantArgs: BootstrapTplArgs{ + ProxyCluster: "test-proxy", + ProxyID: "test-proxy", + // We don't know this til after the lookup so it will be empty in the + // initial args call we are testing here. + ProxySourceService: "", + GRPC: GRPC{ + AgentAddress: "127.0.0.1", + AgentPort: "8502", // Note this is the gRPC port + }, + AdminAccessLogPath: "nul", + AdminBindAddress: "127.0.0.1", + AdminBindPort: "19000", + LocalAgentClusterName: xds.LocalAgentClusterName, + PrometheusBackendPort: "", + PrometheusScrapePath: "/metrics", + }, + OSPlatform: "windows", + }, { Name: "defaults-nodemeta", Flags: []string{"-proxy-id", "test-proxy", "-node-name", "test-node"}, @@ -1101,8 +1126,14 @@ func TestGenerateConfig(t *testing.T) { client, err := api.NewClient(&api.Config{Address: srv.URL, TLSConfig: api.TLSConfig{InsecureSkipVerify: true}}) require.NoError(t, err) + // Default OS Platform "linux". Custom value should be set in the test case + osPlatform := "linux" + if tc.OSPlatform == "windows" { + osPlatform = tc.OSPlatform + } + ui := cli.NewMockUi() - c := New(ui) + c := New(ui, osPlatform) // explicitly set the client to one which can connect to the httptest.Server c.client = client @@ -1111,7 +1142,7 @@ func TestGenerateConfig(t *testing.T) { args := append([]string{"-bootstrap"}, myFlags...) require.NoError(t, c.flags.Parse(args)) - code := c.run(c.flags.Args()) + code := c.run(c.flags.Args(), osPlatform) if tc.WantErr == "" { require.Equal(t, 0, code, ui.ErrorWriter.String()) } else { @@ -1122,7 +1153,8 @@ func TestGenerateConfig(t *testing.T) { // Verify we handled the env and flags right first to get correct template // args. - got, err := c.templateArgs() + got, err := c.templateArgs(osPlatform) + require.NoError(t, err) // Error cases should have returned above require.Equal(t, &tc.WantArgs, got) @@ -1215,7 +1247,7 @@ func TestEnvoy_GatewayRegistration(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { ui := cli.NewMockUi() - c := New(ui) + c := New(ui, defaultOSPlatform) code := c.Run(tc.args) if code != 0 { diff --git a/command/connect/envoy/testdata/defaults-windows.golden b/command/connect/envoy/testdata/defaults-windows.golden new file mode 100644 index 000000000000..59ef580c5d23 --- /dev/null +++ b/command/connect/envoy/testdata/defaults-windows.golden @@ -0,0 +1,210 @@ +{ + "admin": { + "access_log_path": "nul", + "address": { + "socket_address": { + "address": "127.0.0.1", + "port_value": 19000 + } + } + }, + "node": { + "cluster": "test", + "id": "test-proxy", + "metadata": { + "namespace": "default", + "partition": "default" + } + }, + "layered_runtime": { + "layers": [ + { + "name": "base", + "static_layer": { + "re2.max_program_size.error_level": 1048576 + } + } + ] + }, + "static_resources": { + "clusters": [ + { + "name": "local_agent", + "ignore_health_on_host_removal": false, + "connect_timeout": "1s", + "type": "STATIC", + "http2_protocol_options": {}, + "loadAssignment": { + "clusterName": "local_agent", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socket_address": { + "address": "127.0.0.1", + "port_value": 8502 + } + } + } + } + ] + } + ] + } + } + ] + }, + "stats_config": { + "stats_tags": [ + { + "regex": "^cluster\\.(?:passthrough~)?((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.custom_hash" + }, + { + "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.service_subset" + }, + { + "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.service" + }, + { + "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.namespace" + }, + { + "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:([^.]+)\\.)?[^.]+\\.internal[^.]*\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.partition" + }, + { + "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.datacenter" + }, + { + "regex": "^cluster\\.([^.]+\\.(?:[^.]+\\.)?([^.]+)\\.external\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.peer" + }, + { + "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.routing_type" + }, + { + "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)", + "tag_name": "consul.destination.trust_domain" + }, + { + "regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.destination.target" + }, + { + "regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)", + "tag_name": "consul.destination.full_target" + }, + { + "regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.(([^.]+)(?:\\.[^.]+)?(?:\\.[^.]+)?\\.[^.]+\\.)", + "tag_name": "consul.upstream.service" + }, + { + "regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.[^.]+)?\\.([^.]+)\\.)", + "tag_name": "consul.upstream.datacenter" + }, + { + "regex": "^(?:tcp|http)\\.upstream_peered\\.([^.]+(?:\\.[^.]+)?\\.([^.]+)\\.)", + "tag_name": "consul.upstream.peer" + }, + { + "regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.([^.]+(?:\\.([^.]+))?(?:\\.[^.]+)?\\.[^.]+\\.)", + "tag_name": "consul.upstream.namespace" + }, + { + "regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.([^.]+))?\\.[^.]+\\.)", + "tag_name": "consul.upstream.partition" + }, + { + "regex": "^cluster\\.((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.custom_hash" + }, + { + "regex": "^cluster\\.((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.service_subset" + }, + { + "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.service" + }, + { + "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.namespace" + }, + { + "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)", + "tag_name": "consul.datacenter" + }, + { + "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)", + "tag_name": "consul.routing_type" + }, + { + "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)", + "tag_name": "consul.trust_domain" + }, + { + "regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)", + "tag_name": "consul.target" + }, + { + "regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)", + "tag_name": "consul.full_target" + }, + { + "tag_name": "local_cluster", + "fixed_value": "test" + }, + { + "tag_name": "consul.source.service", + "fixed_value": "test" + }, + { + "tag_name": "consul.source.namespace", + "fixed_value": "default" + }, + { + "tag_name": "consul.source.partition", + "fixed_value": "default" + }, + { + "tag_name": "consul.source.datacenter", + "fixed_value": "dc1" + } + ], + "use_all_default_tags": true + }, + "dynamic_resources": { + "lds_config": { + "ads": {}, + "resource_api_version": "V3" + }, + "cds_config": { + "ads": {}, + "resource_api_version": "V3" + }, + "ads_config": { + "api_type": "DELTA_GRPC", + "transport_api_version": "V3", + "grpc_services": { + "initial_metadata": [ + { + "key": "x-consul-token", + "value": "" + } + ], + "envoy_grpc": { + "cluster_name": "local_agent" + } + } + } + } +} + diff --git a/command/registry.go b/command/registry.go index 1d34f746ca90..5f8980c60a5e 100644 --- a/command/registry.go +++ b/command/registry.go @@ -5,6 +5,7 @@ import ( "github.com/hashicorp/consul/command/operator/raft/transferleader" "os" "os/signal" + "runtime" "syscall" "github.com/hashicorp/consul/command/acl" @@ -126,6 +127,8 @@ import ( "github.com/hashicorp/consul/command/cli" ) +const OSPlatform = runtime.GOOS + // RegisteredCommands returns a realized mapping of available CLI commands in a format that // the CLI class can consume. func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { @@ -181,7 +184,7 @@ func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { entry{"connect ca get-config", func(ui cli.Ui) (cli.Command, error) { return caget.New(ui), nil }}, entry{"connect ca set-config", func(ui cli.Ui) (cli.Command, error) { return caset.New(ui), nil }}, entry{"connect proxy", func(ui cli.Ui) (cli.Command, error) { return proxy.New(ui, MakeShutdownCh()), nil }}, - entry{"connect envoy", func(ui cli.Ui) (cli.Command, error) { return envoy.New(ui), nil }}, + entry{"connect envoy", func(ui cli.Ui) (cli.Command, error) { return envoy.New(ui, OSPlatform), nil }}, entry{"connect envoy pipe-bootstrap", func(ui cli.Ui) (cli.Command, error) { return pipebootstrap.New(ui), nil }}, entry{"connect expose", func(ui cli.Ui) (cli.Command, error) { return expose.New(ui), nil }}, entry{"connect redirect-traffic", func(ui cli.Ui) (cli.Command, error) { return redirecttraffic.New(ui), nil }}, From 5e0bec20c6359c92819510601b33265539135450 Mon Sep 17 00:00:00 2001 From: Jose Ignacio Lorenzo <74208929+joselo85@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:35:46 -0300 Subject: [PATCH 02/24] [CONSUL-519] Implement mkfifo Alternative (#84) --- command/connect/envoy/exec_unsupported.go | 4 +- command/connect/envoy/exec_windows.go | 121 ++++++++++++++++++++++ 2 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 command/connect/envoy/exec_windows.go diff --git a/command/connect/envoy/exec_unsupported.go b/command/connect/envoy/exec_unsupported.go index d22b4c8cdf23..4125a021e80b 100644 --- a/command/connect/envoy/exec_unsupported.go +++ b/command/connect/envoy/exec_unsupported.go @@ -1,5 +1,5 @@ -//go:build !linux && !darwin -// +build !linux,!darwin +//go:build !linux && !darwin && !windows +// +build !linux,!darwin,!windows package envoy diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go new file mode 100644 index 000000000000..e274c1b0b596 --- /dev/null +++ b/command/connect/envoy/exec_windows.go @@ -0,0 +1,121 @@ +//go:build windows +// +build windows + +package envoy + +import ( + "errors" + "fmt" + "os" + "os/exec" + + "path/filepath" + "strings" + + "time" +) + +// testSelfExecOverride is a way for the tests to no fork-bomb themselves by +// self-executing the whole test suite for each case recursively. It's gross but +// the least gross option I could think of. +var testSelfExecOverride string + +func isHotRestartOption(s string) bool { + restartOpts := []string{ + "--restart-epoch", + "--hot-restart-version", + "--drain-time-s", + "--parent-shutdown-time-s", + } + for _, opt := range restartOpts { + if s == opt { + return true + } + if strings.HasPrefix(s, opt+"=") { + return true + } + } + return false +} + +func hasHotRestartOption(argSets ...[]string) bool { + for _, args := range argSets { + for _, opt := range args { + if isHotRestartOption(opt) { + return true + } + } + } + return false +} + +func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { + tempFile := filepath.Join(os.TempDir(), + fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) + + f, err := os.Create(tempFile) + if err != nil { + return tempFile, err + } + + defer f.Close() + f.Write(bootstrapJSON) + f.Sync() + + // We can't wait for the process since we need to exec into Envoy before it + // will be able to complete so it will be remain as a zombie until Envoy is + // killed then will be reaped by the init process (pid 0). This is all a bit + // gross but the cleanest workaround I can think of for Envoy 1.10 not + // supporting /dev/fd/ config paths any more. So we are done and leaving + // the child to run it's course without reaping it. + return tempFile, nil +} + +func startProc(binary string, args []string) (p *os.Process, err error) { + if binary, err = exec.LookPath(binary); err == nil { + var procAttr os.ProcAttr + procAttr.Files = []*os.File{os.Stdin, + os.Stdout, os.Stderr} + p, err := os.StartProcess(binary, args, &procAttr) + if err == nil { + return p, nil + } + } + return nil, err +} + +func execEnvoy(binary string, prefixArgs, suffixArgs []string, bootstrapJSON []byte) error { + tempFile, err := makeBootstrapTemp(bootstrapJSON) + if err != nil { + os.RemoveAll(tempFile) + return err + } + // We don't defer a cleanup since we are about to Exec into Envoy which means + // defer will never fire. The child process cleans up for us in the happy + // path. + + // We default to disabling hot restart because it makes it easier to run + // multiple envoys locally for testing without them trying to share memory and + // unix sockets and complain about being different IDs. But if user is + // actually configuring hot-restart explicitly with the --restart-epoch option + // then don't disable it! + disableHotRestart := !hasHotRestartOption(prefixArgs, suffixArgs) + + // First argument needs to be the executable name. + envoyArgs := []string{} + envoyArgs = append(envoyArgs, prefixArgs...) + if disableHotRestart { + envoyArgs = append(envoyArgs, "--disable-hot-restart") + } + envoyArgs = append(envoyArgs, suffixArgs...) + envoyArgs = append(envoyArgs, "--config-path", tempFile) + + // Exec + if proc, err := startProc(binary, envoyArgs); err == nil { + proc.Wait() + } else if err != nil { + return errors.New("Failed to exec envoy: " + err.Error()) + } + + return nil +} From 41c02a060ec6777c216588036be46ec21b314572 Mon Sep 17 00:00:00 2001 From: Jose Ignacio Lorenzo <74208929+joselo85@users.noreply.github.com> Date: Wed, 9 Nov 2022 10:00:28 -0300 Subject: [PATCH 03/24] [CONSUL-542] Create OS Specific Files for Envoy Package (#88) --- .../envoy/admin_access_log_path_unix.go | 6 +++ .../envoy/admin_access_log_path_windows.go | 6 +++ command/connect/envoy/envoy.go | 44 ++++++------------- 3 files changed, 26 insertions(+), 30 deletions(-) create mode 100644 command/connect/envoy/admin_access_log_path_unix.go create mode 100644 command/connect/envoy/admin_access_log_path_windows.go diff --git a/command/connect/envoy/admin_access_log_path_unix.go b/command/connect/envoy/admin_access_log_path_unix.go new file mode 100644 index 000000000000..aedaa156689c --- /dev/null +++ b/command/connect/envoy/admin_access_log_path_unix.go @@ -0,0 +1,6 @@ +//go:build linux || darwin +// +build linux darwin + +package envoy + +const DefaultAdminAccessLogPath = "/dev/null" diff --git a/command/connect/envoy/admin_access_log_path_windows.go b/command/connect/envoy/admin_access_log_path_windows.go new file mode 100644 index 000000000000..d5e78324769b --- /dev/null +++ b/command/connect/envoy/admin_access_log_path_windows.go @@ -0,0 +1,6 @@ +//go:build windows +// +build windows + +package envoy + +const DefaultAdminAccessLogPath = "nul" diff --git a/command/connect/envoy/envoy.go b/command/connect/envoy/envoy.go index 953c7d42d756..acf238f29fb2 100644 --- a/command/connect/envoy/envoy.go +++ b/command/connect/envoy/envoy.go @@ -7,7 +7,6 @@ import ( "net" "os" "os/exec" - "runtime" "strings" "github.com/mitchellh/cli" @@ -23,15 +22,12 @@ import ( "github.com/hashicorp/consul/tlsutil" ) -func New(ui cli.Ui, osPlatform string) *cmd { +func New(ui cli.Ui) *cmd { c := &cmd{UI: ui} - c.init(osPlatform) + c.init() return c } -const DefaultUnixAdminAccessLogPath = "/dev/null" -const DefaultWindowsAdminAccessLogPath = "nul" - type cmd struct { UI cli.Ui flags *flag.FlagSet @@ -84,7 +80,7 @@ var supportedGateways = map[string]api.ServiceKind{ "ingress": api.ServiceKindIngressGateway, } -func (c *cmd) init(osPlatform string) { +func (c *cmd) init() { c.flags = flag.NewFlagSet("", flag.ContinueOnError) c.flags.StringVar(&c.proxyID, "proxy-id", os.Getenv("CONNECT_PROXY_ID"), @@ -110,17 +106,10 @@ func (c *cmd) init(osPlatform string) { "The full path to the envoy binary to run. By default will just search "+ "$PATH. Ignored if -bootstrap is used.") - if osPlatform == "windows" { - c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultWindowsAdminAccessLogPath, - fmt.Sprintf("The path to write the access log for the administration server. If no access "+ - "log is desired specify %q. By default it will use %q.", - DefaultWindowsAdminAccessLogPath, DefaultWindowsAdminAccessLogPath)) - } else { - c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultUnixAdminAccessLogPath, - fmt.Sprintf("The path to write the access log for the administration server. If no access "+ - "log is desired specify %q. By default it will use %q.", - DefaultUnixAdminAccessLogPath, DefaultUnixAdminAccessLogPath)) - } + c.flags.StringVar(&c.adminAccessLogPath, "admin-access-log-path", DefaultAdminAccessLogPath, + fmt.Sprintf("The path to write the access log for the administration server. If no access "+ + "log is desired specify %q. By default it will use %q.", + DefaultAdminAccessLogPath, DefaultAdminAccessLogPath)) c.flags.StringVar(&c.adminBind, "admin-bind", "localhost:19000", "The address:port to start envoy's admin server on. Envoy requires this "+ @@ -268,11 +257,10 @@ func (c *cmd) Run(args []string) int { return 1 } // TODO: refactor - osPlatform := runtime.GOOS - return c.run(c.flags.Args(), osPlatform) + return c.run(c.flags.Args()) } -func (c *cmd) run(args []string, osPlatform string) int { +func (c *cmd) run(args []string) int { if c.nodeName != "" && c.proxyID == "" { c.UI.Error("'-node-name' requires '-proxy-id'") @@ -439,7 +427,7 @@ func (c *cmd) run(args []string, osPlatform string) int { } // Generate config - bootstrapJson, err := c.generateConfig(osPlatform) + bootstrapJson, err := c.generateConfig() if err != nil { c.UI.Error(err.Error()) return 1 @@ -482,7 +470,7 @@ func (c *cmd) findBinary() (string, error) { return exec.LookPath("envoy") } -func (c *cmd) templateArgs(osPlatform string) (*BootstrapTplArgs, error) { +func (c *cmd) templateArgs() (*BootstrapTplArgs, error) { httpCfg := api.DefaultConfig() c.http.MergeOntoConfig(httpCfg) @@ -525,11 +513,7 @@ func (c *cmd) templateArgs(osPlatform string) (*BootstrapTplArgs, error) { adminAccessLogPath := c.adminAccessLogPath if adminAccessLogPath == "" { - if osPlatform == "windows" { - adminAccessLogPath = DefaultWindowsAdminAccessLogPath - } else { - adminAccessLogPath = DefaultUnixAdminAccessLogPath - } + adminAccessLogPath = DefaultAdminAccessLogPath } // Fallback to the old certificate configuration, if none was defined. @@ -570,8 +554,8 @@ func (c *cmd) templateArgs(osPlatform string) (*BootstrapTplArgs, error) { }, nil } -func (c *cmd) generateConfig(osPlatform string) ([]byte, error) { - args, err := c.templateArgs(osPlatform) +func (c *cmd) generateConfig() ([]byte, error) { + args, err := c.templateArgs() if err != nil { return nil, err } From c592e5db89cfd722fb8d7181e378d3f975bf9464 Mon Sep 17 00:00:00 2001 From: Jose Ignacio Lorenzo <74208929+joselo85@users.noreply.github.com> Date: Wed, 9 Nov 2022 16:04:38 -0300 Subject: [PATCH 04/24] [CONSUL-543] Create exec_supported.go (#89) --- command/connect/envoy/exec_supported.go | 60 +++++++++++++++++++++++++ command/connect/envoy/exec_unix.go | 50 --------------------- command/connect/envoy/exec_windows.go | 35 --------------- command/registry.go | 5 +-- 4 files changed, 61 insertions(+), 89 deletions(-) create mode 100644 command/connect/envoy/exec_supported.go diff --git a/command/connect/envoy/exec_supported.go b/command/connect/envoy/exec_supported.go new file mode 100644 index 000000000000..8122765e0dfd --- /dev/null +++ b/command/connect/envoy/exec_supported.go @@ -0,0 +1,60 @@ +//go:build linux || darwin || windows +// +build linux darwin windows + +package envoy + +import ( + "fmt" + "os" + "strings" +) + +// testSelfExecOverride is a way for the tests to no fork-bomb themselves by +// self-executing the whole test suite for each case recursively. It's gross but +// the least gross option I could think of. +var testSelfExecOverride string + +func isHotRestartOption(s string) bool { + restartOpts := []string{ + "--restart-epoch", + "--hot-restart-version", + "--drain-time-s", + "--parent-shutdown-time-s", + } + for _, opt := range restartOpts { + if s == opt { + return true + } + if strings.HasPrefix(s, opt+"=") { + return true + } + } + return false +} + +func hasHotRestartOption(argSets ...[]string) bool { + for _, args := range argSets { + for _, opt := range args { + if isHotRestartOption(opt) { + return true + } + } + } + return false +} + +// execArgs returns the command and args used to execute a binary. By default it +// will return a command of os.Executable with the args unmodified. This is a shim +// for testing, and can be overridden to execute using 'go run' instead. +var execArgs = func(args ...string) (string, []string, error) { + execPath, err := os.Executable() + if err != nil { + return "", nil, err + } + + if strings.HasSuffix(execPath, "/envoy.test") { + return "", nil, fmt.Errorf("set execArgs to use 'go run' instead of doing a self-exec") + } + + return execPath, args, nil +} diff --git a/command/connect/envoy/exec_unix.go b/command/connect/envoy/exec_unix.go index 9ab83eecfe1d..3800b13c4449 100644 --- a/command/connect/envoy/exec_unix.go +++ b/command/connect/envoy/exec_unix.go @@ -16,56 +16,6 @@ import ( "golang.org/x/sys/unix" ) -// testSelfExecOverride is a way for the tests to no fork-bomb themselves by -// self-executing the whole test suite for each case recursively. It's gross but -// the least gross option I could think of. -var testSelfExecOverride string - -func isHotRestartOption(s string) bool { - restartOpts := []string{ - "--restart-epoch", - "--hot-restart-version", - "--drain-time-s", - "--parent-shutdown-time-s", - } - for _, opt := range restartOpts { - if s == opt { - return true - } - if strings.HasPrefix(s, opt+"=") { - return true - } - } - return false -} - -func hasHotRestartOption(argSets ...[]string) bool { - for _, args := range argSets { - for _, opt := range args { - if isHotRestartOption(opt) { - return true - } - } - } - return false -} - -// execArgs returns the command and args used to execute a binary. By default it -// will return a command of os.Executable with the args unmodified. This is a shim -// for testing, and can be overridden to execute using 'go run' instead. -var execArgs = func(args ...string) (string, []string, error) { - execPath, err := os.Executable() - if err != nil { - return "", nil, err - } - - if strings.HasSuffix(execPath, "/envoy.test") { - return "", nil, fmt.Errorf("set execArgs to use 'go run' instead of doing a self-exec") - } - - return execPath, args, nil -} - func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { pipeFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index e274c1b0b596..61f0404839a1 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -10,45 +10,10 @@ import ( "os/exec" "path/filepath" - "strings" "time" ) -// testSelfExecOverride is a way for the tests to no fork-bomb themselves by -// self-executing the whole test suite for each case recursively. It's gross but -// the least gross option I could think of. -var testSelfExecOverride string - -func isHotRestartOption(s string) bool { - restartOpts := []string{ - "--restart-epoch", - "--hot-restart-version", - "--drain-time-s", - "--parent-shutdown-time-s", - } - for _, opt := range restartOpts { - if s == opt { - return true - } - if strings.HasPrefix(s, opt+"=") { - return true - } - } - return false -} - -func hasHotRestartOption(argSets ...[]string) bool { - for _, args := range argSets { - for _, opt := range args { - if isHotRestartOption(opt) { - return true - } - } - } - return false -} - func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { tempFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) diff --git a/command/registry.go b/command/registry.go index 5f8980c60a5e..1d34f746ca90 100644 --- a/command/registry.go +++ b/command/registry.go @@ -5,7 +5,6 @@ import ( "github.com/hashicorp/consul/command/operator/raft/transferleader" "os" "os/signal" - "runtime" "syscall" "github.com/hashicorp/consul/command/acl" @@ -127,8 +126,6 @@ import ( "github.com/hashicorp/consul/command/cli" ) -const OSPlatform = runtime.GOOS - // RegisteredCommands returns a realized mapping of available CLI commands in a format that // the CLI class can consume. func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { @@ -184,7 +181,7 @@ func RegisteredCommands(ui cli.Ui) map[string]mcli.CommandFactory { entry{"connect ca get-config", func(ui cli.Ui) (cli.Command, error) { return caget.New(ui), nil }}, entry{"connect ca set-config", func(ui cli.Ui) (cli.Command, error) { return caset.New(ui), nil }}, entry{"connect proxy", func(ui cli.Ui) (cli.Command, error) { return proxy.New(ui, MakeShutdownCh()), nil }}, - entry{"connect envoy", func(ui cli.Ui) (cli.Command, error) { return envoy.New(ui, OSPlatform), nil }}, + entry{"connect envoy", func(ui cli.Ui) (cli.Command, error) { return envoy.New(ui), nil }}, entry{"connect envoy pipe-bootstrap", func(ui cli.Ui) (cli.Command, error) { return pipebootstrap.New(ui), nil }}, entry{"connect expose", func(ui cli.Ui) (cli.Command, error) { return expose.New(ui), nil }}, entry{"connect redirect-traffic", func(ui cli.Ui) (cli.Command, error) { return redirecttraffic.New(ui), nil }}, From ace9e379d2e947b8ef9a1d314bf345089702ee23 Mon Sep 17 00:00:00 2001 From: Jose Ignacio Lorenzo <74208929+joselo85@users.noreply.github.com> Date: Thu, 10 Nov 2022 16:00:26 -0300 Subject: [PATCH 05/24] [CONSUL-544] Test and Build Changes (#90) --- command/connect/envoy/envoy_test.go | 46 +--- .../envoy/testdata/defaults-windows.golden | 210 ------------------ 2 files changed, 7 insertions(+), 249 deletions(-) delete mode 100644 command/connect/envoy/testdata/defaults-windows.golden diff --git a/command/connect/envoy/envoy_test.go b/command/connect/envoy/envoy_test.go index 4bb2032da80d..31c078dc9967 100644 --- a/command/connect/envoy/envoy_test.go +++ b/command/connect/envoy/envoy_test.go @@ -24,11 +24,9 @@ import ( var update = flag.Bool("update", false, "update golden files") -const defaultOSPlatform = "linux" - func TestEnvoyCommand_noTabs(t *testing.T) { t.Parallel() - if strings.ContainsRune(New(nil, defaultOSPlatform).Help(), '\t') { + if strings.ContainsRune(New(nil).Help(), '\t') { t.Fatal("help has tabs") } } @@ -66,8 +64,8 @@ func TestEnvoyGateway_Validation(t *testing.T) { for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { ui := cli.NewMockUi() - c := New(ui, defaultOSPlatform) - c.init(defaultOSPlatform) + c := New(ui) + c.init() code := c.Run(tc.args) if code == 0 { @@ -122,7 +120,6 @@ type generateConfigTestCase struct { AgentSelf110 bool // fake the agent API from versions v1.10 and earlier WantArgs BootstrapTplArgs WantErr string - OSPlatform string } // This tests the args we use to generate the template directly because they @@ -163,28 +160,6 @@ func TestGenerateConfig(t *testing.T) { PrometheusScrapePath: "/metrics", }, }, - { - Name: "defaults-windows", - Flags: []string{"-proxy-id", "test-proxy"}, - WantArgs: BootstrapTplArgs{ - ProxyCluster: "test-proxy", - ProxyID: "test-proxy", - // We don't know this til after the lookup so it will be empty in the - // initial args call we are testing here. - ProxySourceService: "", - GRPC: GRPC{ - AgentAddress: "127.0.0.1", - AgentPort: "8502", // Note this is the gRPC port - }, - AdminAccessLogPath: "nul", - AdminBindAddress: "127.0.0.1", - AdminBindPort: "19000", - LocalAgentClusterName: xds.LocalAgentClusterName, - PrometheusBackendPort: "", - PrometheusScrapePath: "/metrics", - }, - OSPlatform: "windows", - }, { Name: "defaults-nodemeta", Flags: []string{"-proxy-id", "test-proxy", "-node-name", "test-node"}, @@ -1126,14 +1101,8 @@ func TestGenerateConfig(t *testing.T) { client, err := api.NewClient(&api.Config{Address: srv.URL, TLSConfig: api.TLSConfig{InsecureSkipVerify: true}}) require.NoError(t, err) - // Default OS Platform "linux". Custom value should be set in the test case - osPlatform := "linux" - if tc.OSPlatform == "windows" { - osPlatform = tc.OSPlatform - } - ui := cli.NewMockUi() - c := New(ui, osPlatform) + c := New(ui) // explicitly set the client to one which can connect to the httptest.Server c.client = client @@ -1142,7 +1111,7 @@ func TestGenerateConfig(t *testing.T) { args := append([]string{"-bootstrap"}, myFlags...) require.NoError(t, c.flags.Parse(args)) - code := c.run(c.flags.Args(), osPlatform) + code := c.run(c.flags.Args()) if tc.WantErr == "" { require.Equal(t, 0, code, ui.ErrorWriter.String()) } else { @@ -1153,8 +1122,7 @@ func TestGenerateConfig(t *testing.T) { // Verify we handled the env and flags right first to get correct template // args. - got, err := c.templateArgs(osPlatform) - + got, err := c.templateArgs() require.NoError(t, err) // Error cases should have returned above require.Equal(t, &tc.WantArgs, got) @@ -1247,7 +1215,7 @@ func TestEnvoy_GatewayRegistration(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { ui := cli.NewMockUi() - c := New(ui, defaultOSPlatform) + c := New(ui) code := c.Run(tc.args) if code != 0 { diff --git a/command/connect/envoy/testdata/defaults-windows.golden b/command/connect/envoy/testdata/defaults-windows.golden deleted file mode 100644 index 59ef580c5d23..000000000000 --- a/command/connect/envoy/testdata/defaults-windows.golden +++ /dev/null @@ -1,210 +0,0 @@ -{ - "admin": { - "access_log_path": "nul", - "address": { - "socket_address": { - "address": "127.0.0.1", - "port_value": 19000 - } - } - }, - "node": { - "cluster": "test", - "id": "test-proxy", - "metadata": { - "namespace": "default", - "partition": "default" - } - }, - "layered_runtime": { - "layers": [ - { - "name": "base", - "static_layer": { - "re2.max_program_size.error_level": 1048576 - } - } - ] - }, - "static_resources": { - "clusters": [ - { - "name": "local_agent", - "ignore_health_on_host_removal": false, - "connect_timeout": "1s", - "type": "STATIC", - "http2_protocol_options": {}, - "loadAssignment": { - "clusterName": "local_agent", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socket_address": { - "address": "127.0.0.1", - "port_value": 8502 - } - } - } - } - ] - } - ] - } - } - ] - }, - "stats_config": { - "stats_tags": [ - { - "regex": "^cluster\\.(?:passthrough~)?((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.custom_hash" - }, - { - "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.service_subset" - }, - { - "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.service" - }, - { - "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.namespace" - }, - { - "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:([^.]+)\\.)?[^.]+\\.internal[^.]*\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.partition" - }, - { - "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.datacenter" - }, - { - "regex": "^cluster\\.([^.]+\\.(?:[^.]+\\.)?([^.]+)\\.external\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.peer" - }, - { - "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.routing_type" - }, - { - "regex": "^cluster\\.(?:passthrough~)?((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)", - "tag_name": "consul.destination.trust_domain" - }, - { - "regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.destination.target" - }, - { - "regex": "^cluster\\.(?:passthrough~)?(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)", - "tag_name": "consul.destination.full_target" - }, - { - "regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.(([^.]+)(?:\\.[^.]+)?(?:\\.[^.]+)?\\.[^.]+\\.)", - "tag_name": "consul.upstream.service" - }, - { - "regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.[^.]+)?\\.([^.]+)\\.)", - "tag_name": "consul.upstream.datacenter" - }, - { - "regex": "^(?:tcp|http)\\.upstream_peered\\.([^.]+(?:\\.[^.]+)?\\.([^.]+)\\.)", - "tag_name": "consul.upstream.peer" - }, - { - "regex": "^(?:tcp|http)\\.upstream(?:_peered)?\\.([^.]+(?:\\.([^.]+))?(?:\\.[^.]+)?\\.[^.]+\\.)", - "tag_name": "consul.upstream.namespace" - }, - { - "regex": "^(?:tcp|http)\\.upstream\\.([^.]+(?:\\.[^.]+)?(?:\\.([^.]+))?\\.[^.]+\\.)", - "tag_name": "consul.upstream.partition" - }, - { - "regex": "^cluster\\.((?:([^.]+)~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.custom_hash" - }, - { - "regex": "^cluster\\.((?:[^.]+~)?(?:([^.]+)\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.service_subset" - }, - { - "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?([^.]+)\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.service" - }, - { - "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.namespace" - }, - { - "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?([^.]+)\\.internal[^.]*\\.[^.]+\\.consul\\.)", - "tag_name": "consul.datacenter" - }, - { - "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.([^.]+)\\.[^.]+\\.consul\\.)", - "tag_name": "consul.routing_type" - }, - { - "regex": "^cluster\\.((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.([^.]+)\\.consul\\.)", - "tag_name": "consul.trust_domain" - }, - { - "regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+)\\.[^.]+\\.[^.]+\\.consul\\.)", - "tag_name": "consul.target" - }, - { - "regex": "^cluster\\.(((?:[^.]+~)?(?:[^.]+\\.)?[^.]+\\.[^.]+\\.(?:[^.]+\\.)?[^.]+\\.[^.]+\\.[^.]+)\\.consul\\.)", - "tag_name": "consul.full_target" - }, - { - "tag_name": "local_cluster", - "fixed_value": "test" - }, - { - "tag_name": "consul.source.service", - "fixed_value": "test" - }, - { - "tag_name": "consul.source.namespace", - "fixed_value": "default" - }, - { - "tag_name": "consul.source.partition", - "fixed_value": "default" - }, - { - "tag_name": "consul.source.datacenter", - "fixed_value": "dc1" - } - ], - "use_all_default_tags": true - }, - "dynamic_resources": { - "lds_config": { - "ads": {}, - "resource_api_version": "V3" - }, - "cds_config": { - "ads": {}, - "resource_api_version": "V3" - }, - "ads_config": { - "api_type": "DELTA_GRPC", - "transport_api_version": "V3", - "grpc_services": { - "initial_metadata": [ - { - "key": "x-consul-token", - "value": "" - } - ], - "envoy_grpc": { - "cluster_name": "local_agent" - } - } - } - } -} - From 7fab79fda2f72f3f1bd73960342ffe98e55eb167 Mon Sep 17 00:00:00 2001 From: Jose Ignacio Lorenzo Date: Wed, 16 Nov 2022 17:27:01 -0300 Subject: [PATCH 06/24] Implement os.DevNull --- command/connect/envoy/admin_access_log_path_unix.go | 6 ------ command/connect/envoy/admin_access_log_path_windows.go | 6 ------ command/connect/envoy/envoy.go | 2 ++ 3 files changed, 2 insertions(+), 12 deletions(-) delete mode 100644 command/connect/envoy/admin_access_log_path_unix.go delete mode 100644 command/connect/envoy/admin_access_log_path_windows.go diff --git a/command/connect/envoy/admin_access_log_path_unix.go b/command/connect/envoy/admin_access_log_path_unix.go deleted file mode 100644 index aedaa156689c..000000000000 --- a/command/connect/envoy/admin_access_log_path_unix.go +++ /dev/null @@ -1,6 +0,0 @@ -//go:build linux || darwin -// +build linux darwin - -package envoy - -const DefaultAdminAccessLogPath = "/dev/null" diff --git a/command/connect/envoy/admin_access_log_path_windows.go b/command/connect/envoy/admin_access_log_path_windows.go deleted file mode 100644 index d5e78324769b..000000000000 --- a/command/connect/envoy/admin_access_log_path_windows.go +++ /dev/null @@ -1,6 +0,0 @@ -//go:build windows -// +build windows - -package envoy - -const DefaultAdminAccessLogPath = "nul" diff --git a/command/connect/envoy/envoy.go b/command/connect/envoy/envoy.go index acf238f29fb2..c5e226e5ffda 100644 --- a/command/connect/envoy/envoy.go +++ b/command/connect/envoy/envoy.go @@ -28,6 +28,8 @@ func New(ui cli.Ui) *cmd { return c } +const DefaultAdminAccessLogPath = os.DevNull + type cmd struct { UI cli.Ui flags *flag.FlagSet From 4b2fc2d050c00c38fedba33002a3247c12e43c57 Mon Sep 17 00:00:00 2001 From: Ashesh Vidyut Date: Tue, 13 Jun 2023 15:28:30 +0530 Subject: [PATCH 07/24] using mmap instead of disk files --- command/connect/envoy/exec_windows.go | 4 +++- go.mod | 1 + go.sum | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 61f0404839a1..8e2fdca99287 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -12,13 +12,15 @@ import ( "path/filepath" "time" + + "github.com/go-mmap/mmap" ) func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { tempFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) - f, err := os.Create(tempFile) + f, err := mmap.Open(tempFile, mmap.Write) if err != nil { return tempFile, err } diff --git a/go.mod b/go.mod index 89ef735d985d..8f4c6f4f36b9 100644 --- a/go.mod +++ b/go.mod @@ -155,6 +155,7 @@ require ( github.com/form3tech-oss/jwt-go v3.2.2+incompatible // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-mmap/mmap v0.7.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect diff --git a/go.sum b/go.sum index 59ebf57327e0..14190d392333 100644 --- a/go.sum +++ b/go.sum @@ -315,6 +315,8 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-mmap/mmap v0.7.0 h1:+h1n06sZw0IWBwL9YDzTomNNXxM4LH/l+HVpGaTC+qk= +github.com/go-mmap/mmap v0.7.0/go.mod h1:moN8m00bW6Mpk+Y1xQFeL3xZqycnT4qUAf852ICV/Gc= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= From 906aaa227d69713c6d4fb728624a20d7f3dc09ba Mon Sep 17 00:00:00 2001 From: Ashesh Vidyut Date: Tue, 13 Jun 2023 16:09:14 +0530 Subject: [PATCH 08/24] fix import in exec-unix --- command/connect/envoy/exec_unix.go | 1 - 1 file changed, 1 deletion(-) diff --git a/command/connect/envoy/exec_unix.go b/command/connect/envoy/exec_unix.go index 52a446eb4775..e3d07e2af36d 100644 --- a/command/connect/envoy/exec_unix.go +++ b/command/connect/envoy/exec_unix.go @@ -12,7 +12,6 @@ import ( "os" "os/exec" "path/filepath" - "strings" "syscall" "time" From 2a70c2f72095f73f04fe633b4b3dbc10964f7aea Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 19 Jun 2023 10:56:27 +0530 Subject: [PATCH 09/24] fix nmap open too many arguemtn --- command/connect/envoy/exec_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 8e2fdca99287..1ae99b478c89 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -20,7 +20,7 @@ func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { tempFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) - f, err := mmap.Open(tempFile, mmap.Write) + f, err := mmap.Open(tempFile) if err != nil { return tempFile, err } From fb1fd8e834827f9b9a1a8e943c446597775a1d67 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 19 Jun 2023 21:54:15 +0530 Subject: [PATCH 10/24] go fmt on file --- command/connect/envoy/exec_supported.go | 115 ++++++++++++------------ 1 file changed, 55 insertions(+), 60 deletions(-) diff --git a/command/connect/envoy/exec_supported.go b/command/connect/envoy/exec_supported.go index 8122765e0dfd..09dbf895bb12 100644 --- a/command/connect/envoy/exec_supported.go +++ b/command/connect/envoy/exec_supported.go @@ -1,60 +1,55 @@ -//go:build linux || darwin || windows -// +build linux darwin windows - -package envoy - -import ( - "fmt" - "os" - "strings" -) - -// testSelfExecOverride is a way for the tests to no fork-bomb themselves by -// self-executing the whole test suite for each case recursively. It's gross but -// the least gross option I could think of. -var testSelfExecOverride string - -func isHotRestartOption(s string) bool { - restartOpts := []string{ - "--restart-epoch", - "--hot-restart-version", - "--drain-time-s", - "--parent-shutdown-time-s", - } - for _, opt := range restartOpts { - if s == opt { - return true - } - if strings.HasPrefix(s, opt+"=") { - return true - } - } - return false -} - -func hasHotRestartOption(argSets ...[]string) bool { - for _, args := range argSets { - for _, opt := range args { - if isHotRestartOption(opt) { - return true - } - } - } - return false -} - -// execArgs returns the command and args used to execute a binary. By default it -// will return a command of os.Executable with the args unmodified. This is a shim -// for testing, and can be overridden to execute using 'go run' instead. -var execArgs = func(args ...string) (string, []string, error) { - execPath, err := os.Executable() - if err != nil { - return "", nil, err - } - - if strings.HasSuffix(execPath, "/envoy.test") { - return "", nil, fmt.Errorf("set execArgs to use 'go run' instead of doing a self-exec") - } - - return execPath, args, nil -} +//go:build linux || darwin || windows +// +build linux darwin windows + +package envoy + +import ( + "fmt" + "os" + "strings" +) + +func isHotRestartOption(s string) bool { + restartOpts := []string{ + "--restart-epoch", + "--hot-restart-version", + "--drain-time-s", + "--parent-shutdown-time-s", + } + for _, opt := range restartOpts { + if s == opt { + return true + } + if strings.HasPrefix(s, opt+"=") { + return true + } + } + return false +} + +func hasHotRestartOption(argSets ...[]string) bool { + for _, args := range argSets { + for _, opt := range args { + if isHotRestartOption(opt) { + return true + } + } + } + return false +} + +// execArgs returns the command and args used to execute a binary. By default it +// will return a command of os.Executable with the args unmodified. This is a shim +// for testing, and can be overridden to execute using 'go run' instead. +var execArgs = func(args ...string) (string, []string, error) { + execPath, err := os.Executable() + if err != nil { + return "", nil, err + } + + if strings.HasSuffix(execPath, "/envoy.test") { + return "", nil, fmt.Errorf("set execArgs to use 'go run' instead of doing a self-exec") + } + + return execPath, args, nil +} From 45f6f2ae947fe20182353c157b6cd156846a5696 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 19 Jun 2023 21:56:23 +0530 Subject: [PATCH 11/24] changelog file --- .changelog/17694.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/17694.txt diff --git a/.changelog/17694.txt b/.changelog/17694.txt new file mode 100644 index 000000000000..181179bc9513 --- /dev/null +++ b/.changelog/17694.txt @@ -0,0 +1,3 @@ +```release-note:feature +window: support consul connect envoy command on windows +``` From 4ab3bdb93874218314f9671753cf4348fef3beff Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 19 Jun 2023 22:09:21 +0530 Subject: [PATCH 12/24] fix go mod --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 049c1d5ed08e..532f521a2931 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e github.com/fatih/color v1.14.1 github.com/fsnotify/fsnotify v1.6.0 + github.com/go-mmap/mmap v0.7.0 github.com/go-openapi/runtime v0.25.0 github.com/go-openapi/strfmt v0.21.3 github.com/google/go-cmp v0.5.9 @@ -159,7 +160,6 @@ require ( github.com/form3tech-oss/jwt-go v3.2.2+incompatible // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-mmap/mmap v0.7.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect From 4d62ffc16cea189d403f92a6200891322150160b Mon Sep 17 00:00:00 2001 From: Ashesh Vidyut <134911583+absolutelightning@users.noreply.github.com> Date: Wed, 21 Jun 2023 19:21:45 +0530 Subject: [PATCH 13/24] Update .changelog/17694.txt Co-authored-by: Dhia Ayachi --- .changelog/17694.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/17694.txt b/.changelog/17694.txt index 181179bc9513..703b100d1d3a 100644 --- a/.changelog/17694.txt +++ b/.changelog/17694.txt @@ -1,3 +1,3 @@ ```release-note:feature -window: support consul connect envoy command on windows +Windows: support consul connect envoy command on Windows ``` From 55dba95cdc33eccbb22771a421b509ef757deda2 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Wed, 21 Jun 2023 19:37:43 +0530 Subject: [PATCH 14/24] different mmap library --- command/connect/envoy/exec_windows.go | 9 +++------ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 1ae99b478c89..3b34bbf92550 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -6,26 +6,23 @@ package envoy import ( "errors" "fmt" + "github.com/edsrzf/mmap-go" "os" "os/exec" - "path/filepath" - "time" - - "github.com/go-mmap/mmap" ) func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { tempFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) - f, err := mmap.Open(tempFile) + f, err := mmap.Map(tempFile) if err != nil { return tempFile, err } - defer f.Close() + defer f.UnMap() f.Write(bootstrapJSON) f.Sync() diff --git a/go.mod b/go.mod index 532f521a2931..0fb75928864f 100644 --- a/go.mod +++ b/go.mod @@ -25,11 +25,11 @@ require ( github.com/coredns/coredns v1.6.6 github.com/coreos/go-oidc v2.1.0+incompatible github.com/docker/go-connections v0.4.0 + github.com/edsrzf/mmap-go v1.1.0 github.com/envoyproxy/go-control-plane v0.11.0 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e github.com/fatih/color v1.14.1 github.com/fsnotify/fsnotify v1.6.0 - github.com/go-mmap/mmap v0.7.0 github.com/go-openapi/runtime v0.25.0 github.com/go-openapi/strfmt v0.21.3 github.com/google/go-cmp v0.5.9 diff --git a/go.sum b/go.sum index ba9cec299dd8..50778d14080d 100644 --- a/go.sum +++ b/go.sum @@ -263,6 +263,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= +github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= @@ -332,8 +334,6 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-mmap/mmap v0.7.0 h1:+h1n06sZw0IWBwL9YDzTomNNXxM4LH/l+HVpGaTC+qk= -github.com/go-mmap/mmap v0.7.0/go.mod h1:moN8m00bW6Mpk+Y1xQFeL3xZqycnT4qUAf852ICV/Gc= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= From 6b0a813612fc94d436e030612aa9b21bc451caec Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Wed, 28 Jun 2023 07:29:29 +0530 Subject: [PATCH 15/24] using different library --- command/connect/envoy/exec_windows.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 3b34bbf92550..769950e63f9b 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -17,12 +17,18 @@ func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { tempFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) - f, err := mmap.Map(tempFile) + file, err := os.OpenFile(tempFile, os.O_RDWR, 0644) + + if err != nil { + return tempFile, err + } + + f, err := mmap.Map(file) if err != nil { return tempFile, err } - defer f.UnMap() + defer f.Unmap() f.Write(bootstrapJSON) f.Sync() From 27073a4abb81f7d3f64448004bbf783f36762c4f Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Wed, 28 Jun 2023 08:13:15 +0530 Subject: [PATCH 16/24] fix Map funciton call --- command/connect/envoy/exec_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 769950e63f9b..a1a72f3844d9 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -23,7 +23,7 @@ func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { return tempFile, err } - f, err := mmap.Map(file) + f, err := mmap.Map(file, 0, 0) if err != nil { return tempFile, err } From b4cf245dc2d79d9a723dde93e4633e3b33a4a487 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Wed, 28 Jun 2023 08:14:46 +0530 Subject: [PATCH 17/24] fix mmap call --- command/connect/envoy/exec_windows.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index a1a72f3844d9..9bc17c565b8a 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -29,8 +29,6 @@ func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { } defer f.Unmap() - f.Write(bootstrapJSON) - f.Sync() // We can't wait for the process since we need to exec into Envoy before it // will be able to complete so it will be remain as a zombie until Envoy is From 05b3fbd3166239174c62c6f9cabb4d70d69eddee Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Wed, 28 Jun 2023 21:55:22 +0530 Subject: [PATCH 18/24] fix go mod --- go.sum | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.sum b/go.sum index c824ee576089..ee042500a7f9 100644 --- a/go.sum +++ b/go.sum @@ -214,12 +214,8 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= -github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= From 7a0b16333bb6e18993d1acf90d0bdb74b6baa0a2 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 3 Jul 2023 20:26:39 +0530 Subject: [PATCH 19/24] made code similar to unix using npipe --- command/connect/envoy/exec_windows.go | 50 +++++++++++++++++++++------ 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 9bc17c565b8a..e4ac82f0c200 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -6,29 +6,59 @@ package envoy import ( "errors" "fmt" - "github.com/edsrzf/mmap-go" + "github.com/natefinch/npipe" "os" "os/exec" "path/filepath" "time" ) -func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { - tempFile := filepath.Join(os.TempDir(), +func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { + pipeFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) - file, err := os.OpenFile(tempFile, os.O_RDWR, 0644) - + pipeConn, err := npipe.Dial(pipeFile) if err != nil { return tempFile, err } - f, err := mmap.Map(file, 0, 0) + defer pipeConn.close() + + binary, args, err := execArgs("connect", "envoy", "pipe-bootstrap", pipeFile) if err != nil { - return tempFile, err + return pipeFile, err + } + + // Start the command to connect to the named pipe + cmd := exec.Command(binary, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + stdin, err := cmd.StdinPipe() + if err != nil { + return pipeFile, err + } + + // Start the command and write the config + err = cmd.Start() + if err != nil { + return pipeFile, err + } + + // Write the config + _, err = stdin.Write(bootstrapJSON) + if err != nil { + return pipeFile, err + } + err = stdin.Close() + if err != nil { + return pipeFile, err } - defer f.Unmap() + // Wait for the command to finish + err = cmd.Wait() + if err != nil { + return pipeFile, err + } // We can't wait for the process since we need to exec into Envoy before it // will be able to complete so it will be remain as a zombie until Envoy is @@ -36,7 +66,7 @@ func makeBootstrapTemp(bootstrapJSON []byte) (string, error) { // gross but the cleanest workaround I can think of for Envoy 1.10 not // supporting /dev/fd/ config paths any more. So we are done and leaving // the child to run it's course without reaping it. - return tempFile, nil + return pipeFile, nil } func startProc(binary string, args []string) (p *os.Process, err error) { @@ -53,7 +83,7 @@ func startProc(binary string, args []string) (p *os.Process, err error) { } func execEnvoy(binary string, prefixArgs, suffixArgs []string, bootstrapJSON []byte) error { - tempFile, err := makeBootstrapTemp(bootstrapJSON) + tempFile, err := makeBootstrapPipe(bootstrapJSON) if err != nil { os.RemoveAll(tempFile) return err From fd4ceeda17f36e18073b825da681628f0bb25c45 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 3 Jul 2023 20:31:49 +0530 Subject: [PATCH 20/24] fix go.mod --- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6ac856f09dfa..c4fc7a5c847d 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,6 @@ require ( github.com/coredns/coredns v1.10.1 github.com/coreos/go-oidc v2.1.0+incompatible github.com/docker/go-connections v0.4.0 - github.com/edsrzf/mmap-go v1.1.0 github.com/envoyproxy/go-control-plane v0.11.0 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e github.com/fatih/color v1.14.1 @@ -87,6 +86,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/pointerstructure v1.2.1 github.com/mitchellh/reflectwalk v1.0.2 + github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce github.com/oklog/ulid/v2 v2.1.0 github.com/olekukonko/tablewriter v0.0.4 github.com/patrickmn/go-cache v2.1.0+incompatible @@ -251,6 +251,7 @@ require ( google.golang.org/appengine v1.6.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/resty.v1 v1.12.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index ee042500a7f9..8d340dcdb30d 100644 --- a/go.sum +++ b/go.sum @@ -214,8 +214,6 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= -github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= @@ -741,6 +739,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce h1:TqjP/BTDrwN7zP9xyXVuLsMBXYMt6LLYi55PlrIcq8U= +github.com/natefinch/npipe v0.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:ifHPsLndGGzvgzcaXUvzmt6LxKT4pJ+uzEhtnMt+f7A= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -1460,6 +1460,8 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.9.1/go.mod h1:vo52Hzryw9PnPHcJfPsBiFW62XhNx5OczbV9y+IMpgc= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= From fd75fb78cf09b2ade707439bc6386d8a31ac29a2 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 3 Jul 2023 20:40:27 +0530 Subject: [PATCH 21/24] fix dialing of npipe --- command/connect/envoy/exec_windows.go | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index e4ac82f0c200..92d50c4fc383 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -17,39 +17,32 @@ func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { pipeFile := filepath.Join(os.TempDir(), fmt.Sprintf("envoy-%x-bootstrap.json", time.Now().UnixNano()+int64(os.Getpid()))) - pipeConn, err := npipe.Dial(pipeFile) + binary, args, err := execArgs("connect", "envoy", "pipe-bootstrap", pipeFile) if err != nil { - return tempFile, err + return pipeFile, err } - defer pipeConn.close() - - binary, args, err := execArgs("connect", "envoy", "pipe-bootstrap", pipeFile) + // Dial the named pipe + pipeConn, err := npipe.Dial(pipeFile) if err != nil { return pipeFile, err } + defer pipeConn.Close() // Start the command to connect to the named pipe cmd := exec.Command(binary, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - stdin, err := cmd.StdinPipe() - if err != nil { - return pipeFile, err - } + cmd.Stdin = pipeConn - // Start the command and write the config + // Start the command err = cmd.Start() if err != nil { return pipeFile, err } // Write the config - _, err = stdin.Write(bootstrapJSON) - if err != nil { - return pipeFile, err - } - err = stdin.Close() + _, err = pipeConn.Write(bootstrapJSON) if err != nil { return pipeFile, err } From f500139a89fbc596fb6e254fc363f807109b5875 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Mon, 3 Jul 2023 21:42:24 +0530 Subject: [PATCH 22/24] dont wait --- command/connect/envoy/exec_windows.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 92d50c4fc383..72589e772f3f 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -47,12 +47,6 @@ func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { return pipeFile, err } - // Wait for the command to finish - err = cmd.Wait() - if err != nil { - return pipeFile, err - } - // We can't wait for the process since we need to exec into Envoy before it // will be able to complete so it will be remain as a zombie until Envoy is // killed then will be reaped by the init process (pid 0). This is all a bit From 796a88a9525bf5765ec937ba9dd17350895c8121 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Tue, 4 Jul 2023 10:17:37 +0530 Subject: [PATCH 23/24] check size of written json --- command/connect/envoy/exec_windows.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 72589e772f3f..7b5bd951bd63 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -42,11 +42,15 @@ func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { } // Write the config - _, err = pipeConn.Write(bootstrapJSON) + n, err = pipeConn.Write(bootstrapJSON) if err != nil { return pipeFile, err } + if n < len(bootstrapJSON) { + return pipeFile, fmt.Errorf("failed writing boostrap to child STDIN: %s", err) + } + // We can't wait for the process since we need to exec into Envoy before it // will be able to complete so it will be remain as a zombie until Envoy is // killed then will be reaped by the init process (pid 0). This is all a bit From a39760aeec8352edb7ba18e3de9365e4ede01f99 Mon Sep 17 00:00:00 2001 From: absolutelightning Date: Tue, 4 Jul 2023 10:44:11 +0530 Subject: [PATCH 24/24] fix undefined n --- command/connect/envoy/exec_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/connect/envoy/exec_windows.go b/command/connect/envoy/exec_windows.go index 7b5bd951bd63..e70108794ca0 100644 --- a/command/connect/envoy/exec_windows.go +++ b/command/connect/envoy/exec_windows.go @@ -42,7 +42,7 @@ func makeBootstrapPipe(bootstrapJSON []byte) (string, error) { } // Write the config - n, err = pipeConn.Write(bootstrapJSON) + n, err := pipeConn.Write(bootstrapJSON) if err != nil { return pipeFile, err }