devfile 0.0.14.pre.alpha1-x86_64-linux → 0.0.15.pre.alpha1-x86_64-linux
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/devfile +0 -0
- data/ext/devfile.go +84 -25
- data/ext/volume.go +72 -68
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7dd5cde59eace92d015353ca37457ce78ca42b11a78deedb76f8b6374b81bc6e
|
4
|
+
data.tar.gz: 426dacd724bca8169688bcaf37b8f8714817e0638fb4c2666e2e34e70dbb2bc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc55a8d805d9ac1aa0253b1343e90cf96b6a2bb78ceb6e9713710167b0f054b9994bbd212c4ef02ead8a614eed1a7874c2c6ebfc1cec2a4f134db3a7115318de
|
7
|
+
data.tar.gz: 7f9c71f44ce42160bcc29efeff03efe4fdface8aa59eec4755aebcfbd8aed01740d0558aa42d8d86eaf49b3163a41d60731458ab23122cad72cf61cd9cd4c43f
|
data/bin/devfile
CHANGED
Binary file
|
data/ext/devfile.go
CHANGED
@@ -2,6 +2,8 @@ package main
|
|
2
2
|
|
3
3
|
import (
|
4
4
|
"bytes"
|
5
|
+
"fmt"
|
6
|
+
"sort"
|
5
7
|
"strconv"
|
6
8
|
"text/template"
|
7
9
|
|
@@ -22,21 +24,14 @@ type Devfile struct {
|
|
22
24
|
devfileObj parser.DevfileObj
|
23
25
|
}
|
24
26
|
|
25
|
-
type
|
26
|
-
|
27
|
-
Size
|
27
|
+
type volumeOptions struct {
|
28
|
+
Info generator.VolumeInfo
|
29
|
+
Size string
|
30
|
+
IsEphemeral bool
|
28
31
|
}
|
29
32
|
|
30
33
|
func (d Devfile) getDeployment(name, namespace string, labels, annotations map[string]string, replicas int) (*appsv1.Deployment, error) {
|
31
|
-
containers, err :=
|
32
|
-
if err != nil {
|
33
|
-
return nil, err
|
34
|
-
}
|
35
|
-
initContainers, err := generator.GetInitContainers(d.devfileObj)
|
36
|
-
if err != nil {
|
37
|
-
return nil, err
|
38
|
-
}
|
39
|
-
volumes, _, err := d.getVolumesAndVolumeMounts(containers, initContainers, name)
|
34
|
+
containers, initContainers, volumes, _, err := d.getContainersAndVolumes(name)
|
40
35
|
if err != nil {
|
41
36
|
return nil, err
|
42
37
|
}
|
@@ -152,29 +147,24 @@ func (d Devfile) getIngress(name, namespace string, labels, annotations map[stri
|
|
152
147
|
}
|
153
148
|
|
154
149
|
func (d Devfile) getPVC(name, namespace string, labels, annotations map[string]string) ([]*corev1.PersistentVolumeClaim, error) {
|
155
|
-
|
156
|
-
if err != nil {
|
157
|
-
return nil, err
|
158
|
-
}
|
159
|
-
initContainers, err := generator.GetInitContainers(d.devfileObj)
|
160
|
-
if err != nil {
|
161
|
-
return nil, err
|
162
|
-
}
|
163
|
-
_, pvcNameToPvcOptions, err := d.getVolumesAndVolumeMounts(containers, initContainers, name)
|
150
|
+
_, _, volumes, volumeNameToVolumeOptions, err := d.getContainersAndVolumes(name)
|
164
151
|
if err != nil {
|
165
152
|
return nil, err
|
166
153
|
}
|
167
|
-
|
168
154
|
pvcs := make([]*corev1.PersistentVolumeClaim, 0)
|
169
|
-
for _,
|
170
|
-
|
155
|
+
for _, volume := range volumes {
|
156
|
+
volumeOptions := volumeNameToVolumeOptions[volume.Name]
|
157
|
+
if volumeOptions.IsEphemeral {
|
158
|
+
continue
|
159
|
+
}
|
160
|
+
quantity, err := resource.ParseQuantity(volumeOptions.Size)
|
171
161
|
if err != nil {
|
172
162
|
return nil, err
|
173
163
|
}
|
174
164
|
pvcParams := generator.PVCParams{
|
175
165
|
TypeMeta: generator.GetTypeMeta("PersistentVolumeClaim", "v1"),
|
176
166
|
ObjectMeta: metav1.ObjectMeta{
|
177
|
-
Name:
|
167
|
+
Name: volumeOptions.Info.PVCName,
|
178
168
|
Namespace: namespace,
|
179
169
|
Labels: labels,
|
180
170
|
Annotations: annotations,
|
@@ -222,6 +212,75 @@ func (d Devfile) getAll(name, namespace string, labels, annotations map[string]s
|
|
222
212
|
return result, nil
|
223
213
|
}
|
224
214
|
|
215
|
+
func (d Devfile) getContainersAndVolumes(name string) ([]corev1.Container, []corev1.Container, []corev1.Volume, map[string]volumeOptions, error) {
|
216
|
+
containers, err := generator.GetContainers(d.devfileObj, common.DevfileOptions{})
|
217
|
+
if err != nil {
|
218
|
+
return nil, nil, nil, nil, err
|
219
|
+
}
|
220
|
+
initContainers, err := generator.GetInitContainers(d.devfileObj)
|
221
|
+
if err != nil {
|
222
|
+
return nil, nil, nil, nil, err
|
223
|
+
}
|
224
|
+
allContainers := append(containers, initContainers...)
|
225
|
+
|
226
|
+
volumeComponents, err := d.devfileObj.Data.GetDevfileVolumeComponents(common.DevfileOptions{})
|
227
|
+
if err != nil {
|
228
|
+
return nil, nil, nil, nil, err
|
229
|
+
}
|
230
|
+
volumeNameToVolumeOptions := map[string]volumeOptions{}
|
231
|
+
volumeNameToVolumeInfo := map[string]generator.VolumeInfo{}
|
232
|
+
for _, volumeComponent := range volumeComponents {
|
233
|
+
info := generator.VolumeInfo{
|
234
|
+
PVCName: fmt.Sprintf("%s-%s", name, volumeComponent.Name),
|
235
|
+
VolumeName: volumeComponent.Name,
|
236
|
+
}
|
237
|
+
volumeNameToVolumeInfo[volumeComponent.Name] = info
|
238
|
+
volumeNameToVolumeOptions[volumeComponent.Name] = volumeOptions{
|
239
|
+
Info: info,
|
240
|
+
Size: volumeComponent.Volume.Size,
|
241
|
+
IsEphemeral: *volumeComponent.Volume.Ephemeral,
|
242
|
+
}
|
243
|
+
}
|
244
|
+
|
245
|
+
volumeParams := generator.VolumeParams{
|
246
|
+
Containers: allContainers,
|
247
|
+
VolumeNameToVolumeInfo: volumeNameToVolumeInfo,
|
248
|
+
}
|
249
|
+
options := common.DevfileOptions{}
|
250
|
+
// "containers" and "initContainers" are updated in place with the volume mounts parameters
|
251
|
+
// after the following function is called
|
252
|
+
//volumes, err := generator.GetVolumesAndVolumeMounts(d.devfileObj, volumeParams, options)
|
253
|
+
updatedAllContainers, volumes, err := getVolumesAndVolumeMounts(d.devfileObj, volumeParams, options)
|
254
|
+
if err != nil {
|
255
|
+
return nil, nil, nil, nil, err
|
256
|
+
}
|
257
|
+
// sort all volumes and volume mounts in the containers and initContainers
|
258
|
+
// to keep the array order deterministic
|
259
|
+
sort.SliceStable(volumes, func(i, j int) bool {
|
260
|
+
return volumes[i].Name < volumes[j].Name
|
261
|
+
})
|
262
|
+
|
263
|
+
updatedContainers := make([]corev1.Container, 0)
|
264
|
+
updatedInitContainers := make([]corev1.Container, 0)
|
265
|
+
for _, updated := range updatedAllContainers {
|
266
|
+
sort.SliceStable(updated.VolumeMounts, func(i, j int) bool {
|
267
|
+
return updated.VolumeMounts[i].Name < updated.VolumeMounts[j].Name
|
268
|
+
})
|
269
|
+
for _, container := range containers {
|
270
|
+
if updated.Name == container.Name {
|
271
|
+
updatedContainers = append(updatedContainers, updated)
|
272
|
+
}
|
273
|
+
}
|
274
|
+
for _, initContainer := range initContainers {
|
275
|
+
if updated.Name == initContainer.Name {
|
276
|
+
updatedInitContainers = append(updatedInitContainers, updated)
|
277
|
+
}
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
return updatedContainers, updatedInitContainers, volumes, volumeNameToVolumeOptions, nil
|
282
|
+
}
|
283
|
+
|
225
284
|
func (d Devfile) hasContainerComponents() (bool, error) {
|
226
285
|
containers, err := generator.GetContainers(d.devfileObj, common.DevfileOptions{})
|
227
286
|
if err != nil {
|
data/ext/volume.go
CHANGED
@@ -1,83 +1,108 @@
|
|
1
1
|
package main
|
2
2
|
|
3
3
|
import (
|
4
|
-
"
|
4
|
+
devfileApiV1Alpha2 "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2"
|
5
5
|
"github.com/devfile/library/v2/pkg/devfile/generator"
|
6
|
+
"github.com/devfile/library/v2/pkg/devfile/parser"
|
6
7
|
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
7
8
|
corev1 "k8s.io/api/core/v1"
|
8
|
-
"k8s.io/apimachinery/pkg/api/resource"
|
9
9
|
"strings"
|
10
10
|
)
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
// There's a bug in the devfile library
|
13
|
+
// When a container component which has events and commands attached to it, becomes a init container, the name is
|
14
|
+
// init container is a concatenation of component name, event/command.
|
15
|
+
// However, when generating containerNameToMountPaths, we are using the component name
|
16
|
+
// And in addVolumeMountToContainers, we are comparing the container name with a component name
|
17
|
+
// For init containers this will not match
|
18
|
+
// Temporary fix is to use a string prefix check in addVolumeMountToContainers and return the updatedAllContainers from
|
19
|
+
// getVolumesAndVolumeMounts
|
20
|
+
// TODO: This might not be a perfect fix because maybe a string prefix match can have undesirable effects.
|
21
|
+
// issue: https://gitlab.com/gitlab-org/gitlab/-/issues/408950
|
22
|
+
|
23
|
+
// getVolumesAndVolumeMounts gets the PVC volumes and updates the containers with the volume mounts.
|
24
|
+
func getVolumesAndVolumeMounts(devfileObj parser.DevfileObj, volumeParams generator.VolumeParams, options common.DevfileOptions) ([]corev1.Container, []corev1.Volume, error) {
|
25
|
+
options.ComponentOptions = common.ComponentOptions{
|
26
|
+
ComponentType: devfileApiV1Alpha2.ContainerComponentType,
|
27
|
+
}
|
28
|
+
containerComponents, err := devfileObj.Data.GetComponents(options)
|
14
29
|
if err != nil {
|
15
30
|
return nil, nil, err
|
16
31
|
}
|
17
|
-
|
32
|
+
|
33
|
+
options.ComponentOptions = common.ComponentOptions{
|
34
|
+
ComponentType: devfileApiV1Alpha2.VolumeComponentType,
|
35
|
+
}
|
36
|
+
volumeComponent, err := devfileObj.Data.GetComponents(options)
|
18
37
|
if err != nil {
|
19
38
|
return nil, nil, err
|
20
39
|
}
|
21
40
|
|
22
|
-
var
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
return nil, nil, err
|
41
|
+
var pvcVols []corev1.Volume
|
42
|
+
for volName, volInfo := range volumeParams.VolumeNameToVolumeInfo {
|
43
|
+
emptyDirVolume := false
|
44
|
+
for _, volumeComp := range volumeComponent {
|
45
|
+
if volumeComp.Name == volName && *volumeComp.Volume.Ephemeral {
|
46
|
+
emptyDirVolume = true
|
47
|
+
break
|
30
48
|
}
|
31
|
-
|
49
|
+
}
|
50
|
+
|
51
|
+
// if `ephemeral=true`, a volume with emptyDir should be created
|
52
|
+
if emptyDirVolume {
|
53
|
+
pvcVols = append(pvcVols, getEmptyDirSource(volInfo.VolumeName))
|
32
54
|
} else {
|
33
|
-
|
34
|
-
pvcNameToPvcOptions[volumeComponent.Name] = pvcOptions{
|
35
|
-
Name: pvcName,
|
36
|
-
Size: volumeComponent.Volume.Size,
|
37
|
-
}
|
38
|
-
volumes = append(volumes, getPersistentVolumeClaim(volName, pvcName))
|
55
|
+
pvcVols = append(pvcVols, getPVCSource(volInfo.VolumeName, volInfo.PVCName))
|
39
56
|
}
|
57
|
+
|
40
58
|
// containerNameToMountPaths is a map of the Devfile container name to their Devfile Volume Mount Paths for a given Volume Name
|
41
59
|
containerNameToMountPaths := make(map[string][]string)
|
42
60
|
for _, containerComp := range containerComponents {
|
43
61
|
for _, volumeMount := range containerComp.Container.VolumeMounts {
|
44
62
|
if volName == volumeMount.Name {
|
45
|
-
containerNameToMountPaths[containerComp.Name] = append(containerNameToMountPaths[containerComp.Name],
|
63
|
+
containerNameToMountPaths[containerComp.Name] = append(containerNameToMountPaths[containerComp.Name], getVolumeMountPath(volumeMount))
|
46
64
|
}
|
47
65
|
}
|
48
66
|
}
|
49
67
|
|
50
|
-
addVolumeMountToContainers(
|
68
|
+
addVolumeMountToContainers(volumeParams.Containers, volInfo.VolumeName, containerNameToMountPaths)
|
51
69
|
}
|
70
|
+
return volumeParams.Containers, pvcVols, nil
|
71
|
+
}
|
72
|
+
|
73
|
+
// getPVCSource gets a pvc type volume with the given volume name and pvc name.
|
74
|
+
func getPVCSource(volumeName, pvcName string) corev1.Volume {
|
52
75
|
|
53
|
-
return
|
76
|
+
return corev1.Volume{
|
77
|
+
Name: volumeName,
|
78
|
+
VolumeSource: corev1.VolumeSource{
|
79
|
+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
80
|
+
ClaimName: pvcName,
|
81
|
+
},
|
82
|
+
},
|
83
|
+
}
|
54
84
|
}
|
55
85
|
|
56
|
-
//
|
57
|
-
|
58
|
-
|
59
|
-
|
86
|
+
// getEmptyDirSource gets a volume with emptyDir
|
87
|
+
func getEmptyDirSource(volumeName string) corev1.Volume {
|
88
|
+
return corev1.Volume{
|
89
|
+
Name: volumeName,
|
90
|
+
VolumeSource: corev1.VolumeSource{
|
91
|
+
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
92
|
+
},
|
93
|
+
}
|
94
|
+
}
|
60
95
|
|
96
|
+
// addVolumeMountToContainers adds the Volume Mounts in containerNameToMountPaths to the containers for a given volumeName.
|
97
|
+
// containerNameToMountPaths is a map of a container name to an array of its Mount Paths.
|
98
|
+
func addVolumeMountToContainers(containers []corev1.Container, volumeName string, containerNameToMountPaths map[string][]string) {
|
61
99
|
for containerName, mountPaths := range containerNameToMountPaths {
|
62
100
|
for i := range containers {
|
63
|
-
if containers[i].Name
|
101
|
+
if strings.HasPrefix(containers[i].Name, containerName) {
|
64
102
|
for _, mountPath := range mountPaths {
|
65
103
|
containers[i].VolumeMounts = append(containers[i].VolumeMounts, corev1.VolumeMount{
|
66
104
|
Name: volumeName,
|
67
105
|
MountPath: mountPath,
|
68
|
-
SubPath: "",
|
69
|
-
},
|
70
|
-
)
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
74
|
-
for i := range initContainers {
|
75
|
-
if strings.HasPrefix(initContainers[i].Name, containerName) {
|
76
|
-
for _, mountPath := range mountPaths {
|
77
|
-
initContainers[i].VolumeMounts = append(initContainers[i].VolumeMounts, corev1.VolumeMount{
|
78
|
-
Name: volumeName,
|
79
|
-
MountPath: mountPath,
|
80
|
-
SubPath: "",
|
81
106
|
},
|
82
107
|
)
|
83
108
|
}
|
@@ -86,33 +111,12 @@ func addVolumeMountToContainers(containers []corev1.Container, initContainers []
|
|
86
111
|
}
|
87
112
|
}
|
88
113
|
|
89
|
-
//
|
90
|
-
func
|
91
|
-
|
92
|
-
|
93
|
-
Name
|
94
|
-
VolumeSource: corev1.VolumeSource{
|
95
|
-
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
|
96
|
-
ClaimName: pvcName,
|
97
|
-
},
|
98
|
-
},
|
114
|
+
// getVolumeMountPath gets the volume mount's path.
|
115
|
+
func getVolumeMountPath(volumeMount devfileApiV1Alpha2.VolumeMount) string {
|
116
|
+
// if there is no volume mount path, default to volume mount name as per devfile schema
|
117
|
+
if volumeMount.Path == "" {
|
118
|
+
volumeMount.Path = "/" + volumeMount.Name
|
99
119
|
}
|
100
|
-
}
|
101
|
-
|
102
|
-
// getEmptyDir gets an emptyDir type volume with the given volume name and size.
|
103
|
-
// size should be parseable as a Kubernetes `Quantity` or an error will be returned
|
104
|
-
func getEmptyDir(volumeName string, size string) (corev1.Volume, error) {
|
105
120
|
|
106
|
-
|
107
|
-
qty, err := resource.ParseQuantity(size)
|
108
|
-
if err != nil {
|
109
|
-
return corev1.Volume{}, err
|
110
|
-
}
|
111
|
-
emptyDir.SizeLimit = &qty
|
112
|
-
return corev1.Volume{
|
113
|
-
Name: volumeName,
|
114
|
-
VolumeSource: corev1.VolumeSource{
|
115
|
-
EmptyDir: emptyDir,
|
116
|
-
},
|
117
|
-
}, nil
|
121
|
+
return volumeMount.Path
|
118
122
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devfile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.15.pre.alpha1
|
5
5
|
platform: x86_64-linux
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Library used to generate kubernetes manifests from a Devfile.
|
14
14
|
email:
|