Skip to content

Commit

Permalink
checkConsistency must ignore disabled service if required=false
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas De Loof <[email protected]>
  • Loading branch information
ndeloof committed Mar 22, 2024
1 parent c37fc59 commit d0722c0
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
3 changes: 3 additions & 0 deletions errdefs/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ var (

// ErrIncompatible is returned when a compose project uses an incompatible attribute
ErrIncompatible = errors.New("incompatible attribute")

// ErrDisabled is returned when a resource was found in model but is disabled
ErrDisabled = errors.New("disabled")
)

// IsNotFoundError returns true if the unwrapped error is ErrNotFound
Expand Down
5 changes: 4 additions & 1 deletion loader/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,11 @@ func checkConsistency(project *types.Project) error {
}
}

for dependedService := range s.DependsOn {
for dependedService, cfg := range s.DependsOn {
if _, err := project.GetService(dependedService); err != nil {
if errors.Is(err, errdefs.ErrDisabled) && !cfg.Required {
continue
}
return fmt.Errorf("service %q depends on undefined service %q: %w", s.Name, dependedService, errdefs.ErrInvalid)
}
}
Expand Down
41 changes: 41 additions & 0 deletions loader/validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,45 @@ func TestValidateWatch(t *testing.T) {
err := checkConsistency(&project)
assert.NilError(t, err)
})

t.Run("depends on disabled service", func(t *testing.T) {
project := types.Project{
Services: types.Services{
"myservice": {
Name: "myservice",
Image: "scratch",
DependsOn: map[string]types.ServiceDependency{
"other": {
Required: false,
},
},
},
},
DisabledServices: types.Services{
"other": {
Image: "scratch",
},
},
}
err := checkConsistency(&project)
assert.NilError(t, err)
})

t.Run("depends on unknown service", func(t *testing.T) {
project := types.Project{
Services: types.Services{
"myservice": {
Name: "myservice",
Image: "scratch",
DependsOn: map[string]types.ServiceDependency{
"other": {
Required: false,
},
},
},
},
}
err := checkConsistency(&project)
assert.ErrorContains(t, err, "depends on undefined service")
})
}
5 changes: 3 additions & 2 deletions types/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"sort"

"github.com/compose-spec/compose-go/v2/dotenv"
"github.com/compose-spec/compose-go/v2/errdefs"
"github.com/compose-spec/compose-go/v2/utils"
"github.com/distribution/reference"
"github.com/mitchellh/copystructure"
Expand Down Expand Up @@ -216,9 +217,9 @@ func (p *Project) GetService(name string) (ServiceConfig, error) {
if !ok {
_, ok := p.DisabledServices[name]
if ok {
return ServiceConfig{}, fmt.Errorf("service %s is disabled", name)
return ServiceConfig{}, fmt.Errorf("no such service: %s: %w", name, errdefs.ErrDisabled)
}
return ServiceConfig{}, fmt.Errorf("no such service: %s", name)
return ServiceConfig{}, fmt.Errorf("no such service: %s: %w", name, errdefs.ErrNotFound)
}
return service, nil
}
Expand Down

0 comments on commit d0722c0

Please sign in to comment.