devfile 0.0.11.pre.alpha1-x86_64-linux → 0.0.12.pre.alpha1-x86_64-linux

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: 1791e8e7ff6b1f3de970040c705db46fef04cfb524b95f1e0a41d57f97e6d61d
4
- data.tar.gz: 26ede5ee22624b25fa8142879703a1c80b0fd78bf7e6598da89eec1c4310afbe
3
+ metadata.gz: 1cc3363280657ceecbb55931395fc354e8d13cb814c2a83b11dd679e0a67edd6
4
+ data.tar.gz: b8bdad6991ddc7a87cd72c49fc2d684f8fe055245ae8747136e08df8608a7bd0
5
5
  SHA512:
6
- metadata.gz: cfba06a846d7ec1a8c18b51cf86d4ff1c96af5ccef21df42e21ddfe0004bcbefabc4fde89c86c67077c1769b44a0a3d4ef7cd237278324b6c26090d8fd2e3b8d
7
- data.tar.gz: de8183ccfddadb4e3e59a21df545cedcd2b59967c3be488bccf93e8882c37e8e3bc728dbb670dbc62e15460b9f7bfa35ac517acb89421ea24569dcf140a21e19
6
+ metadata.gz: 928d238a1651d90afb2d1e81e8eafbfbbbb421487a51a21eba8b5262f6649619fcedcbc25ea1bcb4db2632e6e011491eb3abc41bd4736fc3540f2c14fe3b6ef6
7
+ data.tar.gz: 2dec36f8b4bd994a41cc3b20c2fb7099b54558dc1864dcd80b13594a036d84c55932d688dc595b38652c0479329e616ee92090f09a8fb0388877b638d1213a47
data/bin/devfile CHANGED
Binary file
data/ext/devfile.go CHANGED
@@ -1,8 +1,9 @@
1
1
  package main
2
2
 
3
- import "C"
4
3
  import (
5
4
  "bytes"
5
+ "fmt"
6
+ "sort"
6
7
  "strconv"
7
8
  "text/template"
8
9
 
@@ -12,6 +13,7 @@ import (
12
13
  appsv1 "k8s.io/api/apps/v1"
13
14
  corev1 "k8s.io/api/core/v1"
14
15
  networkingv1 "k8s.io/api/networking/v1"
16
+ "k8s.io/apimachinery/pkg/api/resource"
15
17
  metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16
18
  "k8s.io/apimachinery/pkg/runtime"
17
19
  "k8s.io/cli-runtime/pkg/printers"
@@ -22,16 +24,14 @@ type Devfile struct {
22
24
  devfileObj parser.DevfileObj
23
25
  }
24
26
 
27
+ type volumeOptions struct {
28
+ Info generator.VolumeInfo
29
+ Size string
30
+ IsEphemeral bool
31
+ }
32
+
25
33
  func (d Devfile) getDeployment(name, namespace string, labels, annotations map[string]string, replicas int) (*appsv1.Deployment, error) {
26
- containers, err := generator.GetContainers(d.devfileObj, common.DevfileOptions{})
27
- if err != nil {
28
- return nil, err
29
- }
30
- initContainers, err := generator.GetInitContainers(d.devfileObj)
31
- if err != nil {
32
- return nil, err
33
- }
34
- volumes, err := d.getVolumesAndVolumeMounts(containers, initContainers, name)
34
+ containers, initContainers, volumes, _, err := d.getContainersAndVolumes(name)
35
35
  if err != nil {
36
36
  return nil, err
37
37
  }
@@ -146,6 +146,37 @@ func (d Devfile) getIngress(name, namespace string, labels, annotations map[stri
146
146
  return ingress, nil
147
147
  }
148
148
 
149
+ func (d Devfile) getPVC(name, namespace string, labels, annotations map[string]string) ([]*corev1.PersistentVolumeClaim, error) {
150
+ _, _, volumes, volumeNameToVolumeOptions, err := d.getContainersAndVolumes(name)
151
+ if err != nil {
152
+ return nil, err
153
+ }
154
+ pvcs := make([]*corev1.PersistentVolumeClaim, 0)
155
+ for _, volume := range volumes {
156
+ volumeOptions := volumeNameToVolumeOptions[volume.Name]
157
+ if volumeOptions.IsEphemeral {
158
+ continue
159
+ }
160
+ quantity, err := resource.ParseQuantity(volumeOptions.Size)
161
+ if err != nil {
162
+ return nil, err
163
+ }
164
+ pvcParams := generator.PVCParams{
165
+ TypeMeta: generator.GetTypeMeta("PersistentVolumeClaim", "v1"),
166
+ ObjectMeta: metav1.ObjectMeta{
167
+ Name: volumeOptions.Info.PVCName,
168
+ Namespace: namespace,
169
+ Labels: labels,
170
+ Annotations: annotations,
171
+ },
172
+ Quantity: quantity,
173
+ }
174
+ pvc := generator.GetPVC(pvcParams)
175
+ pvcs = append(pvcs, pvc)
176
+ }
177
+ return pvcs, nil
178
+ }
179
+
149
180
  func (d Devfile) getAll(name, namespace string, labels, annotations map[string]string, replicas int, domainTemplate, ingressClass string) ([]runtime.Object, error) {
150
181
 
151
182
  var result []runtime.Object
@@ -170,9 +201,76 @@ func (d Devfile) getAll(name, namespace string, labels, annotations map[string]s
170
201
  result = append(result, ingress)
171
202
  }
172
203
 
204
+ pvcs, err := d.getPVC(name, namespace, labels, annotations)
205
+ if err != nil {
206
+ return nil, err
207
+ }
208
+ for _, pvc := range pvcs {
209
+ result = append(result, pvc)
210
+ }
211
+
173
212
  return result, nil
174
213
  }
175
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
+ if err != nil {
254
+ return nil, nil, nil, nil, err
255
+ }
256
+ // sort all volumes and volume mounts in the containers and initContainers
257
+ // to keep the array order deterministic
258
+ sort.SliceStable(volumes, func(i, j int) bool {
259
+ return volumes[i].Name < volumes[j].Name
260
+ })
261
+ for _, container := range containers {
262
+ sort.SliceStable(container.VolumeMounts, func(i, j int) bool {
263
+ return container.VolumeMounts[i].Name < container.VolumeMounts[j].Name
264
+ })
265
+ }
266
+ for _, initContainer := range initContainers {
267
+ sort.SliceStable(initContainer.VolumeMounts, func(i, j int) bool {
268
+ return initContainer.VolumeMounts[i].Name < initContainer.VolumeMounts[j].Name
269
+ })
270
+ }
271
+ return containers, initContainers, volumes, volumeNameToVolumeOptions, nil
272
+ }
273
+
176
274
  func (d Devfile) hasContainerComponents() (bool, error) {
177
275
  containers, err := generator.GetContainers(d.devfileObj, common.DevfileOptions{})
178
276
  if err != nil {
data/ext/go.mod CHANGED
@@ -1,4 +1,4 @@
1
- module gitlab.com/gitlab-org/incubation-engineering/server-runtime/devfilerubyffi
1
+ module gitlab-org/remote-development/devfile-gem
2
2
 
3
3
  go 1.18
4
4
 
@@ -7,6 +7,7 @@ require (
7
7
  k8s.io/api v0.26.1
8
8
  k8s.io/apimachinery v0.26.1
9
9
  k8s.io/cli-runtime v0.26.1
10
+ sigs.k8s.io/yaml v1.3.0
10
11
  )
11
12
 
12
13
  require (
@@ -115,5 +116,4 @@ require (
115
116
  sigs.k8s.io/controller-runtime v0.13.1 // indirect
116
117
  sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
117
118
  sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
118
- sigs.k8s.io/yaml v1.3.0 // indirect
119
119
  )
data/ext/main.go CHANGED
@@ -30,6 +30,8 @@ func main() {
30
30
  content, err = getService(devfile, args[3], args[4], args[5], args[6])
31
31
  case "ingress":
32
32
  content, err = getIngress(devfile, args[3], args[4], args[5], args[6], args[7], args[8])
33
+ case "pvc":
34
+ content, err = getPVC(devfile, args[3], args[4], args[5], args[6])
33
35
  case "all":
34
36
  content, err = getAll(devfile, args[3], args[4], args[5], args[6], args[7], args[8], args[9])
35
37
  case "flatten":
@@ -62,8 +64,8 @@ func getDeployment(devfile, name, namespace, labelsStr, annotationsStr, replicas
62
64
  if err != nil {
63
65
  return "", err
64
66
  }
65
- if exists == false {
66
- return "", err
67
+ if !exists {
68
+ return "", nil
67
69
  }
68
70
  labels, err := unmarshalKeyValuePair(labelsStr)
69
71
  if err != nil {
@@ -97,8 +99,8 @@ func getService(devfile, name, namespace, labelsStr, annotationsStr string) (str
97
99
  if err != nil {
98
100
  return "", err
99
101
  }
100
- if exists == false {
101
- return "", err
102
+ if !exists {
103
+ return "", nil
102
104
  }
103
105
  labels, err := unmarshalKeyValuePair(labelsStr)
104
106
  if err != nil {
@@ -128,8 +130,8 @@ func getIngress(devfile, name, namespace, labelsStr, annotationsStr, domainTempl
128
130
  if err != nil {
129
131
  return "", err
130
132
  }
131
- if exists == false {
132
- return "", err
133
+ if !exists {
134
+ return "", nil
133
135
  }
134
136
  labels, err := unmarshalKeyValuePair(labelsStr)
135
137
  if err != nil {
@@ -155,7 +157,7 @@ func getIngress(devfile, name, namespace, labelsStr, annotationsStr, domainTempl
155
157
  return content, nil
156
158
  }
157
159
 
158
- func getAll(devfile string, name, namespace, labelsStr, annotationsStr, replicas, domainTemplate, ingressClass string) (string, error) {
160
+ func getPVC(devfile, name, namespace, labelsStr, annotationsStr string) (string, error) {
159
161
  d, err := parseDevfile(devfile)
160
162
  if err != nil {
161
163
  return "", err
@@ -164,9 +166,44 @@ func getAll(devfile string, name, namespace, labelsStr, annotationsStr, replicas
164
166
  if err != nil {
165
167
  return "", err
166
168
  }
167
- if exists == false {
169
+ if !exists {
170
+ return "", nil
171
+ }
172
+ labels, err := unmarshalKeyValuePair(labelsStr)
173
+ if err != nil {
174
+ return "", err
175
+ }
176
+ annotations, err := unmarshalKeyValuePair(annotationsStr)
177
+ if err != nil {
178
+ return "", err
179
+ }
180
+ pvcs, err := d.getPVC(name, namespace, labels, annotations)
181
+ if err != nil {
182
+ return "", err
183
+ }
184
+ var result []runtime.Object
185
+ for _, pvc := range pvcs {
186
+ result = append(result, pvc)
187
+ }
188
+ content, err := marshalResources(result)
189
+ if err != nil {
190
+ return "", err
191
+ }
192
+ return content, nil
193
+ }
194
+
195
+ func getAll(devfile string, name, namespace, labelsStr, annotationsStr, replicas, domainTemplate, ingressClass string) (string, error) {
196
+ d, err := parseDevfile(devfile)
197
+ if err != nil {
198
+ return "", err
199
+ }
200
+ exists, err := d.hasContainerComponents()
201
+ if err != nil {
168
202
  return "", err
169
203
  }
204
+ if !exists {
205
+ return "", nil
206
+ }
170
207
  labels, err := unmarshalKeyValuePair(labelsStr)
171
208
  if err != nil {
172
209
  return "", err
data/lib/devfile.rb CHANGED
@@ -39,6 +39,16 @@ module Devfile
39
39
  stdout
40
40
  end
41
41
 
42
+ def get_pvc(devfile, name, namespace, labels, annotations)
43
+ stdout, stderr, status = Open3.capture3(
44
+ "#{FILE_PATH} deployment '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}'"
45
+ )
46
+
47
+ raise stderr unless status.success?
48
+
49
+ stdout
50
+ end
51
+
42
52
  def get_all(devfile, name, namespace, labels, annotations, replicas, domain_template, ingress_class)
43
53
  stdout, stderr, status = Open3.capture3(
44
54
  "#{FILE_PATH} all '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}' #{replicas} #{domain_template} #{ingress_class}"
metadata CHANGED
@@ -1,17 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devfile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11.pre.alpha1
4
+ version: 0.0.12.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-03-20 00:00:00.000000000 Z
11
+ date: 2023-04-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Library used to generate kubernetes manifests from a Devfile.
14
- email: spatnaik@gitlab.com
14
+ email:
15
+ - cwoolley@gitlab.com
16
+ - vtak@gitlab.com
17
+ - spatnaik@gitlab.com
15
18
  executables: []
16
19
  extensions: []
17
20
  extra_rdoc_files: []
@@ -21,7 +24,6 @@ files:
21
24
  - ext/go.mod
22
25
  - ext/go.sum
23
26
  - ext/main.go
24
- - ext/volume.go
25
27
  - lib/devfile.rb
26
28
  homepage: https://gitlab.com
27
29
  licenses:
data/ext/volume.go DELETED
@@ -1,114 +0,0 @@
1
- package main
2
-
3
- import (
4
- "fmt"
5
- "github.com/devfile/library/v2/pkg/devfile/generator"
6
- "github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
7
- corev1 "k8s.io/api/core/v1"
8
- "k8s.io/apimachinery/pkg/api/resource"
9
- "strings"
10
- )
11
-
12
- func (d Devfile) getVolumesAndVolumeMounts(containers []corev1.Container, initContainers []corev1.Container, pvcNamePrefix string) ([]corev1.Volume, error) {
13
- containerComponents, err := d.devfileObj.Data.GetDevfileContainerComponents(common.DevfileOptions{})
14
- if err != nil {
15
- return nil, err
16
- }
17
- volumeComponents, err := d.devfileObj.Data.GetDevfileVolumeComponents(common.DevfileOptions{})
18
- if err != nil {
19
- return nil, err
20
- }
21
-
22
- var volumes []corev1.Volume
23
- for _, volumeComponent := range volumeComponents {
24
- volName := volumeComponent.Name
25
- if bool(*volumeComponent.Volume.Ephemeral) == true {
26
- emptyDir, err := getEmptyDir(volName, volumeComponent.Volume.Size)
27
- if err != nil {
28
- return nil, err
29
- }
30
- volumes = append(volumes, emptyDir)
31
- } else {
32
- // TODO: figure this out; how should we pass PVC name? should the object be generated here?
33
- pvcName := fmt.Sprintf("%s-%s", pvcNamePrefix, volName)
34
- volumes = append(volumes, getPVC(volName, pvcName))
35
- }
36
- // containerNameToMountPaths is a map of the Devfile container name to their Devfile Volume Mount Paths for a given Volume Name
37
- containerNameToMountPaths := make(map[string][]string)
38
- for _, containerComp := range containerComponents {
39
- for _, volumeMount := range containerComp.Container.VolumeMounts {
40
- if volName == volumeMount.Name {
41
- containerNameToMountPaths[containerComp.Name] = append(containerNameToMountPaths[containerComp.Name], generator.GetVolumeMountPath(volumeMount))
42
- }
43
- }
44
- }
45
-
46
- addVolumeMountToContainers(containers, initContainers, volName, containerNameToMountPaths)
47
- }
48
-
49
- return volumes, nil
50
- }
51
-
52
- // addVolumeMountToContainers adds the Volume Mounts in containerNameToMountPaths to the containers for a given pvc and volumeName
53
- // containerNameToMountPaths is a map of a container name to an array of its Mount Paths.
54
- // To be moved to devfile/library.
55
- func addVolumeMountToContainers(containers []corev1.Container, initContainers []corev1.Container, volumeName string, containerNameToMountPaths map[string][]string) {
56
-
57
- for containerName, mountPaths := range containerNameToMountPaths {
58
- for i := range containers {
59
- if containers[i].Name == containerName {
60
- for _, mountPath := range mountPaths {
61
- containers[i].VolumeMounts = append(containers[i].VolumeMounts, corev1.VolumeMount{
62
- Name: volumeName,
63
- MountPath: mountPath,
64
- SubPath: "",
65
- },
66
- )
67
- }
68
- }
69
- }
70
- for i := range initContainers {
71
- if strings.HasPrefix(initContainers[i].Name, containerName) {
72
- for _, mountPath := range mountPaths {
73
- initContainers[i].VolumeMounts = append(initContainers[i].VolumeMounts, corev1.VolumeMount{
74
- Name: volumeName,
75
- MountPath: mountPath,
76
- SubPath: "",
77
- },
78
- )
79
- }
80
- }
81
- }
82
- }
83
- }
84
-
85
- // getPVC gets a pvc type volume with the given volume name and pvc name.
86
- func getPVC(volumeName, pvcName string) corev1.Volume {
87
-
88
- return corev1.Volume{
89
- Name: volumeName,
90
- VolumeSource: corev1.VolumeSource{
91
- PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
92
- ClaimName: pvcName,
93
- },
94
- },
95
- }
96
- }
97
-
98
- // getEmptyDir gets an emptyDir type volume with the given volume name and size.
99
- // size should be parseable as a Kubernetes `Quantity` or an error will be returned
100
- func getEmptyDir(volumeName string, size string) (corev1.Volume, error) {
101
-
102
- emptyDir := &corev1.EmptyDirVolumeSource{}
103
- qty, err := resource.ParseQuantity(size)
104
- if err != nil {
105
- return corev1.Volume{}, err
106
- }
107
- emptyDir.SizeLimit = &qty
108
- return corev1.Volume{
109
- Name: volumeName,
110
- VolumeSource: corev1.VolumeSource{
111
- EmptyDir: emptyDir,
112
- },
113
- }, nil
114
- }