func (c *containerConfig) setTask(t *api.Task) error { container := t.Spec.GetContainer() if container == nil { return exec.ErrRuntimeUnsupported } if container.Image == "" { return ErrImageRequired } // index the networks by name c.networksAttachments = make(map[string]*api.NetworkAttachment, len(t.Networks)) for _, attachment := range t.Networks { c.networksAttachments[attachment.Network.Spec.Annotations.Name] = attachment } c.task = t preparedSpec, err := template.ExpandContainerSpec(t) if err != nil { return err } c.task.Spec.Runtime = &api.TaskSpec_Container{ Container: preparedSpec, } return nil }
func validateTask(taskSpec api.TaskSpec) error { if err := validateResourceRequirements(taskSpec.Resources); err != nil { return err } if err := validateRestartPolicy(taskSpec.Restart); err != nil { return err } if err := validatePlacement(taskSpec.Placement); err != nil { return err } if taskSpec.GetRuntime() == nil { return grpc.Errorf(codes.InvalidArgument, "TaskSpec: missing runtime") } _, ok := taskSpec.GetRuntime().(*api.TaskSpec_Container) if !ok { return grpc.Errorf(codes.Unimplemented, "RuntimeSpec: unimplemented runtime in service spec") } // Building a empty/dummy Task to validate the templating and // the resulting container spec as well. This is a *best effort* // validation. preparedSpec, err := template.ExpandContainerSpec(&api.Task{ Spec: taskSpec, ServiceID: "serviceid", Slot: 1, NodeID: "nodeid", Networks: []*api.NetworkAttachment{}, Annotations: api.Annotations{ Name: "taskname", }, ServiceAnnotations: api.Annotations{ Name: "servicename", }, Endpoint: &api.Endpoint{}, LogDriver: taskSpec.LogDriver, }) if err != nil { return grpc.Errorf(codes.InvalidArgument, err.Error()) } if err := validateContainerSpec(preparedSpec); err != nil { return err } return nil }