Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cli/command/stack/kubernetes/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ func RunDeploy(dockerCli *KubeCli, opts options.Deploy) error {
}

// Parse the compose file
cfg, version, err := loader.LoadComposefile(dockerCli, opts)
cfg, err := loader.LoadComposefile(dockerCli, opts)
if err != nil {
return err
}
stack, err := LoadStack(opts.Namespace, version, *cfg)
stack, err := LoadStack(opts.Namespace, *cfg)
if err != nil {
return err
}
Expand Down
27 changes: 2 additions & 25 deletions cli/command/stack/kubernetes/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,9 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type versionedConfig struct {
composetypes.Config
version string
}

func (c versionedConfig) MarshalYAML() (interface{}, error) {
services := map[string]composetypes.ServiceConfig{}
for _, service := range c.Services {
services[service.Name] = service
}
return map[string]interface{}{
"services": services,
"networks": c.Networks,
"volumes": c.Volumes,
"secrets": c.Secrets,
"configs": c.Configs,
"version": c.version,
}, nil
}

// LoadStack loads a stack from a Compose config, with a given name.
func LoadStack(name, version string, cfg composetypes.Config) (*apiv1beta1.Stack, error) {
res, err := yaml.Marshal(versionedConfig{
version: version,
Config: cfg,
})
func LoadStack(name string, cfg composetypes.Config) (*apiv1beta1.Stack, error) {
res, err := yaml.Marshal(cfg)
if err != nil {
return nil, err
}
Expand Down
11 changes: 6 additions & 5 deletions cli/command/stack/kubernetes/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (
)

func TestLoadStack(t *testing.T) {
s, err := LoadStack("foo", "3.1", composetypes.Config{
s, err := LoadStack("foo", composetypes.Config{
Version: "3.1",
Filename: "banana",
Services: []composetypes.ServiceConfig{
{
Expand All @@ -29,16 +30,16 @@ func TestLoadStack(t *testing.T) {
Name: "foo",
},
Spec: apiv1beta1.StackSpec{
ComposeFile: string(`configs: {}
networks: {}
secrets: {}
ComposeFile: string(`version: "3.1"
services:
bar:
image: bar
foo:
image: foo
version: "3.1"
networks: {}
volumes: {}
secrets: {}
configs: {}
`),
},
}, s)
Expand Down
10 changes: 5 additions & 5 deletions cli/command/stack/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,21 @@ import (
)

// LoadComposefile parse the composefile specified in the cli and returns its Config and version.
func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes.Config, string, error) {
func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes.Config, error) {
configDetails, err := getConfigDetails(opts.Composefiles, dockerCli.In())
if err != nil {
return nil, "", err
return nil, err
}

dicts := getDictsFrom(configDetails.ConfigFiles)
config, err := loader.Load(configDetails)
if err != nil {
if fpe, ok := err.(*loader.ForbiddenPropertiesError); ok {
return nil, "", errors.Errorf("Compose file contains unsupported options:\n\n%s\n",
return nil, errors.Errorf("Compose file contains unsupported options:\n\n%s\n",
propertyWarnings(fpe.Properties))
}

return nil, "", err
return nil, err
}

unsupportedProperties := loader.GetUnsupportedProperties(dicts...)
Expand All @@ -46,7 +46,7 @@ func LoadComposefile(dockerCli command.Cli, opts options.Deploy) (*composetypes.
fmt.Fprintf(dockerCli.Err(), "Ignoring deprecated options:\n\n%s\n\n",
propertyWarnings(deprecatedProperties))
}
return config, configDetails.Version, nil
return config, nil
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

}

func getDictsFrom(configFiles []composetypes.ConfigFile) []map[string]interface{} {
Expand Down
2 changes: 1 addition & 1 deletion cli/command/stack/swarm/deploy_composefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
)

func deployCompose(ctx context.Context, dockerCli command.Cli, opts options.Deploy) error {
config, _, err := loader.LoadComposefile(dockerCli, opts)
config, err := loader.LoadComposefile(dockerCli, opts)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions cli/compose/loader/full-struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

func fullExampleConfig(workingDir, homeDir string) *types.Config {
return &types.Config{
Version: "3.6",
Services: services(workingDir, homeDir),
Networks: networks(),
Volumes: volumes(),
Expand Down
4 changes: 3 additions & 1 deletion cli/compose/loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ func validateForbidden(configDict map[string]interface{}) error {

func loadSections(config map[string]interface{}, configDetails types.ConfigDetails) (*types.Config, error) {
var err error
cfg := types.Config{}
cfg := types.Config{
Version: schema.Version(config),
}

var loaders = []struct {
key string
Expand Down
3 changes: 3 additions & 0 deletions cli/compose/loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ func strPtr(val string) *string {
}

var sampleConfig = types.Config{
Version: "3.0",
Services: []types.ServiceConfig{
{
Name: "foo",
Expand Down Expand Up @@ -174,6 +175,7 @@ func TestParseYAML(t *testing.T) {
func TestLoad(t *testing.T) {
actual, err := Load(buildConfigDetails(sampleDict, nil))
require.NoError(t, err)
assert.Equal(t, sampleConfig.Version, actual.Version)
assert.Equal(t, serviceSort(sampleConfig.Services), serviceSort(actual.Services))
assert.Equal(t, sampleConfig.Networks, actual.Networks)
assert.Equal(t, sampleConfig.Volumes, actual.Volumes)
Expand Down Expand Up @@ -573,6 +575,7 @@ networks:
require.NoError(t, err)
expected := &types.Config{
Filename: "filename.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "web",
Expand Down
7 changes: 7 additions & 0 deletions cli/compose/loader/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ func TestLoadLogging(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Expand Down Expand Up @@ -325,6 +326,7 @@ func TestLoadMultipleServicePorts(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Expand Down Expand Up @@ -450,6 +452,7 @@ func TestLoadMultipleSecretsConfig(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Expand Down Expand Up @@ -575,6 +578,7 @@ func TestLoadMultipleConfigobjsConfig(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Expand Down Expand Up @@ -690,6 +694,7 @@ func TestLoadMultipleUlimits(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Expand Down Expand Up @@ -808,6 +813,7 @@ func TestLoadMultipleNetworks(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "foo",
Expand Down Expand Up @@ -895,6 +901,7 @@ func TestLoadMultipleConfigs(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &types.Config{
Filename: "base.yml",
Version: "3.4",
Services: []types.ServiceConfig{
{
Name: "bar",
Expand Down
41 changes: 21 additions & 20 deletions cli/compose/loader/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,7 @@ import (

func TestMarshallConfig(t *testing.T) {
cfg := fullExampleConfig("/foo", "/bar")
expected := `configs: {}
networks:
external-network:
name: external-network
external: true
other-external-network:
name: my-cool-network
external: true
other-network:
driver: overlay
driver_opts:
baz: "1"
foo: bar
ipam:
driver: overlay
config:
- subnet: 172.16.238.0/24
- subnet: 2001:3984:3989::/64
some-network: {}
secrets: {}
expected := `version: "3.6"
services:
foo:
build:
Expand Down Expand Up @@ -292,6 +273,24 @@ services:
tmpfs:
size: 10000
working_dir: /code
networks:
external-network:
name: external-network
external: true
other-external-network:
name: my-cool-network
external: true
other-network:
driver: overlay
driver_opts:
baz: "1"
foo: bar
ipam:
driver: overlay
config:
- subnet: 172.16.238.0/24
- subnet: 2001:3984:3989::/64
some-network: {}
volumes:
another-volume:
name: user_specified_name
Expand All @@ -314,6 +313,8 @@ volumes:
baz: "1"
foo: bar
some-volume: {}
secrets: {}
configs: {}
`

actual, err := yaml.Marshal(cfg)
Expand Down
20 changes: 9 additions & 11 deletions cli/compose/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,24 @@ func (cd ConfigDetails) LookupEnv(key string) (string, bool) {
// Config is a full compose file configuration
type Config struct {
Filename string `yaml:"-"`
Services []ServiceConfig
Version string
Services Services
Networks map[string]NetworkConfig
Volumes map[string]VolumeConfig
Secrets map[string]SecretConfig
Configs map[string]ConfigObjConfig
}

// MarshalYAML makes Config implement yaml.Marshaller
func (c *Config) MarshalYAML() (interface{}, error) {
// Services is a list of ServiceConfig
type Services []ServiceConfig

// MarshalYAML makes Services implement yaml.Marshaller
func (s Services) MarshalYAML() (interface{}, error) {
services := map[string]ServiceConfig{}
for _, service := range c.Services {
for _, service := range s {
services[service.Name] = service
}
return map[string]interface{}{
"services": services,
"networks": c.Networks,
"volumes": c.Volumes,
"secrets": c.Secrets,
"configs": c.Configs,
}, nil
return services, nil
}

// ServiceConfig is the configuration of one service
Expand Down