Skip to content

Commit f68aebe

Browse files
gloursszobov
authored andcommitted
use compose-go to load and parse compose files
Signed-off-by: Guillaume Lours <[email protected]>
1 parent ba1a154 commit f68aebe

File tree

172 files changed

+31428
-7487
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

172 files changed

+31428
-7487
lines changed

cli/command/stack/config.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ package stack
22

33
import (
44
"fmt"
5+
"path/filepath"
56

7+
specLoader "github.com/compose-spec/compose-go/v2/loader"
8+
compose "github.com/compose-spec/compose-go/v2/types"
69
"github.com/docker/cli/cli"
710
"github.com/docker/cli/cli/command"
811
"github.com/docker/cli/cli/command/completion"
912
"github.com/docker/cli/cli/command/stack/loader"
1013
"github.com/docker/cli/cli/command/stack/options"
1114
composeLoader "github.com/docker/cli/cli/compose/loader"
12-
composetypes "github.com/docker/cli/cli/compose/types"
1315
"github.com/spf13/cobra"
1416
yaml "gopkg.in/yaml.v2"
1517
)
@@ -45,9 +47,17 @@ func newConfigCommand(dockerCli command.Cli) *cobra.Command {
4547
}
4648

4749
// outputConfig returns the merged and interpolated config file
48-
func outputConfig(configFiles composetypes.ConfigDetails, skipInterpolation bool) (string, error) {
49-
optsFunc := func(opts *composeLoader.Options) {
50+
func outputConfig(configFiles compose.ConfigDetails, skipInterpolation bool) (string, error) {
51+
var dir string
52+
for _, f := range configFiles.ConfigFiles {
53+
if f.Filename != "" {
54+
dir = filepath.Base(f.Filename)
55+
break
56+
}
57+
}
58+
optsFunc := func(opts *specLoader.Options) {
5059
opts.SkipInterpolation = skipInterpolation
60+
opts.SetProjectName(specLoader.NormalizeProjectName(dir), true)
5161
}
5262
config, err := composeLoader.Load(configFiles, optsFunc)
5363
if err != nil {

cli/command/stack/config_test.go

+16-11
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"io"
55
"testing"
66

7-
"github.com/docker/cli/cli/compose/loader"
8-
composetypes "github.com/docker/cli/cli/compose/types"
7+
composetypes "github.com/compose-spec/compose-go/v2/types"
8+
99
"github.com/docker/cli/internal/test"
1010
"gotest.tools/v3/assert"
1111
)
@@ -41,13 +41,18 @@ services:
4141
image: busybox:${VERSION}
4242
command: cat file2.txt
4343
`,
44-
expected: `version: "3.7"
44+
expected: `name: firstconfig
4545
services:
4646
foo:
4747
command:
4848
- cat
4949
- file2.txt
5050
image: busybox:1.0
51+
networks:
52+
default: null
53+
networks:
54+
default:
55+
name: firstconfig_default
5156
`,
5257
},
5358
{
@@ -65,28 +70,28 @@ services:
6570
image: busybox:${VERSION}
6671
command: cat file2.txt
6772
`,
68-
expected: `version: "3.7"
73+
expected: `name: firstconfig
6974
services:
7075
foo:
7176
command:
7277
- cat
7378
- file2.txt
7479
image: busybox:${VERSION}
80+
networks:
81+
default: null
82+
networks:
83+
default:
84+
name: firstconfig_default
7585
`,
7686
},
7787
}
7888

7989
for _, tc := range tests {
8090
t.Run(tc.name, func(t *testing.T) {
81-
firstConfigData, err := loader.ParseYAML([]byte(tc.fileOne))
82-
assert.Check(t, err)
83-
secondConfigData, err := loader.ParseYAML([]byte(tc.fileTwo))
84-
assert.Check(t, err)
85-
8691
actual, err := outputConfig(composetypes.ConfigDetails{
8792
ConfigFiles: []composetypes.ConfigFile{
88-
{Config: firstConfigData, Filename: "firstConfig"},
89-
{Config: secondConfigData, Filename: "secondConfig"},
93+
{Content: []byte(tc.fileOne), Filename: "firstConfig"},
94+
{Content: []byte(tc.fileTwo), Filename: "secondConfig"},
9095
},
9196
Environment: map[string]string{
9297
"VERSION": "1.0",

cli/command/stack/deploy.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ func newDeployCommand(dockerCli command.Cli) *cobra.Command {
2222
if err := validateStackName(opts.Namespace); err != nil {
2323
return err
2424
}
25-
config, err := loader.LoadComposefile(dockerCli, opts)
25+
project, err := loader.LoadComposefile(dockerCli, opts)
2626
if err != nil {
2727
return err
2828
}
29-
return swarm.RunDeploy(cmd.Context(), dockerCli, cmd.Flags(), &opts, config)
29+
return swarm.RunDeploy(cmd.Context(), dockerCli, cmd.Flags(), &opts, project)
3030
},
3131
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
3232
return completeNames(dockerCli)(cmd, args, toComplete)

cli/command/stack/loader/loader.go

+11-18
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,26 @@ import (
1212
"sort"
1313
"strings"
1414

15+
specloader "github.com/compose-spec/compose-go/v2/loader"
16+
composetypes "github.com/compose-spec/compose-go/v2/types"
1517
"github.com/docker/cli/cli/command"
1618
"github.com/docker/cli/cli/command/stack/options"
1719
"github.com/docker/cli/cli/compose/loader"
1820
"github.com/docker/cli/cli/compose/schema"
19-
composetypes "github.com/docker/cli/cli/compose/types"
2021
"github.com/pkg/errors"
2122
)
2223

2324
// LoadComposefile parse the composefile specified in the cli and returns its Config and version.
24-
func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes.Config, error) {
25+
func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes.Project, error) {
2526
configDetails, err := GetConfigDetails(opts.Composefiles, dockerCli.In())
2627
if err != nil {
2728
return nil, err
2829
}
2930

30-
dicts := getDictsFrom(configDetails.ConfigFiles)
31-
config, err := loader.Load(configDetails)
31+
projectNameFunc := func(o *specloader.Options) {
32+
o.SetProjectName(opts.Namespace, true)
33+
}
34+
project, err := loader.Load(configDetails, projectNameFunc)
3235
if err != nil {
3336
if fpe, ok := err.(*loader.ForbiddenPropertiesError); ok {
3437
// this error is intentionally formatted multi-line
@@ -38,28 +41,18 @@ func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes.
3841
return nil, err
3942
}
4043

41-
unsupportedProperties := loader.GetUnsupportedProperties(dicts...)
44+
unsupportedProperties := loader.GetUnsupportedProperties(project.Services)
4245
if len(unsupportedProperties) > 0 {
4346
fmt.Fprintf(dockerCli.Err(), "Ignoring unsupported options: %s\n\n",
4447
strings.Join(unsupportedProperties, ", "))
4548
}
4649

47-
deprecatedProperties := loader.GetDeprecatedProperties(dicts...)
50+
deprecatedProperties := loader.GetDeprecatedProperties(project.Services)
4851
if len(deprecatedProperties) > 0 {
4952
fmt.Fprintf(dockerCli.Err(), "Ignoring deprecated options:\n\n%s\n\n",
5053
propertyWarnings(deprecatedProperties))
5154
}
52-
return config, nil
53-
}
54-
55-
func getDictsFrom(configFiles []composetypes.ConfigFile) []map[string]any {
56-
dicts := []map[string]any{}
57-
58-
for _, configFile := range configFiles {
59-
dicts = append(dicts, configFile.Config)
60-
}
61-
62-
return dicts
55+
return project, nil
6356
}
6457

6558
func propertyWarnings(properties map[string]string) string {
@@ -157,7 +150,7 @@ func loadConfigFile(filename string, stdin io.Reader) (*composetypes.ConfigFile,
157150
return nil, err
158151
}
159152

160-
config, err := loader.ParseYAML(bytes)
153+
config, err := specloader.ParseYAML(bytes)
161154
if err != nil {
162155
return nil, err
163156
}

cli/command/stack/swarm/deploy.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import (
44
"context"
55
"fmt"
66

7+
composetypes "github.com/compose-spec/compose-go/v2/types"
78
"github.com/docker/cli/cli/command"
89
"github.com/docker/cli/cli/command/stack/options"
910
"github.com/docker/cli/cli/compose/convert"
10-
composetypes "github.com/docker/cli/cli/compose/types"
1111
"github.com/docker/docker/api/types/swarm"
1212
"github.com/docker/docker/api/types/versions"
1313
"github.com/pkg/errors"
@@ -23,7 +23,7 @@ const (
2323
)
2424

2525
// RunDeploy is the swarm implementation of docker stack deploy
26-
func RunDeploy(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, opts *options.Deploy, cfg *composetypes.Config) error {
26+
func RunDeploy(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet, opts *options.Deploy, project *composetypes.Project) error {
2727
if err := validateResolveImageFlag(opts); err != nil {
2828
return err
2929
}
@@ -38,7 +38,7 @@ func RunDeploy(ctx context.Context, dockerCli command.Cli, flags *pflag.FlagSet,
3838
"In a future release, --detach=false will become the default.")
3939
}
4040

41-
return deployCompose(ctx, dockerCli, opts, cfg)
41+
return deployCompose(ctx, dockerCli, opts, project)
4242
}
4343

4444
// validateResolveImageFlag validates the opts.resolveImage command line option

cli/command/stack/swarm/deploy_composefile.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import (
55
"errors"
66
"fmt"
77

8+
composetypes "github.com/compose-spec/compose-go/v2/types"
89
"github.com/docker/cli/cli/command"
910
servicecli "github.com/docker/cli/cli/command/service"
1011
"github.com/docker/cli/cli/command/stack/options"
1112
"github.com/docker/cli/cli/compose/convert"
12-
composetypes "github.com/docker/cli/cli/compose/types"
1313
"github.com/docker/docker/api/types"
1414
"github.com/docker/docker/api/types/container"
1515
"github.com/docker/docker/api/types/network"
@@ -18,7 +18,7 @@ import (
1818
"github.com/docker/docker/errdefs"
1919
)
2020

21-
func deployCompose(ctx context.Context, dockerCli command.Cli, opts *options.Deploy, config *composetypes.Config) error {
21+
func deployCompose(ctx context.Context, dockerCli command.Cli, opts *options.Deploy, project *composetypes.Project) error {
2222
if err := checkDaemonIsSwarmManager(ctx, dockerCli); err != nil {
2323
return err
2424
}
@@ -27,38 +27,38 @@ func deployCompose(ctx context.Context, dockerCli command.Cli, opts *options.Dep
2727

2828
if opts.Prune {
2929
services := map[string]struct{}{}
30-
for _, service := range config.Services {
30+
for _, service := range project.Services {
3131
services[service.Name] = struct{}{}
3232
}
3333
pruneServices(ctx, dockerCli, namespace, services)
3434
}
3535

36-
serviceNetworks := getServicesDeclaredNetworks(config.Services)
37-
networks, externalNetworks := convert.Networks(namespace, config.Networks, serviceNetworks)
36+
serviceNetworks := getServicesDeclaredNetworks(project.Services)
37+
networks, externalNetworks := convert.Networks(namespace, project.Networks, serviceNetworks)
3838
if err := validateExternalNetworks(ctx, dockerCli.Client(), externalNetworks); err != nil {
3939
return err
4040
}
4141
if err := createNetworks(ctx, dockerCli, namespace, networks); err != nil {
4242
return err
4343
}
4444

45-
secrets, err := convert.Secrets(namespace, config.Secrets)
45+
secrets, err := convert.Secrets(namespace, project.Secrets)
4646
if err != nil {
4747
return err
4848
}
4949
if err := createSecrets(ctx, dockerCli, secrets); err != nil {
5050
return err
5151
}
5252

53-
configs, err := convert.Configs(namespace, config.Configs)
53+
configs, err := convert.Configs(namespace, project.Configs)
5454
if err != nil {
5555
return err
5656
}
5757
if err := createConfigs(ctx, dockerCli, configs); err != nil {
5858
return err
5959
}
6060

61-
services, err := convert.Services(ctx, namespace, config, dockerCli.Client())
61+
services, err := convert.Services(ctx, namespace, project, dockerCli.Client())
6262
if err != nil {
6363
return err
6464
}
@@ -75,7 +75,7 @@ func deployCompose(ctx context.Context, dockerCli command.Cli, opts *options.Dep
7575
return waitOnServices(ctx, dockerCli, serviceIDs, opts.Quiet)
7676
}
7777

78-
func getServicesDeclaredNetworks(serviceConfigs []composetypes.ServiceConfig) map[string]struct{} {
78+
func getServicesDeclaredNetworks(serviceConfigs composetypes.Services) map[string]struct{} {
7979
serviceNetworks := map[string]struct{}{}
8080
for _, serviceConfig := range serviceConfigs {
8181
if len(serviceConfig.Networks) == 0 {

cli/compose/convert/compose.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import (
44
"os"
55
"strings"
66

7-
composetypes "github.com/docker/cli/cli/compose/types"
8-
"github.com/docker/docker/api/types/network"
7+
composetypes "github.com/compose-spec/compose-go/v2/types"
8+
"github.com/docker/docker/api/types"
9+
networktypes "github.com/docker/docker/api/types/network"
910
"github.com/docker/docker/api/types/swarm"
1011
)
1112

@@ -51,17 +52,17 @@ func AddStackLabel(namespace Namespace, labels map[string]string) map[string]str
5152
type networkMap map[string]composetypes.NetworkConfig
5253

5354
// Networks from the compose-file type to the engine API type
54-
func Networks(namespace Namespace, networks networkMap, servicesNetworks map[string]struct{}) (map[string]network.CreateOptions, []string) {
55+
func Networks(namespace Namespace, networks composetypes.Networks, servicesNetworks map[string]struct{}) (map[string]types.NetworkCreate, []string) {
5556
if networks == nil {
5657
networks = make(map[string]composetypes.NetworkConfig)
5758
}
5859

5960
externalNetworks := []string{}
6061
result := make(map[string]network.CreateOptions)
6162
for internalName := range servicesNetworks {
62-
nw := networks[internalName]
63-
if nw.External.External {
64-
externalNetworks = append(externalNetworks, nw.Name)
63+
network := networks[internalName]
64+
if network.External {
65+
externalNetworks = append(externalNetworks, network.Name)
6566
continue
6667
}
6768

@@ -101,7 +102,7 @@ func Networks(namespace Namespace, networks networkMap, servicesNetworks map[str
101102
func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig) ([]swarm.SecretSpec, error) {
102103
result := []swarm.SecretSpec{}
103104
for name, secret := range secrets {
104-
if secret.External.External {
105+
if secret.External {
105106
continue
106107
}
107108

@@ -136,7 +137,7 @@ func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig)
136137
func Configs(namespace Namespace, configs map[string]composetypes.ConfigObjConfig) ([]swarm.ConfigSpec, error) {
137138
result := []swarm.ConfigSpec{}
138139
for name, config := range configs {
139-
if config.External.External {
140+
if config.External {
140141
continue
141142
}
142143

cli/compose/convert/compose_test.go

+5-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package convert
33
import (
44
"testing"
55

6-
composetypes "github.com/docker/cli/cli/compose/types"
6+
composetypes "github.com/compose-spec/compose-go/v2/types"
77
"github.com/docker/docker/api/types/network"
88
"gotest.tools/v3/assert"
99
is "gotest.tools/v3/assert/cmp"
@@ -46,7 +46,7 @@ func TestNetworks(t *testing.T) {
4646
"attachablenet": {},
4747
"named": {},
4848
}
49-
source := networkMap{
49+
source := composetypes.Networks{
5050
"normal": composetypes.NetworkConfig{
5151
Driver: "overlay",
5252
DriverOpts: map[string]string{
@@ -65,7 +65,7 @@ func TestNetworks(t *testing.T) {
6565
},
6666
},
6767
"outside": composetypes.NetworkConfig{
68-
External: composetypes.External{External: true},
68+
External: true,
6969
Name: "special",
7070
},
7171
"attachablenet": composetypes.NetworkConfig{
@@ -130,9 +130,7 @@ func TestSecrets(t *testing.T) {
130130
Labels: map[string]string{"monster": "mash"},
131131
},
132132
"ext": {
133-
External: composetypes.External{
134-
External: true,
135-
},
133+
External: true,
136134
},
137135
}
138136

@@ -161,9 +159,7 @@ func TestConfigs(t *testing.T) {
161159
Labels: map[string]string{"monster": "mash"},
162160
},
163161
"ext": {
164-
External: composetypes.External{
165-
External: true,
166-
},
162+
External: true,
167163
},
168164
}
169165

0 commit comments

Comments
 (0)