devfile 0.0.14.pre.alpha1-arm64-darwin → 0.0.15.pre.alpha1-arm64-darwin
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: 9ae13e77747c2e3c8dc97a9efb936e661cd8345490e7c4e269982404d0e3b088
|
4
|
+
data.tar.gz: bebdfb30f72d7615ce3a91cc183bbe46c624e3faaa4da19ede4705001510e6f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7495fb0f37dfb0b2b0273f90b1c43d4aaaab1702ac666323a617be15cb02f604afc82f4d24b7ab0f0465f40f7d00e028f7c9228724572be46c1041058da9f70
|
7
|
+
data.tar.gz: 12b6e04cb808144038dd0da5843ae0ee216c047565d6bfc578f9d35075f8e395805df63b413285f6071ba3425195dc38def6dbb537e3a7cfb05cb276264009d0
|
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: arm64-darwin
|
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:
|