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 +4 -4
- data/bin/devfile +0 -0
- data/ext/devfile.go +108 -10
- data/ext/go.mod +2 -2
- data/ext/main.go +45 -8
- data/lib/devfile.rb +10 -0
- metadata +6 -4
- data/ext/volume.go +0 -114
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cc3363280657ceecbb55931395fc354e8d13cb814c2a83b11dd679e0a67edd6
|
4
|
+
data.tar.gz: b8bdad6991ddc7a87cd72c49fc2d684f8fe055245ae8747136e08df8608a7bd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 :=
|
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
|
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
|
66
|
-
return "",
|
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
|
101
|
-
return "",
|
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
|
132
|
-
return "",
|
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
|
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
|
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.
|
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-
|
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:
|
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
|
-
}
|