From 515f3ba1e7653cdc97aa78da87c24e7e0f27378a Mon Sep 17 00:00:00 2001 From: aiordache Date: Mon, 11 Jan 2021 15:54:56 +0100 Subject: [PATCH 1/4] Revisit volume implementation Signed-off-by: aiordache --- local/compose/convergence.go | 2 +- local/compose/create.go | 110 +++++++++++++++++++++++++---------- 2 files changed, 79 insertions(+), 33 deletions(-) diff --git a/local/compose/convergence.go b/local/compose/convergence.go index 0402cc5f8..9966eb107 100644 --- a/local/compose/convergence.go +++ b/local/compose/convergence.go @@ -251,7 +251,7 @@ func (s *composeService) restartContainer(ctx context.Context, container moby.Co } func (s *composeService) createMobyContainer(ctx context.Context, project *types.Project, service types.ServiceConfig, name string, number int, container *moby.Container, autoRemove bool) error { - containerConfig, hostConfig, networkingConfig, err := getCreateOptions(project, service, number, container, autoRemove) + containerConfig, hostConfig, networkingConfig, err := s.getCreateOptions(ctx, project, service, number, container, autoRemove) if err != nil { return err } diff --git a/local/compose/create.go b/local/compose/create.go index 575c18ca4..3ddf9ee9e 100644 --- a/local/compose/create.go +++ b/local/compose/create.go @@ -131,7 +131,8 @@ func getImageName(service types.ServiceConfig, projectName string) string { return imageName } -func getCreateOptions(p *types.Project, s types.ServiceConfig, number int, inherit *moby.Container, autoRemove bool) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) { +func (cs *composeService) getCreateOptions(ctx context.Context, p *types.Project, s types.ServiceConfig, number int, inherit *moby.Container, autoRemove bool) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) { + hash, err := jsonHash(s) if err != nil { return nil, nil, nil, err @@ -169,6 +170,28 @@ func getCreateOptions(p *types.Project, s types.ServiceConfig, number int, inher stdinOpen = s.StdinOpen attachStdin = false ) + image := getImageName(s, p.Name) + imgInspect, _, err := cs.apiClient.ImageInspectWithRaw(ctx, image) + if err != nil { + return nil, nil, nil, err + } + mountOptions, err := buildContainerMountOptions(*p, s, imgInspect, inherit) + if err != nil { + return nil, nil, nil, err + } + volumeMounts := map[string]struct{}{} + binds := []string{} + for _, m := range mountOptions { + if m.Type == mount.TypeVolume { + + } + if m.Type == mount.TypeVolume { + volumeMounts[m.Target] = struct{}{} + if m.Source != "" { + binds = append(binds, fmt.Sprintf("%s:%s:%s", m.Source, m.Target, "rw")) + } + } + } containerConfig := container.Config{ Hostname: s.Hostname, @@ -182,7 +205,7 @@ func getCreateOptions(p *types.Project, s types.ServiceConfig, number int, inher AttachStderr: true, AttachStdout: true, Cmd: runCmd, - Image: getImageName(s, p.Name), + Image: image, WorkingDir: s.WorkingDir, Entrypoint: entrypoint, NetworkDisabled: s.NetworkMode == "disabled", @@ -192,20 +215,28 @@ func getCreateOptions(p *types.Project, s types.ServiceConfig, number int, inher Env: convert.ToMobyEnv(s.Environment), Healthcheck: convert.ToMobyHealthCheck(s.HealthCheck), // Volumes: // FIXME unclear to me the overlap with HostConfig.Mounts + Volumes: volumeMounts, StopTimeout: convert.ToSeconds(s.StopGracePeriod), } - mountOptions, err := buildContainerMountOptions(*p, s, inherit) + // append secrets mounts + bindMounts, err := buildContainerSecretMounts(*p, s, imgInspect, inherit) if err != nil { return nil, nil, nil, err } - bindings := buildContainerBindingOptions(s) + for _, m := range mountOptions { + if m.Type == mount.TypeBind || m.Type == mount.TypeTmpfs { + bindMounts = append(bindMounts, m) + } + } + portBindings := buildContainerPortBindingOptions(s) resources := getDeployResources(s) networkMode := getNetworkMode(p, s) hostConfig := container.HostConfig{ AutoRemove: autoRemove, - Mounts: mountOptions, + Binds: binds, + Mounts: bindMounts, CapAdd: strslice.StrSlice(s.CapAdd), CapDrop: strslice.StrSlice(s.CapDrop), NetworkMode: networkMode, @@ -213,7 +244,7 @@ func getCreateOptions(p *types.Project, s types.ServiceConfig, number int, inher ReadonlyRootfs: s.ReadOnly, // ShmSize: , TODO Sysctls: s.Sysctls, - PortBindings: bindings, + PortBindings: portBindings, Resources: resources, } @@ -253,7 +284,7 @@ func buildContainerPorts(s types.ServiceConfig) nat.PortSet { return ports } -func buildContainerBindingOptions(s types.ServiceConfig) nat.PortMap { +func buildContainerPortBindingOptions(s types.ServiceConfig) nat.PortMap { bindings := nat.PortMap{} for _, port := range s.Ports { p := nat.Port(fmt.Sprintf("%d/%s", port.Target, port.Protocol)) @@ -268,9 +299,8 @@ func buildContainerBindingOptions(s types.ServiceConfig) nat.PortMap { return bindings } -func buildContainerMountOptions(p types.Project, s types.ServiceConfig, inherit *moby.Container) ([]mount.Mount, error) { - mounts := []mount.Mount{} - var inherited []string +func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) { + var mounts = map[string]mount.Mount{} if inherit != nil { for _, m := range inherit.Mounts { if m.Type == "tmpfs" { @@ -280,27 +310,45 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, inherit if m.Type == "volume" { src = m.Name } - mounts = append(mounts, mount.Mount{ + mounts[m.Destination] = mount.Mount{ Type: m.Type, Source: src, Target: m.Destination, ReadOnly: !m.RW, - }) - inherited = append(inherited, m.Destination) + } } } + if img.ContainerConfig != nil { + for k, _ := range img.ContainerConfig.Volumes { - for _, v := range s.Volumes { - if contains(inherited, v.Target) { - continue + mount, err := buildMount(p, types.ServiceVolumeConfig{ + Type: types.VolumeTypeVolume, + Target: k, + }) + if err != nil { + return nil, err + } + mounts[k] = mount } + } + for _, v := range s.Volumes { mount, err := buildMount(p, v) if err != nil { return nil, err } - mounts = append(mounts, mount) + mounts[mount.Target] = mount } + values := make([]mount.Mount, 0, len(mounts)) + for _, v := range mounts { + values = append(values, v) + } + return values, nil +} + +func buildContainerSecretMounts(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) { + var mounts = map[string]mount.Mount{} + secretsDir := "/run/secrets" for _, secret := range s.Secrets { target := secret.Target @@ -315,15 +363,6 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, inherit return nil, fmt.Errorf("unsupported external secret %s", definedSecret.Name) } - if contains(inherited, target) { - // remove inherited mount - pos := indexOf(inherited, target) - if pos >= 0 { - mounts = append(mounts[:pos], mounts[pos+1]) - inherited = append(inherited[:pos], inherited[pos+1]) - } - } - mount, err := buildMount(p, types.ServiceVolumeConfig{ Type: types.VolumeTypeBind, Source: definedSecret.File, @@ -332,10 +371,13 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, inherit if err != nil { return nil, err } - mounts = append(mounts, mount) + mounts[target] = mount } - - return mounts, nil + values := make([]mount.Mount, 0, len(mounts)) + for _, v := range mounts { + values = append(values, v) + } + return values, nil } func buildMount(project types.Project, volume types.ServiceVolumeConfig) (mount.Mount, error) { @@ -349,10 +391,14 @@ func buildMount(project types.Project, volume types.ServiceVolumeConfig) (mount. } } if volume.Type == types.VolumeTypeVolume { - pVolume, ok := project.Volumes[volume.Source] - if ok { - source = pVolume.Name + if volume.Source != "" { + + pVolume, ok := project.Volumes[volume.Source] + if ok { + source = pVolume.Name + } } + } return mount.Mount{ From 747d2de397746887c57fdd300392d42475dee6c0 Mon Sep 17 00:00:00 2001 From: aiordache Date: Thu, 14 Jan 2021 12:47:36 +0100 Subject: [PATCH 2/4] cleanup Signed-off-by: aiordache --- local/compose/create.go | 76 ++++++++++++++++++++--------------------- local/compose/util.go | 9 ----- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/local/compose/create.go b/local/compose/create.go index 3ddf9ee9e..1fef77497 100644 --- a/local/compose/create.go +++ b/local/compose/create.go @@ -131,7 +131,8 @@ func getImageName(service types.ServiceConfig, projectName string) string { return imageName } -func (cs *composeService) getCreateOptions(ctx context.Context, p *types.Project, s types.ServiceConfig, number int, inherit *moby.Container, autoRemove bool) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) { +func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, service types.ServiceConfig, number int, inherit *moby.Container, + autoRemove bool) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) { hash, err := jsonHash(s) if err != nil { @@ -139,14 +140,14 @@ func (cs *composeService) getCreateOptions(ctx context.Context, p *types.Project } labels := map[string]string{} - for k, v := range s.Labels { + for k, v := range service.Labels { labels[k] = v } labels[projectLabel] = p.Name - labels[serviceLabel] = s.Name + labels[serviceLabel] = service.Name labels[versionLabel] = ComposeVersion - if _, ok := s.Labels[oneoffLabel]; !ok { + if _, ok := service.Labels[oneoffLabel]; !ok { labels[oneoffLabel] = "False" } labels[configHashLabel] = hash @@ -158,33 +159,30 @@ func (cs *composeService) getCreateOptions(ctx context.Context, p *types.Project runCmd strslice.StrSlice entrypoint strslice.StrSlice ) - if len(s.Command) > 0 { - runCmd = strslice.StrSlice(s.Command) + if len(service.Command) > 0 { + runCmd = strslice.StrSlice(service.Command) } - if len(s.Entrypoint) > 0 { - entrypoint = strslice.StrSlice(s.Entrypoint) + if len(service.Entrypoint) > 0 { + entrypoint = strslice.StrSlice(service.Entrypoint) } var ( - tty = s.Tty - stdinOpen = s.StdinOpen + tty = service.Tty + stdinOpen = service.StdinOpen attachStdin = false ) - image := getImageName(s, p.Name) - imgInspect, _, err := cs.apiClient.ImageInspectWithRaw(ctx, image) + image := getImageName(service, p.Name) + imgInspect, _, err := s.apiClient.ImageInspectWithRaw(ctx, image) if err != nil { return nil, nil, nil, err } - mountOptions, err := buildContainerMountOptions(*p, s, imgInspect, inherit) + mountOptions, err := buildContainerMountOptions(*p, service, imgInspect, inherit) if err != nil { return nil, nil, nil, err } volumeMounts := map[string]struct{}{} binds := []string{} for _, m := range mountOptions { - if m.Type == mount.TypeVolume { - - } if m.Type == mount.TypeVolume { volumeMounts[m.Target] = struct{}{} if m.Source != "" { @@ -194,10 +192,10 @@ func (cs *composeService) getCreateOptions(ctx context.Context, p *types.Project } containerConfig := container.Config{ - Hostname: s.Hostname, - Domainname: s.DomainName, - User: s.User, - ExposedPorts: buildContainerPorts(s), + Hostname: service.Hostname, + Domainname: service.DomainName, + User: service.User, + ExposedPorts: buildContainerPorts(service), Tty: tty, OpenStdin: stdinOpen, StdinOnce: true, @@ -206,21 +204,21 @@ func (cs *composeService) getCreateOptions(ctx context.Context, p *types.Project AttachStdout: true, Cmd: runCmd, Image: image, - WorkingDir: s.WorkingDir, + WorkingDir: service.WorkingDir, Entrypoint: entrypoint, - NetworkDisabled: s.NetworkMode == "disabled", - MacAddress: s.MacAddress, + NetworkDisabled: service.NetworkMode == "disabled", + MacAddress: service.MacAddress, Labels: labels, - StopSignal: s.StopSignal, - Env: convert.ToMobyEnv(s.Environment), - Healthcheck: convert.ToMobyHealthCheck(s.HealthCheck), + StopSignal: service.StopSignal, + Env: convert.ToMobyEnv(service.Environment), + Healthcheck: convert.ToMobyHealthCheck(service.HealthCheck), // Volumes: // FIXME unclear to me the overlap with HostConfig.Mounts Volumes: volumeMounts, - StopTimeout: convert.ToSeconds(s.StopGracePeriod), + StopTimeout: convert.ToSeconds(service.StopGracePeriod), } // append secrets mounts - bindMounts, err := buildContainerSecretMounts(*p, s, imgInspect, inherit) + bindMounts, err := buildContainerSecretMounts(*p, service) if err != nil { return nil, nil, nil, err } @@ -229,26 +227,26 @@ func (cs *composeService) getCreateOptions(ctx context.Context, p *types.Project bindMounts = append(bindMounts, m) } } - portBindings := buildContainerPortBindingOptions(s) + portBindings := buildContainerPortBindingOptions(service) - resources := getDeployResources(s) - networkMode := getNetworkMode(p, s) + resources := getDeployResources(service) + networkMode := getNetworkMode(p, service) hostConfig := container.HostConfig{ AutoRemove: autoRemove, Binds: binds, Mounts: bindMounts, - CapAdd: strslice.StrSlice(s.CapAdd), - CapDrop: strslice.StrSlice(s.CapDrop), + CapAdd: strslice.StrSlice(service.CapAdd), + CapDrop: strslice.StrSlice(service.CapDrop), NetworkMode: networkMode, - Init: s.Init, - ReadonlyRootfs: s.ReadOnly, + Init: service.Init, + ReadonlyRootfs: service.ReadOnly, // ShmSize: , TODO - Sysctls: s.Sysctls, + Sysctls: service.Sysctls, PortBindings: portBindings, Resources: resources, } - networkConfig := buildDefaultNetworkConfig(s, networkMode, getContainerName(p.Name, s, number)) + networkConfig := buildDefaultNetworkConfig(service, networkMode, getContainerName(p.Name, service, number)) return &containerConfig, &hostConfig, networkConfig, nil } @@ -319,7 +317,7 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby } } if img.ContainerConfig != nil { - for k, _ := range img.ContainerConfig.Volumes { + for k := range img.ContainerConfig.Volumes { mount, err := buildMount(p, types.ServiceVolumeConfig{ Type: types.VolumeTypeVolume, @@ -346,7 +344,7 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby return values, nil } -func buildContainerSecretMounts(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) { +func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount.Mount, error) { var mounts = map[string]mount.Mount{} secretsDir := "/run/secrets" diff --git a/local/compose/util.go b/local/compose/util.go index b0af71cac..dd9cbbcfe 100644 --- a/local/compose/util.go +++ b/local/compose/util.go @@ -38,12 +38,3 @@ func contains(slice []string, item string) bool { } return false } - -func indexOf(slice []string, item string) int { - for i, v := range slice { - if v == item { - return i - } - } - return -1 -} From 774234750d7fbc08737a5dba099417a8db67f9dd Mon Sep 17 00:00:00 2001 From: aiordache Date: Fri, 15 Jan 2021 09:49:56 +0100 Subject: [PATCH 3/4] Parse volumes_from Signed-off-by: aiordache --- local/compose/convergence.go | 1 - local/compose/create.go | 151 +++++++++++++++++++++++++++-------- 2 files changed, 116 insertions(+), 36 deletions(-) diff --git a/local/compose/convergence.go b/local/compose/convergence.go index 9966eb107..e3f46e610 100644 --- a/local/compose/convergence.go +++ b/local/compose/convergence.go @@ -93,7 +93,6 @@ func (s *composeService) ensureService(ctx context.Context, observedState Contai } for _, container := range actual { - container := container name := getCanonicalContainerName(container) diverged := container.Labels[configHashLabel] != expected diff --git a/local/compose/create.go b/local/compose/create.go index 1fef77497..126ef212b 100644 --- a/local/compose/create.go +++ b/local/compose/create.go @@ -50,6 +50,11 @@ func (s *composeService) Create(ctx context.Context, project *types.Project, opt prepareNetworks(project) + err = prepareVolumes(project) + if err != nil { + return err + } + if err := s.ensureNetworks(ctx, project.Networks); err != nil { return err } @@ -91,6 +96,29 @@ func (s *composeService) Create(ctx context.Context, project *types.Project, opt }) } +func prepareVolumes(p *types.Project) error { + for i := range p.Services { + volumesFrom, dependServices, err := getVolumesFrom(p, p.Services[i].VolumesFrom) + if err != nil { + return err + } + p.Services[i].VolumesFrom = volumesFrom + if len(dependServices) > 0 { + if p.Services[i].DependsOn == nil { + p.Services[i].DependsOn = make(types.DependsOnConfig, len(dependServices)) + } + for _, service := range p.Services { + if contains(dependServices, service.Name) { + p.Services[i].DependsOn[service.Name] = types.ServiceDependency{ + Condition: types.ServiceConditionStarted, + } + } + } + } + } + return nil +} + func prepareNetworks(project *types.Project) { for k, network := range project.Networks { network.Labels = network.Labels.Add(networkLabel, k) @@ -134,7 +162,7 @@ func getImageName(service types.ServiceConfig, projectName string) string { func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, service types.ServiceConfig, number int, inherit *moby.Container, autoRemove bool) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) { - hash, err := jsonHash(s) + hash, err := jsonHash(service) if err != nil { return nil, nil, nil, err } @@ -171,25 +199,11 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, stdinOpen = service.StdinOpen attachStdin = false ) - image := getImageName(service, p.Name) - imgInspect, _, err := s.apiClient.ImageInspectWithRaw(ctx, image) + + volumeMounts, binds, mounts, err := s.buildContainerVolumes(ctx, *p, service, inherit) if err != nil { return nil, nil, nil, err } - mountOptions, err := buildContainerMountOptions(*p, service, imgInspect, inherit) - if err != nil { - return nil, nil, nil, err - } - volumeMounts := map[string]struct{}{} - binds := []string{} - for _, m := range mountOptions { - if m.Type == mount.TypeVolume { - volumeMounts[m.Target] = struct{}{} - if m.Source != "" { - binds = append(binds, fmt.Sprintf("%s:%s:%s", m.Source, m.Target, "rw")) - } - } - } containerConfig := container.Config{ Hostname: service.Hostname, @@ -203,7 +217,7 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, AttachStderr: true, AttachStdout: true, Cmd: runCmd, - Image: image, + Image: getImageName(service, p.Name), WorkingDir: service.WorkingDir, Entrypoint: entrypoint, NetworkDisabled: service.NetworkMode == "disabled", @@ -212,21 +226,11 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, StopSignal: service.StopSignal, Env: convert.ToMobyEnv(service.Environment), Healthcheck: convert.ToMobyHealthCheck(service.HealthCheck), - // Volumes: // FIXME unclear to me the overlap with HostConfig.Mounts - Volumes: volumeMounts, + Volumes: volumeMounts, + StopTimeout: convert.ToSeconds(service.StopGracePeriod), } - // append secrets mounts - bindMounts, err := buildContainerSecretMounts(*p, service) - if err != nil { - return nil, nil, nil, err - } - for _, m := range mountOptions { - if m.Type == mount.TypeBind || m.Type == mount.TypeTmpfs { - bindMounts = append(bindMounts, m) - } - } portBindings := buildContainerPortBindingOptions(service) resources := getDeployResources(service) @@ -234,7 +238,7 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, hostConfig := container.HostConfig{ AutoRemove: autoRemove, Binds: binds, - Mounts: bindMounts, + Mounts: mounts, CapAdd: strslice.StrSlice(service.CapAdd), CapDrop: strslice.StrSlice(service.CapDrop), NetworkMode: networkMode, @@ -244,6 +248,8 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, Sysctls: service.Sysctls, PortBindings: portBindings, Resources: resources, + VolumeDriver: service.VolumeDriver, + VolumesFrom: service.VolumesFrom, } networkConfig := buildDefaultNetworkConfig(service, networkMode, getContainerName(p.Name, service, number)) @@ -297,6 +303,69 @@ func buildContainerPortBindingOptions(s types.ServiceConfig) nat.PortMap { return bindings } +func getVolumesFrom(project *types.Project, volumesFrom []string) ([]string, []string, error) { + var volumes = []string{} + var services = []string{} + // parse volumes_from + if len(volumesFrom) == 0 { + return volumes, services, nil + } + for _, vol := range volumesFrom { + spec := strings.Split(vol, ":") + if spec[0] == "container" { + volumes = append(volumes, strings.Join(spec[1:], ":")) + continue + } + serviceName := spec[0] + services = append(services, serviceName) + service, err := project.GetService(serviceName) + if err != nil { + return nil, nil, err + } + + firstContainer := getContainerName(project.Name, service, 1) + v := fmt.Sprintf("%s:%s", firstContainer, strings.Join(spec[1:], ":")) + volumes = append(volumes, v) + } + return volumes, services, nil + +} + +func (s *composeService) buildContainerVolumes(ctx context.Context, p types.Project, service types.ServiceConfig, + inherit *moby.Container) (map[string]struct{}, []string, []mount.Mount, error) { + var mounts = []mount.Mount{} + + image := getImageName(service, p.Name) + imgInspect, _, err := s.apiClient.ImageInspectWithRaw(ctx, image) + if err != nil { + return nil, nil, nil, err + } + + mountOptions, err := buildContainerMountOptions(p, service, imgInspect, inherit) + if err != nil { + return nil, nil, nil, err + } + + // filter binds and volumes mount targets + volumeMounts := map[string]struct{}{} + binds := []string{} + for _, m := range mountOptions { + + if m.Type == mount.TypeVolume { + volumeMounts[m.Target] = struct{}{} + if m.Source != "" { + binds = append(binds, fmt.Sprintf("%s:%s:rw", m.Source, m.Target)) + } + } + } + for _, m := range mountOptions { + if m.Type == mount.TypeBind || m.Type == mount.TypeTmpfs { + mounts = append(mounts, m) + } + } + return volumeMounts, binds, mounts, nil +} + func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) { var mounts = map[string]mount.Mount{} if inherit != nil { @@ -318,7 +387,6 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby } if img.ContainerConfig != nil { for k := range img.ContainerConfig.Volumes { - mount, err := buildMount(p, types.ServiceVolumeConfig{ Type: types.VolumeTypeVolume, Target: k, @@ -327,6 +395,7 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby return nil, err } mounts[k] = mount + } } for _, v := range s.Volumes { @@ -337,6 +406,17 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby mounts[mount.Target] = mount } + secrets, err := buildContainerSecretMounts(p, s) + if err != nil { + return nil, err + } + for _, s := range secrets { + if _, found := mounts[s.Target]; found { + continue + } + mounts[s.Target] = s + } + values := make([]mount.Mount, 0, len(mounts)) for _, v := range mounts { values = append(values, v) @@ -362,9 +442,10 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount } mount, err := buildMount(p, types.ServiceVolumeConfig{ - Type: types.VolumeTypeBind, - Source: definedSecret.File, - Target: target, + Type: types.VolumeTypeBind, + Source: definedSecret.File, + Target: target, + ReadOnly: true, }) if err != nil { return nil, err From 3e3f94c1616417392616c3c3efc263f03699a880 Mon Sep 17 00:00:00 2001 From: aiordache Date: Mon, 18 Jan 2021 11:58:21 +0100 Subject: [PATCH 4/4] update tests Signed-off-by: aiordache --- tests/compose-e2e/compose_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/compose-e2e/compose_test.go b/tests/compose-e2e/compose_test.go index e23f5f61c..8b17a09b2 100644 --- a/tests/compose-e2e/compose_test.go +++ b/tests/compose-e2e/compose_test.go @@ -261,9 +261,18 @@ func TestLocalComposeVolume(t *testing.T) { }) t.Run("check container volume specs", func(t *testing.T) { - res := c.RunDockerCmd("inspect", "compose-e2e-volume_nginx2_1", "--format", "{{ json .HostConfig.Mounts }}") + res := c.RunDockerCmd("inspect", "compose-e2e-volume_nginx2_1", "--format", "{{ json .Mounts }}") + output := res.Stdout() //nolint - res.Assert(t, icmd.Expected{Out: `[{"Type":"volume","Source":"compose-e2e-volume_staticVol","Target":"/usr/share/nginx/html","ReadOnly":true},{"Type":"volume","Target":"/usr/src/app/node_modules"},{"Type":"volume","Source":"myVolume","Target":"/usr/share/nginx/test"}]`}) + assert.Assert(t, strings.Contains(output, `"Destination":"/usr/src/app/node_modules","Driver":"local","Mode":"","RW":true,"Propagation":""`)) + }) + + t.Run("check container bind-mounts specs", func(t *testing.T) { + res := c.RunDockerCmd("inspect", "compose-e2e-volume_nginx_1", "--format", "{{ json .HostConfig.Mounts }}") + output := res.Stdout() + //nolint + assert.Assert(t, strings.Contains(output, `"Type":"bind"`)) + assert.Assert(t, strings.Contains(output, `"Target":"/usr/share/nginx/html"`)) }) t.Run("cleanup volume project", func(t *testing.T) {