in pkg/loader/compose/v3.go [402:542]
func dockerComposeToKomposeMapping(composeObject *types.Config) (kobject.KomposeObject, error) {
// Step 1. Initialize what's going to be returned
komposeObject := kobject.KomposeObject{
ServiceConfigs: make(map[string]kobject.ServiceConfig),
LoadedFrom: "compose",
Secrets: composeObject.Secrets,
}
// Step 2. Parse through the object and convert it to kobject.KomposeObject!
// Here we "clean up" the service configuration so we return something that includes
// all relevant information as well as avoid the unsupported keys as well.
for _, composeServiceConfig := range composeObject.Services {
// Standard import
// No need to modify before importation
name := composeServiceConfig.Name
serviceConfig := kobject.ServiceConfig{}
serviceConfig.Name = name
serviceConfig.Image = composeServiceConfig.Image
serviceConfig.WorkingDir = composeServiceConfig.WorkingDir
serviceConfig.Annotations = composeServiceConfig.Labels
serviceConfig.CapAdd = composeServiceConfig.CapAdd
serviceConfig.CapDrop = composeServiceConfig.CapDrop
serviceConfig.Expose = composeServiceConfig.Expose
serviceConfig.Privileged = composeServiceConfig.Privileged
serviceConfig.User = composeServiceConfig.User
serviceConfig.Stdin = composeServiceConfig.StdinOpen
serviceConfig.Tty = composeServiceConfig.Tty
serviceConfig.TmpFs = composeServiceConfig.Tmpfs
serviceConfig.ContainerName = normalizeContainerNames(composeServiceConfig.ContainerName)
serviceConfig.Command = composeServiceConfig.Entrypoint
serviceConfig.Args = composeServiceConfig.Command
serviceConfig.Labels = composeServiceConfig.Labels
serviceConfig.HostName = composeServiceConfig.Hostname
serviceConfig.DomainName = composeServiceConfig.DomainName
serviceConfig.Secrets = composeServiceConfig.Secrets
if composeServiceConfig.StopGracePeriod != nil {
serviceConfig.StopGracePeriod = composeServiceConfig.StopGracePeriod.String()
}
parseV3Network(&composeServiceConfig, &serviceConfig, composeObject)
if err := parseV3Resources(&composeServiceConfig, &serviceConfig); err != nil {
return kobject.KomposeObject{}, err
}
// Deploy keys
// mode:
serviceConfig.DeployMode = composeServiceConfig.Deploy.Mode
// labels
serviceConfig.DeployLabels = composeServiceConfig.Deploy.Labels
// HealthCheck Liveness
if composeServiceConfig.HealthCheck != nil && !composeServiceConfig.HealthCheck.Disable {
var err error
serviceConfig.HealthChecks.Liveness, err = parseHealthCheck(*composeServiceConfig.HealthCheck, *&composeServiceConfig.Labels)
if err != nil {
return kobject.KomposeObject{}, errors.Wrap(err, "Unable to parse health check")
}
}
// HealthCheck Readiness
var readiness, errReadiness = parseHealthCheckReadiness(*&composeServiceConfig.Labels)
if !readiness.Disable {
serviceConfig.HealthChecks.Readiness = readiness
if errReadiness != nil {
return kobject.KomposeObject{}, errors.Wrap(errReadiness, "Unable to parse health check")
}
}
// restart-policy: deploy.restart_policy.condition will rewrite restart option
// see: https://docs.docker.com/compose/compose-file/#restart_policy
serviceConfig.Restart = composeServiceConfig.Restart
if composeServiceConfig.Deploy.RestartPolicy != nil {
serviceConfig.Restart = composeServiceConfig.Deploy.RestartPolicy.Condition
}
if serviceConfig.Restart == "unless-stopped" {
log.Warnf("Restart policy 'unless-stopped' in service %s is not supported, convert it to 'always'", name)
serviceConfig.Restart = "always"
}
// replicas:
if composeServiceConfig.Deploy.Replicas != nil {
serviceConfig.Replicas = int(*composeServiceConfig.Deploy.Replicas)
}
// placement:
serviceConfig.Placement = loadV3Placement(composeServiceConfig.Deploy.Placement)
if composeServiceConfig.Deploy.UpdateConfig != nil {
serviceConfig.DeployUpdateConfig = *composeServiceConfig.Deploy.UpdateConfig
}
// TODO: Build is not yet supported, see:
// https://github.com/docker/cli/blob/master/cli/compose/types/types.go#L9
// We will have to *manually* add this / parse.
serviceConfig.Build = resolveV3Context(composeObject.Filename, composeServiceConfig.Build.Context)
serviceConfig.Dockerfile = composeServiceConfig.Build.Dockerfile
serviceConfig.BuildArgs = composeServiceConfig.Build.Args
serviceConfig.BuildLabels = composeServiceConfig.Build.Labels
// env
parseV3Environment(&composeServiceConfig, &serviceConfig)
// Get env_file
serviceConfig.EnvFile = composeServiceConfig.EnvFile
// Parse the ports
// v3 uses a new format called "long syntax" starting in 3.2
// https://docs.docker.com/compose/compose-file/#ports
// here we will translate `expose` too, they basically means the same thing in kubernetes
serviceConfig.Port = loadV3Ports(composeServiceConfig.Ports, serviceConfig.Expose)
// Parse the volumes
// Again, in v3, we use the "long syntax" for volumes in terms of parsing
// https://docs.docker.com/compose/compose-file/#long-syntax-3
serviceConfig.VolList = loadV3Volumes(composeServiceConfig.Volumes)
if err := parseKomposeLabels(composeServiceConfig.Labels, &serviceConfig); err != nil {
return kobject.KomposeObject{}, err
}
// Log if the name will been changed
if normalizeServiceNames(name) != name {
log.Infof("Service name in docker-compose has been changed from %q to %q", name, normalizeServiceNames(name))
}
serviceConfig.Configs = composeServiceConfig.Configs
serviceConfig.ConfigsMetaData = composeObject.Configs
if composeServiceConfig.Deploy.EndpointMode == "vip" {
serviceConfig.ServiceType = string(api.ServiceTypeNodePort)
}
// Final step, add to the array!
komposeObject.ServiceConfigs[normalizeServiceNames(name)] = serviceConfig
}
handleV3Volume(&komposeObject, &composeObject.Volumes)
return komposeObject, nil
}