func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, serviceID string) error { apiClient := dockerCli.Client() ctx := context.Background() updateOpts := types.ServiceUpdateOptions{} service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID) if err != nil { return err } rollback, err := flags.GetBool("rollback") if err != nil { return err } spec := &service.Spec if rollback { spec = service.PreviousSpec if spec == nil { return fmt.Errorf("service does not have a previous specification to roll back to") } } err = updateService(flags, spec) if err != nil { return err } // only send auth if flag was set sendAuth, err := flags.GetBool(flagRegistryAuth) if err != nil { return err } if sendAuth { // Retrieve encoded auth token from the image reference // This would be the old image if it didn't change in this update image := spec.TaskTemplate.ContainerSpec.Image encodedAuth, err := command.RetrieveAuthTokenFromImage(ctx, dockerCli, image) if err != nil { return err } updateOpts.EncodedRegistryAuth = encodedAuth } else if rollback { updateOpts.RegistryAuthFrom = types.RegistryAuthFromPreviousSpec } else { updateOpts.RegistryAuthFrom = types.RegistryAuthFromSpec } err = apiClient.ServiceUpdate(ctx, service.ID, service.Version, *spec, updateOpts) if err != nil { return err } fmt.Fprintf(dockerCli.Out(), "%s\n", serviceID) return nil }
func runUpdate(dockerCli *command.DockerCli, flags *pflag.FlagSet, serviceID string) error { apiClient := dockerCli.Client() ctx := context.Background() updateOpts := types.ServiceUpdateOptions{} service, _, err := apiClient.ServiceInspectWithRaw(ctx, serviceID) if err != nil { return err } err = updateService(flags, &service.Spec) if err != nil { return err } // only send auth if flag was set sendAuth, err := flags.GetBool(flagRegistryAuth) if err != nil { return err } if sendAuth { // Retrieve encoded auth token from the image reference // This would be the old image if it didn't change in this update image := service.Spec.TaskTemplate.ContainerSpec.Image encodedAuth, err := dockerCli.RetrieveAuthTokenFromImage(ctx, image) if err != nil { return err } updateOpts.EncodedRegistryAuth = encodedAuth } err = apiClient.ServiceUpdate(ctx, service.ID, service.Version, service.Spec, updateOpts) if err != nil { return err } fmt.Fprintf(dockerCli.Out(), "%s\n", serviceID) return nil }
func deployServices( ctx context.Context, dockerCli *command.DockerCli, services map[string]swarm.ServiceSpec, namespace namespace, sendAuth bool, ) error { apiClient := dockerCli.Client() out := dockerCli.Out() existingServices, err := getServices(ctx, apiClient, namespace.name) if err != nil { return err } existingServiceMap := make(map[string]swarm.Service) for _, service := range existingServices { existingServiceMap[service.Spec.Name] = service } for internalName, serviceSpec := range services { name := namespace.scope(internalName) encodedAuth := "" if sendAuth { // Retrieve encoded auth token from the image reference image := serviceSpec.TaskTemplate.ContainerSpec.Image encodedAuth, err = command.RetrieveAuthTokenFromImage(ctx, dockerCli, image) if err != nil { return err } } if service, exists := existingServiceMap[name]; exists { fmt.Fprintf(out, "Updating service %s (id: %s)\n", name, service.ID) updateOpts := types.ServiceUpdateOptions{} if sendAuth { updateOpts.EncodedRegistryAuth = encodedAuth } response, err := apiClient.ServiceUpdate( ctx, service.ID, service.Version, serviceSpec, updateOpts, ) if err != nil { return err } for _, warning := range response.Warnings { fmt.Fprintln(dockerCli.Err(), warning) } } else { fmt.Fprintf(out, "Creating service %s\n", name) createOpts := types.ServiceCreateOptions{} if sendAuth { createOpts.EncodedRegistryAuth = encodedAuth } if _, err := apiClient.ServiceCreate(ctx, serviceSpec, createOpts); err != nil { return err } } } return nil }
func deployServices( ctx context.Context, dockerCli *command.DockerCli, services map[string]bundlefile.Service, namespace string, sendAuth bool, ) error { apiClient := dockerCli.Client() out := dockerCli.Out() existingServices, err := getServices(ctx, apiClient, namespace) if err != nil { return err } existingServiceMap := make(map[string]swarm.Service) for _, service := range existingServices { existingServiceMap[service.Spec.Name] = service } for internalName, service := range services { name := fmt.Sprintf("%s_%s", namespace, internalName) var ports []swarm.PortConfig for _, portSpec := range service.Ports { ports = append(ports, swarm.PortConfig{ Protocol: swarm.PortConfigProtocol(portSpec.Protocol), TargetPort: portSpec.Port, }) } serviceSpec := swarm.ServiceSpec{ Annotations: swarm.Annotations{ Name: name, Labels: getStackLabels(namespace, service.Labels), }, TaskTemplate: swarm.TaskSpec{ ContainerSpec: swarm.ContainerSpec{ Image: service.Image, Command: service.Command, Args: service.Args, Env: service.Env, // Service Labels will not be copied to Containers // automatically during the deployment so we apply // it here. Labels: getStackLabels(namespace, nil), }, }, EndpointSpec: &swarm.EndpointSpec{ Ports: ports, }, Networks: convertNetworks(service.Networks, namespace, internalName), } cspec := &serviceSpec.TaskTemplate.ContainerSpec if service.WorkingDir != nil { cspec.Dir = *service.WorkingDir } if service.User != nil { cspec.User = *service.User } encodedAuth := "" if sendAuth { // Retrieve encoded auth token from the image reference image := serviceSpec.TaskTemplate.ContainerSpec.Image encodedAuth, err = dockerCli.RetrieveAuthTokenFromImage(ctx, image) if err != nil { return err } } if service, exists := existingServiceMap[name]; exists { fmt.Fprintf(out, "Updating service %s (id: %s)\n", name, service.ID) updateOpts := types.ServiceUpdateOptions{} if sendAuth { updateOpts.EncodedRegistryAuth = encodedAuth } if err := apiClient.ServiceUpdate( ctx, service.ID, service.Version, serviceSpec, updateOpts, ); err != nil { return err } } else { fmt.Fprintf(out, "Creating service %s\n", name) createOpts := types.ServiceCreateOptions{} if sendAuth { createOpts.EncodedRegistryAuth = encodedAuth } if _, err := apiClient.ServiceCreate(ctx, serviceSpec, createOpts); err != nil { return err } } } return nil }