diff --git a/cmd/compose/build.go b/cmd/compose/build.go index 8e4de1df4..f0e26d34a 100644 --- a/cmd/compose/build.go +++ b/cmd/compose/build.go @@ -22,9 +22,9 @@ import ( "os" "strings" - "github.com/compose-spec/compose-go/cli" - "github.com/compose-spec/compose-go/loader" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/cli" + "github.com/compose-spec/compose-go/v2/loader" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" cliopts "github.com/docker/cli/opts" ui "github.com/docker/compose/v2/pkg/progress" @@ -50,7 +50,14 @@ func (opts buildOptions) toAPIBuildOptions(services []string) (api.BuildOptions, var SSHKeys []types.SSHKey var err error if opts.ssh != "" { - SSHKeys, err = loader.ParseShortSSHSyntax(opts.ssh) + id, path, found := strings.Cut(opts.ssh, "=") + if !found && id != "default" { + return api.BuildOptions{}, fmt.Errorf("invalid ssh key %q", opts.ssh) + } + SSHKeys = append(SSHKeys, types.SSHKey{ + ID: id, + Path: path, + }) if err != nil { return api.BuildOptions{}, err } diff --git a/cmd/compose/compose.go b/cmd/compose/compose.go index 55d48e883..76ae4ab09 100644 --- a/cmd/compose/compose.go +++ b/cmd/compose/compose.go @@ -27,10 +27,10 @@ import ( "strings" "syscall" - "github.com/compose-spec/compose-go/cli" - "github.com/compose-spec/compose-go/dotenv" - "github.com/compose-spec/compose-go/types" - composegoutils "github.com/compose-spec/compose-go/utils" + "github.com/compose-spec/compose-go/v2/cli" + "github.com/compose-spec/compose-go/v2/dotenv" + "github.com/compose-spec/compose-go/v2/types" + composegoutils "github.com/compose-spec/compose-go/v2/utils" "github.com/docker/buildx/util/logutil" dockercli "github.com/docker/cli/cli" "github.com/docker/cli/cli-plugins/manager" diff --git a/cmd/compose/compose_test.go b/cmd/compose/compose_test.go index c999ab3de..f6626a6a9 100644 --- a/cmd/compose/compose_test.go +++ b/cmd/compose/compose_test.go @@ -19,7 +19,7 @@ package compose import ( "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "gotest.tools/v3/assert" ) diff --git a/cmd/compose/config.go b/cmd/compose/config.go index b4a9baedf..c86d86a38 100644 --- a/cmd/compose/config.go +++ b/cmd/compose/config.go @@ -24,8 +24,8 @@ import ( "sort" "strings" - "github.com/compose-spec/compose-go/cli" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/cli" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" diff --git a/cmd/compose/create.go b/cmd/compose/create.go index 2e652cf47..a7731bae5 100644 --- a/cmd/compose/create.go +++ b/cmd/compose/create.go @@ -24,7 +24,7 @@ import ( "strings" "time" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" @@ -164,7 +164,15 @@ func (opts createOptions) Apply(project *types.Project) error { return err } - for _, scale := range opts.scale { + err := applyScaleOpts(project, opts.scale) + if err != nil { + return err + } + return nil +} + +func applyScaleOpts(project *types.Project, opts []string) error { + for _, scale := range opts { split := strings.Split(scale, "=") if len(split) != 2 { return fmt.Errorf("invalid --scale option %q. Should be SERVICE=NUM", scale) @@ -174,7 +182,7 @@ func (opts createOptions) Apply(project *types.Project) error { if err != nil { return err } - err = setServiceScale(project, name, uint64(replicas)) + err = setServiceScale(project, name, replicas) if err != nil { return err } diff --git a/cmd/compose/create_test.go b/cmd/compose/create_test.go index 95a2a9614..eecd6d9c0 100644 --- a/cmd/compose/create_test.go +++ b/cmd/compose/create_test.go @@ -21,7 +21,7 @@ import ( "fmt" "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/davecgh/go-spew/spew" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/mocks" diff --git a/cmd/compose/exec.go b/cmd/compose/exec.go index 0df79ec3b..12ebc7005 100644 --- a/cmd/compose/exec.go +++ b/cmd/compose/exec.go @@ -19,7 +19,7 @@ package compose import ( "context" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" "github.com/docker/compose/v2/pkg/api" diff --git a/cmd/compose/options.go b/cmd/compose/options.go index 88135df20..988fa5f1d 100644 --- a/cmd/compose/options.go +++ b/cmd/compose/options.go @@ -19,7 +19,7 @@ package compose import ( "fmt" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/utils" ) diff --git a/cmd/compose/options_test.go b/cmd/compose/options_test.go index 66c72db73..44c602455 100644 --- a/cmd/compose/options_test.go +++ b/cmd/compose/options_test.go @@ -19,7 +19,7 @@ package compose import ( "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/stretchr/testify/require" ) diff --git a/cmd/compose/pull.go b/cmd/compose/pull.go index 6eb6774d6..657f5bbba 100644 --- a/cmd/compose/pull.go +++ b/cmd/compose/pull.go @@ -21,7 +21,7 @@ import ( "fmt" "os" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/morikuni/aec" "github.com/spf13/cobra" diff --git a/cmd/compose/pullOptions_test.go b/cmd/compose/pullOptions_test.go index cb14c4728..2e68d91a9 100644 --- a/cmd/compose/pullOptions_test.go +++ b/cmd/compose/pullOptions_test.go @@ -19,7 +19,7 @@ package compose import ( "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "gotest.tools/v3/assert" ) diff --git a/cmd/compose/push.go b/cmd/compose/push.go index 712b22cea..ddb5904c6 100644 --- a/cmd/compose/push.go +++ b/cmd/compose/push.go @@ -19,7 +19,7 @@ package compose import ( "context" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/spf13/cobra" diff --git a/cmd/compose/run.go b/cmd/compose/run.go index 02b2dd744..6c8c12740 100644 --- a/cmd/compose/run.go +++ b/cmd/compose/run.go @@ -21,12 +21,12 @@ import ( "fmt" "strings" + "github.com/compose-spec/compose-go/v2/format" xprogress "github.com/moby/buildkit/util/progress/progressui" "github.com/sirupsen/logrus" - cgo "github.com/compose-spec/compose-go/cli" - "github.com/compose-spec/compose-go/loader" - "github.com/compose-spec/compose-go/types" + cgo "github.com/compose-spec/compose-go/v2/cli" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/docker/cli/opts" "github.com/mattn/go-shellwords" @@ -98,7 +98,7 @@ func (options runOptions) apply(project *types.Project) error { } for _, v := range options.volumes { - volume, err := loader.ParseVolume(v) + volume, err := format.ParseVolume(v) if err != nil { return err } diff --git a/cmd/compose/scale.go b/cmd/compose/scale.go index 63ab1414a..c547293b8 100644 --- a/cmd/compose/scale.go +++ b/cmd/compose/scale.go @@ -24,7 +24,7 @@ import ( "github.com/docker/cli/cli/command" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "golang.org/x/exp/maps" "github.com/docker/compose/v2/pkg/api" @@ -77,11 +77,11 @@ func runScale(ctx context.Context, dockerCli command.Cli, backend api.Service, o if service.Name != key { continue } - if service.Deploy == nil { - service.Deploy = &types.DeployConfig{} + value := value + service.Scale = &value + if service.Deploy != nil { + service.Deploy.Replicas = &value } - scale := uint64(value) - service.Deploy.Replicas = &scale project.Services[i] = service break } diff --git a/cmd/compose/up.go b/cmd/compose/up.go index a86d1964c..1f0b3a0c8 100644 --- a/cmd/compose/up.go +++ b/cmd/compose/up.go @@ -25,7 +25,7 @@ import ( xprogress "github.com/moby/buildkit/util/progress/progressui" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/docker/compose/v2/cmd/formatter" "github.com/spf13/cobra" @@ -259,7 +259,7 @@ func runUp( }) } -func setServiceScale(project *types.Project, name string, replicas uint64) error { +func setServiceScale(project *types.Project, name string, replicas int) error { for i, s := range project.Services { if s.Name != name { continue @@ -269,10 +269,10 @@ func setServiceScale(project *types.Project, name string, replicas uint64) error if err != nil { return err } - if service.Deploy == nil { - service.Deploy = &types.DeployConfig{} + service.Scale = &replicas + if service.Deploy != nil { + service.Deploy.Replicas = &replicas } - service.Deploy.Replicas = &replicas project.Services[i] = service return nil } diff --git a/cmd/compose/up_test.go b/cmd/compose/up_test.go index 951b11897..294527841 100644 --- a/cmd/compose/up_test.go +++ b/cmd/compose/up_test.go @@ -19,7 +19,7 @@ package compose import ( "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "gotest.tools/v3/assert" ) @@ -31,13 +31,21 @@ func TestApplyScaleOpt(t *testing.T) { }, { Name: "bar", + Deploy: &types.DeployConfig{ + Mode: "test", + }, }, }, } - opt := createOptions{scale: []string{"foo=2"}} - err := opt.Apply(&p) + err := applyScaleOpts(&p, []string{"foo=2", "bar=3"}) assert.NilError(t, err) foo, err := p.GetService("foo") assert.NilError(t, err) - assert.Equal(t, *foo.Deploy.Replicas, uint64(2)) + assert.Equal(t, *foo.Scale, 2) + + bar, err := p.GetService("bar") + assert.NilError(t, err) + assert.Equal(t, *bar.Scale, 3) + assert.Equal(t, *bar.Deploy.Replicas, 3) + } diff --git a/cmd/compose/watch.go b/cmd/compose/watch.go index 7311d9bca..24d704570 100644 --- a/cmd/compose/watch.go +++ b/cmd/compose/watch.go @@ -20,7 +20,7 @@ import ( "context" "fmt" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/docker/compose/v2/internal/locker" diff --git a/go.mod b/go.mod index 2a65d2051..5d20b5d1b 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/Microsoft/go-winio v0.6.1 github.com/buger/goterm v1.0.4 - github.com/compose-spec/compose-go v1.20.2 + github.com/compose-spec/compose-go/v2 v2.0.0-20231121074112-593b77722992 github.com/containerd/console v1.0.3 github.com/containerd/containerd v1.7.7 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index 9c5aff180..48bf3a4ba 100644 --- a/go.sum +++ b/go.sum @@ -132,8 +132,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE= github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= -github.com/compose-spec/compose-go v1.20.2 h1:u/yfZHn4EaHGdidrZycWpxXgFffjYULlTbRfJ51ykjQ= -github.com/compose-spec/compose-go v1.20.2/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM= +github.com/compose-spec/compose-go/v2 v2.0.0-20231121074112-593b77722992 h1:0BM7GPtSRK7djjvG3h67aJYH8eRikBgxkrEG7wNtgaU= +github.com/compose-spec/compose-go/v2 v2.0.0-20231121074112-593b77722992/go.mod h1:uAthZuC/GWStR8mxGMRaQyaOeSqA4V+MZIiAIfuBoIU= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= diff --git a/internal/sync/docker_cp.go b/internal/sync/docker_cp.go index ae5a77ad6..f11364cc2 100644 --- a/internal/sync/docker_cp.go +++ b/internal/sync/docker_cp.go @@ -22,7 +22,7 @@ import ( "io/fs" "os" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/sirupsen/logrus" ) @@ -63,8 +63,8 @@ func (d *DockerCopy) Sync(ctx context.Context, service types.ServiceConfig, path func (d *DockerCopy) sync(ctx context.Context, service types.ServiceConfig, pathMapping PathMapping) error { scale := 1 - if service.Deploy != nil && service.Deploy.Replicas != nil { - scale = int(*service.Deploy.Replicas) + if service.Scale != nil { + scale = *service.Scale } if fi, statErr := os.Stat(pathMapping.HostPath); statErr == nil { diff --git a/internal/sync/shared.go b/internal/sync/shared.go index 2ff9b434c..6e2b117cb 100644 --- a/internal/sync/shared.go +++ b/internal/sync/shared.go @@ -17,7 +17,7 @@ package sync import ( "context" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" ) // PathMapping contains the Compose service and modified host system path. diff --git a/internal/sync/tar.go b/internal/sync/tar.go index bb6a0acf0..ae7d8517e 100644 --- a/internal/sync/tar.go +++ b/internal/sync/tar.go @@ -32,7 +32,7 @@ import ( "github.com/hashicorp/go-multierror" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" "github.com/docker/docker/pkg/archive" ) diff --git a/internal/tracing/attributes.go b/internal/tracing/attributes.go index f0ee29f89..ea03e2195 100644 --- a/internal/tracing/attributes.go +++ b/internal/tracing/attributes.go @@ -22,7 +22,7 @@ import ( "github.com/docker/compose/v2/pkg/utils" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" diff --git a/pkg/api/api.go b/pkg/api/api.go index d07587401..589713d29 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -22,7 +22,7 @@ import ( "strings" "time" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/utils" ) diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index 0d9633151..fc44abe7f 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -19,7 +19,7 @@ package api import ( "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "gotest.tools/v3/assert" ) diff --git a/pkg/api/proxy.go b/pkg/api/proxy.go index b08059a32..446ce8dc4 100644 --- a/pkg/api/proxy.go +++ b/pkg/api/proxy.go @@ -19,7 +19,7 @@ package api import ( "context" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" ) var _ Service = &ServiceProxy{} diff --git a/pkg/compose/attach.go b/pkg/compose/attach.go index f920b4ea5..499f002fd 100644 --- a/pkg/compose/attach.go +++ b/pkg/compose/attach.go @@ -23,7 +23,7 @@ import ( "io" "strings" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/streams" moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" diff --git a/pkg/compose/build.go b/pkg/compose/build.go index 3b8ae0505..9684ea51b 100644 --- a/pkg/compose/build.go +++ b/pkg/compose/build.go @@ -26,7 +26,7 @@ import ( "github.com/moby/buildkit/util/progress/progressui" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/containerd/containerd/platforms" "github.com/docker/buildx/build" "github.com/docker/buildx/builder" diff --git a/pkg/compose/build_classic.go b/pkg/compose/build_classic.go index e49a15cc2..84a2c8e2d 100644 --- a/pkg/compose/build_classic.go +++ b/pkg/compose/build_classic.go @@ -31,7 +31,7 @@ import ( "github.com/docker/docker/api/types/registry" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command/image/build" dockertypes "github.com/docker/docker/api/types" diff --git a/pkg/compose/compose.go b/pkg/compose/compose.go index d0fc1988c..b4f17d222 100644 --- a/pkg/compose/compose.go +++ b/pkg/compose/compose.go @@ -29,7 +29,7 @@ import ( "github.com/docker/docker/api/types/volume" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/distribution/reference" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config/configfile" @@ -177,23 +177,25 @@ func (s *composeService) Config(ctx context.Context, project *types.Project, opt // projectFromName builds a types.Project based on actual resources with compose labels set func (s *composeService) projectFromName(containers Containers, projectName string, services ...string) (*types.Project, error) { project := &types.Project{ - Name: projectName, + Name: projectName, + Services: types.Services{}, } if len(containers) == 0 { return project, fmt.Errorf("no container found for project %q: %w", projectName, api.ErrNotFound) } - set := map[string]*types.ServiceConfig{} + set := map[string]types.ServiceConfig{} for _, c := range containers { serviceLabel := c.Labels[api.ServiceLabel] - _, ok := set[serviceLabel] + service, ok := set[serviceLabel] if !ok { - set[serviceLabel] = &types.ServiceConfig{ + service = types.ServiceConfig{ Name: serviceLabel, Image: c.Image, Labels: c.Labels, } + set[serviceLabel] = service } - set[serviceLabel].Scale++ + service.Scale = increment(service.Scale) } for _, service := range set { dependencies := service.Labels[api.DependenciesLabel] @@ -217,7 +219,7 @@ func (s *composeService) projectFromName(containers Containers, projectName stri service.DependsOn[dependency] = types.ServiceDependency{Condition: condition, Restart: restart, Required: required} } } - project.Services = append(project.Services, *service) + project.Services = append(project.Services, service) } SERVICES: for _, qs := range services { @@ -236,6 +238,14 @@ SERVICES: return project, nil } +func increment(scale *int) *int { + i := 1 + if scale != nil { + i = *scale + 1 + } + return &i +} + func (s *composeService) actualVolumes(ctx context.Context, projectName string) (types.Volumes, error) { opts := volume.ListOptions{ Filters: filters.NewArgs(projectFilter(projectName)), diff --git a/pkg/compose/containers.go b/pkg/compose/containers.go index 075b831c2..ce1722892 100644 --- a/pkg/compose/containers.go +++ b/pkg/compose/containers.go @@ -22,7 +22,7 @@ import ( "sort" "strconv" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/utils" moby "github.com/docker/docker/api/types" diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index 45a9257ed..d2c0fe603 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -29,7 +29,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/containerd/containerd/platforms" "github.com/docker/compose/v2/internal/tracing" moby "github.com/docker/docker/api/types" @@ -428,7 +428,7 @@ func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceD } } return false, err - } else if service.Scale == 0 { + } else if service.Scale != nil && *service.Scale == 0 { // don't wait for the dependency which configured to have 0 containers running return false, nil } @@ -457,8 +457,11 @@ func nextContainerNumber(containers []moby.Container) int { func getScale(config types.ServiceConfig) (int, error) { scale := 1 - if config.Deploy != nil && config.Deploy.Replicas != nil { - scale = int(*config.Deploy.Replicas) + if config.Scale != nil { + scale = *config.Scale + } else if config.Deploy != nil && config.Deploy.Replicas != nil { + // this should not be required as compose-go enforce consistency between scale anr replicas + scale = *config.Deploy.Replicas } if scale > 1 && config.ContainerName != "" { return 0, fmt.Errorf(doubledContainerNameWarning, diff --git a/pkg/compose/convergence_test.go b/pkg/compose/convergence_test.go index d35146c37..0ca12cfcb 100644 --- a/pkg/compose/convergence_test.go +++ b/pkg/compose/convergence_test.go @@ -22,7 +22,7 @@ import ( "strings" "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" @@ -37,31 +37,33 @@ func TestContainerName(t *testing.T) { s := types.ServiceConfig{ Name: "testservicename", ContainerName: "testcontainername", - Scale: 1, + Scale: intPtr(1), Deploy: &types.DeployConfig{}, } ret, err := getScale(s) assert.NilError(t, err) - assert.Equal(t, ret, s.Scale) + assert.Equal(t, ret, *s.Scale) - var zero uint64 // = 0 - s.Deploy.Replicas = &zero + s.Scale = intPtr(0) ret, err = getScale(s) assert.NilError(t, err) - assert.Equal(t, ret, int(*s.Deploy.Replicas)) + assert.Equal(t, ret, *s.Scale) - var two uint64 = 2 - s.Deploy.Replicas = &two + s.Scale = intPtr(2) _, err = getScale(s) assert.Error(t, err, fmt.Sprintf(doubledContainerNameWarning, s.Name, s.ContainerName)) } +func intPtr(i int) *int { + return &i +} + func TestServiceLinks(t *testing.T) { const dbContainerName = "/" + testProject + "-db-1" const webContainerName = "/" + testProject + "-web-1" s := types.ServiceConfig{ Name: "web", - Scale: 1, + Scale: intPtr(1), } containerListOptions := containerType.ListOptions{ @@ -223,8 +225,8 @@ func TestWaitDependencies(t *testing.T) { cli.EXPECT().Client().Return(apiClient).AnyTimes() t.Run("should skip dependencies with scale 0", func(t *testing.T) { - dbService := types.ServiceConfig{Name: "db", Scale: 0} - redisService := types.ServiceConfig{Name: "redis", Scale: 0} + dbService := types.ServiceConfig{Name: "db", Scale: intPtr(0)} + redisService := types.ServiceConfig{Name: "redis", Scale: intPtr(0)} project := types.Project{Name: strings.ToLower(testProject), Services: types.Services{dbService, redisService}} dependencies := types.DependsOnConfig{ "db": {Condition: ServiceConditionRunningOrHealthy}, @@ -233,8 +235,8 @@ func TestWaitDependencies(t *testing.T) { assert.NilError(t, tested.waitDependencies(context.Background(), &project, "", dependencies, nil)) }) t.Run("should skip dependencies with condition service_started", func(t *testing.T) { - dbService := types.ServiceConfig{Name: "db", Scale: 1} - redisService := types.ServiceConfig{Name: "redis", Scale: 1} + dbService := types.ServiceConfig{Name: "db", Scale: intPtr(1)} + redisService := types.ServiceConfig{Name: "redis", Scale: intPtr(1)} project := types.Project{Name: strings.ToLower(testProject), Services: types.Services{dbService, redisService}} dependencies := types.DependsOnConfig{ "db": {Condition: types.ServiceConditionStarted, Required: true}, diff --git a/pkg/compose/convert.go b/pkg/compose/convert.go index 6f092ee2d..4ce4c6acf 100644 --- a/pkg/compose/convert.go +++ b/pkg/compose/convert.go @@ -20,7 +20,7 @@ import ( "fmt" "time" - compose "github.com/compose-spec/compose-go/types" + compose "github.com/compose-spec/compose-go/v2/types" "github.com/docker/docker/api/types/container" ) diff --git a/pkg/compose/create.go b/pkg/compose/create.go index c0a36a8a0..9d4f48ebc 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -41,7 +41,7 @@ import ( "github.com/docker/go-units" "github.com/sirupsen/logrus" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/progress" @@ -810,7 +810,7 @@ func buildContainerConfigMounts(p types.Project, s types.ServiceConfig) ([]mount } definedConfig := p.Configs[config.Source] - if definedConfig.External.External { + if definedConfig.External { return nil, fmt.Errorf("unsupported external config %s", definedConfig.Name) } @@ -860,7 +860,7 @@ func buildContainerSecretMounts(p types.Project, s types.ServiceConfig) ([]mount } definedSecret := p.Secrets[secret.Source] - if definedSecret.External.External { + if definedSecret.External { return nil, fmt.Errorf("unsupported external secret %s", definedSecret.Name) } @@ -1019,7 +1019,7 @@ func buildTmpfsOptions(tmpfs *types.ServiceVolumeTmpfs) *mount.TmpfsOptions { } func (s *composeService) ensureNetwork(ctx context.Context, n *types.NetworkConfig) error { - if n.External.External { + if n.External { return s.resolveExternalNetwork(ctx, n) } @@ -1206,14 +1206,14 @@ func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeCo if !errdefs.IsNotFound(err) { return err } - if volume.External.External { + if volume.External { return fmt.Errorf("external volume %q not found", volume.Name) } err := s.createVolume(ctx, volume) return err } - if volume.External.External { + if volume.External { return nil } diff --git a/pkg/compose/create_test.go b/pkg/compose/create_test.go index 26f7f4d15..4d2bcec7f 100644 --- a/pkg/compose/create_test.go +++ b/pkg/compose/create_test.go @@ -26,7 +26,7 @@ import ( "github.com/docker/compose/v2/pkg/api" - composetypes "github.com/compose-spec/compose-go/types" + composetypes "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" mountTypes "github.com/docker/docker/api/types/mount" diff --git a/pkg/compose/dependencies.go b/pkg/compose/dependencies.go index 94b8d2d21..4a3fa4bd2 100644 --- a/pkg/compose/dependencies.go +++ b/pkg/compose/dependencies.go @@ -22,7 +22,7 @@ import ( "strings" "sync" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "golang.org/x/sync/errgroup" diff --git a/pkg/compose/dependencies_test.go b/pkg/compose/dependencies_test.go index a43b22e17..8b25c3b98 100644 --- a/pkg/compose/dependencies_test.go +++ b/pkg/compose/dependencies_test.go @@ -23,7 +23,7 @@ import ( "sync" "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/utils" testify "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/pkg/compose/down.go b/pkg/compose/down.go index b4a88eb64..009dcf8f5 100644 --- a/pkg/compose/down.go +++ b/pkg/compose/down.go @@ -24,7 +24,7 @@ import ( "github.com/docker/compose/v2/pkg/utils" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" @@ -136,7 +136,7 @@ func checkSelectedServices(options api.DownOptions, project *types.Project) ([]s func (s *composeService) ensureVolumesDown(ctx context.Context, project *types.Project, w progress.Writer) []downOp { var ops []downOp for _, vol := range project.Volumes { - if vol.External.External { + if vol.External { continue } volumeName := vol.Name @@ -171,7 +171,7 @@ func (s *composeService) ensureImagesDown(ctx context.Context, project *types.Pr func (s *composeService) ensureNetworksDown(ctx context.Context, project *types.Project, w progress.Writer) []downOp { var ops []downOp for key, n := range project.Networks { - if n.External.External { + if n.External { continue } // loop capture variable for op closure diff --git a/pkg/compose/down_test.go b/pkg/compose/down_test.go index fdd5153c3..df2c87371 100644 --- a/pkg/compose/down_test.go +++ b/pkg/compose/down_test.go @@ -23,7 +23,7 @@ import ( "strings" "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/streams" moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" diff --git a/pkg/compose/errors.go b/pkg/compose/errors.go index 0dd06c6db..58eea0147 100644 --- a/pkg/compose/errors.go +++ b/pkg/compose/errors.go @@ -20,7 +20,7 @@ import ( "errors" "io/fs" - "github.com/compose-spec/compose-go/errdefs" + "github.com/compose-spec/compose-go/v2/errdefs" ) // Error error to categorize failures and extract metrics info diff --git a/pkg/compose/hash.go b/pkg/compose/hash.go index c4a4c91a4..284ccaa76 100644 --- a/pkg/compose/hash.go +++ b/pkg/compose/hash.go @@ -19,7 +19,7 @@ package compose import ( "encoding/json" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/opencontainers/go-digest" ) @@ -28,12 +28,11 @@ func ServiceHash(o types.ServiceConfig) (string, error) { // remove the Build config when generating the service hash o.Build = nil o.PullPolicy = "" - if o.Deploy == nil { - o.Deploy = &types.DeployConfig{} + o.Scale = nil + if o.Deploy != nil { + o.Deploy.Replicas = nil } - o.Scale = 1 - var one uint64 = 1 - o.Deploy.Replicas = &one + bytes, err := json.Marshal(o) if err != nil { return "", err diff --git a/pkg/compose/hash_test.go b/pkg/compose/hash_test.go index 0520d6cee..73b7f3877 100644 --- a/pkg/compose/hash_test.go +++ b/pkg/compose/hash_test.go @@ -19,7 +19,7 @@ package compose import ( "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "gotest.tools/v3/assert" ) @@ -31,9 +31,9 @@ func TestServiceHash(t *testing.T) { assert.Equal(t, hash1, hash2) } -func serviceConfig(replicas uint64) types.ServiceConfig { +func serviceConfig(replicas int) types.ServiceConfig { return types.ServiceConfig{ - Scale: int(replicas), + Scale: &replicas, Deploy: &types.DeployConfig{ Replicas: &replicas, }, diff --git a/pkg/compose/image_pruner.go b/pkg/compose/image_pruner.go index 26c1bcb10..e29406795 100644 --- a/pkg/compose/image_pruner.go +++ b/pkg/compose/image_pruner.go @@ -22,7 +22,7 @@ import ( "sort" "sync" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/distribution/reference" moby "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" diff --git a/pkg/compose/logs_test.go b/pkg/compose/logs_test.go index 9a96e34de..d60d7c401 100644 --- a/pkg/compose/logs_test.go +++ b/pkg/compose/logs_test.go @@ -23,7 +23,7 @@ import ( "sync" "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" diff --git a/pkg/compose/publish.go b/pkg/compose/publish.go index 7658c0d48..1608ff42a 100644 --- a/pkg/compose/publish.go +++ b/pkg/compose/publish.go @@ -20,7 +20,7 @@ import ( "context" "os" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/distribution/reference" "github.com/docker/buildx/util/imagetools" "github.com/docker/compose/v2/internal/ocipush" @@ -122,12 +122,13 @@ func (s *composeService) generateImageDigestsOverride(ctx context.Context, proje if err != nil { return nil, err } - override := types.Project{} - for _, service := range project.Services { - override.Services = append(override.Services, types.ServiceConfig{ - Name: service.Name, + override := types.Project{ + Services: types.Services{}, + } + for name, service := range project.Services { + override.Services[name] = types.ServiceConfig{ Image: service.Image, - }) + } } return override.MarshalYAML() } diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index 75fd3375b..be9f83e19 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -25,7 +25,7 @@ import ( "io" "strings" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/distribution/reference" "github.com/docker/buildx/driver" moby "github.com/docker/docker/api/types" diff --git a/pkg/compose/push.go b/pkg/compose/push.go index c9f0ebf8d..934eecde6 100644 --- a/pkg/compose/push.go +++ b/pkg/compose/push.go @@ -25,7 +25,7 @@ import ( "io" "strings" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/distribution/reference" "github.com/docker/buildx/driver" moby "github.com/docker/docker/api/types" diff --git a/pkg/compose/restart.go b/pkg/compose/restart.go index db27b1fba..0a93813ed 100644 --- a/pkg/compose/restart.go +++ b/pkg/compose/restart.go @@ -20,7 +20,7 @@ import ( "context" "strings" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/progress" "github.com/docker/compose/v2/pkg/utils" diff --git a/pkg/compose/run.go b/pkg/compose/run.go index 05c5c2ba1..aca15f380 100644 --- a/pkg/compose/run.go +++ b/pkg/compose/run.go @@ -23,7 +23,7 @@ import ( "os" "os/signal" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli" cmd "github.com/docker/cli/cli/command/container" "github.com/docker/compose/v2/pkg/api" @@ -73,7 +73,8 @@ func (s *composeService) prepareRun(ctx context.Context, project *types.Project, if service.ContainerName == "" { service.ContainerName = fmt.Sprintf("%[1]s%[4]s%[2]s%[4]srun%[4]s%[3]s", project.Name, service.Name, stringid.TruncateID(slug), api.Separator) } - service.Scale = 1 + one := 1 + service.Scale = &one service.Restart = "" if service.Deploy != nil { service.Deploy.RestartPolicy = nil diff --git a/pkg/compose/scale.go b/pkg/compose/scale.go index c143b56d8..1e869ea72 100644 --- a/pkg/compose/scale.go +++ b/pkg/compose/scale.go @@ -18,7 +18,7 @@ package compose import ( "context" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/internal/tracing" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/progress" diff --git a/pkg/compose/secrets.go b/pkg/compose/secrets.go index e5570d320..5619d92f5 100644 --- a/pkg/compose/secrets.go +++ b/pkg/compose/secrets.go @@ -24,7 +24,7 @@ import ( "strconv" "time" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" ) diff --git a/pkg/compose/start.go b/pkg/compose/start.go index 1333b5cec..dd35a2e94 100644 --- a/pkg/compose/start.go +++ b/pkg/compose/start.go @@ -30,7 +30,7 @@ import ( "github.com/docker/compose/v2/pkg/progress" "github.com/docker/compose/v2/pkg/utils" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" moby "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "golang.org/x/sync/errgroup" diff --git a/pkg/compose/up.go b/pkg/compose/up.go index 6b168e780..fb54a5965 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -23,7 +23,7 @@ import ( "os/signal" "syscall" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli" "github.com/docker/compose/v2/internal/tracing" "github.com/docker/compose/v2/pkg/api" diff --git a/pkg/compose/viz.go b/pkg/compose/viz.go index 25ea7a2be..3fd5a2386 100644 --- a/pkg/compose/viz.go +++ b/pkg/compose/viz.go @@ -21,7 +21,7 @@ import ( "strconv" "strings" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" ) @@ -30,13 +30,13 @@ type vizGraph map[*types.ServiceConfig][]*types.ServiceConfig func (s *composeService) Viz(_ context.Context, project *types.Project, opts api.VizOptions) (string, error) { graph := make(vizGraph) - for i, serviceConfig := range project.Services { - serviceConfigPtr := &project.Services[i] - graph[serviceConfigPtr] = make([]*types.ServiceConfig, 0, len(serviceConfig.DependsOn)) - for dependencyName := range serviceConfig.DependsOn { + for _, service := range project.Services { + service := service + graph[&service] = make([]*types.ServiceConfig, 0, len(service.DependsOn)) + for dependencyName := range service.DependsOn { // no error should be returned since dependencyName should exist dependency, _ := project.GetService(dependencyName) - graph[serviceConfigPtr] = append(graph[serviceConfigPtr], &dependency) + graph[&service] = append(graph[&service], &dependency) } } diff --git a/pkg/compose/viz_test.go b/pkg/compose/viz_test.go index 9e5fb7312..26cc6185c 100644 --- a/pkg/compose/viz_test.go +++ b/pkg/compose/viz_test.go @@ -21,7 +21,7 @@ import ( "strconv" "testing" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" diff --git a/pkg/compose/watch.go b/pkg/compose/watch.go index a3961b793..288bc2f85 100644 --- a/pkg/compose/watch.go +++ b/pkg/compose/watch.go @@ -27,7 +27,7 @@ import ( "strings" "time" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/internal/sync" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/watch" diff --git a/pkg/compose/watch_test.go b/pkg/compose/watch_test.go index 4f8d674d4..2c9511067 100644 --- a/pkg/compose/watch_test.go +++ b/pkg/compose/watch_test.go @@ -20,7 +20,7 @@ import ( "testing" "time" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/internal/sync" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/mocks" diff --git a/pkg/e2e/scale_test.go b/pkg/e2e/scale_test.go index c17751d96..1cd80ad1d 100644 --- a/pkg/e2e/scale_test.go +++ b/pkg/e2e/scale_test.go @@ -40,18 +40,21 @@ func TestScaleBasicCases(t *testing.T) { t.Log("scale up one service") res = c.RunDockerComposeCmd(t, "--project-directory", "fixtures/scale", "scale", "dbadmin=2") - checkServiceContainer(t, res.Combined(), "scale-basic-tests-dbadmin", "Started", 2) + out := res.Combined() + checkServiceContainer(t, out, "scale-basic-tests-dbadmin", "Started", 2) t.Log("scale up 2 services") res = c.RunDockerComposeCmd(t, "--project-directory", "fixtures/scale", "scale", "front=3", "back=2") - checkServiceContainer(t, res.Combined(), "scale-basic-tests-front", "Running", 2) - checkServiceContainer(t, res.Combined(), "scale-basic-tests-front", "Started", 1) - checkServiceContainer(t, res.Combined(), "scale-basic-tests-back", "Running", 1) - checkServiceContainer(t, res.Combined(), "scale-basic-tests-back", "Started", 1) + out = res.Combined() + checkServiceContainer(t, out, "scale-basic-tests-front", "Running", 2) + checkServiceContainer(t, out, "scale-basic-tests-front", "Started", 1) + checkServiceContainer(t, out, "scale-basic-tests-back", "Running", 1) + checkServiceContainer(t, out, "scale-basic-tests-back", "Started", 1) t.Log("scale down one service") res = c.RunDockerComposeCmd(t, "--project-directory", "fixtures/scale", "scale", "dbadmin=1") - checkServiceContainer(t, res.Combined(), "scale-basic-tests-dbadmin", "Running", 1) + out = res.Combined() + checkServiceContainer(t, out, "scale-basic-tests-dbadmin", "Running", 1) t.Log("scale to 0 a service") res = c.RunDockerComposeCmd(t, "--project-directory", "fixtures/scale", "scale", "dbadmin=0") @@ -59,9 +62,10 @@ func TestScaleBasicCases(t *testing.T) { t.Log("scale down 2 services") res = c.RunDockerComposeCmd(t, "--project-directory", "fixtures/scale", "scale", "front=2", "back=1") - checkServiceContainer(t, res.Combined(), "scale-basic-tests-front", "Running", 2) - assert.Check(t, !strings.Contains(res.Combined(), "Container scale-basic-tests-front-3 Running"), res.Combined()) - checkServiceContainer(t, res.Combined(), "scale-basic-tests-back", "Running", 1) + out = res.Combined() + checkServiceContainer(t, out, "scale-basic-tests-front", "Running", 2) + assert.Check(t, !strings.Contains(out, "Container scale-basic-tests-front-3 Running"), res.Combined()) + checkServiceContainer(t, out, "scale-basic-tests-back", "Running", 1) } func TestScaleWithDepsCases(t *testing.T) { diff --git a/pkg/mocks/mock_docker_compose_api.go b/pkg/mocks/mock_docker_compose_api.go index 7eb0f7d4b..20e23cf7b 100644 --- a/pkg/mocks/mock_docker_compose_api.go +++ b/pkg/mocks/mock_docker_compose_api.go @@ -8,7 +8,7 @@ import ( context "context" reflect "reflect" - types "github.com/compose-spec/compose-go/types" + types "github.com/compose-spec/compose-go/v2/types" api "github.com/docker/compose/v2/pkg/api" gomock "github.com/golang/mock/gomock" ) diff --git a/pkg/remote/git.go b/pkg/remote/git.go index 4c3388630..4d42007cc 100644 --- a/pkg/remote/git.go +++ b/pkg/remote/git.go @@ -25,9 +25,9 @@ import ( "regexp" "strconv" - "github.com/compose-spec/compose-go/cli" - "github.com/compose-spec/compose-go/loader" - "github.com/compose-spec/compose-go/types" + "github.com/compose-spec/compose-go/v2/cli" + "github.com/compose-spec/compose-go/v2/loader" + "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/moby/buildkit/util/gitutil" ) diff --git a/pkg/remote/oci.go b/pkg/remote/oci.go index 3c8b2c995..d8e64509c 100644 --- a/pkg/remote/oci.go +++ b/pkg/remote/oci.go @@ -25,7 +25,7 @@ import ( "strconv" "strings" - "github.com/compose-spec/compose-go/loader" + "github.com/compose-spec/compose-go/v2/loader" "github.com/distribution/reference" "github.com/docker/buildx/store/storeutil" "github.com/docker/buildx/util/imagetools"