func()

in pkg/transformer/kubernetes/k8sutils.go [480:659]


func (k *Kubernetes) UpdateKubernetesObjects(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions, objects *[]runtime.Object) error {
	// Configure the environment variables.
	envs, err := ConfigEnvs(service, opt)
	if err != nil {
		return errors.Wrap(err, "Unable to load env variables")
	}

	// Configure the container volumes.
	volumesMount, volumes, pvc, cms, err := k.ConfigVolumes(name, service)
	if err != nil {
		return errors.Wrap(err, "k.ConfigVolumes failed")
	}
	// Configure Tmpfs
	if len(service.TmpFs) > 0 {
		TmpVolumesMount, TmpVolumes := k.ConfigTmpfs(name, service)
		volumes = append(volumes, TmpVolumes...)
		volumesMount = append(volumesMount, TmpVolumesMount...)
	}

	if pvc != nil && opt.Controller != StatefulStateController {
		// Looping on the slice pvc instead of `*objects = append(*objects, pvc...)`
		// because the type of objects and pvc is different, but when doing append
		// one element at a time it gets converted to runtime.Object for objects slice
		for _, p := range pvc {
			*objects = append(*objects, p)
		}
	}

	if cms != nil {
		for _, c := range cms {
			*objects = append(*objects, c)
		}
	}

	// Configure the container ports.
	ports := ConfigPorts(service)

	// Configure capabilities
	capabilities := ConfigCapabilities(service)

	// Configure annotations
	annotations := transformer.ConfigAnnotations(service)

	// fillTemplate fills the pod template with the value calculated from config
	fillTemplate := func(template *api.PodTemplateSpec) error {
		template.Spec.Containers[0].Name = GetContainerName(service)
		template.Spec.Containers[0].Env = envs
		template.Spec.Containers[0].Command = service.Command
		template.Spec.Containers[0].Args = service.Args
		template.Spec.Containers[0].WorkingDir = service.WorkingDir
		template.Spec.Containers[0].VolumeMounts = append(template.Spec.Containers[0].VolumeMounts, volumesMount...)
		template.Spec.Containers[0].Stdin = service.Stdin
		template.Spec.Containers[0].TTY = service.Tty
		if opt.Controller != StatefulStateController || opt.Volumes == "configMap" {
			template.Spec.Volumes = append(template.Spec.Volumes, volumes...)
		}
		template.Spec.Affinity = ConfigAffinity(service)
		template.Spec.TopologySpreadConstraints = ConfigTopologySpreadConstraints(service)
		// Configure the HealthCheck
		template.Spec.Containers[0].LivenessProbe = configProbe(service.HealthChecks.Liveness)
		template.Spec.Containers[0].ReadinessProbe = configProbe(service.HealthChecks.Readiness)

		if service.StopGracePeriod != "" {
			template.Spec.TerminationGracePeriodSeconds, err = DurationStrToSecondsInt(service.StopGracePeriod)
			if err != nil {
				log.Warningf("Failed to parse duration \"%v\" for service \"%v\"", service.StopGracePeriod, name)
			}
		}

		TranslatePodResource(&service, template)

		// Configure resource reservations
		podSecurityContext := &api.PodSecurityContext{}

		//set pid namespace mode
		if service.Pid != "" {
			if service.Pid == "host" {
				// podSecurityContext.HostPID = true
			} else {
				log.Warningf("Ignoring PID key for service \"%v\". Invalid value \"%v\".", name, service.Pid)
			}
		}

		//set supplementalGroups
		if service.GroupAdd != nil {
			podSecurityContext.SupplementalGroups = service.GroupAdd
		}

		// Setup security context
		securityContext := &api.SecurityContext{}
		if service.Privileged {
			securityContext.Privileged = &service.Privileged
		}
		if service.User != "" {
			uid, err := strconv.ParseInt(service.User, 10, 64)
			if err != nil {
				log.Warn("Ignoring user directive. User to be specified as a UID (numeric).")
			} else {
				securityContext.RunAsUser = &uid
			}
		}

		//set capabilities if it is not empty
		if len(capabilities.Add) > 0 || len(capabilities.Drop) > 0 {
			securityContext.Capabilities = capabilities
		}

		// update template only if securityContext is not empty
		if *securityContext != (api.SecurityContext{}) {
			template.Spec.Containers[0].SecurityContext = securityContext
		}
		if !reflect.DeepEqual(*podSecurityContext, api.PodSecurityContext{}) {
			template.Spec.SecurityContext = podSecurityContext
		}
		template.Spec.Containers[0].Ports = ports
		template.ObjectMeta.Labels = transformer.ConfigLabelsWithNetwork(name, service.Network)

		// Configure the image pull policy
		if policy, err := GetImagePullPolicy(name, service.ImagePullPolicy); err != nil {
			return err
		} else {
			template.Spec.Containers[0].ImagePullPolicy = policy
		}

		// Configure the container restart policy.
		if restart, err := GetRestartPolicy(name, service.Restart); err != nil {
			return err
		} else {
			template.Spec.RestartPolicy = restart
		}

		// Configure hostname/domain_name settings
		if service.HostName != "" {
			template.Spec.Hostname = service.HostName
		}
		if service.DomainName != "" {
			template.Spec.Subdomain = service.DomainName
		}

		if serviceAccountName, ok := service.Labels[compose.LabelServiceAccountName]; ok {
			template.Spec.ServiceAccountName = serviceAccountName
		}

		return nil
	}

	// fillObjectMeta fills the metadata with the value calculated from config
	fillObjectMeta := func(meta *metav1.ObjectMeta) {
		meta.Annotations = annotations
	}

	// update supported controller
	for _, obj := range *objects {
		err = k.UpdateController(obj, fillTemplate, fillObjectMeta)
		if err != nil {
			return errors.Wrap(err, "k.UpdateController failed")
		}
		if len(service.Volumes) > 0 {
			switch objType := obj.(type) {
			case *appsv1.Deployment:
				objType.Spec.Strategy.Type = appsv1.RecreateDeploymentStrategyType
			case *deployapi.DeploymentConfig:
				objType.Spec.Strategy.Type = deployapi.DeploymentStrategyTypeRecreate
			case *appsv1.StatefulSet:
				// embed all PVCs inside the StatefulSet object
				if opt.Volumes == "configMap" {
					break
				}
				persistentVolumeClaims := make([]api.PersistentVolumeClaim, len(pvc))
				for i, persistentVolumeClaim := range pvc {
					persistentVolumeClaims[i] = *persistentVolumeClaim
					persistentVolumeClaims[i].APIVersion = ""
					persistentVolumeClaims[i].Kind = ""
				}
				objType.Spec.VolumeClaimTemplates = persistentVolumeClaims
			}
		}
	}
	return nil
}