mirror of
https://github.com/docker/compose.git
synced 2025-07-25 14:44:29 +02:00
Introduce ECS emulation mode
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
ed1776fec0
commit
7f8bb030e6
@ -396,6 +396,10 @@ func (cs *aciComposeService) Up(ctx context.Context, project *types.Project) err
|
|||||||
return createOrUpdateACIContainers(ctx, cs.ctx, groupDefinition)
|
return createOrUpdateACIContainers(ctx, cs.ctx, groupDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *aciComposeService) Emulate(context.Context, *cli.ProjectOptions) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func (cs *aciComposeService) Down(ctx context.Context, project string) error {
|
func (cs *aciComposeService) Down(ctx context.Context, project string) error {
|
||||||
logrus.Debugf("Down on project with name %q\n", project)
|
logrus.Debugf("Down on project with name %q\n", project)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ func (o *composeOptions) toProjectOptions() (*cli.ProjectOptions, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Command returns the compose command with its child commands
|
// Command returns the compose command with its child commands
|
||||||
func Command() *cobra.Command {
|
func Command(contextType string) *cobra.Command {
|
||||||
command := &cobra.Command{
|
command := &cobra.Command{
|
||||||
Short: "Docker Compose",
|
Short: "Docker Compose",
|
||||||
Use: "compose",
|
Use: "compose",
|
||||||
@ -70,7 +70,7 @@ func Command() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
command.AddCommand(
|
command.AddCommand(
|
||||||
upCommand(),
|
upCommand(contextType),
|
||||||
downCommand(),
|
downCommand(),
|
||||||
psCommand(),
|
psCommand(),
|
||||||
logsCommand(),
|
logsCommand(),
|
||||||
|
@ -24,15 +24,17 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/docker/compose-cli/client"
|
"github.com/docker/compose-cli/client"
|
||||||
|
"github.com/docker/compose-cli/context/store"
|
||||||
"github.com/docker/compose-cli/progress"
|
"github.com/docker/compose-cli/progress"
|
||||||
)
|
)
|
||||||
|
|
||||||
func upCommand() *cobra.Command {
|
func upCommand(contextType string) *cobra.Command {
|
||||||
opts := composeOptions{}
|
opts := composeOptions{}
|
||||||
|
var simulation bool
|
||||||
upCmd := &cobra.Command{
|
upCmd := &cobra.Command{
|
||||||
Use: "up",
|
Use: "up",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runUp(cmd.Context(), opts)
|
return runUp(cmd.Context(), opts, simulation)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
upCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name")
|
upCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name")
|
||||||
@ -40,11 +42,14 @@ func upCommand() *cobra.Command {
|
|||||||
upCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
|
upCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
|
||||||
upCmd.Flags().StringArrayVarP(&opts.Environment, "environment", "e", []string{}, "Environment variables")
|
upCmd.Flags().StringArrayVarP(&opts.Environment, "environment", "e", []string{}, "Environment variables")
|
||||||
upCmd.Flags().BoolP("detach", "d", true, " Detached mode: Run containers in the background")
|
upCmd.Flags().BoolP("detach", "d", true, " Detached mode: Run containers in the background")
|
||||||
|
if contextType == store.EcsContextType {
|
||||||
|
upCmd.Flags().BoolVar(&simulation, "simulate", false, " Simulation mode: run compose app with ECS local container endpoints")
|
||||||
|
}
|
||||||
|
|
||||||
return upCmd
|
return upCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runUp(ctx context.Context, opts composeOptions) error {
|
func runUp(ctx context.Context, opts composeOptions, simulation bool) error {
|
||||||
c, err := client.New(ctx)
|
c, err := client.New(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -60,6 +65,9 @@ func runUp(ctx context.Context, opts composeOptions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if simulation {
|
||||||
|
return c.ComposeService().Emulate(ctx, options)
|
||||||
|
}
|
||||||
return c.ComposeService().Up(ctx, project)
|
return c.ComposeService().Up(ctx, project)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,6 @@ func main() {
|
|||||||
cmd.RmCommand(),
|
cmd.RmCommand(),
|
||||||
cmd.StartCommand(),
|
cmd.StartCommand(),
|
||||||
cmd.InspectCommand(),
|
cmd.InspectCommand(),
|
||||||
compose.Command(),
|
|
||||||
login.Command(),
|
login.Command(),
|
||||||
logout.Command(),
|
logout.Command(),
|
||||||
cmd.VersionCommand(version),
|
cmd.VersionCommand(version),
|
||||||
@ -184,6 +183,8 @@ func main() {
|
|||||||
$ docker context create %s <name>`, cc.Type(), store.EcsContextType))
|
$ docker context create %s <name>`, cc.Type(), store.EcsContextType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
root.AddCommand(compose.Command(ctype))
|
||||||
|
|
||||||
metrics.Track(ctype, os.Args[1:], root.PersistentFlags())
|
metrics.Track(ctype, os.Args[1:], root.PersistentFlags())
|
||||||
|
|
||||||
ctx = apicontext.WithCurrentContext(ctx, currentContext)
|
ctx = apicontext.WithCurrentContext(ctx, currentContext)
|
||||||
|
@ -34,6 +34,11 @@ func (c *composeService) Up(context.Context, *types.Project) error {
|
|||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emulate executes the equivalent to a `compose up` in platform emulation mode
|
||||||
|
func (c *composeService) Emulate(context.Context, *cli.ProjectOptions) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
// Down executes the equivalent to a `compose down`
|
// Down executes the equivalent to a `compose down`
|
||||||
func (c *composeService) Down(context.Context, string) error {
|
func (c *composeService) Down(context.Context, string) error {
|
||||||
return errdefs.ErrNotImplemented
|
return errdefs.ErrNotImplemented
|
||||||
|
@ -35,6 +35,8 @@ type Service interface {
|
|||||||
Ps(ctx context.Context, projectName string) ([]ServiceStatus, error)
|
Ps(ctx context.Context, projectName string) ([]ServiceStatus, error)
|
||||||
// Convert translate compose model into backend's native format
|
// Convert translate compose model into backend's native format
|
||||||
Convert(ctx context.Context, project *types.Project) ([]byte, error)
|
Convert(ctx context.Context, project *types.Project) ([]byte, error)
|
||||||
|
// Emulate executes the equivalent to a `compose up` in platform emulation mode
|
||||||
|
Emulate(ctx context.Context, options *cli.ProjectOptions) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// PortPublisher hold status about published port
|
// PortPublisher hold status about published port
|
||||||
|
112
ecs/emulate.go
Normal file
112
ecs/emulate.go
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 Docker, Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ecs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
"github.com/sanathkr/go-yaml"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *ecsAPIService) Emulate(ctx context.Context, options *cli.ProjectOptions) error {
|
||||||
|
project, err := cli.ProjectFromOptions(options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
project.Networks["credentials_network"] = types.NetworkConfig{
|
||||||
|
Driver: "bridge",
|
||||||
|
Ipam: types.IPAMConfig{
|
||||||
|
Config: []*types.IPAMPool{
|
||||||
|
{
|
||||||
|
Subnet: "169.254.170.0/24",
|
||||||
|
Gateway: "169.254.170.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// On Windows, this directory can be found at "%UserProfile%\.aws"
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, service := range project.Services {
|
||||||
|
service.Networks["credentials_network"] = &types.ServiceNetworkConfig{
|
||||||
|
Ipv4Address: fmt.Sprintf("169.254.170.%d", i+3),
|
||||||
|
}
|
||||||
|
service.DependsOn = append(service.DependsOn, "ecs-local-endpoints")
|
||||||
|
service.Environment["AWS_DEFAULT_REGION"] = aws.String(c.ctx.Region)
|
||||||
|
service.Environment["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"] = aws.String("/creds")
|
||||||
|
service.Environment["ECS_CONTAINER_METADATA_URI"] = aws.String("http://169.254.170.2/v3")
|
||||||
|
project.Services[i] = service
|
||||||
|
}
|
||||||
|
|
||||||
|
project.Services = append(project.Services, types.ServiceConfig{
|
||||||
|
Name: "ecs-local-endpoints",
|
||||||
|
Image: "amazon/amazon-ecs-local-container-endpoints",
|
||||||
|
Volumes: []types.ServiceVolumeConfig{
|
||||||
|
{
|
||||||
|
Type: types.VolumeTypeBind,
|
||||||
|
Source: "/var/run",
|
||||||
|
Target: "/var/run",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: types.VolumeTypeBind,
|
||||||
|
Source: filepath.Join(home, ".aws"),
|
||||||
|
Target: "/home/.aws",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Environment: map[string]*string{
|
||||||
|
"HOME": aws.String("/home"),
|
||||||
|
"AWS_PROFILE": aws.String("default"),
|
||||||
|
},
|
||||||
|
Networks: map[string]*types.ServiceNetworkConfig{
|
||||||
|
"credentials_network": {
|
||||||
|
Ipv4Address: "169.254.170.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
delete(project.Networks, "default")
|
||||||
|
config := map[string]interface{}{
|
||||||
|
"services": project.Services,
|
||||||
|
"networks": project.Networks,
|
||||||
|
"volumes": project.Volumes,
|
||||||
|
"secrets": project.Secrets,
|
||||||
|
"configs": project.Configs,
|
||||||
|
}
|
||||||
|
marshal, err := yaml.Marshal(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("docker-compose", "--context", "default", "--project-directory", project.WorkingDir, "--project-name", project.Name, "-f", "-", "up")
|
||||||
|
cmd.Stdin = strings.NewReader(string(marshal))
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
return cmd.Run()
|
||||||
|
}
|
@ -132,6 +132,10 @@ func (cs *composeService) Down(ctx context.Context, project string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs *composeService) Emulate(context.Context, *cli.ProjectOptions) error {
|
||||||
|
return errdefs.ErrNotImplemented
|
||||||
|
}
|
||||||
|
|
||||||
func (cs *composeService) Ps(ctx context.Context, project string) ([]compose.ServiceStatus, error) {
|
func (cs *composeService) Ps(ctx context.Context, project string) ([]compose.ServiceStatus, error) {
|
||||||
return nil, errdefs.ErrNotImplemented
|
return nil, errdefs.ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
3
go.mod
3
go.mod
@ -22,7 +22,7 @@ require (
|
|||||||
github.com/aws/aws-sdk-go v1.34.8
|
github.com/aws/aws-sdk-go v1.34.8
|
||||||
github.com/awslabs/goformation/v4 v4.14.0
|
github.com/awslabs/goformation/v4 v4.14.0
|
||||||
github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129
|
github.com/buger/goterm v0.0.0-20200322175922-2f3e71b85129
|
||||||
github.com/compose-spec/compose-go v0.0.0-20200818070525-eb1188aae4a2
|
github.com/compose-spec/compose-go v0.0.0-20200824075806-a70cd5945c25
|
||||||
github.com/containerd/console v1.0.0
|
github.com/containerd/console v1.0.0
|
||||||
github.com/containerd/containerd v1.3.5 // indirect
|
github.com/containerd/containerd v1.3.5 // indirect
|
||||||
github.com/docker/cli v0.0.0-20200528204125-dd360c7c0de8
|
github.com/docker/cli v0.0.0-20200528204125-dd360c7c0de8
|
||||||
@ -46,6 +46,7 @@ require (
|
|||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/opencontainers/runc v0.1.1 // indirect
|
github.com/opencontainers/runc v0.1.1 // indirect
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
|
github.com/sanathkr/go-yaml v0.0.0-20170819195128-ed9d249f429b
|
||||||
github.com/sirupsen/logrus v1.6.0
|
github.com/sirupsen/logrus v1.6.0
|
||||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||||
github.com/spf13/cobra v1.0.0
|
github.com/spf13/cobra v1.0.0
|
||||||
|
4
go.sum
4
go.sum
@ -87,8 +87,8 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
|||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||||
github.com/compose-spec/compose-go v0.0.0-20200818070525-eb1188aae4a2 h1:b3JmHJVJt8zXy112yGtRq74G32sPQ8XLJxfHKaP/DOg=
|
github.com/compose-spec/compose-go v0.0.0-20200824075806-a70cd5945c25 h1:mVlGrHJuNGPJNEvCCIrDIZX5FYtNTwFd++y+fJaGTXM=
|
||||||
github.com/compose-spec/compose-go v0.0.0-20200818070525-eb1188aae4a2/go.mod h1:P7PZ0svgjrZ8nv/XvxObbl8o0DCIE9ZbL8pllg6uL4w=
|
github.com/compose-spec/compose-go v0.0.0-20200824075806-a70cd5945c25/go.mod h1:P7PZ0svgjrZ8nv/XvxObbl8o0DCIE9ZbL8pllg6uL4w=
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
|
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
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/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user