mirror of https://github.com/docker/compose.git
project restructure
Signed-off-by: aiordache <anca.iordache@docker.com>
This commit is contained in:
parent
4ffc393909
commit
ce3e4d7717
|
@ -0,0 +1,96 @@
|
||||||
|
package compose
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/compose-spec/compose-go/loader"
|
||||||
|
"github.com/compose-spec/compose-go/types"
|
||||||
|
"github.com/docker/cli/cli/command"
|
||||||
|
"github.com/docker/cli/cli/config/configfile"
|
||||||
|
registry "github.com/docker/cli/cli/registry/client"
|
||||||
|
"github.com/docker/cli/cli/streams"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
|
"github.com/docker/helm-prototype/pkg/compose/internal/convert"
|
||||||
|
"github.com/docker/helm-prototype/pkg/compose/internal/helm"
|
||||||
|
utils "github.com/docker/helm-prototype/pkg/compose/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Client client.APIClient
|
||||||
|
RegistryClient registry.RegistryClient
|
||||||
|
ConfigFile *configfile.ConfigFile
|
||||||
|
Stdout *streams.Out
|
||||||
|
)
|
||||||
|
|
||||||
|
func WithDockerCli(cli command.Cli) {
|
||||||
|
Client = cli.Client()
|
||||||
|
RegistryClient = cli.RegistryClient(false)
|
||||||
|
ConfigFile = cli.ConfigFile()
|
||||||
|
Stdout = cli.Out()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Orchestrator is "kubernetes" or "swarm"
|
||||||
|
type Orchestrator string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Kubernetes specifies to use kubernetes.
|
||||||
|
Kubernetes Orchestrator = "kubernetes"
|
||||||
|
// Swarm specifies to use Docker swarm.
|
||||||
|
Swarm Orchestrator = "swarm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProjectOptions struct {
|
||||||
|
ConfigPaths []string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
Config *types.Config
|
||||||
|
ProjectDir string
|
||||||
|
Name string `yaml:"-" json:"-"`
|
||||||
|
Orchestrator Orchestrator
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// projectFromOptions load a compose project based on command line options
|
||||||
|
func ProjectFromOptions(options *ProjectOptions) (*Project, error) {
|
||||||
|
workingDir, configs, err := utils.GetConfigs(
|
||||||
|
options.Name,
|
||||||
|
options.ConfigPaths,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewProject(types.ConfigDetails{
|
||||||
|
WorkingDir: workingDir,
|
||||||
|
ConfigFiles: configs,
|
||||||
|
Environment: utils.Environment(),
|
||||||
|
}, options.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) GenerateCharts(path string) error {
|
||||||
|
objects, err := convert.MapToKubernetesObjects(p.Config, p.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = helm.Write(p.Name, objects, path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (p *Project) InstallCommand(options *ProjectOptions) error {
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,23 +0,0 @@
|
||||||
package compose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/docker/cli/cli/command"
|
|
||||||
"github.com/docker/cli/cli/config/configfile"
|
|
||||||
registry "github.com/docker/cli/cli/registry/client"
|
|
||||||
"github.com/docker/cli/cli/streams"
|
|
||||||
"github.com/docker/docker/client"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Client client.APIClient
|
|
||||||
RegistryClient registry.RegistryClient
|
|
||||||
ConfigFile *configfile.ConfigFile
|
|
||||||
Stdout *streams.Out
|
|
||||||
)
|
|
||||||
|
|
||||||
func WithDockerCli(cli command.Cli) {
|
|
||||||
Client = cli.Client()
|
|
||||||
RegistryClient = cli.RegistryClient(false)
|
|
||||||
ConfigFile = cli.ConfigFile()
|
|
||||||
Stdout = cli.Out()
|
|
||||||
}
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/helm-prototype/pkg/compose"
|
|
||||||
apps "k8s.io/api/apps/v1"
|
apps "k8s.io/api/apps/v1"
|
||||||
core "k8s.io/api/core/v1"
|
core "k8s.io/api/core/v1"
|
||||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
@ -14,19 +13,19 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/util/intstr"
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MapToKubernetesObjects(model *compose.Project) (map[string]runtime.Object, error) {
|
func MapToKubernetesObjects(model *types.Config, name string) (map[string]runtime.Object, error) {
|
||||||
objects := map[string]runtime.Object{}
|
objects := map[string]runtime.Object{}
|
||||||
|
|
||||||
for _, service := range model.Services {
|
for _, service := range model.Services {
|
||||||
objects[fmt.Sprintf("%s-service.yaml", service.Name)] = mapToService(model, service)
|
objects[fmt.Sprintf("%s-service.yaml", service.Name)] = mapToService(model, service)
|
||||||
if service.Deploy != nil && service.Deploy.Mode == "global" {
|
if service.Deploy != nil && service.Deploy.Mode == "global" {
|
||||||
daemonset, err := mapToDaemonset(service, model)
|
daemonset, err := mapToDaemonset(service, model, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
objects[fmt.Sprintf("%s-daemonset.yaml", service.Name)] = daemonset
|
objects[fmt.Sprintf("%s-daemonset.yaml", service.Name)] = daemonset
|
||||||
} else {
|
} else {
|
||||||
deployment, err := mapToDeployment(service, model)
|
deployment, err := mapToDeployment(service, model, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -41,7 +40,7 @@ func MapToKubernetesObjects(model *compose.Project) (map[string]runtime.Object,
|
||||||
return objects, nil
|
return objects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapToService(model *compose.Project, service types.ServiceConfig) *core.Service {
|
func mapToService(model *types.Config, service types.ServiceConfig) *core.Service {
|
||||||
ports := []core.ServicePort{}
|
ports := []core.ServicePort{}
|
||||||
for _, p := range service.Ports {
|
for _, p := range service.Ports {
|
||||||
ports = append(ports,
|
ports = append(ports,
|
||||||
|
@ -69,7 +68,7 @@ func mapToService(model *compose.Project, service types.ServiceConfig) *core.Ser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapServiceToServiceType(service types.ServiceConfig, model *compose.Project) core.ServiceType {
|
func mapServiceToServiceType(service types.ServiceConfig, model *types.Config) core.ServiceType {
|
||||||
serviceType := core.ServiceTypeClusterIP
|
serviceType := core.ServiceTypeClusterIP
|
||||||
if len(service.Networks) == 0 {
|
if len(service.Networks) == 0 {
|
||||||
// service is implicitly attached to "default" network
|
// service is implicitly attached to "default" network
|
||||||
|
@ -88,10 +87,10 @@ func mapServiceToServiceType(service types.ServiceConfig, model *compose.Project
|
||||||
return serviceType
|
return serviceType
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapToDeployment(service types.ServiceConfig, model *compose.Project) (*apps.Deployment, error) {
|
func mapToDeployment(service types.ServiceConfig, model *types.Config, name string) (*apps.Deployment, error) {
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"com.docker.compose.service": service.Name,
|
"com.docker.compose.service": service.Name,
|
||||||
"com.docker.compose.project": model.Name,
|
"com.docker.compose.project": name,
|
||||||
}
|
}
|
||||||
podTemplate, err := toPodTemplate(service, labels, model)
|
podTemplate, err := toPodTemplate(service, labels, model)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -120,10 +119,10 @@ func mapToDeployment(service types.ServiceConfig, model *compose.Project) (*apps
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapToDaemonset(service types.ServiceConfig, model *compose.Project) (*apps.DaemonSet, error) {
|
func mapToDaemonset(service types.ServiceConfig, model *types.Config, name string) (*apps.DaemonSet, error) {
|
||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"com.docker.compose.service": service.Name,
|
"com.docker.compose.service": service.Name,
|
||||||
"com.docker.compose.project": model.Name,
|
"com.docker.compose.project": name,
|
||||||
}
|
}
|
||||||
podTemplate, err := toPodTemplate(service, labels, model)
|
podTemplate, err := toPodTemplate(service, labels, model)
|
||||||
if err != nil {
|
if err != nil {
|
|
@ -9,7 +9,6 @@ import (
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/helm-prototype/pkg/compose"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
apiv1 "k8s.io/api/core/v1"
|
apiv1 "k8s.io/api/core/v1"
|
||||||
|
@ -17,7 +16,7 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func toPodTemplate(serviceConfig types.ServiceConfig, labels map[string]string, model *compose.Project) (apiv1.PodTemplateSpec, error) {
|
func toPodTemplate(serviceConfig types.ServiceConfig, labels map[string]string, model *types.Config) (apiv1.PodTemplateSpec, error) {
|
||||||
tpl := apiv1.PodTemplateSpec{}
|
tpl := apiv1.PodTemplateSpec{}
|
||||||
nodeAffinity, err := toNodeAffinity(serviceConfig.Deploy)
|
nodeAffinity, err := toNodeAffinity(serviceConfig.Deploy)
|
||||||
if err != nil {
|
if err != nil {
|
|
@ -8,13 +8,12 @@ import (
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/loader"
|
"github.com/compose-spec/compose-go/loader"
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/helm-prototype/pkg/compose"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
apiv1 "k8s.io/api/core/v1"
|
apiv1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadYAML(yaml string) (*compose.Project, error) {
|
func loadYAML(yaml string) (*loader.Config, error) {
|
||||||
dict, err := loader.ParseYAML([]byte(yaml))
|
dict, err := loader.ParseYAML([]byte(yaml))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -23,12 +22,17 @@ func loadYAML(yaml string) (*compose.Project, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return compose.NewProject(types.ConfigDetails{
|
configs := ConfigFiles: []types.ConfigFile{
|
||||||
WorkingDir: workingDir,
|
|
||||||
ConfigFiles: []types.ConfigFile{
|
|
||||||
{Filename: "compose.yaml", Config: dict},
|
{Filename: "compose.yaml", Config: dict},
|
||||||
},
|
},
|
||||||
}, "test")
|
|
||||||
|
config := types.ConfigDetails{
|
||||||
|
WorkingDir: workingDir,
|
||||||
|
ConfigFiles: configs,
|
||||||
|
Environment: utils.Environment(),
|
||||||
|
}
|
||||||
|
model, err := loader.Load(config)
|
||||||
|
return model
|
||||||
}
|
}
|
||||||
|
|
||||||
func podTemplate(t *testing.T, yaml string) apiv1.PodTemplateSpec {
|
func podTemplate(t *testing.T, yaml string) apiv1.PodTemplateSpec {
|
||||||
|
@ -38,11 +42,12 @@ func podTemplate(t *testing.T, yaml string) apiv1.PodTemplateSpec {
|
||||||
}
|
}
|
||||||
|
|
||||||
func podTemplateWithError(yaml string) (apiv1.PodTemplateSpec, error) {
|
func podTemplateWithError(yaml string) (apiv1.PodTemplateSpec, error) {
|
||||||
project, err := loadYAML(yaml)
|
model, err := loadYAML(yaml)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return apiv1.PodTemplateSpec{}, err
|
return apiv1.PodTemplateSpec{}, err
|
||||||
}
|
}
|
||||||
return toPodTemplate(project.Services[0], nil, project)
|
|
||||||
|
return toPodTemplate(model.Services[0], nil, model)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToPodWithDockerSocket(t *testing.T) {
|
func TestToPodWithDockerSocket(t *testing.T) {
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
"github.com/compose-spec/compose-go/types"
|
||||||
"github.com/docker/helm-prototype/pkg/compose"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
apiv1 "k8s.io/api/core/v1"
|
apiv1 "k8s.io/api/core/v1"
|
||||||
|
@ -30,7 +29,7 @@ func hasPersistentVolumes(s types.ServiceConfig) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func toVolumeSpecs(s types.ServiceConfig, model *compose.Project) ([]volumeSpec, error) {
|
func toVolumeSpecs(s types.ServiceConfig, model *types.Config) ([]volumeSpec, error) {
|
||||||
var specs []volumeSpec
|
var specs []volumeSpec
|
||||||
for i, m := range s.Volumes {
|
for i, m := range s.Volumes {
|
||||||
var source *apiv1.VolumeSource
|
var source *apiv1.VolumeSource
|
||||||
|
@ -114,7 +113,7 @@ func or(v string, defaultValue string) string {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func toVolumeMounts(s types.ServiceConfig, model *compose.Project) ([]apiv1.VolumeMount, error) {
|
func toVolumeMounts(s types.ServiceConfig, model *types.Config) ([]apiv1.VolumeMount, error) {
|
||||||
var mounts []apiv1.VolumeMount
|
var mounts []apiv1.VolumeMount
|
||||||
specs, err := toVolumeSpecs(s, model)
|
specs, err := toVolumeSpecs(s, model)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -126,7 +125,7 @@ func toVolumeMounts(s types.ServiceConfig, model *compose.Project) ([]apiv1.Volu
|
||||||
return mounts, nil
|
return mounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toVolumes(s types.ServiceConfig, model *compose.Project) ([]apiv1.Volume, error) {
|
func toVolumes(s types.ServiceConfig, model *types.Config) ([]apiv1.Volume, error) {
|
||||||
var volumes []apiv1.Volume
|
var volumes []apiv1.Volume
|
||||||
specs, err := toVolumeSpecs(s, model)
|
specs, err := toVolumeSpecs(s, model)
|
||||||
if err != nil {
|
if err != nil {
|
|
@ -0,0 +1,34 @@
|
||||||
|
package helm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
|
)
|
||||||
|
|
||||||
|
type KubeConfig struct {
|
||||||
|
namespace string
|
||||||
|
config genericclioptions.RESTClientGetter
|
||||||
|
configOnce sync.Once
|
||||||
|
|
||||||
|
// KubeConfig is the path to the kubeconfig file
|
||||||
|
KubeConfig string
|
||||||
|
// KubeContext is the name of the kubeconfig context.
|
||||||
|
KubeContext string
|
||||||
|
// Bearer KubeToken used for authentication
|
||||||
|
KubeToken string
|
||||||
|
// Kubernetes API Server Endpoint for authentication
|
||||||
|
KubeAPIServer string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *KubeConfig {
|
||||||
|
|
||||||
|
env := KubeConfig{
|
||||||
|
namespace: "",
|
||||||
|
KubeContext: os.Getenv("COMPOSE_KUBECONTEXT"),
|
||||||
|
KubeToken: os.Getenv("COMPOSE_KUBETOKEN"),
|
||||||
|
KubeAPIServer: os.Getenv("COMPOSE_KUBEAPISERVER"),
|
||||||
|
}
|
||||||
|
return &env
|
||||||
|
}
|
|
@ -0,0 +1,124 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
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/prometheus/common/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var SupportedFilenames = []string{"compose.yaml", "compose.yml", "docker-compose.yml", "docker-compose.yaml"}
|
||||||
|
|
||||||
|
func GetConfigs(name string, configPaths []string) (string, []types.ConfigFile, error) {
|
||||||
|
configPath, err := getConfigPaths(configPaths)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
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 workingDir, configs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConfigPaths(configPaths []string) ([]string, error) {
|
||||||
|
paths := []string{}
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(configPaths) != 0 {
|
||||||
|
for _, f := range 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 {
|
||||||
|
log.Warnf("Found multiple config files with supported names: %s", strings.Join(candidates, ", "))
|
||||||
|
log.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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
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,11 +1,11 @@
|
||||||
package compose
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func combine(errors []error) error {
|
func CombineErrors(errors []error) error {
|
||||||
if len(errors) == 0 {
|
if len(errors) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package compose
|
package utils
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LabelDockerComposePrefix = "com.docker.compose"
|
LabelDockerComposePrefix = "com.docker.compose"
|
|
@ -1,26 +0,0 @@
|
||||||
package compose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/compose-spec/compose-go/loader"
|
|
||||||
"github.com/compose-spec/compose-go/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
p := Project{
|
|
||||||
Config: *model,
|
|
||||||
projectDir: config.WorkingDir,
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
return &p, nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue