Skip to content

Commit

Permalink
project.Services is a map
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Nov 30, 2023
1 parent d04699b commit 33951a4
Show file tree
Hide file tree
Showing 25 changed files with 120 additions and 124 deletions.
1 change: 0 additions & 1 deletion cmd/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"strings"

"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"
Expand Down
8 changes: 4 additions & 4 deletions cmd/compose/compose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ import (
func TestFilterServices(t *testing.T) {
p := &types.Project{
Services: types.Services{
{
"foo": {
Name: "foo",
Links: []string{"bar"},
},
{
"bar": {
Name: "bar",
DependsOn: map[string]types.ServiceDependency{
"zot": {},
},
},
{
"zot": {
Name: "zot",
},
{
"qix": {
Name: "qix",
},
},
Expand Down
2 changes: 1 addition & 1 deletion cmd/compose/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func sampleProject() *types.Project {
return &types.Project{
Name: "test",
Services: types.Services{
{
"svc": {
Name: "svc",
Build: &types.BuildConfig{
Context: ".",
Expand Down
5 changes: 1 addition & 4 deletions cmd/compose/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ import (

func applyPlatforms(project *types.Project, buildForSinglePlatform bool) error {
defaultPlatform := project.Environment["DOCKER_DEFAULT_PLATFORM"]
for i := range project.Services {
// mutable reference so platform fields can be updated
service := &project.Services[i]

for _, service := range project.Services {
if service.Build == nil {
continue
}
Expand Down
14 changes: 7 additions & 7 deletions cmd/compose/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestApplyPlatforms_InferFromRuntime(t *testing.T) {
makeProject := func() *types.Project {
return &types.Project{
Services: types.Services{
{
"test": {
Name: "test",
Image: "foo",
Build: &types.BuildConfig{
Expand All @@ -47,14 +47,14 @@ func TestApplyPlatforms_InferFromRuntime(t *testing.T) {
t.Run("SinglePlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, true))
require.EqualValues(t, []string{"alice/32"}, project.Services[0].Build.Platforms)
require.EqualValues(t, []string{"alice/32"}, project.Services["test"].Build.Platforms)
})

t.Run("MultiPlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, false))
require.EqualValues(t, []string{"linux/amd64", "linux/arm64", "alice/32"},
project.Services[0].Build.Platforms)
project.Services["test"].Build.Platforms)
})
}

Expand All @@ -65,7 +65,7 @@ func TestApplyPlatforms_DockerDefaultPlatform(t *testing.T) {
"DOCKER_DEFAULT_PLATFORM": "linux/amd64",
},
Services: types.Services{
{
"test": {
Name: "test",
Image: "foo",
Build: &types.BuildConfig{
Expand All @@ -83,14 +83,14 @@ func TestApplyPlatforms_DockerDefaultPlatform(t *testing.T) {
t.Run("SinglePlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, true))
require.EqualValues(t, []string{"linux/amd64"}, project.Services[0].Build.Platforms)
require.EqualValues(t, []string{"linux/amd64"}, project.Services["test"].Build.Platforms)
})

t.Run("MultiPlatform", func(t *testing.T) {
project := makeProject()
require.NoError(t, applyPlatforms(project, false))
require.EqualValues(t, []string{"linux/amd64", "linux/arm64"},
project.Services[0].Build.Platforms)
project.Services["test"].Build.Platforms)
})
}

Expand All @@ -101,7 +101,7 @@ func TestApplyPlatforms_UnsupportedPlatform(t *testing.T) {
"DOCKER_DEFAULT_PLATFORM": "commodore/64",
},
Services: types.Services{
{
"foo": {
Name: "test",
Image: "foo",
Build: &types.BuildConfig{
Expand Down
12 changes: 6 additions & 6 deletions cmd/compose/pullOptions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ import (
func TestApplyPullOptions(t *testing.T) {
project := &types.Project{
Services: types.Services{
{
"must-build": {
Name: "must-build",
// No image, local build only
Build: &types.BuildConfig{
Context: ".",
},
},
{
"has-build": {
Name: "has-build",
Image: "registry.example.com/myservice",
Build: &types.BuildConfig{
Context: ".",
},
},
{
"must-pull": {
Name: "must-pull",
Image: "registry.example.com/another-service",
},
Expand All @@ -51,7 +51,7 @@ func TestApplyPullOptions(t *testing.T) {
}.apply(project, nil)
assert.NilError(t, err)

assert.Equal(t, project.Services[0].PullPolicy, "") // still default
assert.Equal(t, project.Services[1].PullPolicy, types.PullPolicyMissing)
assert.Equal(t, project.Services[2].PullPolicy, types.PullPolicyMissing)
assert.Equal(t, project.Services["must-build"].PullPolicy, "") // still default
assert.Equal(t, project.Services["has-build"].PullPolicy, types.PullPolicyMissing)
assert.Equal(t, project.Services["must-pull"].PullPolicy, types.PullPolicyMissing)
}
6 changes: 3 additions & 3 deletions cmd/compose/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,16 +300,16 @@ func runRun(ctx context.Context, backend api.Service, project *types.Project, op
func startDependencies(ctx context.Context, backend api.Service, project types.Project, buildOpts *api.BuildOptions, requestedServiceName string, ignoreOrphans bool) error {
dependencies := types.Services{}
var requestedService types.ServiceConfig
for _, service := range project.Services {
for name, service := range project.Services {
if service.Name != requestedServiceName {
dependencies = append(dependencies, service)
dependencies[name] = service
} else {
requestedService = service
}
}

project.Services = dependencies
project.DisabledServices = append(project.DisabledServices, requestedService)
project.DisabledServices[requestedServiceName] = requestedService
err := backend.Create(ctx, &project, api.CreateOptions{
Build: buildOpts,
IgnoreOrphans: ignoreOrphans,
Expand Down
4 changes: 2 additions & 2 deletions cmd/compose/up_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ import (
func TestApplyScaleOpt(t *testing.T) {
p := types.Project{
Services: types.Services{
{
"foo": {
Name: "foo",
},
{
"bar": {
Name: "bar",
Deploy: &types.DeployConfig{
Mode: "test",
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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/v2 v2.0.0-20231121074112-593b77722992
github.com/compose-spec/compose-go/v2 v2.0.0-20231123162526-11ef9572f1a4
github.com/containerd/console v1.0.3
github.com/containerd/containerd v1.7.7
github.com/davecgh/go-spew v1.1.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,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/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/compose-spec/compose-go/v2 v2.0.0-20231123162526-11ef9572f1a4 h1:Lr78By808iuG+2gTyxIDslRpKQCk/lcRqElKsrhzp+U=
github.com/compose-spec/compose-go/v2 v2.0.0-20231123162526-11ef9572f1a4/go.mod h1:PWCgeD8cxiI/DmdpBM407CuLDrZ2W4xuS6/Z9jAi0YQ=
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=
Expand Down
7 changes: 1 addition & 6 deletions internal/tracing/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,12 @@ func ProjectOptions(proj *types.Project) SpanOptions {
return nil
}

disabledServiceNames := make([]string, len(proj.DisabledServices))
for i := range proj.DisabledServices {
disabledServiceNames[i] = proj.DisabledServices[i].Name
}

attrs := []attribute.KeyValue{
attribute.String("project.name", proj.Name),
attribute.String("project.dir", proj.WorkingDir),
attribute.StringSlice("project.compose_files", proj.ComposeFiles),
attribute.StringSlice("project.services.active", proj.ServiceNames()),
attribute.StringSlice("project.services.disabled", disabledServiceNames),
attribute.StringSlice("project.services.disabled", proj.DisabledServiceNames()),
attribute.StringSlice("project.profiles", proj.Profiles),
attribute.StringSlice("project.volumes", proj.VolumeNames()),
attribute.StringSlice("project.networks", proj.NetworkNames()),
Expand Down
45 changes: 21 additions & 24 deletions pkg/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
}

type serviceToBuild struct {
idx int
name string
service types.ServiceConfig
}

Expand All @@ -85,7 +85,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
return nil
}
service, idx := getServiceIndex(project, name)
service := project.Services[name]

if service.Build == nil {
return nil
Expand All @@ -97,7 +97,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
return nil
}
mapServiceMutx.Lock()
serviceToBeBuild[name] = serviceToBuild{idx: idx, service: service}
serviceToBeBuild[name] = serviceToBuild{name: name, service: service}
mapServiceMutx.Unlock()
return nil
}, func(traversal *graphTraversal) {
Expand Down Expand Up @@ -146,7 +146,17 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
}
}

// we use a pre-allocated []string to collect build digest by service index while running concurrent goroutines
builtDigests := make([]string, len(project.Services))
names := project.ServiceNames()
getServiceIndex := func(name string) int {
for idx, n := range names {
if n == name {
return idx
}
}
return -1
}
err = InDependencyOrder(ctx, project, func(ctx context.Context, name string) error {
if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
return nil
Expand All @@ -156,14 +166,13 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
return nil
}
service := serviceToBuild.service
idx := serviceToBuild.idx

if !buildkitEnabled {
id, err := s.doBuildClassic(ctx, project, service, options)
if err != nil {
return err
}
builtDigests[idx] = id
builtDigests[getServiceIndex(name)] = id

if options.Push {
return s.push(ctx, project, api.PushOptions{})
Expand All @@ -184,7 +193,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
if err != nil {
return err
}
builtDigests[idx] = digest
builtDigests[getServiceIndex(name)] = digest

return nil
}, func(traversal *graphTraversal) {
Expand All @@ -204,25 +213,13 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti

for i, imageDigest := range builtDigests {
if imageDigest != "" {
imageRef := api.GetImageNameOrDefault(project.Services[i], project.Name)
imageRef := api.GetImageNameOrDefault(project.Services[names[i]], project.Name)
imageIDs[imageRef] = imageDigest
}
}
return imageIDs, err
}

func getServiceIndex(project *types.Project, name string) (types.ServiceConfig, int) {
var service types.ServiceConfig
var idx int
for i, s := range project.Services {
if s.Name == name {
idx, service = i, s
break
}
}
return service, idx
}

func (s *composeService) ensureImagesExists(ctx context.Context, project *types.Project, buildOpts *api.BuildOptions, quietPull bool) error {
for _, service := range project.Services {
if service.Image == "" && service.Build == nil {
Expand Down Expand Up @@ -264,14 +261,14 @@ func (s *composeService) ensureImagesExists(ctx context.Context, project *types.
}

// set digest as com.docker.compose.image label so we can detect outdated containers
for i, service := range project.Services {
for _, service := range project.Services {
image := api.GetImageNameOrDefault(service, project.Name)
digest, ok := images[image]
if ok {
if project.Services[i].Labels == nil {
project.Services[i].Labels = types.Labels{}
if service.Labels == nil {
service.Labels = types.Labels{}
}
project.Services[i].CustomLabels.Add(api.ImageDigestLabel, digest)
service.CustomLabels.Add(api.ImageDigestLabel, digest)
}
}
return nil
Expand Down Expand Up @@ -440,7 +437,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
Platforms: plats,
Labels: imageLabels,
NetworkMode: service.Build.Network,
ExtraHosts: service.Build.ExtraHosts.AsList(),
ExtraHosts: service.Build.ExtraHosts.AsList(":"),
Ulimits: toUlimitOpt(service.Build.Ulimits),
Session: sessionConfig,
Allow: allow,
Expand Down
2 changes: 1 addition & 1 deletion pkg/compose/build_classic.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func imageBuildOptions(dockerCli command.Cli, project *types.Project, service ty
BuildArgs: resolveAndMergeBuildArgs(dockerCli, project, service, options),
Labels: config.Labels,
NetworkMode: config.Network,
ExtraHosts: config.ExtraHosts.AsList(),
ExtraHosts: config.ExtraHosts.AsList(":"),
Target: config.Target,
Isolation: container.Isolation(config.Isolation),
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/compose/compose.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
if len(containers) == 0 {
return project, fmt.Errorf("no container found for project %q: %w", projectName, api.ErrNotFound)
}
set := map[string]types.ServiceConfig{}
set := types.Services{}
for _, c := range containers {
serviceLabel := c.Labels[api.ServiceLabel]
service, ok := set[serviceLabel]
Expand All @@ -197,7 +197,7 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
}
service.Scale = increment(service.Scale)
}
for _, service := range set {
for name, service := range set {
dependencies := service.Labels[api.DependenciesLabel]
if len(dependencies) > 0 {
service.DependsOn = types.DependsOnConfig{}
Expand All @@ -218,9 +218,11 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
}
service.DependsOn[dependency] = types.ServiceDependency{Condition: condition, Restart: restart, Required: required}
}
set[name] = service
}
project.Services = append(project.Services, service)
}
project.Services = set

SERVICES:
for _, qs := range services {
for _, es := range project.Services {
Expand Down
Loading

0 comments on commit 33951a4

Please sign in to comment.