mirror of https://github.com/docker/compose.git
Use compose-go's Project and ProjectOptions
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
664c48ba1e
commit
622402709a
|
@ -26,6 +26,7 @@ import (
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
|
"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
@ -167,28 +168,26 @@ func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerCo
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
project := compose.Project{
|
project := types.Project{
|
||||||
Name: r.ID,
|
Name: r.ID,
|
||||||
Config: types.Config{
|
Services: []types.ServiceConfig{
|
||||||
Services: []types.ServiceConfig{
|
{
|
||||||
{
|
Name: singleContainerName,
|
||||||
Name: singleContainerName,
|
Image: r.Image,
|
||||||
Image: r.Image,
|
Ports: ports,
|
||||||
Ports: ports,
|
Labels: r.Labels,
|
||||||
Labels: r.Labels,
|
Volumes: serviceConfigVolumes,
|
||||||
Volumes: serviceConfigVolumes,
|
Deploy: &types.DeployConfig{
|
||||||
Deploy: &types.DeployConfig{
|
Resources: types.Resources{
|
||||||
Resources: types.Resources{
|
Limits: &types.Resource{
|
||||||
Limits: &types.Resource{
|
NanoCPUs: fmt.Sprintf("%f", r.CPULimit),
|
||||||
NanoCPUs: fmt.Sprintf("%f", r.CPULimit),
|
MemoryBytes: types.UnitBytes(r.MemLimit.Value()),
|
||||||
MemoryBytes: types.UnitBytes(r.MemLimit.Value()),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Volumes: projectVolumes,
|
|
||||||
},
|
},
|
||||||
|
Volumes: projectVolumes,
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf("Running container %q with name %q\n", r.Image, r.ID)
|
logrus.Debugf("Running container %q with name %q\n", r.Image, r.ID)
|
||||||
|
@ -301,8 +300,8 @@ type aciComposeService struct {
|
||||||
ctx store.AciContext
|
ctx store.AciContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *aciComposeService) Up(ctx context.Context, opts compose.ProjectOptions) error {
|
func (cs *aciComposeService) Up(ctx context.Context, opts cli.ProjectOptions) error {
|
||||||
project, err := compose.ProjectFromOptions(&opts)
|
project, err := cli.ProjectFromOptions(&opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -315,8 +314,8 @@ func (cs *aciComposeService) Up(ctx context.Context, opts compose.ProjectOptions
|
||||||
return createOrUpdateACIContainers(ctx, cs.ctx, groupDefinition)
|
return createOrUpdateACIContainers(ctx, cs.ctx, groupDefinition)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *aciComposeService) Down(ctx context.Context, opts compose.ProjectOptions) error {
|
func (cs *aciComposeService) Down(ctx context.Context, opts cli.ProjectOptions) error {
|
||||||
project, err := compose.ProjectFromOptions(&opts)
|
project, err := cli.ProjectFromOptions(&opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ import (
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
|
||||||
"github.com/docker/api/compose"
|
|
||||||
"github.com/docker/api/containers"
|
"github.com/docker/api/containers"
|
||||||
"github.com/docker/api/context/store"
|
"github.com/docker/api/context/store"
|
||||||
)
|
)
|
||||||
|
@ -47,7 +46,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToContainerGroup converts a compose project into a ACI container group
|
// ToContainerGroup converts a compose project into a ACI container group
|
||||||
func ToContainerGroup(aciContext store.AciContext, p compose.Project) (containerinstance.ContainerGroup, error) {
|
func ToContainerGroup(aciContext store.AciContext, p types.Project) (containerinstance.ContainerGroup, error) {
|
||||||
project := projectAciHelper(p)
|
project := projectAciHelper(p)
|
||||||
containerGroupName := strings.ToLower(project.Name)
|
containerGroupName := strings.ToLower(project.Name)
|
||||||
volumesCache, volumesSlice, err := project.getAciFileVolumes()
|
volumesCache, volumesSlice, err := project.getAciFileVolumes()
|
||||||
|
@ -154,7 +153,7 @@ func getDNSSidecar(containers []containerinstance.Container) containerinstance.C
|
||||||
return dnsSideCar
|
return dnsSideCar
|
||||||
}
|
}
|
||||||
|
|
||||||
type projectAciHelper compose.Project
|
type projectAciHelper types.Project
|
||||||
|
|
||||||
func (p projectAciHelper) getAciSecretVolumes() ([]containerinstance.Volume, error) {
|
func (p projectAciHelper) getAciSecretVolumes() ([]containerinstance.Volume, error) {
|
||||||
var secretVolumes []containerinstance.Volume
|
var secretVolumes []containerinstance.Volume
|
||||||
|
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
|
||||||
"github.com/docker/api/compose"
|
|
||||||
"github.com/docker/api/containers"
|
"github.com/docker/api/containers"
|
||||||
"github.com/docker/api/context/store"
|
"github.com/docker/api/context/store"
|
||||||
|
|
||||||
|
@ -46,7 +45,7 @@ func (suite *ConvertTestSuite) BeforeTest(suiteName, testName string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ConvertTestSuite) TestProjectName() {
|
func (suite *ConvertTestSuite) TestProjectName() {
|
||||||
project := compose.Project{
|
project := types.Project{
|
||||||
Name: "TEST",
|
Name: "TEST",
|
||||||
}
|
}
|
||||||
containerGroup, err := ToContainerGroup(suite.ctx, project)
|
containerGroup, err := ToContainerGroup(suite.ctx, project)
|
||||||
|
@ -110,18 +109,15 @@ func (suite *ConvertTestSuite) TestContainerGroupToContainer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerWithDnsSideCarSide() {
|
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerWithDnsSideCarSide() {
|
||||||
project := compose.Project{
|
project := types.Project{
|
||||||
Name: "",
|
Services: []types.ServiceConfig{
|
||||||
Config: types.Config{
|
{
|
||||||
Services: []types.ServiceConfig{
|
Name: "service1",
|
||||||
{
|
Image: "image1",
|
||||||
Name: "service1",
|
},
|
||||||
Image: "image1",
|
{
|
||||||
},
|
Name: "service2",
|
||||||
{
|
Image: "image2",
|
||||||
Name: "service2",
|
|
||||||
Image: "image2",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -142,14 +138,11 @@ func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerWithDnsSideCa
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ConvertTestSuite) TestComposeSingleContainerGroupToContainerNoDnsSideCarSide() {
|
func (suite *ConvertTestSuite) TestComposeSingleContainerGroupToContainerNoDnsSideCarSide() {
|
||||||
project := compose.Project{
|
project := types.Project{
|
||||||
Name: "",
|
Services: []types.ServiceConfig{
|
||||||
Config: types.Config{
|
{
|
||||||
Services: []types.ServiceConfig{
|
Name: "service1",
|
||||||
{
|
Image: "image1",
|
||||||
Name: "service1",
|
|
||||||
Image: "image1",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -163,28 +156,25 @@ func (suite *ConvertTestSuite) TestComposeSingleContainerGroupToContainerNoDnsSi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerMultiplePorts() {
|
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerMultiplePorts() {
|
||||||
project := compose.Project{
|
project := types.Project{
|
||||||
Name: "",
|
Services: []types.ServiceConfig{
|
||||||
Config: types.Config{
|
{
|
||||||
Services: []types.ServiceConfig{
|
Name: "service1",
|
||||||
{
|
Image: "image1",
|
||||||
Name: "service1",
|
Ports: []types.ServicePortConfig{
|
||||||
Image: "image1",
|
{
|
||||||
Ports: []types.ServicePortConfig{
|
Published: 80,
|
||||||
{
|
Target: 80,
|
||||||
Published: 80,
|
|
||||||
Target: 80,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
Name: "service2",
|
{
|
||||||
Image: "image2",
|
Name: "service2",
|
||||||
Ports: []types.ServicePortConfig{
|
Image: "image2",
|
||||||
{
|
Ports: []types.ServicePortConfig{
|
||||||
Published: 8080,
|
{
|
||||||
Target: 8080,
|
Published: 8080,
|
||||||
},
|
Target: 8080,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -215,19 +205,16 @@ func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerMultiplePorts
|
||||||
|
|
||||||
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimits() {
|
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimits() {
|
||||||
_0_1Gb := 0.1 * 1024 * 1024 * 1024
|
_0_1Gb := 0.1 * 1024 * 1024 * 1024
|
||||||
project := compose.Project{
|
project := types.Project{
|
||||||
Name: "",
|
Services: []types.ServiceConfig{
|
||||||
Config: types.Config{
|
{
|
||||||
Services: []types.ServiceConfig{
|
Name: "service1",
|
||||||
{
|
Image: "image1",
|
||||||
Name: "service1",
|
Deploy: &types.DeployConfig{
|
||||||
Image: "image1",
|
Resources: types.Resources{
|
||||||
Deploy: &types.DeployConfig{
|
Limits: &types.Resource{
|
||||||
Resources: types.Resources{
|
NanoCPUs: "0.1",
|
||||||
Limits: &types.Resource{
|
MemoryBytes: types.UnitBytes(_0_1Gb),
|
||||||
NanoCPUs: "0.1",
|
|
||||||
MemoryBytes: types.UnitBytes(_0_1Gb),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -245,19 +232,16 @@ func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimitsDefaults() {
|
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimitsDefaults() {
|
||||||
project := compose.Project{
|
project := types.Project{
|
||||||
Name: "",
|
Services: []types.ServiceConfig{
|
||||||
Config: types.Config{
|
{
|
||||||
Services: []types.ServiceConfig{
|
Name: "service1",
|
||||||
{
|
Image: "image1",
|
||||||
Name: "service1",
|
Deploy: &types.DeployConfig{
|
||||||
Image: "image1",
|
Resources: types.Resources{
|
||||||
Deploy: &types.DeployConfig{
|
Limits: &types.Resource{
|
||||||
Resources: types.Resources{
|
NanoCPUs: "",
|
||||||
Limits: &types.Resource{
|
MemoryBytes: 0,
|
||||||
NanoCPUs: "",
|
|
||||||
MemoryBytes: 0,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,11 +23,10 @@ import (
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance"
|
"github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance"
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
|
compose "github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/cli/cli/config"
|
"github.com/docker/cli/cli/config"
|
||||||
"github.com/docker/cli/cli/config/configfile"
|
"github.com/docker/cli/cli/config/configfile"
|
||||||
"github.com/docker/cli/cli/config/types"
|
"github.com/docker/cli/cli/config/types"
|
||||||
|
|
||||||
"github.com/docker/api/compose"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Specific username from ACR docs : https://github.com/Azure/acr/blob/master/docs/AAD-OAuth.md#getting-credentials-programatically
|
// Specific username from ACR docs : https://github.com/Azure/acr/blob/master/docs/AAD-OAuth.md#getting-credentials-programatically
|
||||||
|
|
|
@ -24,8 +24,6 @@ import (
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
cliconfigtypes "github.com/docker/cli/cli/config/types"
|
cliconfigtypes "github.com/docker/cli/cli/config/types"
|
||||||
|
|
||||||
"github.com/docker/api/compose"
|
|
||||||
|
|
||||||
"github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance"
|
"github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance"
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
|
@ -173,7 +171,7 @@ func (suite *RegistryConvertTestSuite) TestHubAndSeveralACRRegistries() {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func composeServices(images ...string) compose.Project {
|
func composeServices(images ...string) types.Project {
|
||||||
var services []types.ServiceConfig
|
var services []types.ServiceConfig
|
||||||
for index, name := range images {
|
for index, name := range images {
|
||||||
service := types.ServiceConfig{
|
service := types.ServiceConfig{
|
||||||
|
@ -182,10 +180,8 @@ func composeServices(images ...string) compose.Project {
|
||||||
}
|
}
|
||||||
services = append(services, service)
|
services = append(services, service)
|
||||||
}
|
}
|
||||||
return compose.Project{
|
return types.Project{
|
||||||
Config: types.Config{
|
Services: services,
|
||||||
Services: services,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,14 +20,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/docker/api/client"
|
"github.com/docker/api/client"
|
||||||
"github.com/docker/api/compose"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func downCommand() *cobra.Command {
|
func downCommand() *cobra.Command {
|
||||||
opts := compose.ProjectOptions{}
|
opts := cli.ProjectOptions{}
|
||||||
downCmd := &cobra.Command{
|
downCmd := &cobra.Command{
|
||||||
Use: "down",
|
Use: "down",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
@ -35,13 +35,13 @@ func downCommand() *cobra.Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
downCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name")
|
downCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name")
|
||||||
downCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir")
|
downCmd.Flags().StringVar(&opts.WorkingDir, "workdir", ".", "Work dir")
|
||||||
downCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
|
downCmd.Flags().StringArrayVarP(&opts.ConfigPaths, "file", "f", []string{}, "Compose configuration files")
|
||||||
|
|
||||||
return downCmd
|
return downCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDown(ctx context.Context, opts compose.ProjectOptions) error {
|
func runDown(ctx context.Context, opts cli.ProjectOptions) error {
|
||||||
c, err := client.New(ctx)
|
c, err := client.New(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -20,15 +20,15 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/docker/api/client"
|
"github.com/docker/api/client"
|
||||||
"github.com/docker/api/compose"
|
|
||||||
"github.com/docker/api/progress"
|
"github.com/docker/api/progress"
|
||||||
)
|
)
|
||||||
|
|
||||||
func upCommand() *cobra.Command {
|
func upCommand() *cobra.Command {
|
||||||
opts := compose.ProjectOptions{}
|
opts := cli.ProjectOptions{}
|
||||||
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 {
|
||||||
|
@ -36,7 +36,7 @@ func upCommand() *cobra.Command {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
upCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name")
|
upCmd.Flags().StringVarP(&opts.Name, "project-name", "p", "", "Project name")
|
||||||
upCmd.Flags().StringVar(&opts.WorkDir, "workdir", ".", "Work dir")
|
upCmd.Flags().StringVar(&opts.WorkingDir, "workdir", ".", "Work dir")
|
||||||
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")
|
||||||
|
@ -44,7 +44,7 @@ func upCommand() *cobra.Command {
|
||||||
return upCmd
|
return upCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runUp(ctx context.Context, opts compose.ProjectOptions) error {
|
func runUp(ctx context.Context, opts cli.ProjectOptions) error {
|
||||||
c, err := client.New(ctx)
|
c, err := client.New(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -18,12 +18,14 @@ package compose
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Service manages a compose project
|
// Service manages a compose project
|
||||||
type Service interface {
|
type Service interface {
|
||||||
// Up executes the equivalent to a `compose up`
|
// Up executes the equivalent to a `compose up`
|
||||||
Up(ctx context.Context, opts ProjectOptions) error
|
Up(ctx context.Context, opts cli.ProjectOptions) error
|
||||||
// Down executes the equivalent to a `compose down`
|
// Down executes the equivalent to a `compose down`
|
||||||
Down(ctx context.Context, opts ProjectOptions) error
|
Down(ctx context.Context, opts cli.ProjectOptions) error
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,172 +0,0 @@
|
||||||
/*
|
|
||||||
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 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"
|
|
||||||
)
|
|
||||||
|
|
||||||
var supportedFilenames = []string{
|
|
||||||
"compose.yml",
|
|
||||||
"compose.yaml",
|
|
||||||
"docker-compose.yml",
|
|
||||||
"docker-compose.yaml",
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectOptions configures a compose project
|
|
||||||
type ProjectOptions struct {
|
|
||||||
Name string
|
|
||||||
WorkDir string
|
|
||||||
ConfigPaths []string
|
|
||||||
Environment []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Project represents a compose project with a name
|
|
||||||
type Project struct {
|
|
||||||
types.Config
|
|
||||||
projectDir string
|
|
||||||
Name string `yaml:"-" json:"-"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProjectFromOptions load a compose project based on given options
|
|
||||||
func ProjectFromOptions(options *ProjectOptions) (*Project, error) {
|
|
||||||
configPath, err := getConfigPathFromOptions(options)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
configs, err := parseConfigs(configPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
name := options.Name
|
|
||||||
if name == "" {
|
|
||||||
r := regexp.MustCompile(`[^a-z0-9\\-_]+`)
|
|
||||||
absPath, err := filepath.Abs(options.WorkDir)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
name = r.ReplaceAllString(strings.ToLower(filepath.Base(absPath)), "")
|
|
||||||
}
|
|
||||||
|
|
||||||
return newProject(types.ConfigDetails{
|
|
||||||
WorkingDir: options.WorkDir,
|
|
||||||
ConfigFiles: configs,
|
|
||||||
Environment: getAsEqualsMap(options.Environment),
|
|
||||||
}, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newProject(config types.ConfigDetails, name string) (*Project, error) {
|
|
||||||
model, err := loader.Load(config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p := Project{
|
|
||||||
Config: *model,
|
|
||||||
projectDir: config.WorkingDir,
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
return &p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getConfigPathFromOptions(options *ProjectOptions) ([]string, error) {
|
|
||||||
var paths []string
|
|
||||||
pwd := options.WorkDir
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
var 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. Is %q the right directory?", pwd)
|
|
||||||
}
|
|
||||||
pwd = parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseConfigs(configPaths []string) ([]types.ConfigFile, error) {
|
|
||||||
var files []types.ConfigFile
|
|
||||||
for _, f := range configPaths {
|
|
||||||
var b []byte
|
|
||||||
var err error
|
|
||||||
if f == "-" {
|
|
||||||
b, err = ioutil.ReadAll(os.Stdin)
|
|
||||||
} else {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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,60 +0,0 @@
|
||||||
/*
|
|
||||||
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 compose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ComposeTest struct {
|
|
||||||
suite.Suite
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *ComposeTest) TestParseComposeFile() {
|
|
||||||
files := []string{"../tests/composefiles/aci-demo/aci_demo_port.yaml"}
|
|
||||||
config, err := parseConfigs(files)
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
services := config[0].Config["services"].(map[string]interface{})
|
|
||||||
Expect(len(services)).To(Equal(3))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (suite *ComposeTest) TestParseComposeStdin() {
|
|
||||||
files := []string{"-"}
|
|
||||||
f, err := os.Open("../tests/composefiles/aci-demo/aci_demo_port.yaml")
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
defer func() {
|
|
||||||
err := f.Close()
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
}()
|
|
||||||
oldStdin := os.Stdin
|
|
||||||
defer func() { os.Stdin = oldStdin }() // Restore original Stdin
|
|
||||||
|
|
||||||
os.Stdin = f
|
|
||||||
config, err := parseConfigs(files)
|
|
||||||
Expect(err).To(BeNil())
|
|
||||||
services := config[0].Config["services"].(map[string]interface{})
|
|
||||||
Expect(len(services)).To(Equal(3))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestComposeProject(t *testing.T) {
|
|
||||||
RegisterTestingT(t)
|
|
||||||
suite.Run(t, new(ComposeTest))
|
|
||||||
}
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/compose-spec/compose-go/cli"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/docker/api/context/cloud"
|
"github.com/docker/api/context/cloud"
|
||||||
|
@ -109,8 +110,8 @@ func (cs *containerService) Delete(ctx context.Context, id string, force bool) e
|
||||||
|
|
||||||
type composeService struct{}
|
type composeService struct{}
|
||||||
|
|
||||||
func (cs *composeService) Up(ctx context.Context, opts compose.ProjectOptions) error {
|
func (cs *composeService) Up(ctx context.Context, opts cli.ProjectOptions) error {
|
||||||
prj, err := compose.ProjectFromOptions(&opts)
|
prj, err := cli.ProjectFromOptions(&opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -118,8 +119,8 @@ func (cs *composeService) Up(ctx context.Context, opts compose.ProjectOptions) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *composeService) Down(ctx context.Context, opts compose.ProjectOptions) error {
|
func (cs *composeService) Down(ctx context.Context, opts cli.ProjectOptions) error {
|
||||||
prj, err := compose.ProjectFromOptions(&opts)
|
prj, err := cli.ProjectFromOptions(&opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -16,7 +16,7 @@ require (
|
||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
|
||||||
github.com/Microsoft/hcsshim v0.8.9 // indirect
|
github.com/Microsoft/hcsshim v0.8.9 // indirect
|
||||||
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-20200423124427-63dcf8c22cae
|
github.com/compose-spec/compose-go v0.0.0-20200629133725-59b25574fd55
|
||||||
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/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb // indirect
|
github.com/containerd/continuity v0.0.0-20200413184840-d3ef23f19fbb // indirect
|
||||||
|
|
11
go.sum
11
go.sum
|
@ -61,8 +61,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-20200423124427-63dcf8c22cae h1:5zRbbF5Gbkl7ZEJrKwYha2JMWgnfpPjSmv8+jCmkeSA=
|
github.com/compose-spec/compose-go v0.0.0-20200629133725-59b25574fd55 h1:vX1uiHKgVnFBPBLxz6P28n+TKGt3jGThvDr2vkSP8D0=
|
||||||
github.com/compose-spec/compose-go v0.0.0-20200423124427-63dcf8c22cae/go.mod h1:1PUpzRF1O/65VOqXZuwpCuYY7pJxbIq1jbAvAf62FGM=
|
github.com/compose-spec/compose-go v0.0.0-20200629133725-59b25574fd55/go.mod h1:ArodJ6gsEB7iWKrbV3fSHZ08LlBvSVB0Oqg04fX86t4=
|
||||||
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=
|
||||||
|
@ -179,6 +179,8 @@ github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
|
||||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||||
|
@ -214,8 +216,8 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
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.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg=
|
||||||
github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
github.com/moby/term v0.0.0-20200611042045-63b9a826fb74 h1:kvRIeqJNICemq2UFLx8q/Pj+1IRNZS0XPTaMFkuNsvg=
|
github.com/moby/term v0.0.0-20200611042045-63b9a826fb74 h1:kvRIeqJNICemq2UFLx8q/Pj+1IRNZS0XPTaMFkuNsvg=
|
||||||
github.com/moby/term v0.0.0-20200611042045-63b9a826fb74/go.mod h1:pJ0Ot5YGdTcMdxnPMyGCfAr6fKXe0g9cDlz16MuFEBE=
|
github.com/moby/term v0.0.0-20200611042045-63b9a826fb74/go.mod h1:pJ0Ot5YGdTcMdxnPMyGCfAr6fKXe0g9cDlz16MuFEBE=
|
||||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
|
@ -272,7 +274,6 @@ 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.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
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 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
|
Loading…
Reference in New Issue