diff --git a/docker-compose.yaml b/docker-compose.yaml index ab127b6..5b1c656 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -17,6 +17,7 @@ services: target: /run/secrets/basic-auth-user cap_add: - CAP_NET_RAW + nats: image: docker.io/library/nats-streaming:0.11.2 command: @@ -25,6 +26,7 @@ services: - "8222" - "--store=memory" - "--cluster_id=faas-cluster" + prometheus: image: docker.io/prom/prometheus:v2.14.0 volumes: @@ -33,6 +35,7 @@ services: target: /etc/prometheus/prometheus.yml cap_add: - CAP_NET_RAW + gateway: image: "docker.io/openfaas/gateway:0.18.17${ARCH_SUFFIX}" environment: @@ -58,6 +61,11 @@ services: target: /run/secrets/basic-auth-user cap_add: - CAP_NET_RAW + depends_on: + - basic-auth-plugin + - nats + - prometheus + queue-worker: image: docker.io/openfaas/queue-worker:0.11.2 environment: @@ -80,3 +88,5 @@ services: target: /run/secrets/basic-auth-user cap_add: - CAP_NET_RAW + depends_on: + - nats diff --git a/pkg/cninetwork/weave.go b/pkg/cninetwork/weave.go index 43ccfaa..71b4fca 100644 --- a/pkg/cninetwork/weave.go +++ b/pkg/cninetwork/weave.go @@ -18,19 +18,6 @@ type Dev struct { CIDRs []*net.IPNet `json:"CIDRs,omitempty"` } -func linkToNetDev(link netlink.Link) (Dev, error) { - addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) - if err != nil { - return Dev{}, err - } - - netDev := Dev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr} - for _, addr := range addrs { - netDev.CIDRs = append(netDev.CIDRs, addr.IPNet) - } - return netDev, nil -} - // ConnectedToBridgeVethPeerIds returns peer indexes of veth links connected to // the given bridge. The peer index is used to query from a container netns // whether the container is connected to the bridge. diff --git a/pkg/cninetwork/weave_linux.go b/pkg/cninetwork/weave_linux.go new file mode 100644 index 0000000..3950ab2 --- /dev/null +++ b/pkg/cninetwork/weave_linux.go @@ -0,0 +1,19 @@ +// +build linux + +package cninetwork + +import "github.com/vishvananda/netlink" + +func linkToNetDev(link netlink.Link) (Dev, error) { + + addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) + if err != nil { + return Dev{}, err + } + + netDev := Dev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr} + for _, addr := range addrs { + netDev.CIDRs = append(netDev.CIDRs, addr.IPNet) + } + return netDev, nil +} diff --git a/pkg/cninetwork/weave_mac.go b/pkg/cninetwork/weave_mac.go new file mode 100644 index 0000000..983e705 --- /dev/null +++ b/pkg/cninetwork/weave_mac.go @@ -0,0 +1,10 @@ +// +build darwin + +package cninetwork + +import "github.com/vishvananda/netlink" + +func linkToNetDev(link netlink.Link) (Dev, error) { + + return Dev{}, nil +} diff --git a/pkg/depends_on.go b/pkg/depends_on.go new file mode 100644 index 0000000..97925f2 --- /dev/null +++ b/pkg/depends_on.go @@ -0,0 +1,35 @@ +package pkg + +import "fmt" + +func buildInstallOrder(svcs []Service) []string { + graph := Graph{nodes: []*Node{}} + + nodeMap := map[string]*Node{} + for _, s := range svcs { + n := &Node{Name: s.Name} + nodeMap[s.Name] = n + graph.nodes = append(graph.nodes, n) + } + + for _, s := range svcs { + for _, d := range s.DependsOn { + nodeMap[s.Name].Edges = append(nodeMap[s.Name].Edges, nodeMap[d]) + } + } + + resolved := &Graph{} + unresolved := &Graph{} + for _, g := range graph.nodes { + resolve(g, resolved, unresolved) + } + + fmt.Printf("Installation order:\n") + order := []string{} + for _, node := range resolved.nodes { + fmt.Printf("- %s\n", node.Name) + order = append(order, node.Name) + } + + return order +} diff --git a/pkg/depends_on_test.go b/pkg/depends_on_test.go new file mode 100644 index 0000000..88fa6c0 --- /dev/null +++ b/pkg/depends_on_test.go @@ -0,0 +1,224 @@ +package pkg + +import ( + "log" + "testing" +) + +func Test_buildInstallOrder_ARequiresB(t *testing.T) { + svcs := []Service{ + { + Name: "A", + DependsOn: []string{"B"}, + }, + { + Name: "B", + DependsOn: []string{}, + }, + } + + order := buildInstallOrder(svcs) + + if len(order) < len(svcs) { + t.Fatalf("length of order too short: %d", len(order)) + } + + got := order[0] + want := "B" + if got != want { + t.Fatalf("%s should be last to be installed, but was: %s", want, got) + } +} + +func Test_buildInstallOrder_ARequiresBAndC(t *testing.T) { + svcs := []Service{ + { + Name: "A", + DependsOn: []string{"B", "C"}, + }, + { + Name: "B", + DependsOn: []string{}, + }, + { + Name: "C", + DependsOn: []string{}, + }, + } + + order := buildInstallOrder(svcs) + + if len(order) < len(svcs) { + t.Fatalf("length of order too short: %d", len(order)) + } + + a := indexStr(order, "a") + b := indexStr(order, "b") + c := indexStr(order, "c") + + if a > b { + t.Fatalf("a should be after dependencies") + } + if a > c { + t.Fatalf("a should be after dependencies") + } + +} + +func Test_buildInstallOrder_ARequiresBRequiresC(t *testing.T) { + svcs := []Service{ + { + Name: "A", + DependsOn: []string{"B"}, + }, + { + Name: "B", + DependsOn: []string{"C"}, + }, + { + Name: "C", + DependsOn: []string{}, + }, + } + + order := buildInstallOrder(svcs) + + if len(order) < len(svcs) { + t.Fatalf("length of order too short: %d", len(order)) + } + + got := order[0] + want := "C" + if got != want { + t.Fatalf("%s should be last to be installed, but was: %s", want, got) + } + got = order[1] + want = "B" + if got != want { + t.Fatalf("%s should be last to be installed, but was: %s", want, got) + } + got = order[2] + want = "A" + if got != want { + t.Fatalf("%s should be last to be installed, but was: %s", want, got) + } +} + +func Test_buildInstallOrderCircularARequiresBRequiresA(t *testing.T) { + svcs := []Service{ + { + Name: "A", + DependsOn: []string{"B"}, + }, + { + Name: "B", + DependsOn: []string{"A"}, + }, + } + + defer func() { recover() }() + + buildInstallOrder(svcs) + + t.Fatalf("did not panic as expected") +} + +func Test_buildInstallOrderComposeFile(t *testing.T) { + // svcs := []Service{} + file, err := LoadComposeFileWithArch("../", "docker-compose.yaml", func() (string, string) { + return "x86_64", "Linux" + }) + + if err != nil { + t.Fatalf("unable to load compose file: %s", err) + } + + svcs, err := ParseCompose(file) + if err != nil { + t.Fatalf("unable to parse compose file: %s", err) + } + + for _, s := range svcs { + log.Printf("Service: %s\n", s.Name) + for _, d := range s.DependsOn { + log.Printf("Link: %s => %s\n", s.Name, d) + } + } + + order := buildInstallOrder(svcs) + + if len(order) < len(svcs) { + t.Fatalf("length of order too short: %d", len(order)) + } + + queueWorker := indexStr(order, "queue-worker") + nats := indexStr(order, "nats") + gateway := indexStr(order, "gateway") + prometheus := indexStr(order, "prometheus") + + if prometheus > gateway { + t.Fatalf("Prometheus order was after gateway, and should be before") + } + if nats > gateway { + t.Fatalf("NATS order was after gateway, and should be before") + } + if nats > queueWorker { + t.Fatalf("NATS order was after queue-worker, and should be before") + } +} + +func Test_buildInstallOrderOpenFaaS(t *testing.T) { + svcs := []Service{ + { + Name: "queue-worker", + DependsOn: []string{"nats"}, + }, + { + Name: "prometheus", + DependsOn: []string{}, + }, + { + Name: "gateway", + DependsOn: []string{"prometheus", "nats", "basic-auth-plugin"}, + }, + { + Name: "basic-auth-plugin", + DependsOn: []string{}, + }, + { + Name: "nats", + DependsOn: []string{}, + }, + } + + order := buildInstallOrder(svcs) + + if len(order) < len(svcs) { + t.Fatalf("length of order too short: %d", len(order)) + } + + queueWorker := indexStr(order, "queue-worker") + nats := indexStr(order, "nats") + gateway := indexStr(order, "gateway") + prometheus := indexStr(order, "prometheus") + + if prometheus > gateway { + t.Fatalf("Prometheus order was after gateway, and should be before") + } + if nats > gateway { + t.Fatalf("NATS order was after gateway, and should be before") + } + if nats > queueWorker { + t.Fatalf("NATS order was after queue-worker, and should be before") + } +} + +func indexStr(st []string, t string) int { + for n, s := range st { + if s == t { + return n + } + + } + return -1 +} diff --git a/pkg/graph.go b/pkg/graph.go new file mode 100644 index 0000000..30ae276 --- /dev/null +++ b/pkg/graph.go @@ -0,0 +1,69 @@ +package pkg + +import "log" + +// resolve finds the order of dependencies for a graph +// of nodes. +// Inspired by algorithm from +// https://www.electricmonk.nl/log/2008/08/07/dependency-resolving-algorithm/ +func resolve(node *Node, resolved, unresolved *Graph) { + unresolved.nodes = append(unresolved.nodes, node) + + for _, edge := range node.Edges { + + if !resolved.Contains(edge) && unresolved.Contains(edge) { + log.Panicf("edge: %s may be a circular dependency", edge.Name) + } + + resolve(edge, resolved, unresolved) + } + + for _, r := range resolved.nodes { + if r.Name == node.Name { + return + } + } + + resolved.nodes = append(resolved.nodes, node) + + unresolved.Remove(node) +} + +func newNode(name string, edges []*Node) *Node { + return &Node{ + Name: name, + Edges: edges, + } +} + +type Node struct { + Name string + Edges []*Node +} + +type Graph struct { + nodes []*Node +} + +func (g *Graph) Contains(target *Node) bool { + for _, g := range g.nodes { + if g.Name == target.Name { + return true + } + } + + return false +} +func (g *Graph) Remove(target *Node) { + var found *int + for i, n := range g.nodes { + if n == target { + found = &i + break + } + } + + if found != nil { + g.nodes = append(g.nodes[:*found], g.nodes[*found+1:]...) + } +} diff --git a/pkg/graph_test.go b/pkg/graph_test.go new file mode 100644 index 0000000..b72a354 --- /dev/null +++ b/pkg/graph_test.go @@ -0,0 +1,41 @@ +package pkg + +import "testing" + +func Test_RemoveMedial(t *testing.T) { + g := Graph{nodes: []*Node{}} + a := &Node{Name: "A"} + b := &Node{Name: "B"} + c := &Node{Name: "C"} + + g.nodes = append(g.nodes, a) + g.nodes = append(g.nodes, b) + g.nodes = append(g.nodes, c) + + g.Remove(b) + + for _, n := range g.nodes { + if n.Name == b.Name { + t.Fatalf("Found deleted node: %s", n.Name) + } + } +} + +func Test_RemoveFinal(t *testing.T) { + g := Graph{nodes: []*Node{}} + a := &Node{Name: "A"} + b := &Node{Name: "B"} + c := &Node{Name: "C"} + + g.nodes = append(g.nodes, a) + g.nodes = append(g.nodes, b) + g.nodes = append(g.nodes, c) + + g.Remove(c) + + for _, n := range g.nodes { + if n.Name == c.Name { + t.Fatalf("Found deleted node: %s", c.Name) + } + } +} diff --git a/pkg/supervisor.go b/pkg/supervisor.go index ee749af..86c00ea 100644 --- a/pkg/supervisor.go +++ b/pkg/supervisor.go @@ -34,12 +34,13 @@ const ( ) type Service struct { - Image string - Env []string - Name string - Mounts []Mount - Caps []string - Args []string + Image string + Env []string + Name string + Mounts []Mount + Caps []string + Args []string + DependsOn []string } type Mount struct { @@ -92,7 +93,7 @@ func (s *Supervisor) Start(svcs []Service) error { images := map[string]containerd.Image{} for _, svc := range svcs { - fmt.Printf("Preparing: %s with image: %s\n", svc.Name, svc.Image) + fmt.Printf("Preparing %s with image: %s\n", svc.Name, svc.Image) img, err := service.PrepareImage(ctx, s.client, svc.Image, defaultSnapshotter, faasServicesPullAlways) if err != nil { @@ -104,12 +105,26 @@ func (s *Supervisor) Start(svcs []Service) error { } for _, svc := range svcs { - fmt.Printf("Reconciling: %s\n", svc.Name) - + fmt.Printf("Removing old container for: %s\n", svc.Name) containerErr := service.Remove(ctx, s.client, svc.Name) if containerErr != nil { return containerErr } + } + + order := buildInstallOrder(svcs) + + for _, key := range order { + + var svc *Service + for _, s := range svcs { + if s.Name == key { + svc = &s + break + } + } + + fmt.Printf("Starting: %s\n", svc.Name) image := images[svc.Name] @@ -123,7 +138,6 @@ func (s *Supervisor) Start(svcs []Service) error { Options: []string{"rbind", "rw"}, }) } - } mounts = append(mounts, specs.Mount{ @@ -153,11 +167,11 @@ func (s *Supervisor) Start(svcs []Service) error { ) if containerCreateErr != nil { - log.Printf("Error creating container %s\n", containerCreateErr) + log.Printf("Error creating container: %s\n", containerCreateErr) return containerCreateErr } - log.Printf("Created container %s\n", newContainer.ID()) + log.Printf("Created container: %s\n", newContainer.ID()) task, err := newContainer.NewTask(ctx, cio.NewCreator(cio.WithStdio)) if err != nil { @@ -176,6 +190,7 @@ func (s *Supervisor) Start(svcs []Service) error { if err != nil { return err } + log.Printf("%s has IP: %s\n", newContainer.ID(), ip.String()) hosts, _ := ioutil.ReadFile("hosts") @@ -277,10 +292,11 @@ func ParseCompose(config *compose.Config) ([]Service, error) { Name: s.Name, Image: s.Image, // ShellCommand is just an alias of string slice - Args: []string(s.Command), - Caps: s.CapAdd, - Env: env, - Mounts: mounts, + Args: []string(s.Command), + Caps: s.CapAdd, + Env: env, + Mounts: mounts, + DependsOn: s.DependsOn, } } @@ -289,6 +305,12 @@ func ParseCompose(config *compose.Config) ([]Service, error) { // LoadComposeFile is a helper method for loading a docker-compose file func LoadComposeFile(wd string, file string) (*compose.Config, error) { + return LoadComposeFileWithArch(wd, file, env.GetClientArch) +} + +// LoadComposeFileWithArch is a helper method for loading a docker-compose file +func LoadComposeFileWithArch(wd string, file string, archGetter ArchGetter) (*compose.Config, error) { + file = path.Join(wd, file) b, err := ioutil.ReadFile(file) if err != nil { @@ -300,7 +322,7 @@ func LoadComposeFile(wd string, file string) (*compose.Config, error) { return nil, err } - archSuffix, err := GetArchSuffix(env.GetClientArch) + archSuffix, err := GetArchSuffix(archGetter) if err != nil { return nil, err } diff --git a/pkg/supervisor_test.go b/pkg/supervisor_test.go index 937f5ed..43a7774 100644 --- a/pkg/supervisor_test.go +++ b/pkg/supervisor_test.go @@ -7,8 +7,10 @@ import ( ) func Test_ParseCompose(t *testing.T) { + wd := "testdata" - expected := map[string]Service{ + + want := map[string]Service{ "basic-auth-plugin": { Name: "basic-auth-plugin", Image: "docker.io/openfaas/basic-auth-plugin:0.18.17", @@ -73,7 +75,8 @@ func Test_ParseCompose(t *testing.T) { Dest: path.Join("/run/secrets", "basic-auth-user"), }, }, - Caps: []string{"CAP_NET_RAW"}, + Caps: []string{"CAP_NET_RAW"}, + DependsOn: []string{"nats"}, }, "queue-worker": { Name: "queue-worker", @@ -103,32 +106,39 @@ func Test_ParseCompose(t *testing.T) { }, } - compose, err := LoadComposeFile(wd, "docker-compose.yaml") + compose, err := LoadComposeFileWithArch(wd, "docker-compose.yaml", func() (string, string) { return "x86_64", "Linux" }) if err != nil { - t.Fatalf("can not read docker-compose fixture: %s", err) + t.Fatalf("can't read docker-compose file: %s", err) } services, err := ParseCompose(compose) if err != nil { - t.Fatalf("can not parse compose services: %s", err) + t.Fatalf("can't parse compose services: %s", err) } - if len(services) != len(expected) { - t.Fatalf("expected: %d services, got: %d", len(expected), len(services)) + if len(services) != len(want) { + t.Fatalf("want: %d services, got: %d", len(want), len(services)) } for _, service := range services { - exp, ok := expected[service.Name] + exp, ok := want[service.Name] + + if service.Name == "gateway" { + if len(service.DependsOn) == 0 { + t.Fatalf("gateway should have at least one depends_on entry") + } + } + if !ok { - t.Fatalf("unexpected service: %s", service.Name) + t.Fatalf("incorrect service: %s", service.Name) } if service.Name != exp.Name { - t.Fatalf("incorrect service Name:\n\texpected: %s,\n\tgot: %s", exp.Name, service.Name) + t.Fatalf("incorrect service Name:\n\twant: %s,\n\tgot: %s", exp.Name, service.Name) } if service.Image != exp.Image { - t.Fatalf("incorrect service Image:\n\texpected: %s,\n\tgot: %s", exp.Image, service.Image) + t.Fatalf("incorrect service Image:\n\twant: %s,\n\tgot: %s", exp.Image, service.Image) } equalStringSlice(t, exp.Env, service.Env) @@ -136,41 +146,41 @@ func Test_ParseCompose(t *testing.T) { equalStringSlice(t, exp.Args, service.Args) if !reflect.DeepEqual(exp.Mounts, service.Mounts) { - t.Fatalf("incorrect service Mounts:\n\texpected: %+v,\n\tgot: %+v", exp.Mounts, service.Mounts) + t.Fatalf("incorrect service Mounts:\n\twant: %+v,\n\tgot: %+v", exp.Mounts, service.Mounts) } } } -func equalStringSlice(t *testing.T, expected, found []string) { +func equalStringSlice(t *testing.T, want, found []string) { t.Helper() - if (expected == nil) != (found == nil) { - t.Fatalf("unexpected nil slice: expected %+v, got %+v", expected, found) + if (want == nil) != (found == nil) { + t.Fatalf("unexpected nil slice: want %+v, got %+v", want, found) } - if len(expected) != len(found) { - t.Fatalf("unequal slice length: expected %+v, got %+v", expected, found) + if len(want) != len(found) { + t.Fatalf("unequal slice length: want %+v, got %+v", want, found) } - for i := range expected { - if expected[i] != found[i] { - t.Fatalf("unexpected value at postition %d: expected %s, got %s", i, expected[i], found[i]) + for i := range want { + if want[i] != found[i] { + t.Fatalf("unexpected value at postition %d: want %s, got %s", i, want[i], found[i]) } } } -func equalMountSlice(t *testing.T, expected, found []Mount) { +func equalMountSlice(t *testing.T, want, found []Mount) { t.Helper() - if (expected == nil) != (found == nil) { - t.Fatalf("unexpected nil slice: expected %+v, got %+v", expected, found) + if (want == nil) != (found == nil) { + t.Fatalf("unexpected nil slice: want %+v, got %+v", want, found) } - if len(expected) != len(found) { - t.Fatalf("unequal slice length: expected %+v, got %+v", expected, found) + if len(want) != len(found) { + t.Fatalf("unequal slice length: want %+v, got %+v", want, found) } - for i := range expected { - if !reflect.DeepEqual(expected[i], found[i]) { - t.Fatalf("unexpected value at postition %d: expected %s, got %s", i, expected[i], found[i]) + for i := range want { + if !reflect.DeepEqual(want[i], found[i]) { + t.Fatalf("unexpected value at postition %d: want %s, got %s", i, want[i], found[i]) } } } @@ -178,7 +188,7 @@ func equalMountSlice(t *testing.T, expected, found []Mount) { func Test_GetArchSuffix(t *testing.T) { cases := []struct { name string - expected string + want string foundArch string foundOS string err string @@ -192,37 +202,37 @@ func Test_GetArchSuffix(t *testing.T) { name: "x86 has no suffix", foundOS: "Linux", foundArch: "x86_64", - expected: "", + want: "", }, { name: "unknown arch has no suffix", foundOS: "Linux", foundArch: "anything_else", - expected: "", + want: "", }, { name: "armhf has armhf suffix", foundOS: "Linux", foundArch: "armhf", - expected: "-armhf", + want: "-armhf", }, { name: "armv7l has armhf suffix", foundOS: "Linux", foundArch: "armv7l", - expected: "-armhf", + want: "-armhf", }, { name: "arm64 has arm64 suffix", foundOS: "Linux", foundArch: "arm64", - expected: "-arm64", + want: "-arm64", }, { name: "aarch64 has arm64 suffix", foundOS: "Linux", foundArch: "aarch64", - expected: "-arm64", + want: "-arm64", }, } @@ -231,15 +241,15 @@ func Test_GetArchSuffix(t *testing.T) { suffix, err := GetArchSuffix(testArchGetter(tc.foundArch, tc.foundOS)) if tc.err != "" && err == nil { - t.Fatalf("expected error %s but got nil", tc.err) + t.Fatalf("want error %s but got nil", tc.err) } else if tc.err != "" && err.Error() != tc.err { - t.Fatalf("expected error %s, got %s", tc.err, err.Error()) + t.Fatalf("want error %s, got %s", tc.err, err.Error()) } else if tc.err == "" && err != nil { t.Fatalf("unexpected error %s", err.Error()) } - if suffix != tc.expected { - t.Fatalf("expected suffix %s, got %s", tc.expected, suffix) + if suffix != tc.want { + t.Fatalf("want suffix %s, got %s", tc.want, suffix) } }) } diff --git a/pkg/testdata/docker-compose.yaml b/pkg/testdata/docker-compose.yaml index 41b21b6..5b1c656 100644 --- a/pkg/testdata/docker-compose.yaml +++ b/pkg/testdata/docker-compose.yaml @@ -1,12 +1,12 @@ version: "3.7" services: basic-auth-plugin: - image: docker.io/openfaas/basic-auth-plugin:0.18.17 + image: "docker.io/openfaas/basic-auth-plugin:0.18.17${ARCH_SUFFIX}" environment: - port: "8080" - secret_mount_path: "/run/secrets" - user_filename: "basic-auth-user" - pass_filename: "basic-auth-password" + - port=8080 + - secret_mount_path=/run/secrets + - user_filename=basic-auth-user + - pass_filename=basic-auth-password volumes: # we assume cwd == /var/lib/faasd - type: bind @@ -17,6 +17,7 @@ services: target: /run/secrets/basic-auth-user cap_add: - CAP_NET_RAW + nats: image: docker.io/library/nats-streaming:0.11.2 command: @@ -25,6 +26,7 @@ services: - "8222" - "--store=memory" - "--cluster_id=faas-cluster" + prometheus: image: docker.io/prom/prometheus:v2.14.0 volumes: @@ -33,21 +35,22 @@ services: target: /etc/prometheus/prometheus.yml cap_add: - CAP_NET_RAW + gateway: - image: docker.io/openfaas/gateway:0.18.17 + image: "docker.io/openfaas/gateway:0.18.17${ARCH_SUFFIX}" environment: - basic_auth: "true" - functions_provider_url: "http://faasd-provider:8081/" - direct_functions: "false" - read_timeout: "60s" - write_timeout: "60s" - upstream_timeout: "65s" - faas_nats_address: "nats" - faas_nats_port: "4222" - auth_proxy_url: "http://basic-auth-plugin:8080/validate" - auth_proxy_pass_body: "false" - secret_mount_path: "/run/secrets" - scale_from_zero: "true" + - basic_auth=true + - functions_provider_url=http://faasd-provider:8081/ + - direct_functions=false + - read_timeout=60s + - write_timeout=60s + - upstream_timeout=65s + - faas_nats_address=nats + - faas_nats_port=4222 + - auth_proxy_url=http://basic-auth-plugin:8080/validate + - auth_proxy_pass_body=false + - secret_mount_path=/run/secrets + - scale_from_zero=true volumes: # we assume cwd == /var/lib/faasd - type: bind @@ -58,18 +61,23 @@ services: target: /run/secrets/basic-auth-user cap_add: - CAP_NET_RAW + depends_on: + - basic-auth-plugin + - nats + - prometheus + queue-worker: image: docker.io/openfaas/queue-worker:0.11.2 environment: - faas_nats_address: "nats" - faas_nats_port: "4222" - gateway_invoke: "true" - faas_gateway_address: "gateway" - ack_wait: "5m5s" - max_inflight: "1" - write_debug: "false" - basic_auth: "true" - secret_mount_path: "/run/secrets" + - faas_nats_address=nats + - faas_nats_port=4222 + - gateway_invoke=true + - faas_gateway_address=gateway + - ack_wait=5m5s + - max_inflight=1 + - write_debug=false + - basic_auth=true + - secret_mount_path=/run/secrets volumes: # we assume cwd == /var/lib/faasd - type: bind @@ -80,3 +88,5 @@ services: target: /run/secrets/basic-auth-user cap_add: - CAP_NET_RAW + depends_on: + - nats