diff --git a/cli/command/service/opts.go b/cli/command/service/opts.go index bcd7d8f40fec..43570a73d168 100644 --- a/cli/command/service/opts.go +++ b/cli/command/service/opts.go @@ -457,6 +457,36 @@ func convertExtraHostsToSwarmHosts(extraHosts []string) []string { return hosts } +type isolationOpts struct { + value *container.Isolation + source string +} + +func (o *isolationOpts) Set(value string) error { + o.source = value + tv := container.Isolation(value) + if tv.IsDefault() || tv.IsHyperV() || tv.IsProcess() { + o.value = &tv + return nil + } + return fmt.Errorf("Unknown isolation mode %s. Valid values are %v, %v, %v", value, container.IsolationDefault, container.IsolationProcess, container.IsolationHyperV) +} + +func (o *isolationOpts) Type() string { + return "isolation" +} + +func (o *isolationOpts) String() string { + return o.source +} + +func (o *isolationOpts) Value() container.Isolation { + if o.value == nil { + return container.IsolationEmpty + } + return *o.value +} + type serviceOptions struct { detach bool quiet bool @@ -506,7 +536,7 @@ type serviceOptions struct { secrets opts.SecretOpt configs opts.ConfigOpt - isolation string + isolation isolationOpts } func newServiceOptions() *serviceOptions { @@ -616,7 +646,7 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N Hosts: convertExtraHostsToSwarmHosts(options.hosts.GetAll()), StopGracePeriod: options.ToStopGracePeriod(flags), Healthcheck: healthConfig, - Isolation: options.isolation, + Isolation: options.isolation.Value(), }, Networks: networks, Resources: options.resources.ToResourceRequirements(), @@ -787,8 +817,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu flags.StringVar(&opts.stopSignal, flagStopSignal, "", "Signal to stop the container") flags.SetAnnotation(flagStopSignal, "version", []string{"1.28"}) - flags.StringVar(&opts.isolation, flagIsolation, "", "defines the isolation mode (hyperv, process)") - flags.SetAnnotation(flagIsolation, "version", []string{"1.32"}) + flags.Var(&opts.isolation, flagIsolation, "defines the isolation mode (hyperv, process)") + flags.SetAnnotation(flagIsolation, "version", []string{"1.35"}) } const ( diff --git a/cli/command/service/update.go b/cli/command/service/update.go index 06c636d886e8..afb72c963a84 100644 --- a/cli/command/service/update.go +++ b/cli/command/service/update.go @@ -269,6 +269,19 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags } } + updateIsolation := func(flag string, field *container.Isolation) error { + if flags.Changed(flag) { + o := isolationOpts{} + val := flags.Lookup(flag).Value.String() + err := o.Set(val) + if err != nil { + return err + } + *field = o.Value() + } + return nil + } + cspec := spec.TaskTemplate.ContainerSpec task := &spec.TaskTemplate @@ -288,7 +301,9 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags updateString(flagWorkdir, &cspec.Dir) updateString(flagUser, &cspec.User) updateString(flagHostname, &cspec.Hostname) - updateString(flagIsolation, &cspec.Isolation) + if err := updateIsolation(flagIsolation, &cspec.Isolation); err != nil { + return err + } if err := updateMounts(flags, &cspec.Mounts); err != nil { return err } diff --git a/cli/compose/convert/service.go b/cli/compose/convert/service.go index 593a3b7399ca..1dfc21eb0858 100644 --- a/cli/compose/convert/service.go +++ b/cli/compose/convert/service.go @@ -122,6 +122,11 @@ func Service( } } + isolation := container.Isolation(service.Isolation) + if !isolation.IsDefault() && !isolation.IsHyperV() && !isolation.IsProcess() { + return swarm.ServiceSpec{}, fmt.Errorf("Unsupported isolation %s. Valid values are %s, %s, %s", isolation, container.IsolationDefault, container.IsolationProcess, container.IsolationHyperV) + } + serviceSpec := swarm.ServiceSpec{ Annotations: swarm.Annotations{ Name: name, @@ -149,7 +154,7 @@ func Service( Configs: configs, ReadOnly: service.ReadOnly, Privileges: &privileges, - Isolation: service.Isolation, + Isolation: isolation, }, LogDriver: logDriver, Resources: resources, diff --git a/cli/compose/convert/service_test.go b/cli/compose/convert/service_test.go index 583e1eee263d..ada504083058 100644 --- a/cli/compose/convert/service_test.go +++ b/cli/compose/convert/service_test.go @@ -375,11 +375,11 @@ func TestConvertUpdateConfigOrder(t *testing.T) { func TestIsolation(t *testing.T) { src := composetypes.ServiceConfig{ - Isolation: "test", + Isolation: "hyperv", } result, err := Service("1.32", Namespace{name: "foo"}, src, nil, nil, nil, nil) if err != nil { t.Fatal(err) } - assert.Equal(t, "test", result.TaskTemplate.ContainerSpec.Isolation) + assert.Equal(t, container.IsolationHyperV, result.TaskTemplate.ContainerSpec.Isolation) } diff --git a/cli/trust/trust.go b/cli/trust/trust.go index 829ab84e3957..07fb0d09d61d 100644 --- a/cli/trust/trust.go +++ b/cli/trust/trust.go @@ -127,7 +127,7 @@ func GetNotaryRepository(in io.Reader, out io.Writer, userAgent string, repoInfo } // Skip configuration headers since request is not going to Docker daemon - modifiers := registry.DockerHeaders(userAgent, http.Header{}) + modifiers := registry.Headers(userAgent, http.Header{}) authTransport := transport.NewTransport(base, modifiers...) pingClient := &http.Client{ Transport: authTransport,