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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/bin/devfile +0 -0
  3. data/ext/devfile.go +84 -25
  4. data/ext/volume.go +72 -68
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a51dbd46d989075807ea91333a1bcabca598d5bbfb6a6010c0aca3eb82a6cd83
4
- data.tar.gz: 1f6dde67b986ef69691c6a577209332f6bd88095b50de0e6fdc1a8b1c776f81e
3
+ metadata.gz: 9ae13e77747c2e3c8dc97a9efb936e661cd8345490e7c4e269982404d0e3b088
4
+ data.tar.gz: bebdfb30f72d7615ce3a91cc183bbe46c624e3faaa4da19ede4705001510e6f7
5
5
  SHA512:
6
- metadata.gz: 1ca4a2dbdda67b2f53e0a2159564b99297ba2eeb24595a6ece5b45720881484ca826dbccedb20028b5aee0090806d8ff8e4707c6b0da4c21304b0cabb358efe9
7
- data.tar.gz: dcde2fe0951b7654eed898eb81165d20f8b0e0c2b5e0339b642099ea13709b8795ac9f9dd75a42372e708422cca07e81bc21a333a54791ad7a359b92887b35fc
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 pvcOptions struct {
26
- Name string
27
- Size string
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 := generator.GetContainers(d.devfileObj, common.DevfileOptions{})
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
- containers, err := generator.GetContainers(d.devfileObj, common.DevfileOptions{})
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 _, options := range pvcNameToPvcOptions {
170
- quantity, err := resource.ParseQuantity(options.Size)
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: options.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
- "fmt"
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
- func (d Devfile) getVolumesAndVolumeMounts(containers []corev1.Container, initContainers []corev1.Container, volumeNamePrefix string) ([]corev1.Volume, map[string]pvcOptions, error) {
13
- containerComponents, err := d.devfileObj.Data.GetDevfileContainerComponents(common.DevfileOptions{})
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
- volumeComponents, err := d.devfileObj.Data.GetDevfileVolumeComponents(common.DevfileOptions{})
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 volumes []corev1.Volume
23
- pvcNameToPvcOptions := map[string]pvcOptions{}
24
- for _, volumeComponent := range volumeComponents {
25
- volName := volumeComponent.Name
26
- if bool(*volumeComponent.Volume.Ephemeral) == true {
27
- emptyDir, err := getEmptyDir(volName, volumeComponent.Volume.Size)
28
- if err != nil {
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
- volumes = append(volumes, emptyDir)
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
- pvcName := fmt.Sprintf("%s-%s", volumeNamePrefix, volumeComponent.Name)
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], generator.GetVolumeMountPath(volumeMount))
63
+ containerNameToMountPaths[containerComp.Name] = append(containerNameToMountPaths[containerComp.Name], getVolumeMountPath(volumeMount))
46
64
  }
47
65
  }
48
66
  }
49
67
 
50
- addVolumeMountToContainers(containers, initContainers, volumeComponent.Name, containerNameToMountPaths)
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 volumes, pvcNameToPvcOptions, nil
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
- // addVolumeMountToContainers adds the Volume Mounts in containerNameToMountPaths to the containers for a given pvc and volumeName
57
- // containerNameToMountPaths is a map of a container name to an array of its Mount Paths.
58
- // To be moved to devfile/library.
59
- func addVolumeMountToContainers(containers []corev1.Container, initContainers []corev1.Container, volumeName string, containerNameToMountPaths map[string][]string) {
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 == containerName {
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
- // getPersistentVolumeClaim gets a pvc type volume with the given volume name and pvc name.
90
- func getPersistentVolumeClaim(volumeName, pvcName string) corev1.Volume {
91
-
92
- return corev1.Volume{
93
- Name: volumeName,
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
- emptyDir := &corev1.EmptyDirVolumeSource{}
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.14.pre.alpha1
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-26 00:00:00.000000000 Z
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: