Fix missing attribute when convert with multiple docker-compose files

Signed-off-by: xianlubird <xianlubird@gmail.com>
This commit is contained in:
xianlubird
2018-05-03 11:51:55 +08:00
parent 28031a9453
commit 04e9ee9949
11 changed files with 760 additions and 31 deletions
+205 -31
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,44 +67,55 @@ func parseV3(files []string) (kobject.KomposeObject, error) {
return kobject.KomposeObject{}, err
}
// Load and then parse the YAML first!
loadedFile, err := ioutil.ReadFile(files[0])
if err != nil {
return kobject.KomposeObject{}, err
}
// Parse the Compose File
parsedComposeFile, err := loader.ParseYAML(loadedFile)
if err != nil {
return kobject.KomposeObject{}, err
}
// Config file
configFile := types.ConfigFile{
Filename: files[0],
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,
ConfigFiles: []types.ConfigFile{configFile},
Environment: env,
}
var config *types.Config
for _, file := range files {
// Load and then parse the YAML first!
loadedFile, err := ioutil.ReadFile(file)
if err != nil {
return kobject.KomposeObject{}, err
}
// Actual config
// 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)
if err != nil {
return kobject.KomposeObject{}, err
// Parse the Compose File
parsedComposeFile, err := loader.ParseYAML(loadedFile)
if err != nil {
return kobject.KomposeObject{}, err
}
// Config file
configFile := types.ConfigFile{
Filename: file,
Config: parsedComposeFile,
}
// Config details
configDetails := types.ConfigDetails{
WorkingDir: workingDir,
ConfigFiles: []types.ConfigFile{configFile},
Environment: env,
}
// Actual config
// 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
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
@@ -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
}