• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes / kompose / 6696194161

30 Oct 2023 05:02PM UTC coverage: 54.96%. Remained the same
6696194161

push

github

web-flow
chore(deps)(deps): bump golang.org/x/tools from 0.13.0 to 0.14.0 (#1723)

Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.13.0 to 0.14.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.13.0...v0.14.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

2205 of 4012 relevant lines covered (54.96%)

7.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.62
/pkg/transformer/kubernetes/podspec.go
1
package kubernetes
2

3
import (
4
        "reflect"
5
        "strconv"
6

7
        mapset "github.com/deckarep/golang-set"
8
        "github.com/kubernetes/kompose/pkg/kobject"
9
        "github.com/pkg/errors"
10
        log "github.com/sirupsen/logrus"
11
        api "k8s.io/api/core/v1"
12
        "k8s.io/apimachinery/pkg/api/resource"
13
        "k8s.io/apimachinery/pkg/util/intstr"
14
)
15

16
// PodSpec holds the spec of k8s pod.
17
type PodSpec struct {
18
        api.PodSpec
19
}
20

21
// PodSpecOption holds the function to apply on a PodSpec
22
type PodSpecOption func(*PodSpec)
23

24
// AddContainer method is responsible for adding a new container to a k8s Pod.
25
func AddContainer(service kobject.ServiceConfig, opt kobject.ConvertOptions) PodSpecOption {
6✔
26
        return func(podSpec *PodSpec) {
12✔
27
                name := GetContainerName(service)
6✔
28
                image := service.Image
6✔
29

6✔
30
                if image == "" {
6✔
31
                        image = name
×
32
                }
×
33

34
                envs, err := ConfigEnvs(service, opt)
6✔
35
                if err != nil {
6✔
36
                        panic("Unable to load env variables")
×
37
                }
38

39
                podSpec.Containers = append(podSpec.Containers, api.Container{
6✔
40
                        Name:           name,
6✔
41
                        Image:          image,
6✔
42
                        Env:            envs,
6✔
43
                        Command:        service.Command,
6✔
44
                        Args:           service.Args,
6✔
45
                        WorkingDir:     service.WorkingDir,
6✔
46
                        Stdin:          service.Stdin,
6✔
47
                        TTY:            service.Tty,
6✔
48
                        LivenessProbe:  configProbe(service.HealthChecks.Liveness),
6✔
49
                        ReadinessProbe: configProbe(service.HealthChecks.Readiness),
6✔
50
                })
6✔
51
                if service.ImagePullSecret != "" {
6✔
52
                        podSpec.ImagePullSecrets = append(podSpec.ImagePullSecrets, api.LocalObjectReference{
×
53
                                Name: service.ImagePullSecret,
×
54
                        })
×
55
                }
×
56
                podSpec.Affinity = ConfigAffinity(service)
6✔
57
        }
58
}
59

60
// TerminationGracePeriodSeconds method is responsible for attributing the grace period seconds option to a pod
61
func TerminationGracePeriodSeconds(name string, service kobject.ServiceConfig) PodSpecOption {
6✔
62
        return func(podSpec *PodSpec) {
12✔
63
                var err error
6✔
64
                if service.StopGracePeriod != "" {
6✔
65
                        podSpec.TerminationGracePeriodSeconds, err = DurationStrToSecondsInt(service.StopGracePeriod)
×
66
                        if err != nil {
×
67
                                log.Warningf("Failed to parse duration \"%v\" for service \"%v\"", service.StopGracePeriod, name)
×
68
                        }
×
69
                }
70
        }
71
}
72

73
// ResourcesLimits Configure the resource limits
74
func ResourcesLimits(service kobject.ServiceConfig) PodSpecOption {
6✔
75
        return func(podSpec *PodSpec) {
12✔
76
                if service.MemLimit != 0 || service.CPULimit != 0 {
6✔
77
                        resourceLimit := api.ResourceList{}
×
78

×
79
                        if service.MemLimit != 0 {
×
80
                                resourceLimit[api.ResourceMemory] = *resource.NewQuantity(int64(service.MemLimit), "RandomStringForFormat")
×
81
                        }
×
82

83
                        if service.CPULimit != 0 {
×
84
                                resourceLimit[api.ResourceCPU] = *resource.NewMilliQuantity(service.CPULimit, resource.DecimalSI)
×
85
                        }
×
86

87
                        for i := range podSpec.Containers {
×
88
                                podSpec.Containers[i].Resources.Limits = resourceLimit
×
89
                        }
×
90
                }
91
        }
92
}
93

94
// ResourcesRequests Configure the resource requests
95
func ResourcesRequests(service kobject.ServiceConfig) PodSpecOption {
6✔
96
        return func(podSpec *PodSpec) {
12✔
97
                if service.MemReservation != 0 || service.CPUReservation != 0 {
6✔
98
                        resourceRequests := api.ResourceList{}
×
99

×
100
                        if service.MemReservation != 0 {
×
101
                                resourceRequests[api.ResourceMemory] = *resource.NewQuantity(int64(service.MemReservation), "RandomStringForFormat")
×
102
                        }
×
103

104
                        if service.CPUReservation != 0 {
×
105
                                resourceRequests[api.ResourceCPU] = *resource.NewMilliQuantity(service.CPUReservation, resource.DecimalSI)
×
106
                        }
×
107

108
                        for i := range podSpec.Containers {
×
109
                                podSpec.Containers[i].Resources.Requests = resourceRequests
×
110
                        }
×
111
                }
112
        }
113
}
114

115
// SecurityContext Configure SecurityContext
116
func SecurityContext(name string, service kobject.ServiceConfig) PodSpecOption {
6✔
117
        return func(podSpec *PodSpec) {
12✔
118
                // Configure resource reservations
6✔
119
                podSecurityContext := &api.PodSecurityContext{}
6✔
120

6✔
121
                //set pid namespace mode
6✔
122
                if service.Pid != "" {
6✔
123
                        if service.Pid == "host" {
×
124
                                // podSecurityContext.HostPID = true
×
125
                        } else {
×
126
                                log.Warningf("Ignoring PID key for service \"%v\". Invalid value \"%v\".", name, service.Pid)
×
127
                        }
×
128
                }
129

130
                //set supplementalGroups
131
                if service.GroupAdd != nil {
6✔
132
                        podSecurityContext.SupplementalGroups = service.GroupAdd
×
133
                }
×
134

135
                //set Pod FsGroup
136
                if service.FsGroup != 0 {
6✔
137
                        podSecurityContext.FSGroup = &service.FsGroup
×
138
                }
×
139

140
                // Setup security context
141
                securityContext := &api.SecurityContext{}
6✔
142
                if service.Privileged {
6✔
143
                        securityContext.Privileged = &service.Privileged
×
144
                }
×
145
                if service.User != "" {
6✔
146
                        uid, err := strconv.ParseInt(service.User, 10, 64)
×
147
                        if err != nil {
×
148
                                log.Warn("Ignoring user directive. User to be specified as a UID (numeric).")
×
149
                        } else {
×
150
                                securityContext.RunAsUser = &uid
×
151
                        }
×
152
                }
153

154
                // Configure capabilities
155
                capabilities := ConfigCapabilities(service)
6✔
156

6✔
157
                //set capabilities if it is not empty
6✔
158
                if len(capabilities.Add) > 0 || len(capabilities.Drop) > 0 {
6✔
159
                        securityContext.Capabilities = capabilities
×
160
                }
×
161

162
                // update template only if securityContext is not empty
163
                if *securityContext != (api.SecurityContext{}) {
6✔
164
                        podSpec.Containers[0].SecurityContext = securityContext
×
165
                }
×
166
                if !reflect.DeepEqual(*podSecurityContext, api.PodSecurityContext{}) {
6✔
167
                        podSpec.SecurityContext = podSecurityContext
×
168
                }
×
169
        }
170
}
171

172
// SetVolumeNames method return a set of volume names
173
func SetVolumeNames(volumes []api.Volume) mapset.Set {
12✔
174
        set := mapset.NewSet()
12✔
175
        for _, volume := range volumes {
18✔
176
                set.Add(volume.Name)
6✔
177
        }
6✔
178
        return set
12✔
179
}
180

181
// SetVolumes method returns a method that adds the volumes to the pod spec
182
func SetVolumes(volumes []api.Volume) PodSpecOption {
6✔
183
        return func(podSpec *PodSpec) {
12✔
184
                volumesSet := SetVolumeNames(volumes)
6✔
185
                containerVolumesSet := SetVolumeNames(podSpec.Volumes)
6✔
186
                for diffVolumeName := range volumesSet.Difference(containerVolumesSet).Iter() {
8✔
187
                        for _, volume := range volumes {
4✔
188
                                if volume.Name == diffVolumeName {
4✔
189
                                        podSpec.Volumes = append(podSpec.Volumes, volume)
2✔
190
                                        break
2✔
191
                                }
192
                        }
193
                }
194
        }
195
}
196

197
// SetVolumeMountPaths method returns a set of volumes mount path
198
func SetVolumeMountPaths(volumesMount []api.VolumeMount) mapset.Set {
15✔
199
        set := mapset.NewSet()
15✔
200
        for _, volumeMount := range volumesMount {
21✔
201
                set.Add(volumeMount.MountPath)
6✔
202
        }
6✔
203

204
        return set
15✔
205
}
206

207
// SetVolumeMounts returns a function which adds the volume mounts option to the pod spec
208
func SetVolumeMounts(volumesMount []api.VolumeMount) PodSpecOption {
6✔
209
        return func(podSpec *PodSpec) {
12✔
210
                volumesMountSet := SetVolumeMountPaths(volumesMount)
6✔
211
                for i := range podSpec.Containers {
15✔
212
                        containerVolumeMountsSet := SetVolumeMountPaths(podSpec.Containers[i].VolumeMounts)
9✔
213
                        for diffVolumeMountPath := range volumesMountSet.Difference(containerVolumeMountsSet).Iter() {
13✔
214
                                for _, volumeMount := range volumesMount {
8✔
215
                                        if volumeMount.MountPath == diffVolumeMountPath {
8✔
216
                                                podSpec.Containers[i].VolumeMounts = append(podSpec.Containers[i].VolumeMounts, volumeMount)
4✔
217
                                                break
4✔
218
                                        }
219
                                }
220
                        }
221
                }
222
        }
223
}
224

225
// SetPorts Configure ports
226
func SetPorts(service kobject.ServiceConfig) PodSpecOption {
6✔
227
        return func(podSpec *PodSpec) {
12✔
228
                // Configure the container ports.
6✔
229
                ports := ConfigPorts(service)
6✔
230
                for i := range podSpec.Containers {
15✔
231
                        if GetContainerName(service) == podSpec.Containers[i].Name {
15✔
232
                                podSpec.Containers[i].Ports = ports
6✔
233
                        }
6✔
234
                }
235
        }
236
}
237

238
// ImagePullPolicy Configure the image pull policy
239
func ImagePullPolicy(name string, service kobject.ServiceConfig) PodSpecOption {
6✔
240
        return func(podSpec *PodSpec) {
12✔
241
                if policy, err := GetImagePullPolicy(name, service.ImagePullPolicy); err != nil {
6✔
242
                        panic(err)
×
243
                } else {
6✔
244
                        for i := range podSpec.Containers {
15✔
245
                                podSpec.Containers[i].ImagePullPolicy = policy
9✔
246
                        }
9✔
247
                }
248
        }
249
}
250

251
// RestartPolicy Configure the container restart policy.
252
func RestartPolicy(name string, service kobject.ServiceConfig) PodSpecOption {
6✔
253
        return func(podSpec *PodSpec) {
12✔
254
                if restart, err := GetRestartPolicy(name, service.Restart); err != nil {
6✔
255
                        panic(err)
×
256
                } else {
6✔
257
                        podSpec.RestartPolicy = restart
6✔
258
                }
6✔
259
        }
260
}
261

262
// HostName configure the host name of a pod
263
func HostName(service kobject.ServiceConfig) PodSpecOption {
6✔
264
        return func(podSpec *PodSpec) {
12✔
265
                // Configure hostname/domain_name settings
6✔
266
                if service.HostName != "" {
6✔
267
                        podSpec.Hostname = service.HostName
×
268
                }
×
269
        }
270
}
271

272
// DomainName configure the domain name of a pod
273
func DomainName(service kobject.ServiceConfig) PodSpecOption {
6✔
274
        return func(podSpec *PodSpec) {
12✔
275
                if service.DomainName != "" {
6✔
276
                        podSpec.Subdomain = service.DomainName
×
277
                }
×
278
        }
279
}
280

281
func configProbe(healthCheck kobject.HealthCheck) *api.Probe {
72✔
282
        probe := api.Probe{}
72✔
283
        // We check to see if it's blank or disable
72✔
284
        if reflect.DeepEqual(healthCheck, kobject.HealthCheck{}) || healthCheck.Disable {
130✔
285
                return nil
58✔
286
        }
58✔
287

288
        if len(healthCheck.Test) > 0 {
16✔
289
                probe.ProbeHandler = api.ProbeHandler{
2✔
290
                        Exec: &api.ExecAction{
2✔
291
                                Command: healthCheck.Test,
2✔
292
                        },
2✔
293
                }
2✔
294
        } else if !reflect.ValueOf(healthCheck.HTTPPath).IsZero() && !reflect.ValueOf(healthCheck.HTTPPort).IsZero() {
16✔
295
                probe.ProbeHandler = api.ProbeHandler{
2✔
296
                        HTTPGet: &api.HTTPGetAction{
2✔
297
                                Path: healthCheck.HTTPPath,
2✔
298
                                Port: intstr.FromInt(int(healthCheck.HTTPPort)),
2✔
299
                        },
2✔
300
                }
2✔
301
        } else if !reflect.ValueOf(healthCheck.TCPPort).IsZero() {
22✔
302
                probe.ProbeHandler = api.ProbeHandler{
10✔
303
                        TCPSocket: &api.TCPSocketAction{
10✔
304
                                Port: intstr.FromInt(int(healthCheck.TCPPort)),
10✔
305
                        },
10✔
306
                }
10✔
307
        } else {
10✔
308
                panic(errors.New("Health check must contain a command"))
×
309
        }
310

311
        probe.TimeoutSeconds = healthCheck.Timeout
14✔
312
        probe.PeriodSeconds = healthCheck.Interval
14✔
313
        probe.FailureThreshold = healthCheck.Retries
14✔
314

14✔
315
        // See issue: https://github.com/docker/cli/issues/116
14✔
316
        // StartPeriod has been added to v3.4 of the compose
14✔
317
        probe.InitialDelaySeconds = healthCheck.StartPeriod
14✔
318
        return &probe
14✔
319
}
320

321
// ServiceAccountName is responsible for setting the service account name to the pod spec
322
func ServiceAccountName(serviceAccountName string) PodSpecOption {
2✔
323
        return func(podSpec *PodSpec) {
4✔
324
                podSpec.ServiceAccountName = serviceAccountName
2✔
325
        }
2✔
326
}
327

328
// TopologySpreadConstraints is responsible for setting the topology spread constraints to the pod spec
329
func TopologySpreadConstraints(service kobject.ServiceConfig) PodSpecOption {
6✔
330
        return func(podSpec *PodSpec) {
12✔
331
                podSpec.TopologySpreadConstraints = ConfigTopologySpreadConstraints(service)
6✔
332
        }
6✔
333
}
334

335
// Append is responsible for adding the pod spec options to the particular pod
336
func (podSpec *PodSpec) Append(ops ...PodSpecOption) *PodSpec {
20✔
337
        for _, option := range ops {
100✔
338
                option(podSpec)
80✔
339
        }
80✔
340
        return podSpec
20✔
341
}
342

343
// Get is responsible for returning the pod spec of a particular pod
344
func (podSpec *PodSpec) Get() api.PodSpec {
9✔
345
        return podSpec.PodSpec
9✔
346
}
9✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc