Skip to content

Commit

Permalink
Merge pull request #359 from ndeloof/fix_profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
ndeloof authored Mar 1, 2023
2 parents 7a7b593 + 5b5e141 commit bbbdf2b
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 6 deletions.
1 change: 1 addition & 0 deletions consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ const (
ComposeProjectName = "COMPOSE_PROJECT_NAME"
ComposePathSeparator = "COMPOSE_PATH_SEPARATOR"
ComposeFilePath = "COMPOSE_FILE"
ComposeProfiles = "COMPOSE_PROFILES"
)
5 changes: 3 additions & 2 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,10 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
}
}

if len(opts.Profiles) > 0 {
project.ApplyProfiles(opts.Profiles)
if profiles, ok := project.Environment[consts.ComposeProfiles]; ok && len(opts.Profiles) == 0 {
opts.Profiles = strings.Split(profiles, ",")
}
project.ApplyProfiles(opts.Profiles)

err = project.ResolveServicesEnvironment(opts.discardEnvFiles)

Expand Down
2 changes: 1 addition & 1 deletion loader/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ func TestMergeTopLevelExtensions(t *testing.T) {
assert.DeepEqual(t, &types.Project{
Name: "",
WorkingDir: "",
Services: types.Services{},
Services: nil,
Networks: types.Networks{},
Volumes: types.Volumes{},
Secrets: types.Secrets{},
Expand Down
48 changes: 47 additions & 1 deletion types/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Project struct {

// DisabledServices track services which have been disable as profile is not active
DisabledServices Services `yaml:"-" json:"-"`
Profiles []string `yaml:"-" json:"-"`
}

// ServiceNames return names for all services in this Compose config
Expand Down Expand Up @@ -119,6 +120,16 @@ func (p *Project) GetServices(names ...string) (Services, error) {
return services, nil
}

// GetDisabledService retrieve disabled service by name
func (p Project) GetDisabledService(name string) (ServiceConfig, error) {
for _, config := range p.DisabledServices {
if config.Name == name {
return config, nil
}
}
return ServiceConfig{}, fmt.Errorf("no such service: %s", name)
}

// GetService retrieve a specific service by name
func (p *Project) GetService(name string) (ServiceConfig, error) {
services, err := p.GetServices(name)
Expand Down Expand Up @@ -247,7 +258,7 @@ func (p *Project) ApplyProfiles(profiles []string) {
}
}
var enabled, disabled Services
for _, service := range p.Services {
for _, service := range p.AllServices() {
if service.HasProfile(profiles) {
enabled = append(enabled, service)
} else {
Expand All @@ -256,6 +267,41 @@ func (p *Project) ApplyProfiles(profiles []string) {
}
p.Services = enabled
p.DisabledServices = disabled
p.Profiles = profiles
}

// EnableServices ensure services are enabled and activate profiles accordingly
func (p *Project) EnableServices(names ...string) error {
if len(names) == 0 {
return nil
}
var enabled []string
for _, name := range names {
_, err := p.GetService(name)
if err == nil {
// already enabled
continue
}
def, err := p.GetDisabledService(name)
if err != nil {
return err
}
enabled = append(enabled, def.Profiles...)
}

profiles := p.Profiles
PROFILES:
for _, profile := range enabled {
for _, p := range profiles {
if p == profile {
continue PROFILES
}
}
profiles = append(profiles, profile)
}
p.ApplyProfiles(profiles)

return p.ResolveServicesEnvironment(true)
}

// WithoutUnnecessaryResources drops networks/volumes/secrets/configs that are not referenced by active services
Expand Down
26 changes: 24 additions & 2 deletions types/project_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,22 @@ func Test_ApplyProfiles(t *testing.T) {
assert.Equal(t, len(p.Services), 2)
assert.Equal(t, p.Services[0].Name, "service_1")
assert.Equal(t, p.Services[1].Name, "service_2")
assert.Equal(t, len(p.DisabledServices), 3)
assert.Equal(t, p.DisabledServices[0].Name, "service_3")
assert.Equal(t, p.DisabledServices[1].Name, "service_4")
assert.Equal(t, p.DisabledServices[2].Name, "service_5")

err := p.EnableServices("service_4")
assert.NilError(t, err)

assert.Equal(t, len(p.Services), 4)
assert.Equal(t, p.Services[0].Name, "service_1")
assert.Equal(t, p.Services[1].Name, "service_2")
assert.Equal(t, p.Services[2].Name, "service_4")
assert.Equal(t, p.Services[3].Name, "service_5")
assert.Equal(t, len(p.DisabledServices), 1)
assert.Equal(t, p.DisabledServices[0].Name, "service_3")

}

func Test_WithoutUnnecessaryResources(t *testing.T) {
Expand Down Expand Up @@ -60,7 +74,7 @@ func Test_NoProfiles(t *testing.T) {
p := makeProject()
p.ApplyProfiles(nil)
assert.Equal(t, len(p.Services), 1)
assert.Equal(t, len(p.DisabledServices), 2)
assert.Equal(t, len(p.DisabledServices), 4)
assert.Equal(t, p.Services[0].Name, "service_1")
}

Expand All @@ -79,8 +93,10 @@ func Test_ForServices(t *testing.T) {
err := p.ForServices([]string{"service_2"})
assert.NilError(t, err)

assert.Equal(t, len(p.DisabledServices), 1)
assert.Equal(t, len(p.DisabledServices), 3)
assert.Equal(t, p.DisabledServices[0].Name, "service_3")
assert.Equal(t, p.DisabledServices[1].Name, "service_4")
assert.Equal(t, p.DisabledServices[2].Name, "service_5")
}

func Test_ForServicesCycle(t *testing.T) {
Expand All @@ -103,6 +119,12 @@ func makeProject() Project {
Name: "service_3",
Profiles: []string{"bar"},
DependsOn: map[string]ServiceDependency{"service_2": {}},
}, ServiceConfig{
Name: "service_4",
Profiles: []string{"zot"},
}, ServiceConfig{
Name: "service_5",
Profiles: []string{"zot"},
}),
Networks: Networks{},
Volumes: Volumes{},
Expand Down

0 comments on commit bbbdf2b

Please sign in to comment.