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

Sign up to get free protection for your applications and to get access to all the features.
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
- }