mirror of https://github.com/docker/compose.git
Use `Project` from compose-go
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
dcf84f2499
commit
c5895fe09a
|
@ -7,9 +7,10 @@ import (
|
|||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/cli/cli/command"
|
||||
amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
"github.com/docker/ecs-plugin/pkg/docker"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -18,8 +19,8 @@ func ComposeCommand(dockerCli command.Cli) *cobra.Command {
|
|||
cmd := &cobra.Command{
|
||||
Use: "compose",
|
||||
}
|
||||
opts := &compose.ProjectOptions{}
|
||||
opts.AddFlags(cmd.Flags())
|
||||
opts := &cli.ProjectOptions{}
|
||||
AddFlags(opts, cmd.Flags())
|
||||
|
||||
cmd.AddCommand(
|
||||
ConvertCommand(dockerCli, opts),
|
||||
|
@ -42,10 +43,10 @@ func (o upOptions) LoadBalancerArn() *string {
|
|||
return &o.loadBalancerArn
|
||||
}
|
||||
|
||||
func ConvertCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||
func ConvertCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "convert",
|
||||
RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error {
|
||||
RunE: WithProject(projectOpts, func(project *types.Project, args []string) error {
|
||||
clusteropts, err := docker.GetAwsContext(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -71,7 +72,7 @@ func ConvertCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions)
|
|||
return cmd
|
||||
}
|
||||
|
||||
func UpCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||
func UpCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||
opts := upOptions{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "up",
|
||||
|
@ -87,11 +88,11 @@ func UpCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobr
|
|||
return cmd
|
||||
}
|
||||
|
||||
func PsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||
func PsCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||
opts := upOptions{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "ps",
|
||||
RunE: compose.WithProject(projectOpts, func(project *compose.Project, args []string) error {
|
||||
RunE: WithProject(projectOpts, func(project *types.Project, args []string) error {
|
||||
clusteropts, err := docker.GetAwsContext(dockerCli)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -120,7 +121,7 @@ type downOptions struct {
|
|||
DeleteCluster bool
|
||||
}
|
||||
|
||||
func DownCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||
func DownCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||
opts := downOptions{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "down",
|
||||
|
@ -136,7 +137,7 @@ func DownCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *co
|
|||
return cmd
|
||||
}
|
||||
|
||||
func LogsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *cobra.Command {
|
||||
func LogsCommand(dockerCli command.Cli, projectOpts *cli.ProjectOptions) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "logs [PROJECT NAME]",
|
||||
RunE: docker.WithAwsContext(dockerCli, func(clusteropts docker.AwsContext, args []string) error {
|
||||
|
@ -147,7 +148,7 @@ func LogsCommand(dockerCli command.Cli, projectOpts *compose.ProjectOptions) *co
|
|||
var name string
|
||||
|
||||
if len(args) == 0 {
|
||||
project, err := compose.ProjectFromOptions(projectOpts)
|
||||
project, err := cli.ProjectFromOptions(projectOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,26 +1,23 @@
|
|||
package compose
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
type ProjectOptions struct {
|
||||
ConfigPaths []string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (o *ProjectOptions) AddFlags(flags *pflag.FlagSet) {
|
||||
func AddFlags(o *cli.ProjectOptions, flags *pflag.FlagSet) {
|
||||
flags.StringArrayVarP(&o.ConfigPaths, "file", "f", nil, "Specify an alternate compose file")
|
||||
flags.StringVarP(&o.Name, "project-name", "n", "", "Specify an alternate project name (default: directory name)")
|
||||
}
|
||||
|
||||
type ProjectFunc func(project *Project, args []string) error
|
||||
type ProjectFunc func(project *types.Project, args []string) error
|
||||
|
||||
// WithProject wrap a ProjectFunc into a cobra command
|
||||
func WithProject(options *ProjectOptions, f ProjectFunc) func(cmd *cobra.Command, args []string) error {
|
||||
func WithProject(options *cli.ProjectOptions, f ProjectFunc) func(cmd *cobra.Command, args []string) error {
|
||||
return func(cmd *cobra.Command, args []string) error {
|
||||
project, err := ProjectFromOptions(options)
|
||||
project, err := cli.ProjectFromOptions(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
"github.com/docker/cli/cli/command"
|
||||
amazon "github.com/docker/ecs-plugin/pkg/amazon/backend"
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
"github.com/docker/ecs-plugin/pkg/docker"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -57,7 +57,7 @@ func CreateSecret(dockerCli command.Cli) *cobra.Command {
|
|||
}
|
||||
name := args[0]
|
||||
|
||||
secret := types.NewSecret(name, opts.Username, opts.Password, opts.Description)
|
||||
secret := compose.NewSecret(name, opts.Username, opts.Password, opts.Description)
|
||||
id, err := backend.CreateSecret(context.Background(), secret)
|
||||
fmt.Println(id)
|
||||
return err
|
||||
|
@ -140,7 +140,7 @@ func DeleteSecret(dockerCli command.Cli) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func printList(out io.Writer, secrets []types.Secret) {
|
||||
func printList(out io.Writer, secrets []compose.Secret) {
|
||||
printSection(out, len(secrets), func(w io.Writer) {
|
||||
for _, secret := range secrets {
|
||||
fmt.Fprintf(w, "%s\t%s\t%s\n", secret.ID, secret.Name, secret.Description)
|
||||
|
|
|
@ -14,7 +14,7 @@ require (
|
|||
github.com/bugsnag/panicwrap v1.2.0 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cloudflare/cfssl v1.4.1 // indirect
|
||||
github.com/compose-spec/compose-go v0.0.0-20200409090215-53c0040c9127
|
||||
github.com/compose-spec/compose-go v0.0.0-20200622094647-0bb9a6c7d89a
|
||||
github.com/containerd/containerd v1.3.2 // indirect
|
||||
github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb // indirect
|
||||
github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492
|
||||
|
@ -35,11 +35,11 @@ require (
|
|||
github.com/manifoldco/promptui v0.7.0
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||
github.com/miekg/pkcs11 v1.0.3 // indirect
|
||||
github.com/mitchellh/mapstructure v1.2.2
|
||||
github.com/mitchellh/mapstructure v1.3.2
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/onsi/ginkgo v1.11.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||
github.com/sirupsen/logrus v1.5.0
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/spf13/cobra v0.0.5
|
||||
github.com/spf13/pflag v1.0.5
|
||||
|
@ -52,7 +52,6 @@ require (
|
|||
gopkg.in/fatih/pool.v2 v2.0.0 // indirect
|
||||
gopkg.in/gorethink/gorethink.v3 v3.0.5 // indirect
|
||||
gopkg.in/ini.v1 v1.55.0
|
||||
gotest.tools v2.2.0+incompatible
|
||||
gotest.tools/v3 v3.0.2
|
||||
vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787 // indirect
|
||||
)
|
||||
|
|
29
ecs/go.sum
29
ecs/go.sum
|
@ -54,8 +54,12 @@ github.com/cloudflare/cfssl v1.4.1 h1:vScfU2DrIUI9VPHBVeeAQ0q5A+9yshO1Gz+3QoUQiK
|
|||
github.com/cloudflare/cfssl v1.4.1/go.mod h1:KManx/OJPb5QY+y0+o/898AMcM128sF0bURvoVUSjTo=
|
||||
github.com/cloudflare/go-metrics v0.0.0-20151117154305-6a9aea36fb41/go.mod h1:eaZPlJWD+G9wseg1BuRXlHnjntPMrywMsyxf+LTOdP4=
|
||||
github.com/cloudflare/redoctober v0.0.0-20171127175943-746a508df14c/go.mod h1:6Se34jNoqrd8bTxrmJB2Bg2aoZ2CdSXonils9NsiNgo=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200409090215-53c0040c9127 h1:mAsQN3s19glh3KBOQjiRYBhqaX1SdzNqhB3/cuqgSbE=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200409090215-53c0040c9127/go.mod h1:1PUpzRF1O/65VOqXZuwpCuYY7pJxbIq1jbAvAf62FGM=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200616184722-5b8dc203fd7f h1:XE6hHZdPjxN8uGaRlvdCB8YwXbz1PXnQ0CboNygdL2o=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200616184722-5b8dc203fd7f/go.mod h1:d3Vb4tH01Pr4YKD3RvfwguRcezDBUYJTVYgpCSRYSVg=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200617133919-fca3bb55c5cc h1:jZfF+HzxW+c8Em308MvcK7j5+ZqIAWqFjN1RZnVFzck=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200617133919-fca3bb55c5cc/go.mod h1:d3Vb4tH01Pr4YKD3RvfwguRcezDBUYJTVYgpCSRYSVg=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200622094647-0bb9a6c7d89a h1:FmEuebUePUA0Kd/NSiCmdPG/n6eKdZdBtIbfejVtRS8=
|
||||
github.com/compose-spec/compose-go v0.0.0-20200622094647-0bb9a6c7d89a/go.mod h1:ih9anT8po+49hrb+1j3ldIJ/YRAaBH52ErlQLTKE2Yo=
|
||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
|
@ -134,9 +138,12 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
|||
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
|
@ -151,6 +158,7 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
|||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
|
@ -183,6 +191,8 @@ github.com/kisielk/sqlstruct v0.0.0-20150923205031-648daed35d49/go.mod h1:yyMNCy
|
|||
github.com/kisom/goutils v1.1.0/go.mod h1:+UBTfd78habUYWFbNWTJNG+jNG/i/lGURakr4A/yNRw=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
|
@ -218,8 +228,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
|
|||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4=
|
||||
github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
|
@ -282,8 +292,8 @@ github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvH
|
|||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
|
||||
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
|
@ -330,6 +340,7 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2
|
|||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56 h1:yhqBHs09SmmUoNOHc9jgK4a60T3XFRtPAkYxVnqgY50=
|
||||
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
|
@ -450,6 +461,8 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
|
||||
|
|
|
@ -5,14 +5,9 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
ecsapi "github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/aws/aws-sdk-go/service/elbv2"
|
||||
cloudmapapi "github.com/aws/aws-sdk-go/service/servicediscovery"
|
||||
|
||||
ecsapi "github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/awslabs/goformation/v4/cloudformation"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/ec2"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/ecs"
|
||||
|
@ -21,10 +16,11 @@ import (
|
|||
"github.com/awslabs/goformation/v4/cloudformation/logs"
|
||||
cloudmap "github.com/awslabs/goformation/v4/cloudformation/servicediscovery"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/tags"
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/compatibility"
|
||||
"github.com/compose-spec/compose-go/compatibility"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
sdk "github.com/docker/ecs-plugin/pkg/amazon/sdk"
|
||||
btypes "github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -35,11 +31,38 @@ const (
|
|||
ParameterLoadBalancerARN = "ParameterLoadBalancerARN"
|
||||
)
|
||||
|
||||
type FargateCompatibilityChecker struct {
|
||||
*compatibility.AllowList
|
||||
}
|
||||
|
||||
// Convert a compose project into a CloudFormation template
|
||||
func (b Backend) Convert(project *compose.Project) (*cloudformation.Template, error) {
|
||||
warnings := compatibility.Check(project)
|
||||
for _, w := range warnings {
|
||||
logrus.Warn(w)
|
||||
func (b Backend) Convert(project *types.Project) (*cloudformation.Template, error) {
|
||||
var checker compatibility.Checker = FargateCompatibilityChecker{
|
||||
&compatibility.AllowList{
|
||||
Supported: []string{
|
||||
"services.command",
|
||||
"services.container_name",
|
||||
"services.depends_on",
|
||||
"services.entrypoint",
|
||||
"services.environment",
|
||||
"services.healthcheck",
|
||||
"services.healthcheck.interval",
|
||||
"services.healthcheck.start_period",
|
||||
"services.healthcheck.test",
|
||||
"services.healthcheck.timeout",
|
||||
"services.networks",
|
||||
"services.ports",
|
||||
"services.ports.mode",
|
||||
"services.ports.target",
|
||||
"services.ports.protocol",
|
||||
"services.user",
|
||||
"services.working_dir",
|
||||
},
|
||||
},
|
||||
}
|
||||
compatibility.Check(project, checker)
|
||||
for _, err := range checker.Errors() {
|
||||
logrus.Warn(err.Error())
|
||||
}
|
||||
|
||||
template := cloudformation.NewTemplate()
|
||||
|
@ -188,7 +211,7 @@ func (b Backend) Convert(project *compose.Project) (*cloudformation.Template, er
|
|||
return template, nil
|
||||
}
|
||||
|
||||
func getLoadBalancerType(project *compose.Project) string {
|
||||
func getLoadBalancerType(project *types.Project) string {
|
||||
for _, service := range project.Services {
|
||||
for _, port := range service.Ports {
|
||||
if port.Published != 80 && port.Published != 443 {
|
||||
|
@ -199,7 +222,7 @@ func getLoadBalancerType(project *compose.Project) string {
|
|||
return elbv2.LoadBalancerTypeEnumApplication
|
||||
}
|
||||
|
||||
func getLoadBalancerSecurityGroups(project *compose.Project, template *cloudformation.Template) []string {
|
||||
func getLoadBalancerSecurityGroups(project *types.Project, template *cloudformation.Template) []string {
|
||||
securityGroups := []string{}
|
||||
for _, network := range project.Networks {
|
||||
if !network.Internal {
|
||||
|
@ -210,7 +233,7 @@ func getLoadBalancerSecurityGroups(project *compose.Project, template *cloudform
|
|||
return uniqueStrings(securityGroups)
|
||||
}
|
||||
|
||||
func createLoadBalancer(project *compose.Project, template *cloudformation.Template) string {
|
||||
func createLoadBalancer(project *types.Project, template *cloudformation.Template) string {
|
||||
loadBalancerName := fmt.Sprintf("%sLoadBalancer", strings.Title(project.Name))
|
||||
// Create LoadBalancer if `ParameterLoadBalancerName` is not set
|
||||
template.Conditions["CreateLoadBalancer"] = cloudformation.Equals("", cloudformation.Ref(ParameterLoadBalancerARN))
|
||||
|
@ -270,7 +293,7 @@ func createListener(service types.ServiceConfig, port types.ServicePortConfig, t
|
|||
return listenerName
|
||||
}
|
||||
|
||||
func createTargetGroup(project *compose.Project, service types.ServiceConfig, port types.ServicePortConfig, template *cloudformation.Template, protocol string) string {
|
||||
func createTargetGroup(project *types.Project, service types.ServiceConfig, port types.ServicePortConfig, template *cloudformation.Template, protocol string) string {
|
||||
targetGroupName := fmt.Sprintf(
|
||||
"%s%s%dTargetGroup",
|
||||
normalizeResourceName(service.Name),
|
||||
|
@ -345,7 +368,7 @@ func createTaskExecutionRole(service types.ServiceConfig, err error, definition
|
|||
return taskExecutionRole, nil
|
||||
}
|
||||
|
||||
func createCluster(project *compose.Project, template *cloudformation.Template) string {
|
||||
func createCluster(project *types.Project, template *cloudformation.Template) string {
|
||||
template.Resources["Cluster"] = &ecs.Cluster{
|
||||
ClusterName: project.Name,
|
||||
Tags: []tags.Tag{
|
||||
|
@ -360,7 +383,7 @@ func createCluster(project *compose.Project, template *cloudformation.Template)
|
|||
return cluster
|
||||
}
|
||||
|
||||
func createCloudMap(project *compose.Project, template *cloudformation.Template) {
|
||||
func createCloudMap(project *types.Project, template *cloudformation.Template) {
|
||||
template.Resources["CloudMap"] = &cloudmap.PrivateDnsNamespace{
|
||||
Description: fmt.Sprintf("Service Map for Docker Compose project %s", project.Name),
|
||||
Name: fmt.Sprintf("%s.local", project.Name),
|
||||
|
@ -368,8 +391,8 @@ func createCloudMap(project *compose.Project, template *cloudformation.Template)
|
|||
}
|
||||
}
|
||||
|
||||
func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
|
||||
if sg, ok := net.Extras[btypes.ExtensionSecurityGroup]; ok {
|
||||
func convertNetwork(project *types.Project, net types.NetworkConfig, vpc string, template *cloudformation.Template) string {
|
||||
if sg, ok := net.Extensions[compose.ExtensionSecurityGroup]; ok {
|
||||
logrus.Debugf("Security Group for network %q set by user to %q", net.Name, sg)
|
||||
return sg.(string)
|
||||
}
|
||||
|
@ -420,7 +443,7 @@ func convertNetwork(project *compose.Project, net types.NetworkConfig, vpc strin
|
|||
return cloudformation.Ref(securityGroup)
|
||||
}
|
||||
|
||||
func networkResourceName(project *compose.Project, network string) string {
|
||||
func networkResourceName(project *types.Project, network string) string {
|
||||
return fmt.Sprintf("%s%sNetwork", normalizeResourceName(project.Name), normalizeResourceName(network))
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,11 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/elbv2"
|
||||
"github.com/awslabs/goformation/v4/cloudformation"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/ec2"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/iam"
|
||||
|
||||
"github.com/awslabs/goformation/v4/cloudformation/elasticloadbalancingv2"
|
||||
"github.com/awslabs/goformation/v4/cloudformation/iam"
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/compose-spec/compose-go/loader"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
)
|
||||
|
@ -58,6 +56,10 @@ version: "3"
|
|||
services:
|
||||
test:
|
||||
image: hello_world
|
||||
networks:
|
||||
- front-tier
|
||||
- back-tier
|
||||
|
||||
networks:
|
||||
front-tier:
|
||||
name: public
|
||||
|
@ -103,7 +105,7 @@ services:
|
|||
assert.Check(t, lb.Type == elbv2.LoadBalancerTypeEnumNetwork)
|
||||
}
|
||||
|
||||
func convertResultAsString(t *testing.T, project *compose.Project, clusterName string) string {
|
||||
func convertResultAsString(t *testing.T, project *types.Project, clusterName string) string {
|
||||
client, err := NewBackend("", clusterName, "")
|
||||
assert.NilError(t, err)
|
||||
result, err := client.Convert(project)
|
||||
|
@ -113,12 +115,12 @@ func convertResultAsString(t *testing.T, project *compose.Project, clusterName s
|
|||
return fmt.Sprintf("%s\n", string(resultAsJSON))
|
||||
}
|
||||
|
||||
func load(t *testing.T, paths ...string) *compose.Project {
|
||||
options := compose.ProjectOptions{
|
||||
func load(t *testing.T, paths ...string) *types.Project {
|
||||
options := cli.ProjectOptions{
|
||||
Name: t.Name(),
|
||||
ConfigPaths: paths,
|
||||
}
|
||||
project, err := compose.ProjectFromOptions(&options)
|
||||
project, err := cli.ProjectFromOptions(&options)
|
||||
assert.NilError(t, err)
|
||||
return project
|
||||
}
|
||||
|
@ -130,14 +132,11 @@ func convertYaml(t *testing.T, yaml string) *cloudformation.Template {
|
|||
ConfigFiles: []types.ConfigFile{
|
||||
{Config: dict},
|
||||
},
|
||||
}, func(options *loader.Options) {
|
||||
options.Name = "Test"
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
err = compose.Normalize(model)
|
||||
assert.NilError(t, err)
|
||||
template, err := Backend{}.Convert(&compose.Project{
|
||||
Config: *model,
|
||||
Name: "test",
|
||||
})
|
||||
template, err := Backend{}.Convert(model)
|
||||
assert.NilError(t, err)
|
||||
return template
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ package backend
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
)
|
||||
|
||||
func (b *Backend) Down(ctx context.Context, options compose.ProjectOptions) error {
|
||||
func (b *Backend) Down(ctx context.Context, options cli.ProjectOptions) error {
|
||||
name := options.Name
|
||||
if name == "" {
|
||||
project, err := compose.ProjectFromOptions(&options)
|
||||
project, err := cli.ProjectFromOptions(&options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func (b *Backend) Down(ctx context.Context, options compose.ProjectOptions) erro
|
|||
return err
|
||||
}
|
||||
|
||||
err = b.WaitStackCompletion(ctx, name, types.StackDelete)
|
||||
err = b.WaitStackCompletion(ctx, name, compose.StackDelete)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/sdk"
|
||||
btypes "github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
"github.com/golang/mock/gomock"
|
||||
)
|
||||
|
@ -23,10 +23,10 @@ func TestDown(t *testing.T) {
|
|||
recorder := m.EXPECT()
|
||||
recorder.DeleteStack(ctx, "test_project").Return(nil)
|
||||
recorder.GetStackID(ctx, "test_project").Return("stack-123", nil)
|
||||
recorder.WaitStackComplete(ctx, "stack-123", btypes.StackDelete).Return(nil)
|
||||
recorder.WaitStackComplete(ctx, "stack-123", compose.StackDelete).Return(nil)
|
||||
recorder.DescribeStackEvents(ctx, "stack-123").Return(nil, nil)
|
||||
|
||||
c.Down(ctx, compose.ProjectOptions{
|
||||
c.Down(ctx, cli.ProjectOptions{
|
||||
ConfigPaths: []string{},
|
||||
Name: "test_project",
|
||||
})
|
||||
|
|
|
@ -6,11 +6,11 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
)
|
||||
|
||||
func (b *Backend) Ps(ctx context.Context, project *compose.Project) ([]types.TaskStatus, error) {
|
||||
func (b *Backend) Ps(ctx context.Context, project *types.Project) ([]compose.TaskStatus, error) {
|
||||
cluster := b.Cluster
|
||||
if cluster == "" {
|
||||
cluster = project.Name
|
||||
|
@ -19,17 +19,17 @@ func (b *Backend) Ps(ctx context.Context, project *compose.Project) ([]types.Tas
|
|||
for _, service := range project.Services {
|
||||
tasks, err := b.api.ListTasks(ctx, cluster, service.Name)
|
||||
if err != nil {
|
||||
return []types.TaskStatus{}, err
|
||||
return []compose.TaskStatus{}, err
|
||||
}
|
||||
arns = append(arns, tasks...)
|
||||
}
|
||||
if len(arns) == 0 {
|
||||
return []types.TaskStatus{}, nil
|
||||
return []compose.TaskStatus{}, nil
|
||||
}
|
||||
|
||||
tasks, err := b.api.DescribeTasks(ctx, cluster, arns...)
|
||||
if err != nil {
|
||||
return []types.TaskStatus{}, err
|
||||
return []compose.TaskStatus{}, err
|
||||
}
|
||||
|
||||
networkInterfaces := []string{}
|
||||
|
@ -40,21 +40,21 @@ func (b *Backend) Ps(ctx context.Context, project *compose.Project) ([]types.Tas
|
|||
}
|
||||
publicIps, err := b.api.GetPublicIPs(ctx, networkInterfaces...)
|
||||
if err != nil {
|
||||
return []types.TaskStatus{}, err
|
||||
return []compose.TaskStatus{}, err
|
||||
}
|
||||
|
||||
sort.Slice(tasks, func(i, j int) bool {
|
||||
return strings.Compare(tasks[i].Service, tasks[j].Service) < 0
|
||||
})
|
||||
|
||||
for i, t := range tasks {
|
||||
for i, task := range tasks {
|
||||
ports := []string{}
|
||||
s, err := project.GetService(t.Service)
|
||||
s, err := project.GetService(task.Service)
|
||||
if err != nil {
|
||||
return []types.TaskStatus{}, err
|
||||
return []compose.TaskStatus{}, err
|
||||
}
|
||||
for _, p := range s.Ports {
|
||||
ports = append(ports, fmt.Sprintf("%s:%d->%d/%s", publicIps[t.NetworkInterface], p.Published, p.Target, p.Protocol))
|
||||
ports = append(ports, fmt.Sprintf("%s:%d->%d/%s", publicIps[task.NetworkInterface], p.Published, p.Target, p.Protocol))
|
||||
}
|
||||
tasks[i].Name = s.Name
|
||||
tasks[i].Ports = ports
|
||||
|
|
|
@ -3,18 +3,18 @@ package backend
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
)
|
||||
|
||||
func (b Backend) CreateSecret(ctx context.Context, secret types.Secret) (string, error) {
|
||||
func (b Backend) CreateSecret(ctx context.Context, secret compose.Secret) (string, error) {
|
||||
return b.api.CreateSecret(ctx, secret)
|
||||
}
|
||||
|
||||
func (b Backend) InspectSecret(ctx context.Context, id string) (types.Secret, error) {
|
||||
func (b Backend) InspectSecret(ctx context.Context, id string) (compose.Secret, error) {
|
||||
return b.api.InspectSecret(ctx, id)
|
||||
}
|
||||
|
||||
func (b Backend) ListSecrets(ctx context.Context) ([]types.Secret, error) {
|
||||
func (b Backend) ListSecrets(ctx context.Context) ([]compose.Secret, error) {
|
||||
return b.api.ListSecrets(ctx)
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,13 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
)
|
||||
|
||||
func (b *Backend) Up(ctx context.Context, options compose.ProjectOptions) error {
|
||||
project, err := compose.ProjectFromOptions(&options)
|
||||
func (b *Backend) Up(ctx context.Context, options cli.ProjectOptions) error {
|
||||
project, err := cli.ProjectFromOptions(&options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -66,12 +67,12 @@ func (b *Backend) Up(ctx context.Context, options compose.ProjectOptions) error
|
|||
}
|
||||
|
||||
fmt.Println()
|
||||
return b.WaitStackCompletion(ctx, project.Name, types.StackCreate)
|
||||
return b.WaitStackCompletion(ctx, project.Name, compose.StackCreate)
|
||||
}
|
||||
|
||||
func (b Backend) GetVPC(ctx context.Context, project *compose.Project) (string, error) {
|
||||
func (b Backend) GetVPC(ctx context.Context, project *types.Project) (string, error) {
|
||||
//check compose file for custom VPC selected
|
||||
if vpc, ok := project.Extras[types.ExtensionVPC]; ok {
|
||||
if vpc, ok := project.Extensions[compose.ExtensionVPC]; ok {
|
||||
vpcID := vpc.(string)
|
||||
ok, err := b.api.VpcExists(ctx, vpcID)
|
||||
if err != nil {
|
||||
|
@ -88,9 +89,9 @@ func (b Backend) GetVPC(ctx context.Context, project *compose.Project) (string,
|
|||
return defaultVPC, nil
|
||||
}
|
||||
|
||||
func (b Backend) GetLoadBalancer(ctx context.Context, project *compose.Project) (string, error) {
|
||||
func (b Backend) GetLoadBalancer(ctx context.Context, project *types.Project) (string, error) {
|
||||
//check compose file for custom VPC selected
|
||||
if lb, ok := project.Extras[types.ExtensionLB]; ok {
|
||||
if lb, ok := project.Extensions[compose.ExtensionLB]; ok {
|
||||
lbName := lb.(string)
|
||||
ok, err := b.api.LoadBalancerExists(ctx, lbName)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
package compatibility
|
||||
|
||||
import (
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
)
|
||||
|
||||
type Warning string
|
||||
type Warnings []string
|
||||
|
||||
type Checker interface {
|
||||
CheckService(service *types.ServiceConfig)
|
||||
CheckCapAdd(service *types.ServiceConfig)
|
||||
CheckDNS(service *types.ServiceConfig)
|
||||
CheckDNSOpts(service *types.ServiceConfig)
|
||||
CheckDNSSearch(service *types.ServiceConfig)
|
||||
CheckDomainName(service *types.ServiceConfig)
|
||||
CheckExtraHosts(service *types.ServiceConfig)
|
||||
CheckHostname(service *types.ServiceConfig)
|
||||
CheckIpc(service *types.ServiceConfig)
|
||||
CheckLabels(service *types.ServiceConfig)
|
||||
CheckLinks(service *types.ServiceConfig)
|
||||
CheckLogging(service *types.ServiceConfig)
|
||||
CheckMacAddress(service *types.ServiceConfig)
|
||||
CheckNetworkMode(service *types.ServiceConfig)
|
||||
CheckPid(service *types.ServiceConfig)
|
||||
CheckSysctls(service *types.ServiceConfig)
|
||||
CheckTmpfs(service *types.ServiceConfig)
|
||||
CheckUserNSMode(service *types.ServiceConfig)
|
||||
Errors() []error
|
||||
}
|
||||
|
||||
// Check the compose model do not use unsupported features and inject sane defaults for ECS deployment
|
||||
func Check(project *compose.Project) []error {
|
||||
c := FargateCompatibilityChecker{}
|
||||
for i, service := range project.Services {
|
||||
c.CheckService(&service)
|
||||
project.Services[i] = service
|
||||
}
|
||||
return c.errors
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package compatibility
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func load(t *testing.T, paths ...string) *compose.Project {
|
||||
options := compose.ProjectOptions{
|
||||
Name: t.Name(),
|
||||
ConfigPaths: paths,
|
||||
}
|
||||
project, err := compose.ProjectFromOptions(&options)
|
||||
assert.NilError(t, err)
|
||||
return project
|
||||
}
|
||||
func TestInvalidNetworkMode(t *testing.T) {
|
||||
project := load(t, "../backend/testdata/invalid_network_mode.yaml")
|
||||
err := Check(project)
|
||||
assert.Error(t, err[0], "'network_mode' \"bridge\" is not supported")
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
package compatibility
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
)
|
||||
|
||||
type FargateCompatibilityChecker struct {
|
||||
errors []error
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) error(message string, args ...interface{}) {
|
||||
c.errors = append(c.errors, fmt.Errorf(message, args...))
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) Errors() []error {
|
||||
return c.errors
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckService(service *types.ServiceConfig) {
|
||||
c.CheckCapAdd(service)
|
||||
c.CheckDNS(service)
|
||||
c.CheckDNSOpts(service)
|
||||
c.CheckDNSSearch(service)
|
||||
c.CheckDomainName(service)
|
||||
c.CheckExtraHosts(service)
|
||||
c.CheckHostname(service)
|
||||
c.CheckIpc(service)
|
||||
c.CheckLabels(service)
|
||||
c.CheckLinks(service)
|
||||
c.CheckLogging(service)
|
||||
c.CheckMacAddress(service)
|
||||
c.CheckNetworkMode(service)
|
||||
c.CheckPid(service)
|
||||
c.CheckSysctls(service)
|
||||
c.CheckTmpfs(service)
|
||||
c.CheckUserNSMode(service)
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckNetworkMode(service *types.ServiceConfig) {
|
||||
if service.NetworkMode != "" && service.NetworkMode != ecs.NetworkModeAwsvpc {
|
||||
c.error("'network_mode' %q is not supported", service.NetworkMode)
|
||||
}
|
||||
service.NetworkMode = ecs.NetworkModeAwsvpc
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckLinks(service *types.ServiceConfig) {
|
||||
if len(service.Links) != 0 {
|
||||
c.error("'links' is not supported")
|
||||
service.Links = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckLogging(service *types.ServiceConfig) {
|
||||
c.CheckLoggingDriver(service)
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckLoggingDriver(service *types.ServiceConfig) {
|
||||
if service.LogDriver != "" && service.LogDriver != ecs.LogDriverAwslogs {
|
||||
c.error("'log_driver' %q is not supported", service.LogDriver)
|
||||
service.LogDriver = ecs.LogDriverAwslogs
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckPid(service *types.ServiceConfig) {
|
||||
if service.Pid != "" {
|
||||
c.error("'pid' is not supported")
|
||||
service.Pid = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckUserNSMode(service *types.ServiceConfig) {
|
||||
if service.UserNSMode != "" {
|
||||
c.error("'userns_mode' is not supported")
|
||||
service.UserNSMode = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckIpc(service *types.ServiceConfig) {
|
||||
if service.Ipc != "" {
|
||||
c.error("'ipc' is not supported")
|
||||
service.Ipc = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckMacAddress(service *types.ServiceConfig) {
|
||||
if service.MacAddress != "" {
|
||||
c.error("'mac_address' is not supported")
|
||||
service.MacAddress = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckHostname(service *types.ServiceConfig) {
|
||||
if service.Hostname != "" {
|
||||
c.error("'hostname' is not supported")
|
||||
service.Hostname = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckDomainName(service *types.ServiceConfig) {
|
||||
if service.DomainName != "" {
|
||||
c.error("'domainname' is not supported")
|
||||
service.DomainName = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckDNSSearch(service *types.ServiceConfig) {
|
||||
if len(service.DNSSearch) > 0 {
|
||||
c.error("'dns_search' is not supported")
|
||||
service.DNSSearch = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckDNS(service *types.ServiceConfig) {
|
||||
if len(service.DNS) > 0 {
|
||||
c.error("'dns' is not supported")
|
||||
service.DNS = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckDNSOpts(service *types.ServiceConfig) {
|
||||
if len(service.DNSOpts) > 0 {
|
||||
c.error("'dns_opt' is not supported")
|
||||
service.DNSOpts = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckExtraHosts(service *types.ServiceConfig) {
|
||||
if len(service.ExtraHosts) > 0 {
|
||||
c.error("'extra_hosts' is not supported")
|
||||
service.ExtraHosts = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckCapAdd(service *types.ServiceConfig) {
|
||||
for i, v := range service.CapAdd {
|
||||
if v != "SYS_PTRACE" {
|
||||
c.error("'cap_add' %s is not supported", v)
|
||||
l := len(service.CapAdd)
|
||||
service.CapAdd[i] = service.CapAdd[l-1]
|
||||
service.CapAdd = service.CapAdd[:l-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckTmpfs(service *types.ServiceConfig) {
|
||||
if len(service.Tmpfs) > 0 {
|
||||
c.error("'tmpfs' is not supported")
|
||||
service.Tmpfs = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckSysctls(service *types.ServiceConfig) {
|
||||
if len(service.Sysctls) > 0 {
|
||||
c.error("'sysctls' is not supported")
|
||||
service.Sysctls = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *FargateCompatibilityChecker) CheckLabels(service *types.ServiceConfig) {
|
||||
for k, v := range service.Labels {
|
||||
if v == "" {
|
||||
c.error("'labels' with an empty value is not supported")
|
||||
delete(service.Labels, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var _ Checker = &FargateCompatibilityChecker{}
|
|
@ -5,7 +5,7 @@ import (
|
|||
|
||||
cf "github.com/aws/aws-sdk-go/service/cloudformation"
|
||||
"github.com/awslabs/goformation/v4/cloudformation"
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
)
|
||||
|
||||
//go:generate mockgen -destination=./api_mock.go -self_package "github.com/docker/ecs-plugin/pkg/amazon" -package=amazon . API
|
||||
|
@ -38,19 +38,19 @@ type downAPI interface {
|
|||
}
|
||||
|
||||
type logsAPI interface {
|
||||
GetLogs(ctx context.Context, name string, consumer types.LogConsumer) error
|
||||
GetLogs(ctx context.Context, name string, consumer compose.LogConsumer) error
|
||||
}
|
||||
|
||||
type secretsAPI interface {
|
||||
CreateSecret(ctx context.Context, secret types.Secret) (string, error)
|
||||
InspectSecret(ctx context.Context, id string) (types.Secret, error)
|
||||
ListSecrets(ctx context.Context) ([]types.Secret, error)
|
||||
CreateSecret(ctx context.Context, secret compose.Secret) (string, error)
|
||||
InspectSecret(ctx context.Context, id string) (compose.Secret, error)
|
||||
ListSecrets(ctx context.Context) ([]compose.Secret, error)
|
||||
DeleteSecret(ctx context.Context, id string, recover bool) error
|
||||
}
|
||||
|
||||
type listAPI interface {
|
||||
ListTasks(ctx context.Context, cluster string, name string) ([]string, error)
|
||||
DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]types.TaskStatus, error)
|
||||
DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]compose.TaskStatus, error)
|
||||
GetPublicIPs(ctx context.Context, interfaces ...string) (map[string]string, error)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,10 @@ import (
|
|||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
|
||||
cloudformation "github.com/aws/aws-sdk-go/service/cloudformation"
|
||||
cloudformation0 "github.com/awslabs/goformation/v4/cloudformation"
|
||||
btypes "github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
)
|
||||
|
||||
|
@ -53,7 +54,7 @@ func (mr *MockAPIMockRecorder) ClusterExists(arg0, arg1 interface{}) *gomock.Cal
|
|||
}
|
||||
|
||||
// CreateSecret mocks base method
|
||||
func (m *MockAPI) CreateSecret(arg0 context.Context, arg1 btypes.Secret) (string, error) {
|
||||
func (m *MockAPI) CreateSecret(arg0 context.Context, arg1 compose.Secret) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateSecret", arg0, arg1)
|
||||
ret0, _ := ret[0].(string)
|
||||
|
@ -139,14 +140,14 @@ func (mr *MockAPIMockRecorder) DescribeStackEvents(arg0, arg1 interface{}) *gomo
|
|||
}
|
||||
|
||||
// DescribeTasks mocks base method
|
||||
func (m *MockAPI) DescribeTasks(arg0 context.Context, arg1 string, arg2 ...string) ([]btypes.TaskStatus, error) {
|
||||
func (m *MockAPI) DescribeTasks(arg0 context.Context, arg1 string, arg2 ...string) ([]compose.TaskStatus, error) {
|
||||
m.ctrl.T.Helper()
|
||||
varargs := []interface{}{arg0, arg1}
|
||||
for _, a := range arg2 {
|
||||
varargs = append(varargs, a)
|
||||
}
|
||||
ret := m.ctrl.Call(m, "DescribeTasks", varargs...)
|
||||
ret0, _ := ret[0].([]btypes.TaskStatus)
|
||||
ret0, _ := ret[0].([]compose.TaskStatus)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
@ -174,7 +175,7 @@ func (mr *MockAPIMockRecorder) GetDefaultVPC(arg0 interface{}) *gomock.Call {
|
|||
}
|
||||
|
||||
// GetLogs mocks base method
|
||||
func (m *MockAPI) GetLogs(arg0 context.Context, arg1 string, arg2 btypes.LogConsumer) error {
|
||||
func (m *MockAPI) GetLogs(arg0 context.Context, arg1 string, arg2 compose.LogConsumer) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetLogs", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(error)
|
||||
|
@ -238,10 +239,10 @@ func (mr *MockAPIMockRecorder) GetSubNets(arg0, arg1 interface{}) *gomock.Call {
|
|||
}
|
||||
|
||||
// InspectSecret mocks base method
|
||||
func (m *MockAPI) InspectSecret(arg0 context.Context, arg1 string) (btypes.Secret, error) {
|
||||
func (m *MockAPI) InspectSecret(arg0 context.Context, arg1 string) (compose.Secret, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InspectSecret", arg0, arg1)
|
||||
ret0, _ := ret[0].(btypes.Secret)
|
||||
ret0, _ := ret[0].(compose.Secret)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
@ -253,10 +254,10 @@ func (mr *MockAPIMockRecorder) InspectSecret(arg0, arg1 interface{}) *gomock.Cal
|
|||
}
|
||||
|
||||
// ListSecrets mocks base method
|
||||
func (m *MockAPI) ListSecrets(arg0 context.Context) ([]btypes.Secret, error) {
|
||||
func (m *MockAPI) ListSecrets(arg0 context.Context) ([]compose.Secret, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListSecrets", arg0)
|
||||
ret0, _ := ret[0].([]btypes.Secret)
|
||||
ret0, _ := ret[0].([]compose.Secret)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
|
|
@ -13,11 +13,10 @@ import (
|
|||
"github.com/awslabs/goformation/v4/cloudformation/tags"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/docker/cli/opts"
|
||||
t "github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
)
|
||||
|
||||
func Convert(project *compose.Project, service types.ServiceConfig) (*ecs.TaskDefinition, error) {
|
||||
func Convert(project *types.Project, service types.ServiceConfig) (*ecs.TaskDefinition, error) {
|
||||
cpu, mem, err := toLimits(service)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -318,8 +317,8 @@ func getImage(image string) string {
|
|||
|
||||
func getRepoCredentials(service types.ServiceConfig) *ecs.TaskDefinition_RepositoryCredentials {
|
||||
// extract registry and namespace string from image name
|
||||
for key, value := range service.Extras {
|
||||
if key == t.ExtensionPullCredentials {
|
||||
for key, value := range service.Extensions {
|
||||
if key == compose.ExtensionPullCredentials {
|
||||
return &ecs.TaskDefinition_RepositoryCredentials{CredentialsParameter: value.(string)}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,10 +23,8 @@ import (
|
|||
"github.com/aws/aws-sdk-go/service/secretsmanager"
|
||||
"github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface"
|
||||
cf "github.com/awslabs/goformation/v4/cloudformation"
|
||||
"github.com/docker/ecs-plugin/pkg/compose"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
t "github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
)
|
||||
|
||||
type sdk struct {
|
||||
|
@ -189,9 +187,9 @@ func (s sdk) WaitStackComplete(ctx context.Context, name string, operation int)
|
|||
StackName: aws.String(name),
|
||||
}
|
||||
switch operation {
|
||||
case t.StackCreate:
|
||||
case compose.StackCreate:
|
||||
return s.CF.WaitUntilStackCreateCompleteWithContext(ctx, input)
|
||||
case t.StackDelete:
|
||||
case compose.StackDelete:
|
||||
return s.CF.WaitUntilStackDeleteCompleteWithContext(ctx, input)
|
||||
default:
|
||||
return fmt.Errorf("internal error: unexpected stack operation %d", operation)
|
||||
|
@ -236,7 +234,7 @@ func (s sdk) DeleteStack(ctx context.Context, name string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (s sdk) CreateSecret(ctx context.Context, secret t.Secret) (string, error) {
|
||||
func (s sdk) CreateSecret(ctx context.Context, secret compose.Secret) (string, error) {
|
||||
logrus.Debug("Create secret " + secret.Name)
|
||||
secretStr, err := secret.GetCredString()
|
||||
if err != nil {
|
||||
|
@ -254,17 +252,17 @@ func (s sdk) CreateSecret(ctx context.Context, secret t.Secret) (string, error)
|
|||
return *response.ARN, nil
|
||||
}
|
||||
|
||||
func (s sdk) InspectSecret(ctx context.Context, id string) (t.Secret, error) {
|
||||
func (s sdk) InspectSecret(ctx context.Context, id string) (compose.Secret, error) {
|
||||
logrus.Debug("Inspect secret " + id)
|
||||
response, err := s.SM.DescribeSecret(&secretsmanager.DescribeSecretInput{SecretId: &id})
|
||||
if err != nil {
|
||||
return t.Secret{}, err
|
||||
return compose.Secret{}, err
|
||||
}
|
||||
labels := map[string]string{}
|
||||
for _, tag := range response.Tags {
|
||||
labels[*tag.Key] = *tag.Value
|
||||
}
|
||||
secret := t.Secret{
|
||||
secret := compose.Secret{
|
||||
ID: *response.ARN,
|
||||
Name: *response.Name,
|
||||
Labels: labels,
|
||||
|
@ -275,14 +273,14 @@ func (s sdk) InspectSecret(ctx context.Context, id string) (t.Secret, error) {
|
|||
return secret, nil
|
||||
}
|
||||
|
||||
func (s sdk) ListSecrets(ctx context.Context) ([]t.Secret, error) {
|
||||
func (s sdk) ListSecrets(ctx context.Context) ([]compose.Secret, error) {
|
||||
|
||||
logrus.Debug("List secrets ...")
|
||||
response, err := s.SM.ListSecrets(&secretsmanager.ListSecretsInput{})
|
||||
if err != nil {
|
||||
return []t.Secret{}, err
|
||||
return []compose.Secret{}, err
|
||||
}
|
||||
var secrets []t.Secret
|
||||
var secrets []compose.Secret
|
||||
|
||||
for _, sec := range response.SecretList {
|
||||
|
||||
|
@ -294,7 +292,7 @@ func (s sdk) ListSecrets(ctx context.Context) ([]t.Secret, error) {
|
|||
if sec.Description != nil {
|
||||
description = *sec.Description
|
||||
}
|
||||
secrets = append(secrets, t.Secret{
|
||||
secrets = append(secrets, compose.Secret{
|
||||
ID: *sec.ARN,
|
||||
Name: *sec.Name,
|
||||
Labels: labels,
|
||||
|
@ -311,7 +309,7 @@ func (s sdk) DeleteSecret(ctx context.Context, id string, recover bool) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (s sdk) GetLogs(ctx context.Context, name string, consumer types.LogConsumer) error {
|
||||
func (s sdk) GetLogs(ctx context.Context, name string, consumer compose.LogConsumer) error {
|
||||
logGroup := fmt.Sprintf("/docker-compose/%s", name)
|
||||
var startTime int64
|
||||
for {
|
||||
|
@ -357,7 +355,7 @@ func (s sdk) ListTasks(ctx context.Context, cluster string, service string) ([]s
|
|||
return arns, nil
|
||||
}
|
||||
|
||||
func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]t.TaskStatus, error) {
|
||||
func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string) ([]compose.TaskStatus, error) {
|
||||
tasks, err := s.ECS.DescribeTasksWithContext(ctx, &ecs.DescribeTasksInput{
|
||||
Cluster: aws.String(cluster),
|
||||
Tasks: aws.StringSlice(arns),
|
||||
|
@ -365,7 +363,7 @@ func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string)
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := []t.TaskStatus{}
|
||||
result := []compose.TaskStatus{}
|
||||
for _, task := range tasks.Tasks {
|
||||
var networkInterface string
|
||||
for _, attachement := range task.Attachments {
|
||||
|
@ -377,7 +375,7 @@ func (s sdk) DescribeTasks(ctx context.Context, cluster string, arns ...string)
|
|||
}
|
||||
}
|
||||
}
|
||||
result = append(result, t.TaskStatus{
|
||||
result = append(result, compose.TaskStatus{
|
||||
State: *task.LastStatus,
|
||||
Service: strings.Replace(*task.Group, "service:", "", 1),
|
||||
NetworkInterface: networkInterface,
|
||||
|
|
|
@ -4,19 +4,20 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/awslabs/goformation/v4/cloudformation"
|
||||
"github.com/docker/ecs-plugin/pkg/amazon/types"
|
||||
"github.com/compose-spec/compose-go/cli"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
)
|
||||
|
||||
type API interface {
|
||||
Up(ctx context.Context, options ProjectOptions) error
|
||||
Down(ctx context.Context, options ProjectOptions) error
|
||||
Up(ctx context.Context, options cli.ProjectOptions) error
|
||||
Down(ctx context.Context, options cli.ProjectOptions) error
|
||||
|
||||
Convert(project *Project) (*cloudformation.Template, error)
|
||||
Convert(project *types.Project) (*cloudformation.Template, error)
|
||||
Logs(ctx context.Context, projectName string) error
|
||||
Ps(background context.Context, project *Project) ([]types.TaskStatus, error)
|
||||
Ps(background context.Context, project *types.Project) ([]TaskStatus, error)
|
||||
|
||||
CreateSecret(ctx context.Context, secret types.Secret) (string, error)
|
||||
InspectSecret(ctx context.Context, id string) (types.Secret, error)
|
||||
ListSecrets(ctx context.Context) ([]types.Secret, error)
|
||||
CreateSecret(ctx context.Context, secret Secret) (string, error)
|
||||
InspectSecret(ctx context.Context, id string) (Secret, error)
|
||||
ListSecrets(ctx context.Context) ([]Secret, error)
|
||||
DeleteSecret(ctx context.Context, id string, recover bool) error
|
||||
}
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Normalize a compose-go model to move deprecated attributes to canonical position, and introduce implicit defaults
|
||||
// FIXME move this to compose-go
|
||||
func Normalize(model *types.Config) error {
|
||||
if len(model.Networks) == 0 {
|
||||
// Compose application model implies a default network if none is explicitly set.
|
||||
model.Networks["default"] = types.NetworkConfig{
|
||||
Name: "default",
|
||||
}
|
||||
}
|
||||
|
||||
for i, s := range model.Services {
|
||||
if len(s.Networks) == 0 {
|
||||
// Service without explicit network attachment are implicitly exposed on default network
|
||||
s.Networks = map[string]*types.ServiceNetworkConfig{"default": nil}
|
||||
}
|
||||
|
||||
for i, p := range s.Ports {
|
||||
if p.Published == 0 {
|
||||
p.Published = p.Target
|
||||
s.Ports[i] = p
|
||||
}
|
||||
}
|
||||
|
||||
if s.LogDriver != "" {
|
||||
logrus.Warn("`log_driver` is deprecated. Use the `logging` attribute")
|
||||
if s.Logging == nil {
|
||||
s.Logging = &types.LoggingConfig{}
|
||||
}
|
||||
if s.Logging.Driver == "" {
|
||||
s.Logging.Driver = s.LogDriver
|
||||
} else {
|
||||
return fmt.Errorf("can't use both 'log_driver' (deprecated) and 'logging.driver'")
|
||||
}
|
||||
}
|
||||
if len(s.LogOpt) != 0 {
|
||||
logrus.Warn("`log_opts` is deprecated. Use the `logging` attribute")
|
||||
if s.Logging == nil {
|
||||
s.Logging = &types.LoggingConfig{}
|
||||
}
|
||||
for k, v := range s.LogOpt {
|
||||
if _, ok := s.Logging.Options[k]; !ok {
|
||||
s.Logging.Options[k] = v
|
||||
} else {
|
||||
return fmt.Errorf("can't use both 'log_opt' (deprecated) and 'logging.options'")
|
||||
}
|
||||
}
|
||||
}
|
||||
model.Services[i] = s
|
||||
}
|
||||
|
||||
for i, n := range model.Networks {
|
||||
if n.Name == "" {
|
||||
n.Name = i
|
||||
model.Networks[i] = n
|
||||
}
|
||||
}
|
||||
|
||||
for i, v := range model.Volumes {
|
||||
if v.Name == "" {
|
||||
v.Name = i
|
||||
model.Volumes[i] = v
|
||||
}
|
||||
}
|
||||
|
||||
for i, c := range model.Configs {
|
||||
if c.Name == "" {
|
||||
c.Name = i
|
||||
model.Configs[i] = c
|
||||
}
|
||||
}
|
||||
|
||||
for i, s := range model.Secrets {
|
||||
if s.Name == "" {
|
||||
s.Name = i
|
||||
model.Secrets[i] = s
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
package compose
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/compose-spec/compose-go/loader"
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Project struct {
|
||||
types.Config
|
||||
projectDir string
|
||||
Name string `yaml:"-" json:"-"`
|
||||
}
|
||||
|
||||
func NewProject(config types.ConfigDetails, name string) (*Project, error) {
|
||||
model, err := loader.Load(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = Normalize(model)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := Project{
|
||||
Config: *model,
|
||||
projectDir: config.WorkingDir,
|
||||
Name: name,
|
||||
}
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// projectFromOptions load a compose project based on command line options
|
||||
func ProjectFromOptions(options *ProjectOptions) (*Project, error) {
|
||||
configPath, err := getConfigPathFromOptions(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name := options.Name
|
||||
if name == "" {
|
||||
name = os.Getenv("COMPOSE_PROJECT_NAME")
|
||||
}
|
||||
|
||||
workingDir := filepath.Dir(configPath[0])
|
||||
|
||||
if name == "" {
|
||||
r := regexp.MustCompile(`[^a-z0-9\\-_]+`)
|
||||
name = r.ReplaceAllString(strings.ToLower(filepath.Base(workingDir)), "")
|
||||
}
|
||||
|
||||
configs, err := parseConfigs(configPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewProject(types.ConfigDetails{
|
||||
WorkingDir: workingDir,
|
||||
ConfigFiles: configs,
|
||||
Environment: environment(),
|
||||
}, name)
|
||||
}
|
||||
|
||||
func getConfigPathFromOptions(options *ProjectOptions) ([]string, error) {
|
||||
paths := []string{}
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(options.ConfigPaths) != 0 {
|
||||
for _, f := range options.ConfigPaths {
|
||||
if f == "-" {
|
||||
paths = append(paths, f)
|
||||
continue
|
||||
}
|
||||
if !filepath.IsAbs(f) {
|
||||
f = filepath.Join(pwd, f)
|
||||
}
|
||||
if _, err := os.Stat(f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
paths = append(paths, f)
|
||||
}
|
||||
return paths, nil
|
||||
}
|
||||
|
||||
sep := os.Getenv("COMPOSE_FILE_SEPARATOR")
|
||||
if sep == "" {
|
||||
sep = string(os.PathListSeparator)
|
||||
}
|
||||
f := os.Getenv("COMPOSE_FILE")
|
||||
if f != "" {
|
||||
return strings.Split(f, sep), nil
|
||||
}
|
||||
|
||||
for {
|
||||
candidates := []string{}
|
||||
for _, n := range SupportedFilenames {
|
||||
f := filepath.Join(pwd, n)
|
||||
if _, err := os.Stat(f); err == nil {
|
||||
candidates = append(candidates, f)
|
||||
}
|
||||
}
|
||||
if len(candidates) > 0 {
|
||||
winner := candidates[0]
|
||||
if len(candidates) > 1 {
|
||||
logrus.Warnf("Found multiple config files with supported names: %s", strings.Join(candidates, ", "))
|
||||
logrus.Warnf("Using %s\n", winner)
|
||||
}
|
||||
return []string{winner}, nil
|
||||
}
|
||||
parent := filepath.Dir(pwd)
|
||||
if parent == pwd {
|
||||
return nil, fmt.Errorf("Can't find a suitable configuration file in this directory or any parent. Are you in the right directory?")
|
||||
}
|
||||
pwd = parent
|
||||
}
|
||||
}
|
||||
|
||||
var SupportedFilenames = []string{"compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml"}
|
||||
|
||||
func parseConfigs(configPaths []string) ([]types.ConfigFile, error) {
|
||||
files := []types.ConfigFile{}
|
||||
for _, f := range configPaths {
|
||||
var (
|
||||
b []byte
|
||||
err error
|
||||
)
|
||||
if f == "-" {
|
||||
b, err = ioutil.ReadAll(os.Stdin)
|
||||
} else {
|
||||
if _, err := os.Stat(f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b, err = ioutil.ReadFile(f)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config, err := loader.ParseYAML(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files = append(files, types.ConfigFile{Filename: f, Config: config})
|
||||
}
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func environment() map[string]string {
|
||||
return getAsEqualsMap(os.Environ())
|
||||
}
|
||||
|
||||
// getAsEqualsMap split key=value formatted strings into a key : value map
|
||||
func getAsEqualsMap(em []string) map[string]string {
|
||||
m := make(map[string]string)
|
||||
for _, v := range em {
|
||||
kv := strings.SplitN(v, "=", 2)
|
||||
m[kv[0]] = kv[1]
|
||||
}
|
||||
return m
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
package compose
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func Test_project_name(t *testing.T) {
|
||||
p, err := ProjectFromOptions(&ProjectOptions{
|
||||
Name: "my_project",
|
||||
ConfigPaths: []string{"testdata/simple/compose.yaml"},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.Name, "my_project")
|
||||
|
||||
p, err = ProjectFromOptions(&ProjectOptions{
|
||||
Name: "",
|
||||
ConfigPaths: []string{"testdata/simple/compose.yaml"},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.Name, "simple")
|
||||
|
||||
os.Setenv("COMPOSE_PROJECT_NAME", "my_project_from_env")
|
||||
p, err = ProjectFromOptions(&ProjectOptions{
|
||||
Name: "",
|
||||
ConfigPaths: []string{"testdata/simple/compose.yaml"},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, p.Name, "my_project_from_env")
|
||||
}
|
||||
|
||||
func Test_project_from_set_of_files(t *testing.T) {
|
||||
p, err := ProjectFromOptions(&ProjectOptions{
|
||||
Name: "my_project",
|
||||
ConfigPaths: []string{
|
||||
"testdata/simple/compose.yaml",
|
||||
"testdata/simple/compose-with-overrides.yaml",
|
||||
},
|
||||
})
|
||||
assert.NilError(t, err)
|
||||
service, err := p.GetService("simple")
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, service.Image, "haproxy")
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package types
|
||||
package compose
|
||||
|
||||
import "encoding/json"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package types
|
||||
package compose
|
||||
|
||||
const (
|
||||
ExtensionSecurityGroup = "x-aws-securitygroup"
|
Loading…
Reference in New Issue