Visitar URL original
Add isolation mode on service update/create and compose files · docker/cli@e4d3b1d · GitHub
Skip to content

Commit e4d3b1d

Browse files
committed
Add isolation mode on service update/create and compose files
Signed-off-by: Simon Ferquel <simon.ferquel@docker.com>
1 parent 9022ea5 commit e4d3b1d

14 files changed

Lines changed: 700 additions & 0 deletions

File tree

‎cli/command/service/opts.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,8 @@ type serviceOptions struct {
505505
healthcheck healthCheckOptions
506506
secrets opts.SecretOpt
507507
configs opts.ConfigOpt
508+
509+
isolation string
508510
}
509511

510512
func newServiceOptions() *serviceOptions {
@@ -614,6 +616,7 @@ func (options *serviceOptions) ToService(ctx context.Context, apiClient client.N
614616
Hosts: convertExtraHostsToSwarmHosts(options.hosts.GetAll()),
615617
StopGracePeriod: options.ToStopGracePeriod(flags),
616618
Healthcheck: healthConfig,
619+
Isolation: container.Isolation(options.isolation),
617620
},
618621
Networks: networks,
619622
Resources: options.resources.ToResourceRequirements(),
@@ -784,6 +787,8 @@ func addServiceFlags(flags *pflag.FlagSet, opts *serviceOptions, defaultFlagValu
784787

785788
flags.StringVar(&opts.stopSignal, flagStopSignal, "", "Signal to stop the container")
786789
flags.SetAnnotation(flagStopSignal, "version", []string{"1.28"})
790+
flags.StringVar(&opts.isolation, flagIsolation, "", "Service container isolation mode")
791+
flags.SetAnnotation(flagIsolation, "version", []string{"1.35"})
787792
}
788793

789794
const (
@@ -879,4 +884,5 @@ const (
879884
flagConfig = "config"
880885
flagConfigAdd = "config-add"
881886
flagConfigRemove = "config-rm"
887+
flagIsolation = "isolation"
882888
)

‎cli/command/service/update.go‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,14 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
269269
}
270270
}
271271

272+
updateIsolation := func(flag string, field *container.Isolation) error {
273+
if flags.Changed(flag) {
274+
val, _ := flags.GetString(flag)
275+
*field = container.Isolation(val)
276+
}
277+
return nil
278+
}
279+
272280
cspec := spec.TaskTemplate.ContainerSpec
273281
task := &spec.TaskTemplate
274282

@@ -288,6 +296,9 @@ func updateService(ctx context.Context, apiClient client.NetworkAPIClient, flags
288296
updateString(flagWorkdir, &cspec.Dir)
289297
updateString(flagUser, &cspec.User)
290298
updateString(flagHostname, &cspec.Hostname)
299+
if err := updateIsolation(flagIsolation, &cspec.Isolation); err != nil {
300+
return err
301+
}
291302
if err := updateMounts(flags, &cspec.Mounts); err != nil {
292303
return err
293304
}

‎cli/command/service/update_test.go‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,3 +518,32 @@ func TestUpdateStopSignal(t *testing.T) {
518518
updateService(nil, nil, flags, spec)
519519
assert.Equal(t, "SIGWINCH", cspec.StopSignal)
520520
}
521+
522+
func TestUpdateIsolationValid(t *testing.T) {
523+
flags := newUpdateCommand(nil).Flags()
524+
err := flags.Set("isolation", "process")
525+
require.NoError(t, err)
526+
spec := swarm.ServiceSpec{
527+
TaskTemplate: swarm.TaskSpec{
528+
ContainerSpec: &swarm.ContainerSpec{},
529+
},
530+
}
531+
err = updateService(context.Background(), nil, flags, &spec)
532+
require.NoError(t, err)
533+
assert.Equal(t, container.IsolationProcess, spec.TaskTemplate.ContainerSpec.Isolation)
534+
}
535+
536+
func TestUpdateIsolationInvalid(t *testing.T) {
537+
// validation depends on daemon os / version so validation should be done on the daemon side
538+
flags := newUpdateCommand(nil).Flags()
539+
err := flags.Set("isolation", "test")
540+
require.NoError(t, err)
541+
spec := swarm.ServiceSpec{
542+
TaskTemplate: swarm.TaskSpec{
543+
ContainerSpec: &swarm.ContainerSpec{},
544+
},
545+
}
546+
err = updateService(context.Background(), nil, flags, &spec)
547+
require.NoError(t, err)
548+
assert.Equal(t, container.Isolation("test"), spec.TaskTemplate.ContainerSpec.Isolation)
549+
}

‎cli/compose/convert/service.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ func Service(
149149
Configs: configs,
150150
ReadOnly: service.ReadOnly,
151151
Privileges: &privileges,
152+
Isolation: container.Isolation(service.Isolation),
152153
},
153154
LogDriver: logDriver,
154155
Resources: resources,

‎cli/compose/convert/service_test.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,3 +424,12 @@ func TestConvertFileObjectDefaults(t *testing.T) {
424424
}
425425
assert.Equal(t, expected, swarmRef)
426426
}
427+
428+
func TestServiceConvertsIsolation(t *testing.T) {
429+
src := composetypes.ServiceConfig{
430+
Isolation: "hyperv",
431+
}
432+
result, err := Service("1.35", Namespace{name: "foo"}, src, nil, nil, nil, nil)
433+
require.NoError(t, err)
434+
assert.Equal(t, container.IsolationHyperV, result.TaskTemplate.ContainerSpec.Isolation)
435+
}

‎cli/compose/loader/loader_test.go‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/docker/cli/cli/compose/types"
13+
"github.com/docker/docker/api/types/container"
1314
"github.com/sirupsen/logrus"
1415
"github.com/stretchr/testify/assert"
1516
"github.com/stretchr/testify/require"
@@ -1454,5 +1455,37 @@ func TestLoadVolumesWarnOnDeprecatedExternalNameVersion33(t *testing.T) {
14541455
}
14551456
assert.Equal(t, expected, volumes)
14561457
assert.Equal(t, "", buf.String())
1458+
}
14571459

1460+
func TestLoadV35(t *testing.T) {
1461+
actual, err := loadYAML(`
1462+
version: "3.5"
1463+
services:
1464+
foo:
1465+
image: busybox
1466+
isolation: process
1467+
configs:
1468+
super:
1469+
external: true
1470+
`)
1471+
require.NoError(t, err)
1472+
require.Len(t, actual.Services, 1)
1473+
assert.Equal(t, container.IsolationProcess, actual.Services[0].Isolation)
1474+
}
1475+
1476+
func TestLoadV35InvalidIsolation(t *testing.T) {
1477+
// validation should be done only on the daemon side
1478+
actual, err := loadYAML(`
1479+
version: "3.5"
1480+
services:
1481+
foo:
1482+
image: busybox
1483+
isolation: invalid
1484+
configs:
1485+
super:
1486+
external: true
1487+
`)
1488+
require.NoError(t, err)
1489+
require.Len(t, actual.Services, 1)
1490+
assert.Equal(t, container.Isolation("invalid"), actual.Services[0].Isolation)
14581491
}

‎cli/compose/schema/bindata.go‎

Lines changed: 23 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)