mirror of https://github.com/docker/compose.git
project.Services is a map
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
cda04f288e
commit
138facea62
|
@ -23,7 +23,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/v2/cli"
|
"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/compose-spec/compose-go/v2/types"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
cliopts "github.com/docker/cli/opts"
|
cliopts "github.com/docker/cli/opts"
|
||||||
|
|
|
@ -26,20 +26,20 @@ import (
|
||||||
func TestFilterServices(t *testing.T) {
|
func TestFilterServices(t *testing.T) {
|
||||||
p := &types.Project{
|
p := &types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"foo": {
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Links: []string{"bar"},
|
Links: []string{"bar"},
|
||||||
},
|
},
|
||||||
{
|
"bar": {
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
DependsOn: map[string]types.ServiceDependency{
|
DependsOn: map[string]types.ServiceDependency{
|
||||||
"zot": {},
|
"zot": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"zot": {
|
||||||
Name: "zot",
|
Name: "zot",
|
||||||
},
|
},
|
||||||
{
|
"qix": {
|
||||||
Name: "qix",
|
Name: "qix",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -86,7 +86,7 @@ func sampleProject() *types.Project {
|
||||||
return &types.Project{
|
return &types.Project{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"svc": {
|
||||||
Name: "svc",
|
Name: "svc",
|
||||||
Build: &types.BuildConfig{
|
Build: &types.BuildConfig{
|
||||||
Context: ".",
|
Context: ".",
|
||||||
|
|
|
@ -25,10 +25,7 @@ import (
|
||||||
|
|
||||||
func applyPlatforms(project *types.Project, buildForSinglePlatform bool) error {
|
func applyPlatforms(project *types.Project, buildForSinglePlatform bool) error {
|
||||||
defaultPlatform := project.Environment["DOCKER_DEFAULT_PLATFORM"]
|
defaultPlatform := project.Environment["DOCKER_DEFAULT_PLATFORM"]
|
||||||
for i := range project.Services {
|
for _, service := range project.Services {
|
||||||
// mutable reference so platform fields can be updated
|
|
||||||
service := &project.Services[i]
|
|
||||||
|
|
||||||
if service.Build == nil {
|
if service.Build == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ func TestApplyPlatforms_InferFromRuntime(t *testing.T) {
|
||||||
makeProject := func() *types.Project {
|
makeProject := func() *types.Project {
|
||||||
return &types.Project{
|
return &types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"test": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Image: "foo",
|
Image: "foo",
|
||||||
Build: &types.BuildConfig{
|
Build: &types.BuildConfig{
|
||||||
|
@ -47,14 +47,14 @@ func TestApplyPlatforms_InferFromRuntime(t *testing.T) {
|
||||||
t.Run("SinglePlatform", func(t *testing.T) {
|
t.Run("SinglePlatform", func(t *testing.T) {
|
||||||
project := makeProject()
|
project := makeProject()
|
||||||
require.NoError(t, applyPlatforms(project, true))
|
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) {
|
t.Run("MultiPlatform", func(t *testing.T) {
|
||||||
project := makeProject()
|
project := makeProject()
|
||||||
require.NoError(t, applyPlatforms(project, false))
|
require.NoError(t, applyPlatforms(project, false))
|
||||||
require.EqualValues(t, []string{"linux/amd64", "linux/arm64", "alice/32"},
|
require.EqualValues(t, []string{"linux/amd64", "linux/arm64", "alice/32"},
|
||||||
project.Services[0].Build.Platforms)
|
project.Services["test"].Build.Platforms)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ func TestApplyPlatforms_DockerDefaultPlatform(t *testing.T) {
|
||||||
"DOCKER_DEFAULT_PLATFORM": "linux/amd64",
|
"DOCKER_DEFAULT_PLATFORM": "linux/amd64",
|
||||||
},
|
},
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"test": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Image: "foo",
|
Image: "foo",
|
||||||
Build: &types.BuildConfig{
|
Build: &types.BuildConfig{
|
||||||
|
@ -83,14 +83,14 @@ func TestApplyPlatforms_DockerDefaultPlatform(t *testing.T) {
|
||||||
t.Run("SinglePlatform", func(t *testing.T) {
|
t.Run("SinglePlatform", func(t *testing.T) {
|
||||||
project := makeProject()
|
project := makeProject()
|
||||||
require.NoError(t, applyPlatforms(project, true))
|
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) {
|
t.Run("MultiPlatform", func(t *testing.T) {
|
||||||
project := makeProject()
|
project := makeProject()
|
||||||
require.NoError(t, applyPlatforms(project, false))
|
require.NoError(t, applyPlatforms(project, false))
|
||||||
require.EqualValues(t, []string{"linux/amd64", "linux/arm64"},
|
require.EqualValues(t, []string{"linux/amd64", "linux/arm64"},
|
||||||
project.Services[0].Build.Platforms)
|
project.Services["test"].Build.Platforms)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ func TestApplyPlatforms_UnsupportedPlatform(t *testing.T) {
|
||||||
"DOCKER_DEFAULT_PLATFORM": "commodore/64",
|
"DOCKER_DEFAULT_PLATFORM": "commodore/64",
|
||||||
},
|
},
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"foo": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Image: "foo",
|
Image: "foo",
|
||||||
Build: &types.BuildConfig{
|
Build: &types.BuildConfig{
|
||||||
|
|
|
@ -26,21 +26,21 @@ import (
|
||||||
func TestApplyPullOptions(t *testing.T) {
|
func TestApplyPullOptions(t *testing.T) {
|
||||||
project := &types.Project{
|
project := &types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"must-build": {
|
||||||
Name: "must-build",
|
Name: "must-build",
|
||||||
// No image, local build only
|
// No image, local build only
|
||||||
Build: &types.BuildConfig{
|
Build: &types.BuildConfig{
|
||||||
Context: ".",
|
Context: ".",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"has-build": {
|
||||||
Name: "has-build",
|
Name: "has-build",
|
||||||
Image: "registry.example.com/myservice",
|
Image: "registry.example.com/myservice",
|
||||||
Build: &types.BuildConfig{
|
Build: &types.BuildConfig{
|
||||||
Context: ".",
|
Context: ".",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"must-pull": {
|
||||||
Name: "must-pull",
|
Name: "must-pull",
|
||||||
Image: "registry.example.com/another-service",
|
Image: "registry.example.com/another-service",
|
||||||
},
|
},
|
||||||
|
@ -51,7 +51,7 @@ func TestApplyPullOptions(t *testing.T) {
|
||||||
}.apply(project, nil)
|
}.apply(project, nil)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
|
|
||||||
assert.Equal(t, project.Services[0].PullPolicy, "") // still default
|
assert.Equal(t, project.Services["must-build"].PullPolicy, "") // still default
|
||||||
assert.Equal(t, project.Services[1].PullPolicy, types.PullPolicyMissing)
|
assert.Equal(t, project.Services["has-build"].PullPolicy, types.PullPolicyMissing)
|
||||||
assert.Equal(t, project.Services[2].PullPolicy, types.PullPolicyMissing)
|
assert.Equal(t, project.Services["must-pull"].PullPolicy, types.PullPolicyMissing)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
func startDependencies(ctx context.Context, backend api.Service, project types.Project, buildOpts *api.BuildOptions, requestedServiceName string, ignoreOrphans bool) error {
|
||||||
dependencies := types.Services{}
|
dependencies := types.Services{}
|
||||||
var requestedService types.ServiceConfig
|
var requestedService types.ServiceConfig
|
||||||
for _, service := range project.Services {
|
for name, service := range project.Services {
|
||||||
if service.Name != requestedServiceName {
|
if service.Name != requestedServiceName {
|
||||||
dependencies = append(dependencies, service)
|
dependencies[name] = service
|
||||||
} else {
|
} else {
|
||||||
requestedService = service
|
requestedService = service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project.Services = dependencies
|
project.Services = dependencies
|
||||||
project.DisabledServices = append(project.DisabledServices, requestedService)
|
project.DisabledServices[requestedServiceName] = requestedService
|
||||||
err := backend.Create(ctx, &project, api.CreateOptions{
|
err := backend.Create(ctx, &project, api.CreateOptions{
|
||||||
Build: buildOpts,
|
Build: buildOpts,
|
||||||
IgnoreOrphans: ignoreOrphans,
|
IgnoreOrphans: ignoreOrphans,
|
||||||
|
|
|
@ -26,10 +26,10 @@ import (
|
||||||
func TestApplyScaleOpt(t *testing.T) {
|
func TestApplyScaleOpt(t *testing.T) {
|
||||||
p := types.Project{
|
p := types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"foo": {
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
},
|
},
|
||||||
{
|
"bar": {
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Deploy: &types.DeployConfig{
|
Deploy: &types.DeployConfig{
|
||||||
Mode: "test",
|
Mode: "test",
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -6,7 +6,7 @@ require (
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
github.com/Microsoft/go-winio v0.6.1
|
github.com/Microsoft/go-winio v0.6.1
|
||||||
github.com/buger/goterm v1.0.4
|
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/console v1.0.3
|
||||||
github.com/containerd/containerd v1.7.7
|
github.com/containerd/containerd v1.7.7
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
|
|
4
go.sum
4
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/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 h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
|
||||||
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
|
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-20231123162526-11ef9572f1a4 h1:Lr78By808iuG+2gTyxIDslRpKQCk/lcRqElKsrhzp+U=
|
||||||
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/go.mod h1:PWCgeD8cxiI/DmdpBM407CuLDrZ2W4xuS6/Z9jAi0YQ=
|
||||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
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/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||||
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=
|
||||||
|
|
|
@ -58,17 +58,12 @@ func ProjectOptions(proj *types.Project) SpanOptions {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
disabledServiceNames := make([]string, len(proj.DisabledServices))
|
|
||||||
for i := range proj.DisabledServices {
|
|
||||||
disabledServiceNames[i] = proj.DisabledServices[i].Name
|
|
||||||
}
|
|
||||||
|
|
||||||
attrs := []attribute.KeyValue{
|
attrs := []attribute.KeyValue{
|
||||||
attribute.String("project.name", proj.Name),
|
attribute.String("project.name", proj.Name),
|
||||||
attribute.String("project.dir", proj.WorkingDir),
|
attribute.String("project.dir", proj.WorkingDir),
|
||||||
attribute.StringSlice("project.compose_files", proj.ComposeFiles),
|
attribute.StringSlice("project.compose_files", proj.ComposeFiles),
|
||||||
attribute.StringSlice("project.services.active", proj.ServiceNames()),
|
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.profiles", proj.Profiles),
|
||||||
attribute.StringSlice("project.volumes", proj.VolumeNames()),
|
attribute.StringSlice("project.volumes", proj.VolumeNames()),
|
||||||
attribute.StringSlice("project.networks", proj.NetworkNames()),
|
attribute.StringSlice("project.networks", proj.NetworkNames()),
|
||||||
|
|
|
@ -67,7 +67,7 @@ func (s *composeService) Build(ctx context.Context, project *types.Project, opti
|
||||||
}
|
}
|
||||||
|
|
||||||
type serviceToBuild struct {
|
type serviceToBuild struct {
|
||||||
idx int
|
name string
|
||||||
service types.ServiceConfig
|
service types.ServiceConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
service, idx := getServiceIndex(project, name)
|
service := project.Services[name]
|
||||||
|
|
||||||
if service.Build == nil {
|
if service.Build == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -97,7 +97,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
mapServiceMutx.Lock()
|
mapServiceMutx.Lock()
|
||||||
serviceToBeBuild[name] = serviceToBuild{idx: idx, service: service}
|
serviceToBeBuild[name] = serviceToBuild{name: name, service: service}
|
||||||
mapServiceMutx.Unlock()
|
mapServiceMutx.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}, func(traversal *graphTraversal) {
|
}, func(traversal *graphTraversal) {
|
||||||
|
@ -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))
|
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 {
|
err = InDependencyOrder(ctx, project, func(ctx context.Context, name string) error {
|
||||||
if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
|
if len(options.Services) > 0 && !utils.Contains(options.Services, name) {
|
||||||
return nil
|
return nil
|
||||||
|
@ -156,14 +166,13 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
service := serviceToBuild.service
|
service := serviceToBuild.service
|
||||||
idx := serviceToBuild.idx
|
|
||||||
|
|
||||||
if !buildkitEnabled {
|
if !buildkitEnabled {
|
||||||
id, err := s.doBuildClassic(ctx, project, service, options)
|
id, err := s.doBuildClassic(ctx, project, service, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
builtDigests[idx] = id
|
builtDigests[getServiceIndex(name)] = id
|
||||||
|
|
||||||
if options.Push {
|
if options.Push {
|
||||||
return s.push(ctx, project, api.PushOptions{})
|
return s.push(ctx, project, api.PushOptions{})
|
||||||
|
@ -184,7 +193,7 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
builtDigests[idx] = digest
|
builtDigests[getServiceIndex(name)] = digest
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, func(traversal *graphTraversal) {
|
}, func(traversal *graphTraversal) {
|
||||||
|
@ -204,25 +213,13 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
||||||
|
|
||||||
for i, imageDigest := range builtDigests {
|
for i, imageDigest := range builtDigests {
|
||||||
if imageDigest != "" {
|
if imageDigest != "" {
|
||||||
imageRef := api.GetImageNameOrDefault(project.Services[i], project.Name)
|
imageRef := api.GetImageNameOrDefault(project.Services[names[i]], project.Name)
|
||||||
imageIDs[imageRef] = imageDigest
|
imageIDs[imageRef] = imageDigest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return imageIDs, err
|
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 {
|
func (s *composeService) ensureImagesExists(ctx context.Context, project *types.Project, buildOpts *api.BuildOptions, quietPull bool) error {
|
||||||
for _, service := range project.Services {
|
for _, service := range project.Services {
|
||||||
if service.Image == "" && service.Build == nil {
|
if service.Image == "" && service.Build == nil {
|
||||||
|
@ -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
|
// 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)
|
image := api.GetImageNameOrDefault(service, project.Name)
|
||||||
digest, ok := images[image]
|
digest, ok := images[image]
|
||||||
if ok {
|
if ok {
|
||||||
if project.Services[i].Labels == nil {
|
if service.Labels == nil {
|
||||||
project.Services[i].Labels = types.Labels{}
|
service.Labels = types.Labels{}
|
||||||
}
|
}
|
||||||
project.Services[i].CustomLabels.Add(api.ImageDigestLabel, digest)
|
service.CustomLabels.Add(api.ImageDigestLabel, digest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -440,7 +437,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se
|
||||||
Platforms: plats,
|
Platforms: plats,
|
||||||
Labels: imageLabels,
|
Labels: imageLabels,
|
||||||
NetworkMode: service.Build.Network,
|
NetworkMode: service.Build.Network,
|
||||||
ExtraHosts: service.Build.ExtraHosts.AsList(),
|
ExtraHosts: service.Build.ExtraHosts.AsList(":"),
|
||||||
Ulimits: toUlimitOpt(service.Build.Ulimits),
|
Ulimits: toUlimitOpt(service.Build.Ulimits),
|
||||||
Session: sessionConfig,
|
Session: sessionConfig,
|
||||||
Allow: allow,
|
Allow: allow,
|
||||||
|
|
|
@ -229,7 +229,7 @@ func imageBuildOptions(dockerCli command.Cli, project *types.Project, service ty
|
||||||
BuildArgs: resolveAndMergeBuildArgs(dockerCli, project, service, options),
|
BuildArgs: resolveAndMergeBuildArgs(dockerCli, project, service, options),
|
||||||
Labels: config.Labels,
|
Labels: config.Labels,
|
||||||
NetworkMode: config.Network,
|
NetworkMode: config.Network,
|
||||||
ExtraHosts: config.ExtraHosts.AsList(),
|
ExtraHosts: config.ExtraHosts.AsList(":"),
|
||||||
Target: config.Target,
|
Target: config.Target,
|
||||||
Isolation: container.Isolation(config.Isolation),
|
Isolation: container.Isolation(config.Isolation),
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
|
||||||
if len(containers) == 0 {
|
if len(containers) == 0 {
|
||||||
return project, fmt.Errorf("no container found for project %q: %w", projectName, api.ErrNotFound)
|
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 {
|
for _, c := range containers {
|
||||||
serviceLabel := c.Labels[api.ServiceLabel]
|
serviceLabel := c.Labels[api.ServiceLabel]
|
||||||
service, ok := set[serviceLabel]
|
service, ok := set[serviceLabel]
|
||||||
|
@ -197,7 +197,7 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
|
||||||
}
|
}
|
||||||
service.Scale = increment(service.Scale)
|
service.Scale = increment(service.Scale)
|
||||||
}
|
}
|
||||||
for _, service := range set {
|
for name, service := range set {
|
||||||
dependencies := service.Labels[api.DependenciesLabel]
|
dependencies := service.Labels[api.DependenciesLabel]
|
||||||
if len(dependencies) > 0 {
|
if len(dependencies) > 0 {
|
||||||
service.DependsOn = types.DependsOnConfig{}
|
service.DependsOn = types.DependsOnConfig{}
|
||||||
|
@ -218,9 +218,11 @@ func (s *composeService) projectFromName(containers Containers, projectName stri
|
||||||
}
|
}
|
||||||
service.DependsOn[dependency] = types.ServiceDependency{Condition: condition, Restart: restart, Required: required}
|
service.DependsOn[dependency] = types.ServiceDependency{Condition: condition, Restart: restart, Required: required}
|
||||||
}
|
}
|
||||||
|
set[name] = service
|
||||||
}
|
}
|
||||||
project.Services = append(project.Services, service)
|
|
||||||
}
|
}
|
||||||
|
project.Services = set
|
||||||
|
|
||||||
SERVICES:
|
SERVICES:
|
||||||
for _, qs := range services {
|
for _, qs := range services {
|
||||||
for _, es := range project.Services {
|
for _, es := range project.Services {
|
||||||
|
|
|
@ -227,7 +227,10 @@ func TestWaitDependencies(t *testing.T) {
|
||||||
t.Run("should skip dependencies with scale 0", func(t *testing.T) {
|
t.Run("should skip dependencies with scale 0", func(t *testing.T) {
|
||||||
dbService := types.ServiceConfig{Name: "db", Scale: intPtr(0)}
|
dbService := types.ServiceConfig{Name: "db", Scale: intPtr(0)}
|
||||||
redisService := types.ServiceConfig{Name: "redis", Scale: intPtr(0)}
|
redisService := types.ServiceConfig{Name: "redis", Scale: intPtr(0)}
|
||||||
project := types.Project{Name: strings.ToLower(testProject), Services: types.Services{dbService, redisService}}
|
project := types.Project{Name: strings.ToLower(testProject), Services: types.Services{
|
||||||
|
"db": dbService,
|
||||||
|
"redis": redisService,
|
||||||
|
}}
|
||||||
dependencies := types.DependsOnConfig{
|
dependencies := types.DependsOnConfig{
|
||||||
"db": {Condition: ServiceConditionRunningOrHealthy},
|
"db": {Condition: ServiceConditionRunningOrHealthy},
|
||||||
"redis": {Condition: ServiceConditionRunningOrHealthy},
|
"redis": {Condition: ServiceConditionRunningOrHealthy},
|
||||||
|
@ -237,7 +240,10 @@ func TestWaitDependencies(t *testing.T) {
|
||||||
t.Run("should skip dependencies with condition service_started", func(t *testing.T) {
|
t.Run("should skip dependencies with condition service_started", func(t *testing.T) {
|
||||||
dbService := types.ServiceConfig{Name: "db", Scale: intPtr(1)}
|
dbService := types.ServiceConfig{Name: "db", Scale: intPtr(1)}
|
||||||
redisService := types.ServiceConfig{Name: "redis", Scale: intPtr(1)}
|
redisService := types.ServiceConfig{Name: "redis", Scale: intPtr(1)}
|
||||||
project := types.Project{Name: strings.ToLower(testProject), Services: types.Services{dbService, redisService}}
|
project := types.Project{Name: strings.ToLower(testProject), Services: types.Services{
|
||||||
|
"db": dbService,
|
||||||
|
"redis": redisService,
|
||||||
|
}}
|
||||||
dependencies := types.DependsOnConfig{
|
dependencies := types.DependsOnConfig{
|
||||||
"db": {Condition: types.ServiceConditionStarted, Required: true},
|
"db": {Condition: types.ServiceConditionStarted, Required: true},
|
||||||
"redis": {Condition: types.ServiceConditionStarted, Required: true},
|
"redis": {Condition: types.ServiceConditionStarted, Required: true},
|
||||||
|
|
|
@ -94,11 +94,7 @@ func (s *composeService) create(ctx context.Context, project *types.Project, opt
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
allServices := project.AllServices()
|
allServiceNames := append(project.ServiceNames(), project.DisabledServiceNames()...)
|
||||||
allServiceNames := []string{}
|
|
||||||
for _, service := range allServices {
|
|
||||||
allServiceNames = append(allServiceNames, service.Name)
|
|
||||||
}
|
|
||||||
orphans := observedState.filter(isNotService(allServiceNames...))
|
orphans := observedState.filter(isNotService(allServiceNames...))
|
||||||
if len(orphans) > 0 && !options.IgnoreOrphans {
|
if len(orphans) > 0 && !options.IgnoreOrphans {
|
||||||
if options.RemoveOrphans {
|
if options.RemoveOrphans {
|
||||||
|
@ -263,7 +259,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
|
||||||
DNS: service.DNS,
|
DNS: service.DNS,
|
||||||
DNSSearch: service.DNSSearch,
|
DNSSearch: service.DNSSearch,
|
||||||
DNSOptions: service.DNSOpts,
|
DNSOptions: service.DNSOpts,
|
||||||
ExtraHosts: service.ExtraHosts.AsList(),
|
ExtraHosts: service.ExtraHosts.AsList(":"),
|
||||||
SecurityOpt: securityOpts,
|
SecurityOpt: securityOpts,
|
||||||
UsernsMode: container.UsernsMode(service.UserNSMode),
|
UsernsMode: container.UsernsMode(service.UserNSMode),
|
||||||
UTSMode: container.UTSMode(service.Uts),
|
UTSMode: container.UTSMode(service.Uts),
|
||||||
|
|
|
@ -101,8 +101,8 @@ func TestPrepareNetworkLabels(t *testing.T) {
|
||||||
func TestBuildContainerMountOptions(t *testing.T) {
|
func TestBuildContainerMountOptions(t *testing.T) {
|
||||||
project := composetypes.Project{
|
project := composetypes.Project{
|
||||||
Name: "myProject",
|
Name: "myProject",
|
||||||
Services: []composetypes.ServiceConfig{
|
Services: composetypes.Services{
|
||||||
{
|
"myService": {
|
||||||
Name: "myService",
|
Name: "myService",
|
||||||
Volumes: []composetypes.ServiceVolumeConfig{
|
Volumes: []composetypes.ServiceVolumeConfig{
|
||||||
{
|
{
|
||||||
|
@ -144,7 +144,7 @@ func TestBuildContainerMountOptions(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mounts, err := buildContainerMountOptions(project, project.Services[0], moby.ImageInspect{}, inherit)
|
mounts, err := buildContainerMountOptions(project, project.Services["myService"], moby.ImageInspect{}, inherit)
|
||||||
sort.Slice(mounts, func(i, j int) bool {
|
sort.Slice(mounts, func(i, j int) bool {
|
||||||
return mounts[i].Target < mounts[j].Target
|
return mounts[i].Target < mounts[j].Target
|
||||||
})
|
})
|
||||||
|
@ -154,7 +154,7 @@ func TestBuildContainerMountOptions(t *testing.T) {
|
||||||
assert.Equal(t, mounts[1].Target, "/var/myvolume2")
|
assert.Equal(t, mounts[1].Target, "/var/myvolume2")
|
||||||
assert.Equal(t, mounts[2].Target, "\\\\.\\pipe\\docker_engine")
|
assert.Equal(t, mounts[2].Target, "\\\\.\\pipe\\docker_engine")
|
||||||
|
|
||||||
mounts, err = buildContainerMountOptions(project, project.Services[0], moby.ImageInspect{}, inherit)
|
mounts, err = buildContainerMountOptions(project, project.Services["myService"], moby.ImageInspect{}, inherit)
|
||||||
sort.Slice(mounts, func(i, j int) bool {
|
sort.Slice(mounts, func(i, j int) bool {
|
||||||
return mounts[i].Target < mounts[j].Target
|
return mounts[i].Target < mounts[j].Target
|
||||||
})
|
})
|
||||||
|
@ -180,8 +180,8 @@ func TestDefaultNetworkSettings(t *testing.T) {
|
||||||
}
|
}
|
||||||
project := composetypes.Project{
|
project := composetypes.Project{
|
||||||
Name: "myProject",
|
Name: "myProject",
|
||||||
Services: []composetypes.ServiceConfig{
|
Services: composetypes.Services{
|
||||||
service,
|
"myService": service,
|
||||||
},
|
},
|
||||||
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{
|
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{
|
||||||
"myNetwork1": {
|
"myNetwork1": {
|
||||||
|
@ -205,8 +205,8 @@ func TestDefaultNetworkSettings(t *testing.T) {
|
||||||
}
|
}
|
||||||
project := composetypes.Project{
|
project := composetypes.Project{
|
||||||
Name: "myProject",
|
Name: "myProject",
|
||||||
Services: []composetypes.ServiceConfig{
|
Services: composetypes.Services{
|
||||||
service,
|
"myService": service,
|
||||||
},
|
},
|
||||||
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{
|
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{
|
||||||
"myNetwork1": {
|
"myNetwork1": {
|
||||||
|
@ -233,8 +233,8 @@ func TestDefaultNetworkSettings(t *testing.T) {
|
||||||
}
|
}
|
||||||
project := composetypes.Project{
|
project := composetypes.Project{
|
||||||
Name: "myProject",
|
Name: "myProject",
|
||||||
Services: []composetypes.ServiceConfig{
|
Services: composetypes.Services{
|
||||||
service,
|
"myService": service,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ func TestDefaultNetworkSettings(t *testing.T) {
|
||||||
}
|
}
|
||||||
project := composetypes.Project{
|
project := composetypes.Project{
|
||||||
Name: "myProject",
|
Name: "myProject",
|
||||||
Services: []composetypes.ServiceConfig{service},
|
Services: composetypes.Services{"myService": service},
|
||||||
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{
|
Networks: composetypes.Networks(map[string]composetypes.NetworkConfig{
|
||||||
"default": {
|
"default": {
|
||||||
Name: "myProject_default",
|
Name: "myProject_default",
|
||||||
|
|
|
@ -33,19 +33,19 @@ import (
|
||||||
func createTestProject() *types.Project {
|
func createTestProject() *types.Project {
|
||||||
return &types.Project{
|
return &types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"test1": {
|
||||||
Name: "test1",
|
Name: "test1",
|
||||||
DependsOn: map[string]types.ServiceDependency{
|
DependsOn: map[string]types.ServiceDependency{
|
||||||
"test2": {},
|
"test2": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"test2": {
|
||||||
Name: "test2",
|
Name: "test2",
|
||||||
DependsOn: map[string]types.ServiceDependency{
|
DependsOn: map[string]types.ServiceDependency{
|
||||||
"test3": {},
|
"test3": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"test3": {
|
||||||
Name: "test3",
|
Name: "test3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -59,7 +59,7 @@ func TestTraversalWithMultipleParents(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
project := types.Project{
|
project := types.Project{
|
||||||
Services: types.Services{dependent},
|
Services: types.Services{"dependent": dependent},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 1; i <= 100; i++ {
|
for i := 1; i <= 100; i++ {
|
||||||
|
@ -67,7 +67,7 @@ func TestTraversalWithMultipleParents(t *testing.T) {
|
||||||
dependent.DependsOn[name] = types.ServiceDependency{}
|
dependent.DependsOn[name] = types.ServiceDependency{}
|
||||||
|
|
||||||
svc := types.ServiceConfig{Name: name}
|
svc := types.ServiceConfig{Name: name}
|
||||||
project.Services = append(project.Services, svc)
|
project.Services[name] = svc
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
@ -132,7 +132,7 @@ func TestBuildGraph(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "builds graph with single service",
|
desc: "builds graph with single service",
|
||||||
services: types.Services{
|
services: types.Services{
|
||||||
{
|
"test": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
DependsOn: types.DependsOnConfig{},
|
DependsOn: types.DependsOnConfig{},
|
||||||
},
|
},
|
||||||
|
@ -150,11 +150,11 @@ func TestBuildGraph(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "builds graph with two separate services",
|
desc: "builds graph with two separate services",
|
||||||
services: types.Services{
|
services: types.Services{
|
||||||
{
|
"test": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
DependsOn: types.DependsOnConfig{},
|
DependsOn: types.DependsOnConfig{},
|
||||||
},
|
},
|
||||||
{
|
"another": {
|
||||||
Name: "another",
|
Name: "another",
|
||||||
DependsOn: types.DependsOnConfig{},
|
DependsOn: types.DependsOnConfig{},
|
||||||
},
|
},
|
||||||
|
@ -179,13 +179,13 @@ func TestBuildGraph(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "builds graph with a service and a dependency",
|
desc: "builds graph with a service and a dependency",
|
||||||
services: types.Services{
|
services: types.Services{
|
||||||
{
|
"test": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
DependsOn: types.DependsOnConfig{
|
DependsOn: types.DependsOnConfig{
|
||||||
"another": types.ServiceDependency{},
|
"another": types.ServiceDependency{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"another": {
|
||||||
Name: "another",
|
Name: "another",
|
||||||
DependsOn: types.DependsOnConfig{},
|
DependsOn: types.DependsOnConfig{},
|
||||||
},
|
},
|
||||||
|
@ -214,19 +214,19 @@ func TestBuildGraph(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "builds graph with multiple dependency levels",
|
desc: "builds graph with multiple dependency levels",
|
||||||
services: types.Services{
|
services: types.Services{
|
||||||
{
|
"test": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
DependsOn: types.DependsOnConfig{
|
DependsOn: types.DependsOnConfig{
|
||||||
"another": types.ServiceDependency{},
|
"another": types.ServiceDependency{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"another": {
|
||||||
Name: "another",
|
Name: "another",
|
||||||
DependsOn: types.DependsOnConfig{
|
DependsOn: types.DependsOnConfig{
|
||||||
"another_dep": types.ServiceDependency{},
|
"another_dep": types.ServiceDependency{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"another_dep": {
|
||||||
Name: "another_dep",
|
Name: "another_dep",
|
||||||
DependsOn: types.DependsOnConfig{},
|
DependsOn: types.DependsOnConfig{},
|
||||||
},
|
},
|
||||||
|
|
|
@ -184,12 +184,12 @@ func TestDownRemoveImages(t *testing.T) {
|
||||||
Project: &types.Project{
|
Project: &types.Project{
|
||||||
Name: strings.ToLower(testProject),
|
Name: strings.ToLower(testProject),
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{Name: "local-anonymous"},
|
"local-anonymous": {Name: "local-anonymous"},
|
||||||
{Name: "local-named", Image: "local-named-image"},
|
"local-named": {Name: "local-named", Image: "local-named-image"},
|
||||||
{Name: "remote", Image: "remote-image"},
|
"remote": {Name: "remote", Image: "remote-image"},
|
||||||
{Name: "remote-tagged", Image: "registry.example.com/remote-image-tagged:v1.0"},
|
"remote-tagged": {Name: "remote-tagged", Image: "registry.example.com/remote-image-tagged:v1.0"},
|
||||||
{Name: "no-images-anonymous"},
|
"no-images-anonymous": {Name: "no-images-anonymous"},
|
||||||
{Name: "no-images-named", Image: "missing-named-image"},
|
"no-images-named": {Name: "no-images-named", Image: "missing-named-image"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ func TestComposeService_Logs_Demux(t *testing.T) {
|
||||||
opts := compose.LogOptions{
|
opts := compose.LogOptions{
|
||||||
Project: &types.Project{
|
Project: &types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{Name: "service"},
|
"service": {Name: "service"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -153,8 +153,8 @@ func TestComposeService_Logs_ServiceFiltering(t *testing.T) {
|
||||||
// reference `serviceB` even though it has running services for this proj
|
// reference `serviceB` even though it has running services for this proj
|
||||||
proj := &types.Project{
|
proj := &types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{Name: "serviceA"},
|
"serviceA": {Name: "serviceA"},
|
||||||
{Name: "serviceC"},
|
"serviceC": {Name: "serviceC"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
consumer := &testLogConsumer{}
|
consumer := &testLogConsumer{}
|
||||||
|
|
|
@ -63,8 +63,8 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
|
||||||
imagesBeingPulled = map[string]string{}
|
imagesBeingPulled = map[string]string{}
|
||||||
)
|
)
|
||||||
|
|
||||||
for i, service := range project.Services {
|
i := 0
|
||||||
i, service := i, service
|
for _, service := range project.Services {
|
||||||
if service.Image == "" {
|
if service.Image == "" {
|
||||||
w.Event(progress.Event{
|
w.Event(progress.Event{
|
||||||
ID: service.Name,
|
ID: service.Name,
|
||||||
|
@ -113,10 +113,11 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
|
||||||
|
|
||||||
imagesBeingPulled[service.Image] = service.Name
|
imagesBeingPulled[service.Image] = service.Name
|
||||||
|
|
||||||
|
idx, service := i, service
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
_, err := s.pullServiceImage(ctx, service, s.configFile(), w, false, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
_, err := s.pullServiceImage(ctx, service, s.configFile(), w, false, project.Environment["DOCKER_DEFAULT_PLATFORM"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pullErrors[i] = err
|
pullErrors[idx] = err
|
||||||
if service.Build != nil {
|
if service.Build != nil {
|
||||||
mustBuild = append(mustBuild, service.Name)
|
mustBuild = append(mustBuild, service.Name)
|
||||||
}
|
}
|
||||||
|
@ -134,6 +135,7 @@ func (s *composeService) pull(ctx context.Context, project *types.Project, opts
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
err = eg.Wait()
|
err = eg.Wait()
|
||||||
|
@ -260,7 +262,7 @@ func encodedAuth(ref reference.Named, configFile driver.Auth) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *composeService) pullRequiredImages(ctx context.Context, project *types.Project, images map[string]string, quietPull bool) error {
|
func (s *composeService) pullRequiredImages(ctx context.Context, project *types.Project, images map[string]string, quietPull bool) error {
|
||||||
var needPull types.Services
|
var needPull []types.ServiceConfig
|
||||||
for _, service := range project.Services {
|
for _, service := range project.Services {
|
||||||
if service.Image == "" {
|
if service.Image == "" {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -34,7 +34,7 @@ func TestViz(t *testing.T) {
|
||||||
Name: "viz-test",
|
Name: "viz-test",
|
||||||
WorkingDir: "/home",
|
WorkingDir: "/home",
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"service1": {
|
||||||
Name: "service1",
|
Name: "service1",
|
||||||
Image: "image-for-service1",
|
Image: "image-for-service1",
|
||||||
Ports: []types.ServicePortConfig{
|
Ports: []types.ServicePortConfig{
|
||||||
|
@ -53,12 +53,12 @@ func TestViz(t *testing.T) {
|
||||||
"internal": nil,
|
"internal": nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"service2": {
|
||||||
Name: "service2",
|
Name: "service2",
|
||||||
Image: "image-for-service2",
|
Image: "image-for-service2",
|
||||||
Ports: []types.ServicePortConfig{},
|
Ports: []types.ServicePortConfig{},
|
||||||
},
|
},
|
||||||
{
|
"service3": {
|
||||||
Name: "service3",
|
Name: "service3",
|
||||||
Image: "some-image",
|
Image: "some-image",
|
||||||
DependsOn: map[string]types.ServiceDependency{
|
DependsOn: map[string]types.ServiceDependency{
|
||||||
|
@ -66,7 +66,7 @@ func TestViz(t *testing.T) {
|
||||||
"service1": {},
|
"service1": {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"service4": {
|
||||||
Name: "service4",
|
Name: "service4",
|
||||||
Image: "another-image",
|
Image: "another-image",
|
||||||
DependsOn: map[string]types.ServiceDependency{
|
DependsOn: map[string]types.ServiceDependency{
|
||||||
|
@ -82,7 +82,7 @@ func TestViz(t *testing.T) {
|
||||||
"external": nil,
|
"external": nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"With host IP": {
|
||||||
Name: "With host IP",
|
Name: "With host IP",
|
||||||
Image: "user/image-name",
|
Image: "user/image-name",
|
||||||
DependsOn: map[string]types.ServiceDependency{
|
DependsOn: map[string]types.ServiceDependency{
|
||||||
|
|
|
@ -106,7 +106,7 @@ func TestWatch_Sync(t *testing.T) {
|
||||||
|
|
||||||
proj := types.Project{
|
proj := types.Project{
|
||||||
Services: types.Services{
|
Services: types.Services{
|
||||||
{
|
"test": {
|
||||||
Name: "test",
|
Name: "test",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -79,10 +79,10 @@ func TestRestartWithDependencies(t *testing.T) {
|
||||||
c.RunDockerComposeCmd(t, "-f", "./fixtures/restart-test/compose-depends-on.yaml", "up", "-d")
|
c.RunDockerComposeCmd(t, "-f", "./fixtures/restart-test/compose-depends-on.yaml", "up", "-d")
|
||||||
|
|
||||||
res := c.RunDockerComposeCmd(t, "restart", baseService)
|
res := c.RunDockerComposeCmd(t, "restart", baseService)
|
||||||
fmt.Println(res.Combined())
|
out := res.Combined()
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", baseService)), res.Combined())
|
assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", baseService)), out)
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", depWithRestart)), res.Combined())
|
assert.Assert(t, strings.Contains(out, fmt.Sprintf("Container e2e-restart-deps-%s-1 Started", depWithRestart)), out)
|
||||||
assert.Assert(t, !strings.Contains(res.Combined(), depNoRestart), res.Combined())
|
assert.Assert(t, !strings.Contains(out, depNoRestart), out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRestartWithProfiles(t *testing.T) {
|
func TestRestartWithProfiles(t *testing.T) {
|
||||||
|
|
|
@ -106,12 +106,14 @@ func TestStartStopWithDependencies(t *testing.T) {
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-bar-1 Stopped"), res.Combined())
|
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-bar-1 Stopped"), res.Combined())
|
||||||
|
|
||||||
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "start", "foo")
|
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "start", "foo")
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-bar-1 Started"), res.Combined())
|
out := res.Combined()
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), "Container e2e-start-stop-with-dependencies-foo-1 Started"), res.Combined())
|
assert.Assert(t, strings.Contains(out, "Container e2e-start-stop-with-dependencies-bar-1 Started"), out)
|
||||||
|
assert.Assert(t, strings.Contains(out, "Container e2e-start-stop-with-dependencies-foo-1 Started"), out)
|
||||||
|
|
||||||
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--status", "running")
|
res = c.RunDockerComposeCmd(t, "--project-name", projectName, "ps", "--status", "running")
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), "e2e-start-stop-with-dependencies-bar-1"), res.Combined())
|
out = res.Combined()
|
||||||
assert.Assert(t, strings.Contains(res.Combined(), "e2e-start-stop-with-dependencies-foo-1"), res.Combined())
|
assert.Assert(t, strings.Contains(out, "e2e-start-stop-with-dependencies-bar-1"), out)
|
||||||
|
assert.Assert(t, strings.Contains(out, "e2e-start-stop-with-dependencies-foo-1"), out)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Up no-deps links", func(t *testing.T) {
|
t.Run("Up no-deps links", func(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue