diff --git a/gateway/handlers/createhandler.go b/gateway/handlers/createhandler.go index 1bc6497e..7eb65dfb 100644 --- a/gateway/handlers/createhandler.go +++ b/gateway/handlers/createhandler.go @@ -73,18 +73,30 @@ func makeSpec(request *requests.CreateFunctionRequest, maxRestarts uint64, resta } else { constraints = linuxOnlyConstraints } - labels := map[string]string{"function": "true"} + + labels := map[string]string{ + "com.openfaas.function": request.Service, + "function": "true", // backwards-compatible + } + if request.Labels != nil { for k, v := range *request.Labels { labels[k] = v } } + fmt.Println(labels) nets := []swarm.NetworkAttachmentConfig{ - {Target: request.Network}, + { + Target: request.Network, + }, } spec := swarm.ServiceSpec{ + Annotations: swarm.Annotations{ + Name: request.Service, + Labels: labels, + }, TaskTemplate: swarm.TaskSpec{ RestartPolicy: &swarm.RestartPolicy{ MaxAttempts: &maxRestarts, @@ -100,10 +112,6 @@ func makeSpec(request *requests.CreateFunctionRequest, maxRestarts uint64, resta Constraints: constraints, }, }, - Annotations: swarm.Annotations{ - Name: request.Service, - Labels: labels, - }, } // TODO: request.EnvProcess should only be set if it's not nil, otherwise we override anything in the Docker image already diff --git a/gateway/handlers/reader.go b/gateway/handlers/reader.go index 46b3646e..ea8cd578 100644 --- a/gateway/handlers/reader.go +++ b/gateway/handlers/reader.go @@ -50,12 +50,15 @@ func MakeFunctionReader(metricsOptions metrics.MetricOptions, c client.ServiceAP } } + // Required (copy by value) + labels := service.Spec.Annotations.Labels f := requests.Function{ Name: service.Spec.Name, Image: service.Spec.TaskTemplate.ContainerSpec.Image, InvocationCount: 0, Replicas: *service.Spec.Mode.Replicated.Replicas, EnvProcess: envProcess, + Labels: &labels, } functions = append(functions, f) diff --git a/gateway/handlers/update_handler.go b/gateway/handlers/update_handler.go index 5cabf595..acee9b88 100644 --- a/gateway/handlers/update_handler.go +++ b/gateway/handlers/update_handler.go @@ -81,33 +81,34 @@ func updateSpec(request *requests.CreateFunctionRequest, spec *swarm.ServiceSpec constraints = linuxOnlyConstraints } - nets := []swarm.NetworkAttachmentConfig{ - {Target: request.Network}, - } - spec.TaskTemplate.RestartPolicy.MaxAttempts = &maxRestarts spec.TaskTemplate.RestartPolicy.Condition = swarm.RestartPolicyConditionAny spec.TaskTemplate.RestartPolicy.Delay = &restartDelay spec.TaskTemplate.ContainerSpec.Image = request.Image spec.TaskTemplate.ContainerSpec.Labels = map[string]string{ - "function": "true", - "uid": fmt.Sprintf("%d", time.Now().Nanosecond()), + "function": "true", + "com.openfaas.function": request.Service, + "com.openfaas.uid": fmt.Sprintf("%d", time.Now().Nanosecond()), } if request.Labels != nil { for k, v := range *request.Labels { spec.TaskTemplate.ContainerSpec.Labels[k] = v + spec.Annotations.Labels[k] = v } } - spec.TaskTemplate.Networks = nets + spec.TaskTemplate.Networks = []swarm.NetworkAttachmentConfig{ + { + Target: request.Network, + }, + } + spec.TaskTemplate.Placement = &swarm.Placement{ Constraints: constraints, } - spec.Annotations = swarm.Annotations{ - Name: request.Service, - } + spec.Annotations.Name = request.Service spec.RollbackConfig = &swarm.UpdateConfig{ FailureAction: "pause", diff --git a/gateway/requests/requests.go b/gateway/requests/requests.go index b221d98f..c4463de2 100644 --- a/gateway/requests/requests.go +++ b/gateway/requests/requests.go @@ -67,6 +67,10 @@ type Function struct { InvocationCount float64 `json:"invocationCount"` // TODO: shouldn't this be int64? Replicas uint64 `json:"replicas"` EnvProcess string `json:"envProcess"` + + // Labels are metadata for functions which may be used by the + // back-end for making scheduling or routing decisions + Labels *map[string]string `json:"labels"` } // AsyncReport is the report from a function executed on a queue worker. diff --git a/gateway/tests/reader_test.go b/gateway/tests/reader_test.go index 7cc0ae69..79beb0b3 100644 --- a/gateway/tests/reader_test.go +++ b/gateway/tests/reader_test.go @@ -116,6 +116,10 @@ func TestReaderSuccessReturnsCorrectBodyWithZeroFunctions(t *testing.T) { func TestReaderSuccessReturnsCorrectBodyWithOneFunction(t *testing.T) { replicas := uint64(5) + labels := map[string]string{ + "function": "bar", + } + services := []swarm.Service{ swarm.Service{ Spec: swarm.ServiceSpec{ @@ -125,17 +129,16 @@ func TestReaderSuccessReturnsCorrectBodyWithOneFunction(t *testing.T) { }, }, Annotations: swarm.Annotations{ - Name: "bar", + Name: "bar", + Labels: labels, }, TaskTemplate: swarm.TaskSpec{ ContainerSpec: swarm.ContainerSpec{ Env: []string{ "fprocess=bar", }, - Image: "foo/bar:latest", - Labels: map[string]string{ - "function": "bar", - }, + Image: "foo/bar:latest", + Labels: labels, }, }, }, @@ -159,6 +162,9 @@ func TestReaderSuccessReturnsCorrectBodyWithOneFunction(t *testing.T) { InvocationCount: 0, Replicas: 5, EnvProcess: "bar", + Labels: &map[string]string{ + "function": "bar", + }, }, } marshalled, _ := json.Marshal(functions)