From 71469641683520f2db5904aa6ddc71886dedea20 Mon Sep 17 00:00:00 2001 From: aiordache Date: Tue, 7 Apr 2020 17:04:03 +0200 Subject: [PATCH] support multi-service compose Signed-off-by: aiordache --- compose/internal/env.go | 7 +++++++ compose/internal/kube/kube.go | 33 ++++++++++++++++++++++++++++---- compose/internal/kube/pod.go | 10 +++++----- compose/internal/kube/volumes.go | 4 ++-- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/compose/internal/env.go b/compose/internal/env.go index d16f6eac3..8397ac0f8 100644 --- a/compose/internal/env.go +++ b/compose/internal/env.go @@ -74,6 +74,13 @@ func GetConfig(name string, configPaths []string) (*types.Config, string, error) } func GetChartInMemory(config *types.Config, name string) (*chart.Chart, error) { + for k, v := range config.Volumes { + volumeName := strings.ReplaceAll(k, "_", "-") + if volumeName != k { + config.Volumes[volumeName] = v + delete(config.Volumes, k) + } + } objects, err := kube.MapToKubernetesObjects(config, name) if err != nil { return nil, err diff --git a/compose/internal/kube/kube.go b/compose/internal/kube/kube.go index 75d44842a..713235157 100644 --- a/compose/internal/kube/kube.go +++ b/compose/internal/kube/kube.go @@ -2,12 +2,14 @@ package kube import ( "fmt" + "log" "strings" "time" "github.com/compose-spec/compose-go/types" apps "k8s.io/api/apps/v1" core "k8s.io/api/core/v1" + resource "k8s.io/apimachinery/pkg/api/resource" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" @@ -17,7 +19,13 @@ func MapToKubernetesObjects(model *types.Config, name string) (map[string]runtim objects := map[string]runtime.Object{} for _, service := range model.Services { - objects[fmt.Sprintf("%s-service.yaml", service.Name)] = mapToService(model, service) + svcObject := mapToService(model, service) + if svcObject != nil { + objects[fmt.Sprintf("%s-service.yaml", service.Name)] = svcObject + } else { + log.Println("Missing port mapping from service config.") + } + if service.Deploy != nil && service.Deploy.Mode == "global" { daemonset, err := mapToDaemonset(service, model, name) if err != nil { @@ -33,7 +41,8 @@ func MapToKubernetesObjects(model *types.Config, name string) (map[string]runtim } for _, vol := range service.Volumes { if vol.Type == "volume" { - objects[fmt.Sprintf("%s-persistentvolumeclain.yaml", service.Name)] = mapToPVC(service, vol) + vol.Source = strings.ReplaceAll(vol.Source, "_", "-") + objects[fmt.Sprintf("%s-persistentvolumeclaim.yaml", vol.Source)] = mapToPVC(service, vol) } } } @@ -51,7 +60,9 @@ func mapToService(model *types.Config, service types.ServiceConfig) *core.Servic Protocol: toProtocol(p.Protocol), }) } - + if len(ports) == 0 { + return nil + } return &core.Service{ TypeMeta: meta.TypeMeta{ Kind: "Service", @@ -167,13 +178,27 @@ func toDeploymentStrategy(deploy *types.DeployConfig) apps.DeploymentStrategy { } func mapToPVC(service types.ServiceConfig, vol types.ServiceVolumeConfig) runtime.Object { + rwaccess := core.ReadWriteOnce + if vol.ReadOnly { + rwaccess = core.ReadOnlyMany + } return &core.PersistentVolumeClaim{ + TypeMeta: meta.TypeMeta{ + Kind: "PersistentVolumeClaim", + APIVersion: "v1", + }, ObjectMeta: meta.ObjectMeta{ Name: vol.Source, Labels: map[string]string{"com.docker.compose.service": service.Name}, }, Spec: core.PersistentVolumeClaimSpec{ - VolumeName: vol.Source, + VolumeName: vol.Source, + AccessModes: []core.PersistentVolumeAccessMode{rwaccess}, + Resources: core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceStorage: resource.MustParse("100Mi"), + }, + }, }, } } diff --git a/compose/internal/kube/pod.go b/compose/internal/kube/pod.go index e0ef2614e..18102a568 100644 --- a/compose/internal/kube/pod.go +++ b/compose/internal/kube/pod.go @@ -18,10 +18,10 @@ import ( func toPodTemplate(serviceConfig types.ServiceConfig, labels map[string]string, model *types.Config) (apiv1.PodTemplateSpec, error) { tpl := apiv1.PodTemplateSpec{} - nodeAffinity, err := toNodeAffinity(serviceConfig.Deploy) - if err != nil { - return apiv1.PodTemplateSpec{}, err - } + //nodeAffinity, err := toNodeAffinity(serviceConfig.Deploy) + //if err != nil { + // return apiv1.PodTemplateSpec{}, err + //} hostAliases, err := toHostAliases(serviceConfig.ExtraHosts) if err != nil { return apiv1.PodTemplateSpec{}, err @@ -73,7 +73,7 @@ func toPodTemplate(serviceConfig types.ServiceConfig, labels map[string]string, tpl.Spec.Hostname = serviceConfig.Hostname tpl.Spec.TerminationGracePeriodSeconds = toTerminationGracePeriodSeconds(serviceConfig.StopGracePeriod) tpl.Spec.HostAliases = hostAliases - tpl.Spec.Affinity = nodeAffinity + //tpl.Spec.Affinity = nodeAffinity // we dont want to remove all containers and recreate them because: // an admission plugin can add sidecar containers // we for sure want to keep the main container to be additive diff --git a/compose/internal/kube/volumes.go b/compose/internal/kube/volumes.go index b814280f9..3646de1e9 100644 --- a/compose/internal/kube/volumes.go +++ b/compose/internal/kube/volumes.go @@ -42,7 +42,7 @@ func toVolumeSpecs(s types.ServiceConfig, model *types.Config) ([]volumeSpec, er source = gitVolume(m.Source) } else if m.Type == "volume" { if m.Source != "" { - name = m.Source + name = strings.ReplaceAll(m.Source, "_", "-") } } else { // bind mount @@ -133,7 +133,7 @@ func toVolumes(s types.ServiceConfig, model *types.Config) ([]apiv1.Volume, erro } for _, spec := range specs { if spec.source == nil { - continue + spec.source = emptyVolumeInMemory() } volumes = append(volumes, apiv1.Volume{ Name: spec.mount.Name,