Fix missing attribute when convert with multiple docker-compose files

Signed-off-by: xianlubird <xianlubird@gmail.com>
This commit is contained in:
xianlubird 2018-04-26 17:58:18 +08:00
parent 28031a9453
commit 04e9ee9949
11 changed files with 760 additions and 31 deletions

View File

@ -31,6 +31,7 @@ import (
"os"
"fmt"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
@ -66,8 +67,16 @@ func parseV3(files []string) (kobject.KomposeObject, error) {
return kobject.KomposeObject{}, err
}
// get environment variables
env, err := buildEnvironment()
if err != nil {
return kobject.KomposeObject{}, errors.Wrap(err, "cannot build environment variables")
}
var config *types.Config
for _, file := range files {
// Load and then parse the YAML first!
loadedFile, err := ioutil.ReadFile(files[0])
loadedFile, err := ioutil.ReadFile(file)
if err != nil {
return kobject.KomposeObject{}, err
}
@ -80,16 +89,10 @@ func parseV3(files []string) (kobject.KomposeObject, error) {
// Config file
configFile := types.ConfigFile{
Filename: files[0],
Filename: file,
Config: parsedComposeFile,
}
// get environment variables
env, err := buildEnvironment()
if err != nil {
return kobject.KomposeObject{}, errors.Wrap(err, "cannot build environment variables")
}
// Config details
configDetails := types.ConfigDetails{
WorkingDir: workingDir,
@ -101,10 +104,19 @@ func parseV3(files []string) (kobject.KomposeObject, error) {
// We load it in order to retrieve the parsed output configuration!
// This will output a github.com/docker/cli ServiceConfig
// Which is similar to our version of ServiceConfig
config, err := loader.Load(configDetails)
currentConfig, err := loader.Load(configDetails)
if err != nil {
return kobject.KomposeObject{}, err
}
if config == nil {
config = currentConfig
} else {
config, err = mergeComposeObject(config, currentConfig)
if err != nil {
return kobject.KomposeObject{}, err
}
}
}
// TODO: Check all "unsupported" keys and output details
// Specifically, keys such as "volumes_from" are not supported in V3.
@ -398,3 +410,165 @@ func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.Kompose
return komposeObject, nil
}
func mergeComposeObject(oldCompose *types.Config, newCompose *types.Config) (*types.Config, error) {
if oldCompose == nil || newCompose == nil {
return nil, fmt.Errorf("Merge multiple compose error, compose config is nil")
}
oldComposeServiceNameMap := make(map[string]int, len(oldCompose.Services))
for index, service := range oldCompose.Services {
oldComposeServiceNameMap[service.Name] = index
}
for _, service := range newCompose.Services {
index := 0
if tmpIndex, ok := oldComposeServiceNameMap[service.Name]; !ok {
oldCompose.Services = append(oldCompose.Services, service)
continue
} else {
index = tmpIndex
}
tmpOldService := oldCompose.Services[index]
if service.Build.Dockerfile != "" {
tmpOldService.Build = service.Build
}
if len(service.CapAdd) != 0 {
tmpOldService.CapAdd = service.CapAdd
}
if len(service.CapDrop) != 0 {
tmpOldService.CapDrop = service.CapDrop
}
if service.CgroupParent != "" {
tmpOldService.CgroupParent = service.CgroupParent
}
if len(service.Command) != 0 {
tmpOldService.Command = service.Command
}
if len(service.Configs) != 0 {
tmpOldService.Configs = service.Configs
}
if service.ContainerName != "" {
tmpOldService.ContainerName = service.ContainerName
}
if service.CredentialSpec.File != "" || service.CredentialSpec.Registry != "" {
tmpOldService.CredentialSpec = service.CredentialSpec
}
if len(service.DependsOn) != 0 {
tmpOldService.DependsOn = service.DependsOn
}
if service.Deploy.Mode != "" {
tmpOldService.Deploy = service.Deploy
}
if len(service.Devices) != 0 {
tmpOldService.Devices = service.Devices
}
if len(service.DNS) != 0 {
tmpOldService.DNS = service.DNS
}
if len(service.DNSSearch) != 0 {
tmpOldService.DNSSearch = service.DNSSearch
}
if service.DomainName != "" {
tmpOldService.DomainName = service.DomainName
}
if len(service.Entrypoint) != 0 {
tmpOldService.Entrypoint = service.Entrypoint
}
if len(service.Environment) != 0 {
tmpOldService.Environment = service.Environment
}
if len(service.EnvFile) != 0 {
tmpOldService.EnvFile = service.EnvFile
}
if len(service.Expose) != 0 {
tmpOldService.Expose = service.Expose
}
if len(service.ExternalLinks) != 0 {
tmpOldService.ExternalLinks = service.ExternalLinks
}
if len(service.ExtraHosts) != 0 {
tmpOldService.ExtraHosts = service.ExtraHosts
}
if service.Hostname != "" {
tmpOldService.Hostname = service.Hostname
}
if service.HealthCheck != nil {
tmpOldService.HealthCheck = service.HealthCheck
}
if service.Image != "" {
tmpOldService.Image = service.Image
}
if service.Ipc != "" {
tmpOldService.Ipc = service.Ipc
}
if len(service.Labels) != 0 {
tmpOldService.Labels = service.Labels
}
if len(service.Links) != 0 {
tmpOldService.Links = service.Links
}
if service.Logging != nil {
tmpOldService.Logging = service.Logging
}
if service.MacAddress != "" {
tmpOldService.MacAddress = service.MacAddress
}
if service.NetworkMode != "" {
tmpOldService.NetworkMode = service.NetworkMode
}
if len(service.Networks) != 0 {
tmpOldService.Networks = service.Networks
}
if service.Pid != "" {
tmpOldService.Pid = service.Pid
}
if len(service.Ports) != 0 {
tmpOldService.Ports = service.Ports
}
if service.Privileged != tmpOldService.Privileged {
tmpOldService.Privileged = service.Privileged
}
if service.ReadOnly != tmpOldService.ReadOnly {
tmpOldService.ReadOnly = service.ReadOnly
}
if service.Restart != "" {
tmpOldService.Restart = service.Restart
}
if len(service.Secrets) != 0 {
tmpOldService.Secrets = service.Secrets
}
if len(service.SecurityOpt) != 0 {
tmpOldService.SecurityOpt = service.SecurityOpt
}
if service.StdinOpen != tmpOldService.StdinOpen {
tmpOldService.StdinOpen = service.StdinOpen
}
if service.StopGracePeriod != nil {
tmpOldService.StopGracePeriod = service.StopGracePeriod
}
if service.StopSignal != "" {
tmpOldService.StopSignal = service.StopSignal
}
if len(service.Tmpfs) != 0 {
tmpOldService.Tmpfs = service.Tmpfs
}
if service.Tty != tmpOldService.Tty {
tmpOldService.Tty = service.Tty
}
if len(service.Ulimits) != 0 {
tmpOldService.Ulimits = service.Ulimits
}
if service.User != "" {
tmpOldService.User = service.User
}
if len(service.Volumes) != 0 {
tmpOldService.Volumes = service.Volumes
}
if service.WorkingDir != "" {
tmpOldService.WorkingDir = service.WorkingDir
}
oldCompose.Services[index] = tmpOldService
}
return oldCompose, nil
}

View File

@ -122,7 +122,23 @@ cmd="kompose -f $KOMPOSE_ROOT/script/test/fixtures/mem-limit/docker-compose-mb.y
sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/mem-limit/output-mb-k8s-template.json > /tmp/output-k8s.json
convert::expect_success "$cmd" "/tmp/output-k8s.json"
######
# Tests merge multiple docker-compose files
cmd="kompose convert -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/base.yml -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/dev.yml --stdout -j"
sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/output-base-template.json > /tmp/output-k8s.json
convert::expect_success "$cmd" "/tmp/output-k8s.json"
cmd="kompose convert -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/compose-port-base.yml -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/compose-port-prod.yml --stdout -j"
sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/output-compose-port-template.json > /tmp/output-k8s.json
convert::expect_success "$cmd" "/tmp/output-k8s.json"
cmd="kompose convert -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/compose-port-base.yml -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/compose-new-service-prob.yml --stdout -j"
sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/output-compose-new-service-template.json > /tmp/output-k8s.json
convert::expect_success "$cmd" "/tmp/output-k8s.json"
cmd="kompose --provider=openshift convert -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/compose-port-base.yml -f $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/compose-new-service-prob.yml --stdout -j"
sed -e "s;%VERSION%;$version;g" -e "s;%CMD%;$cmd;g" $KOMPOSE_ROOT/script/test/fixtures/merge-multiple-compose/output-openshift-template.json > /tmp/output-os.json
convert::expect_success "$cmd" "/tmp/output-os.json"
######
# Tests related to docker-compose file in /script/test/fixtures/ports-with-proto

View File

@ -0,0 +1,12 @@
version: '3'
services:
web:
image: richarvey/nginx-php-fpm
environment:
- ERRORS=0
- HIDE_NGINX_HEADERS=0
- REMOVE_FILES=0
- RUN_SCRIPTS=0
- PHP_ERRORS_STDERR=0
- ENABLE_XDEBUG=0

View File

@ -0,0 +1,8 @@
version: '3'
services:
server:
ports:
- 5000:5000
new-my-service:
image: nginx

View File

@ -0,0 +1,11 @@
version: '3'
services:
server:
image: test
container_name: test_server
build:
context: .
dockerfile: Dockerfile-dev
ports:
- 3000:3000

View File

@ -0,0 +1,6 @@
version: '3'
services:
server:
ports:
- 5000:5000

View File

@ -0,0 +1,11 @@
version: '3'
services:
web:
environment:
- ERRORS=1
- HIDE_NGINX_HEADERS=0
- REMOVE_FILES=0
- RUN_SCRIPTS=1
- PHP_ERRORS_STDERR=1
- ENABLE_XDEBUG=1

View File

@ -0,0 +1,71 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "web",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "web"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "web"
}
},
"spec": {
"containers": [
{
"name": "web",
"image": "richarvey/nginx-php-fpm",
"env": [
{
"name": "ENABLE_XDEBUG",
"value": "1"
},
{
"name": "ERRORS",
"value": "1"
},
{
"name": "HIDE_NGINX_HEADERS",
"value": "0"
},
{
"name": "PHP_ERRORS_STDERR",
"value": "1"
},
{
"name": "REMOVE_FILES",
"value": "0"
},
{
"name": "RUN_SCRIPTS",
"value": "1"
}
],
"resources": {}
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
}
]
}

View File

@ -0,0 +1,118 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "server",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"ports": [
{
"name": "5000",
"port": 5000,
"targetPort": 5000
}
],
"selector": {
"io.kompose.service": "server"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "new-my-service",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "new-my-service"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "new-my-service"
}
},
"spec": {
"containers": [
{
"name": "new-my-service",
"image": "nginx",
"resources": {}
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "server",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
}
},
"spec": {
"containers": [
{
"name": "test_server",
"image": "test",
"ports": [
{
"containerPort": 5000
}
],
"resources": {}
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
}
]
}

View File

@ -0,0 +1,80 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "server",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"ports": [
{
"name": "5000",
"port": 5000,
"targetPort": 5000
}
],
"selector": {
"io.kompose.service": "server"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "Deployment",
"apiVersion": "extensions/v1beta1",
"metadata": {
"name": "server",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"replicas": 1,
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
}
},
"spec": {
"containers": [
{
"name": "test_server",
"image": "test",
"ports": [
{
"containerPort": 5000
}
],
"resources": {}
}
],
"restartPolicy": "Always"
}
},
"strategy": {}
},
"status": {}
}
]
}

View File

@ -0,0 +1,222 @@
{
"kind": "List",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "server",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"ports": [
{
"name": "5000",
"port": 5000,
"targetPort": 5000
}
],
"selector": {
"io.kompose.service": "server"
}
},
"status": {
"loadBalancer": {}
}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "new-my-service",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "new-my-service"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"strategy": {
"resources": {}
},
"triggers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"new-my-service"
],
"from": {
"kind": "ImageStreamTag",
"name": "new-my-service:latest"
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"io.kompose.service": "new-my-service"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "new-my-service"
}
},
"spec": {
"containers": [
{
"name": "new-my-service",
"image": " ",
"resources": {}
}
],
"restartPolicy": "Always"
}
}
},
"status": {}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "new-my-service",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "new-my-service"
}
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "nginx"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
},
{
"kind": "DeploymentConfig",
"apiVersion": "v1",
"metadata": {
"name": "server",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
},
"annotations": {
"kompose.cmd": "%CMD%",
"kompose.version": "%VERSION%"
}
},
"spec": {
"strategy": {
"resources": {}
},
"triggers": [
{
"type": "ConfigChange"
},
{
"type": "ImageChange",
"imageChangeParams": {
"automatic": true,
"containerNames": [
"test_server"
],
"from": {
"kind": "ImageStreamTag",
"name": "server:latest"
}
}
}
],
"replicas": 1,
"test": false,
"selector": {
"io.kompose.service": "server"
},
"template": {
"metadata": {
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
}
},
"spec": {
"containers": [
{
"name": "test_server",
"image": " ",
"ports": [
{
"containerPort": 5000
}
],
"resources": {}
}
],
"restartPolicy": "Always"
}
}
},
"status": {}
},
{
"kind": "ImageStream",
"apiVersion": "v1",
"metadata": {
"name": "server",
"creationTimestamp": null,
"labels": {
"io.kompose.service": "server"
}
},
"spec": {
"tags": [
{
"name": "latest",
"annotations": null,
"from": {
"kind": "DockerImage",
"name": "test"
},
"generation": null,
"importPolicy": {}
}
]
},
"status": {
"dockerImageRepository": ""
}
}
]
}