devfile 0.0.14.pre.alpha1-arm64-darwin → 0.0.16.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a51dbd46d989075807ea91333a1bcabca598d5bbfb6a6010c0aca3eb82a6cd83
4
- data.tar.gz: 1f6dde67b986ef69691c6a577209332f6bd88095b50de0e6fdc1a8b1c776f81e
3
+ metadata.gz: 56a3c3826a2e29c86391abee17d8f5f94b378038ebcb27518985aeb01dbc2329
4
+ data.tar.gz: e5e2a94cbe3bbf0465c84db27136db92612cb81013271ba861e9b5475937bb10
5
5
  SHA512:
6
- metadata.gz: 1ca4a2dbdda67b2f53e0a2159564b99297ba2eeb24595a6ece5b45720881484ca826dbccedb20028b5aee0090806d8ff8e4707c6b0da4c21304b0cabb358efe9
7
- data.tar.gz: dcde2fe0951b7654eed898eb81165d20f8b0e0c2b5e0339b642099ea13709b8795ac9f9dd75a42372e708422cca07e81bc21a333a54791ad7a359b92887b35fc
6
+ metadata.gz: 45ec260b80c3d17bece4930478cb492e0158bbdd6550d092ef5c7bf08aa23d61be2c322de3945887488def7b41212fe38c5ac63e5715b3053db8fce1f70aabc3
7
+ data.tar.gz: 632a7f1d8205b83180d24d7cac8fb97c30af0ce57c81e07a29d1acb16874e636ac87bfcacb3ad58955a95150254373782198d11ece9eb258fb5bc543ff602ba7
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{})
150
+ _, _, volumes, volumeNameToVolumeOptions, err := d.getContainersAndVolumes(name)
156
151
  if err != nil {
157
152
  return nil, err
158
153
  }
159
- initContainers, err := generator.GetInitContainers(d.devfileObj)
160
- if err != nil {
161
- return nil, err
162
- }
163
- _, pvcNameToPvcOptions, err := d.getVolumesAndVolumeMounts(containers, initContainers, name)
164
- if err != nil {
165
- return nil, err
166
- }
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 {
@@ -233,8 +292,12 @@ func (d Devfile) hasContainerComponents() (bool, error) {
233
292
  return false, nil
234
293
  }
235
294
 
236
- func (d Devfile) getFlattenedDevfileContent() string {
237
- return string(d.devfileObj.Ctx.GetDevfileContent())
295
+ func (d Devfile) getFlattenedDevfileContent() (string, error) {
296
+ b, err := yaml.Marshal(d.devfileObj.Data)
297
+ if err != nil {
298
+ return "", err
299
+ }
300
+ return string(b), nil
238
301
  }
239
302
 
240
303
  func parseDevfile(content string) (Devfile, error) {
data/ext/go.mod CHANGED
@@ -1,8 +1,9 @@
1
1
  module gitlab-org/remote-development/devfile-gem
2
2
 
3
- go 1.18
3
+ go 1.19
4
4
 
5
5
  require (
6
+ github.com/devfile/api/v2 v2.2.0
6
7
  github.com/devfile/library/v2 v2.2.0
7
8
  k8s.io/api v0.26.1
8
9
  k8s.io/apimachinery v0.26.1
@@ -19,7 +20,6 @@ require (
19
20
  github.com/cespare/xxhash/v2 v2.1.2 // indirect
20
21
  github.com/containerd/containerd v1.5.9 // indirect
21
22
  github.com/davecgh/go-spew v1.1.1 // indirect
22
- github.com/devfile/api/v2 v2.2.0 // indirect
23
23
  github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273 // indirect
24
24
  github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba // indirect
25
25
  github.com/docker/cli v20.10.11+incompatible // indirect
data/ext/main.go CHANGED
@@ -232,7 +232,10 @@ func flatten(devfile string) (string, error) {
232
232
  if err != nil {
233
233
  return "", err
234
234
  }
235
- flattenedDevfile := d.getFlattenedDevfileContent()
235
+ flattenedDevfile, err := d.getFlattenedDevfileContent()
236
+ if err != nil {
237
+ return "", err
238
+ }
236
239
  content, err := marshalDevfile(flattenedDevfile)
237
240
  if err != nil {
238
241
  return "", err
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.16.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-05-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Library used to generate kubernetes manifests from a Devfile.
14
14
  email:
@@ -46,7 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
46
  - !ruby/object:Gem::Version
47
47
  version: 1.3.1
48
48
  requirements: []
49
- rubygems_version: 3.4.9
49
+ rubygems_version: 3.4.12
50
50
  signing_key:
51
51
  specification_version: 4
52
52
  summary: Parse and generate kubernetes manifests from a Devfile