devfile 0.0.6.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 +135 -24
- data/ext/go.mod +2 -2
- data/ext/main.go +98 -60
- 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,15 +1,19 @@
|
|
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
|
|
9
10
|
"github.com/devfile/library/v2/pkg/devfile/generator"
|
10
11
|
"github.com/devfile/library/v2/pkg/devfile/parser"
|
11
12
|
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
13
|
+
appsv1 "k8s.io/api/apps/v1"
|
14
|
+
corev1 "k8s.io/api/core/v1"
|
12
15
|
networkingv1 "k8s.io/api/networking/v1"
|
16
|
+
"k8s.io/apimachinery/pkg/api/resource"
|
13
17
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
14
18
|
"k8s.io/apimachinery/pkg/runtime"
|
15
19
|
"k8s.io/cli-runtime/pkg/printers"
|
@@ -20,16 +24,14 @@ type Devfile struct {
|
|
20
24
|
devfileObj parser.DevfileObj
|
21
25
|
}
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
32
|
-
volumes, err := d.getVolumesAndVolumeMounts(containers, initContainers, name)
|
27
|
+
type volumeOptions struct {
|
28
|
+
Info generator.VolumeInfo
|
29
|
+
Size string
|
30
|
+
IsEphemeral bool
|
31
|
+
}
|
32
|
+
|
33
|
+
func (d Devfile) getDeployment(name, namespace string, labels, annotations map[string]string, replicas int) (*appsv1.Deployment, error) {
|
34
|
+
containers, initContainers, volumes, _, err := d.getContainersAndVolumes(name)
|
33
35
|
if err != nil {
|
34
36
|
return nil, err
|
35
37
|
}
|
@@ -52,7 +54,7 @@ func (d Devfile) getDeployment(name, namespace string, labels, annotations map[s
|
|
52
54
|
return deployment, err
|
53
55
|
}
|
54
56
|
|
55
|
-
func (d Devfile) getService(name, namespace string, labels, annotations map[string]string) (
|
57
|
+
func (d Devfile) getService(name, namespace string, labels, annotations map[string]string) (*corev1.Service, error) {
|
56
58
|
service, err := generator.GetService(d.devfileObj, generator.ServiceParams{
|
57
59
|
TypeMeta: generator.GetTypeMeta("Service", "v1"),
|
58
60
|
ObjectMeta: generator.GetObjectMeta(name, namespace, labels, annotations),
|
@@ -65,7 +67,12 @@ func (d Devfile) getService(name, namespace string, labels, annotations map[stri
|
|
65
67
|
return service, err
|
66
68
|
}
|
67
69
|
|
68
|
-
func (d Devfile) getIngress(name, namespace string, labels, annotations map[string]string, domainTemplate, ingressClass string) (
|
70
|
+
func (d Devfile) getIngress(name, namespace string, labels, annotations map[string]string, domainTemplate, ingressClass string) (*networkingv1.Ingress, error) {
|
71
|
+
|
72
|
+
if ingressClass == "none" {
|
73
|
+
return nil, nil
|
74
|
+
}
|
75
|
+
|
69
76
|
components, err := d.devfileObj.Data.GetDevfileContainerComponents(common.DevfileOptions{})
|
70
77
|
if err != nil {
|
71
78
|
return nil, err
|
@@ -75,7 +82,10 @@ func (d Devfile) getIngress(name, namespace string, labels, annotations map[stri
|
|
75
82
|
var rules []networkingv1.IngressRule
|
76
83
|
|
77
84
|
// Create a new template and parse the letter into it.
|
78
|
-
t := template.
|
85
|
+
t, err := template.New("domainTemplate").Parse(domainTemplate)
|
86
|
+
if err != nil {
|
87
|
+
return nil, err
|
88
|
+
}
|
79
89
|
|
80
90
|
for _, component := range components {
|
81
91
|
for _, endpoint := range component.Container.Endpoints {
|
@@ -113,23 +123,16 @@ func (d Devfile) getIngress(name, namespace string, labels, annotations map[stri
|
|
113
123
|
return nil, nil
|
114
124
|
}
|
115
125
|
|
116
|
-
// since annotations is a map, it is passed by reference in go
|
117
|
-
// hence to modify it, create a new copy
|
118
|
-
ingressAnnotations := map[string]string{
|
119
|
-
"kubernetes.io/ingress.class": ingressClass,
|
120
|
-
}
|
121
|
-
for k, v := range annotations {
|
122
|
-
ingressAnnotations[k] = v
|
123
|
-
}
|
124
126
|
ingress := &networkingv1.Ingress{
|
125
127
|
TypeMeta: generator.GetTypeMeta("Ingress", "networking.k8s.io/v1"),
|
126
128
|
ObjectMeta: metav1.ObjectMeta{
|
127
129
|
Name: name,
|
128
130
|
Namespace: namespace,
|
129
131
|
Labels: labels,
|
130
|
-
Annotations:
|
132
|
+
Annotations: annotations,
|
131
133
|
},
|
132
134
|
Spec: networkingv1.IngressSpec{
|
135
|
+
IngressClassName: &ingressClass,
|
133
136
|
//TLS: []networkingv1.IngressTLS{
|
134
137
|
// {
|
135
138
|
// Hosts: hosts,
|
@@ -143,21 +146,129 @@ func (d Devfile) getIngress(name, namespace string, labels, annotations map[stri
|
|
143
146
|
return ingress, nil
|
144
147
|
}
|
145
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
|
+
|
146
180
|
func (d Devfile) getAll(name, namespace string, labels, annotations map[string]string, replicas int, domainTemplate, ingressClass string) ([]runtime.Object, error) {
|
181
|
+
|
182
|
+
var result []runtime.Object
|
183
|
+
|
147
184
|
deployment, err := d.getDeployment(name, namespace, labels, annotations, replicas)
|
148
185
|
if err != nil {
|
149
186
|
return nil, err
|
150
187
|
}
|
188
|
+
result = append(result, deployment)
|
189
|
+
|
151
190
|
service, err := d.getService(name, namespace, labels, annotations)
|
152
191
|
if err != nil {
|
153
192
|
return nil, err
|
154
193
|
}
|
194
|
+
result = append(result, service)
|
195
|
+
|
155
196
|
ingress, err := d.getIngress(name, namespace, labels, annotations, domainTemplate, ingressClass)
|
156
197
|
if err != nil {
|
157
198
|
return nil, err
|
158
199
|
}
|
200
|
+
if ingress != nil {
|
201
|
+
result = append(result, ingress)
|
202
|
+
}
|
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
|
+
|
212
|
+
return result, nil
|
213
|
+
}
|
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...)
|
159
225
|
|
160
|
-
|
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
|
161
272
|
}
|
162
273
|
|
163
274
|
func (d Devfile) hasContainerComponents() (bool, error) {
|
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
@@ -9,11 +9,6 @@ import (
|
|
9
9
|
"k8s.io/apimachinery/pkg/runtime"
|
10
10
|
)
|
11
11
|
|
12
|
-
type Result struct {
|
13
|
-
content string
|
14
|
-
err error
|
15
|
-
}
|
16
|
-
|
17
12
|
func main() {
|
18
13
|
args := os.Args
|
19
14
|
|
@@ -25,27 +20,30 @@ func main() {
|
|
25
20
|
fnName := os.Args[1]
|
26
21
|
devfile := os.Args[2]
|
27
22
|
|
28
|
-
var
|
23
|
+
var content string
|
24
|
+
var err error
|
29
25
|
|
30
26
|
switch fnName {
|
31
27
|
case "deployment":
|
32
|
-
|
28
|
+
content, err = getDeployment(devfile, args[3], args[4], args[5], args[6], args[7])
|
33
29
|
case "service":
|
34
|
-
|
30
|
+
content, err = getService(devfile, args[3], args[4], args[5], args[6])
|
35
31
|
case "ingress":
|
36
|
-
|
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])
|
37
35
|
case "all":
|
38
|
-
|
36
|
+
content, err = getAll(devfile, args[3], args[4], args[5], args[6], args[7], args[8], args[9])
|
39
37
|
case "flatten":
|
40
|
-
|
38
|
+
content, err = flatten(devfile)
|
41
39
|
}
|
42
40
|
|
43
|
-
if
|
44
|
-
fmt.Fprint(os.Stderr,
|
41
|
+
if err != nil {
|
42
|
+
fmt.Fprint(os.Stderr, err)
|
45
43
|
os.Exit(1)
|
46
44
|
}
|
47
45
|
|
48
|
-
fmt.Print(
|
46
|
+
fmt.Print(content)
|
49
47
|
}
|
50
48
|
|
51
49
|
func unmarshalKeyValuePair(data string) (map[string]string, error) {
|
@@ -57,147 +55,187 @@ func unmarshalKeyValuePair(data string) (map[string]string, error) {
|
|
57
55
|
return values, err
|
58
56
|
}
|
59
57
|
|
60
|
-
func getDeployment(devfile, name, namespace, labelsStr, annotationsStr, replicas string)
|
58
|
+
func getDeployment(devfile, name, namespace, labelsStr, annotationsStr, replicas string) (string, error) {
|
61
59
|
d, err := parseDevfile(devfile)
|
62
60
|
if err != nil {
|
63
|
-
return
|
61
|
+
return "", err
|
64
62
|
}
|
65
63
|
exists, err := d.hasContainerComponents()
|
66
64
|
if err != nil {
|
67
|
-
return
|
65
|
+
return "", err
|
68
66
|
}
|
69
|
-
if exists
|
70
|
-
return
|
67
|
+
if !exists {
|
68
|
+
return "", nil
|
71
69
|
}
|
72
70
|
labels, err := unmarshalKeyValuePair(labelsStr)
|
73
71
|
if err != nil {
|
74
|
-
return
|
72
|
+
return "", err
|
75
73
|
}
|
76
74
|
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
77
75
|
if err != nil {
|
78
|
-
return
|
76
|
+
return "", err
|
79
77
|
}
|
80
78
|
replicasInt, err := strconv.Atoi(replicas)
|
81
79
|
if err != nil {
|
82
|
-
return
|
80
|
+
return "", err
|
83
81
|
}
|
84
82
|
deployment, err := d.getDeployment(name, namespace, labels, annotations, replicasInt)
|
85
83
|
if err != nil {
|
86
|
-
return
|
84
|
+
return "", err
|
87
85
|
}
|
88
86
|
content, err := marshalResources([]runtime.Object{deployment})
|
89
87
|
if err != nil {
|
90
|
-
return
|
88
|
+
return "", err
|
91
89
|
}
|
92
|
-
return
|
90
|
+
return content, nil
|
93
91
|
}
|
94
92
|
|
95
|
-
func getService(devfile, name, namespace, labelsStr, annotationsStr string)
|
93
|
+
func getService(devfile, name, namespace, labelsStr, annotationsStr string) (string, error) {
|
96
94
|
d, err := parseDevfile(devfile)
|
97
95
|
if err != nil {
|
98
|
-
return
|
96
|
+
return "", err
|
99
97
|
}
|
100
98
|
exists, err := d.hasContainerComponents()
|
101
99
|
if err != nil {
|
102
|
-
return
|
100
|
+
return "", err
|
103
101
|
}
|
104
|
-
if exists
|
105
|
-
return
|
102
|
+
if !exists {
|
103
|
+
return "", nil
|
106
104
|
}
|
107
105
|
labels, err := unmarshalKeyValuePair(labelsStr)
|
108
106
|
if err != nil {
|
109
|
-
return
|
107
|
+
return "", err
|
110
108
|
}
|
111
109
|
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
112
110
|
if err != nil {
|
113
|
-
return
|
111
|
+
return "", err
|
114
112
|
}
|
115
113
|
service, err := d.getService(name, namespace, labels, annotations)
|
116
114
|
if err != nil {
|
117
|
-
return
|
115
|
+
return "", err
|
118
116
|
}
|
119
117
|
content, err := marshalResources([]runtime.Object{service})
|
120
118
|
if err != nil {
|
121
|
-
return
|
119
|
+
return "", err
|
122
120
|
}
|
123
|
-
return
|
121
|
+
return content, nil
|
124
122
|
}
|
125
123
|
|
126
|
-
func getIngress(devfile, name, namespace, labelsStr, annotationsStr, domainTemplate, ingressClass string)
|
124
|
+
func getIngress(devfile, name, namespace, labelsStr, annotationsStr, domainTemplate, ingressClass string) (string, error) {
|
127
125
|
d, err := parseDevfile(devfile)
|
128
126
|
if err != nil {
|
129
|
-
return
|
127
|
+
return "", err
|
130
128
|
}
|
131
129
|
exists, err := d.hasContainerComponents()
|
132
130
|
if err != nil {
|
133
|
-
return
|
131
|
+
return "", err
|
134
132
|
}
|
135
|
-
if exists
|
136
|
-
return
|
133
|
+
if !exists {
|
134
|
+
return "", nil
|
137
135
|
}
|
138
136
|
labels, err := unmarshalKeyValuePair(labelsStr)
|
139
137
|
if err != nil {
|
140
|
-
return
|
138
|
+
return "", err
|
141
139
|
}
|
142
140
|
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
143
141
|
if err != nil {
|
144
|
-
return
|
142
|
+
return "", err
|
145
143
|
}
|
146
144
|
ingress, err := d.getIngress(name, namespace, labels, annotations, domainTemplate, ingressClass)
|
147
145
|
if err != nil {
|
148
|
-
return
|
146
|
+
return "", err
|
149
147
|
}
|
148
|
+
|
149
|
+
if ingress == nil {
|
150
|
+
return "", nil
|
151
|
+
}
|
152
|
+
|
150
153
|
content, err := marshalResources([]runtime.Object{ingress})
|
151
154
|
if err != nil {
|
152
|
-
return
|
155
|
+
return "", err
|
156
|
+
}
|
157
|
+
return content, nil
|
158
|
+
}
|
159
|
+
|
160
|
+
func getPVC(devfile, name, namespace, labelsStr, annotationsStr string) (string, error) {
|
161
|
+
d, err := parseDevfile(devfile)
|
162
|
+
if err != nil {
|
163
|
+
return "", err
|
164
|
+
}
|
165
|
+
exists, err := d.hasContainerComponents()
|
166
|
+
if err != nil {
|
167
|
+
return "", err
|
168
|
+
}
|
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
|
153
191
|
}
|
154
|
-
return
|
192
|
+
return content, nil
|
155
193
|
}
|
156
194
|
|
157
|
-
func getAll(devfile string, name, namespace, labelsStr, annotationsStr, replicas, domainTemplate, ingressClass string)
|
195
|
+
func getAll(devfile string, name, namespace, labelsStr, annotationsStr, replicas, domainTemplate, ingressClass string) (string, error) {
|
158
196
|
d, err := parseDevfile(devfile)
|
159
197
|
if err != nil {
|
160
|
-
return
|
198
|
+
return "", err
|
161
199
|
}
|
162
200
|
exists, err := d.hasContainerComponents()
|
163
201
|
if err != nil {
|
164
|
-
return
|
202
|
+
return "", err
|
165
203
|
}
|
166
|
-
if exists
|
167
|
-
return
|
204
|
+
if !exists {
|
205
|
+
return "", nil
|
168
206
|
}
|
169
207
|
labels, err := unmarshalKeyValuePair(labelsStr)
|
170
208
|
if err != nil {
|
171
|
-
return
|
209
|
+
return "", err
|
172
210
|
}
|
173
211
|
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
174
212
|
if err != nil {
|
175
|
-
return
|
213
|
+
return "", err
|
176
214
|
}
|
177
215
|
replicasInt, err := strconv.Atoi(replicas)
|
178
216
|
if err != nil {
|
179
|
-
return
|
217
|
+
return "", err
|
180
218
|
}
|
181
219
|
resources, err := d.getAll(name, namespace, labels, annotations, replicasInt, domainTemplate, ingressClass)
|
182
220
|
if err != nil {
|
183
|
-
return
|
221
|
+
return "", err
|
184
222
|
}
|
185
223
|
content, err := marshalResources(resources)
|
186
224
|
if err != nil {
|
187
|
-
return
|
225
|
+
return "", err
|
188
226
|
}
|
189
|
-
return
|
227
|
+
return content, nil
|
190
228
|
}
|
191
229
|
|
192
|
-
func flatten(devfile string)
|
230
|
+
func flatten(devfile string) (string, error) {
|
193
231
|
d, err := parseDevfile(devfile)
|
194
232
|
if err != nil {
|
195
|
-
return
|
233
|
+
return "", err
|
196
234
|
}
|
197
235
|
flattenedDevfile := d.getFlattenedDevfileContent()
|
198
236
|
content, err := marshalDevfile(flattenedDevfile)
|
199
237
|
if err != nil {
|
200
|
-
return
|
238
|
+
return "", err
|
201
239
|
}
|
202
|
-
return
|
240
|
+
return content, err
|
203
241
|
}
|
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
|
-
}
|