Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make transforming more deterministic #1744

Merged
merged 4 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions pkg/transformer/kubernetes/k8sutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,14 +686,16 @@ func getServiceGroupID(service kobject.ServiceConfig, mode string) string {
// A warn/info message should be printed to let the user know.
func KomposeObjectToServiceConfigGroupMapping(komposeObject *kobject.KomposeObject, opt kobject.ConvertOptions) map[string]kobject.ServiceConfigGroup {
serviceConfigGroup := make(map[string]kobject.ServiceConfigGroup)
sortedServiceConfigs := SortedKeys(komposeObject.ServiceConfigs)

for name, service := range komposeObject.ServiceConfigs {
groupID := getServiceGroupID(service, opt.ServiceGroupMode)
for _, service := range sortedServiceConfigs {
serviceConfig := komposeObject.ServiceConfigs[service]
groupID := getServiceGroupID(serviceConfig, opt.ServiceGroupMode)
if groupID != "" {
service.Name = name
service.InGroup = true
serviceConfigGroup[groupID] = append(serviceConfigGroup[groupID], service)
komposeObject.ServiceConfigs[name] = service
serviceConfig.Name = service
serviceConfig.InGroup = true
serviceConfigGroup[groupID] = append(serviceConfigGroup[groupID], serviceConfig)
komposeObject.ServiceConfigs[service] = serviceConfig
}
}

Expand Down Expand Up @@ -806,9 +808,9 @@ func (k *Kubernetes) RemoveDupObjects(objs *[]runtime.Object) {
}

// SortedKeys Ensure the kubernetes objects are in a consistent order
func SortedKeys(komposeObject kobject.KomposeObject) []string {
func SortedKeys[V kobject.ServiceConfig | kobject.ServiceConfigGroup](serviceConfig map[string]V) []string {
var sortedKeys []string
for name := range komposeObject.ServiceConfigs {
for name := range serviceConfig {
sortedKeys = append(sortedKeys, name)
}
sort.Strings(sortedKeys)
Expand Down
2 changes: 1 addition & 1 deletion pkg/transformer/kubernetes/k8sutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ func TestSortedKeys(t *testing.T) {
komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{"b": service, "a": service1},
}
a := SortedKeys(komposeObject)
a := SortedKeys(komposeObject.ServiceConfigs)
if !reflect.DeepEqual(a, c) {
t.Logf("Test Fail output should be %s", c)
}
Expand Down
37 changes: 21 additions & 16 deletions pkg/transformer/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -1455,28 +1455,33 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
if opt.ServiceGroupMode != "" {
log.Debugf("Service group mode is: %s", opt.ServiceGroupMode)
komposeObjectToServiceConfigGroupMapping := KomposeObjectToServiceConfigGroupMapping(&komposeObject, opt)
for name, group := range komposeObjectToServiceConfigGroupMapping {
sortedGroupMappingKeys := SortedKeys(komposeObjectToServiceConfigGroupMapping)
for _, group := range sortedGroupMappingKeys {
groupMapping := komposeObjectToServiceConfigGroupMapping[group]
var objects []runtime.Object
podSpec := PodSpec{}

var groupName string
// if using volume group, the name here will be a volume config string. reset to the first service name
if opt.ServiceGroupMode == "volume" {
if opt.ServiceGroupName != "" {
name = opt.ServiceGroupName
groupName = opt.ServiceGroupName
} else {
var names []string
for _, svc := range group {
for _, svc := range groupMapping {
names = append(names, svc.Name)
}
name = strings.Join(names, "-")
groupName = strings.Join(names, "-")
}
} else {
groupName = group
}

// added a container
// ports conflict check between services
portsUses := map[string]bool{}

for _, service := range group {
for _, service := range groupMapping {
// first do ports check
ports := ConfigPorts(service)
for _, port := range ports {
Expand All @@ -1487,25 +1492,25 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
portsUses[key] = true
}

log.Infof("Group Service %s to [%s]", service.Name, name)
log.Infof("Group Service %s to [%s]", service.Name, groupName)
service.WithKomposeAnnotation = opt.WithKomposeAnnotation
podSpec.Append(AddContainer(service, opt))

if err := buildServiceImage(opt, service, service.Name); err != nil {
return nil, err
}
// override..
objects = append(objects, k.CreateWorkloadAndConfigMapObjects(name, service, opt)...)
k.configKubeServiceAndIngressForService(service, name, &objects)
objects = append(objects, k.CreateWorkloadAndConfigMapObjects(groupName, service, opt)...)
k.configKubeServiceAndIngressForService(service, groupName, &objects)

// Configure the container volumes.
volumesMount, volumes, pvc, cms, err := k.ConfigVolumes(name, service)
volumesMount, volumes, pvc, cms, err := k.ConfigVolumes(groupName, service)
if err != nil {
return nil, errors.Wrap(err, "k.ConfigVolumes failed")
}
// Configure Tmpfs
if len(service.TmpFs) > 0 {
TmpVolumesMount, TmpVolumes := k.ConfigTmpfs(name, service)
TmpVolumesMount, TmpVolumes := k.ConfigTmpfs(groupName, service)
volumes = append(volumes, TmpVolumes...)
volumesMount = append(volumesMount, TmpVolumesMount...)
}
Expand All @@ -1527,22 +1532,22 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.

podSpec.Append(
SetPorts(service),
ImagePullPolicy(name, service),
RestartPolicy(name, service),
SecurityContext(name, service),
ImagePullPolicy(groupName, service),
RestartPolicy(groupName, service),
SecurityContext(groupName, service),
HostName(service),
DomainName(service),
ResourcesLimits(service),
ResourcesRequests(service),
TerminationGracePeriodSeconds(name, service),
TerminationGracePeriodSeconds(groupName, service),
TopologySpreadConstraints(service),
)

if serviceAccountName, ok := service.Labels[compose.LabelServiceAccountName]; ok {
podSpec.Append(ServiceAccountName(serviceAccountName))
}

err = k.UpdateKubernetesObjectsMultipleContainers(name, service, &objects, podSpec)
err = k.UpdateKubernetesObjectsMultipleContainers(groupName, service, &objects, podSpec)
if err != nil {
return nil, errors.Wrap(err, "Error transforming Kubernetes objects")
}
Expand All @@ -1557,7 +1562,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
allobjects = append(allobjects, objects...)
}
}
sortedKeys := SortedKeys(komposeObject)
sortedKeys := SortedKeys(komposeObject.ServiceConfigs)
for _, name := range sortedKeys {
service := komposeObject.ServiceConfigs[name]

Expand Down
2 changes: 1 addition & 1 deletion pkg/transformer/openshift/openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
}
}

sortedKeys := kubernetes.SortedKeys(komposeObject)
sortedKeys := kubernetes.SortedKeys(komposeObject.ServiceConfigs)
for _, name := range sortedKeys {
service := komposeObject.ServiceConfigs[name]
var objects []runtime.Object
Expand Down
18 changes: 9 additions & 9 deletions script/test/fixtures/service-group/output-k8s.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,25 +41,25 @@ spec:
containers:
- env:
- name: TZ
image: librenms/librenms:latest
name: librenms
ports:
- containerPort: 8000
hostPort: 8000
protocol: TCP
image: librenms/dispatcher:latest
name: dispatcher
resources: {}
volumeMounts:
- mountPath: /data
name: librenms-dispatcher-claim0
- env:
- name: TZ
image: librenms/dispatcher:latest
name: dispatcher
image: librenms/librenms:latest
name: librenms
ports:
- containerPort: 8000
hostPort: 8000
protocol: TCP
resources: {}
volumeMounts:
- mountPath: /data
name: librenms-dispatcher-claim0
hostname: dispatcher
hostname: librenms
restartPolicy: Always
volumes:
- name: librenms-dispatcher-claim0
Expand Down