devfile 0.0.2.pre.alpha1 → 0.0.4.pre.alpha1
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 +56 -37
- data/ext/go.mod +5 -5
- data/ext/go.sum +8 -4
- data/ext/main.go +153 -63
- data/ext/volume.go +114 -0
- data/lib/devfile.rb +35 -29
- metadata +5 -6
- data/ext/extconf.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68fe0dafd8b89c774342888d1a56ee69357492ef1f7c800695c2cf0e160fc40d
|
4
|
+
data.tar.gz: ed969d122de436b5d6ad9dec8385e92623921f888ee7ab7b29d882c3abb5dc6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 914809b92174b11f397c3218ca2d7b12ffbad7abba4a6489864a90df0fcb13a72b9711c87dc538a560718db823ac8475fff3221bdd6137b5e477795d5c49b866
|
7
|
+
data.tar.gz: a462a444b95b7cbe6fd76fb375a58384dbac3870fee69487273d8c46b61941f8b3cbabad844e3f6d1ec3deb25f3738f0fdb468f95ca99177c05becc2bf0b0674
|
data/bin/devfile
ADDED
Binary file
|
data/ext/devfile.go
CHANGED
@@ -4,37 +4,42 @@ import "C"
|
|
4
4
|
import (
|
5
5
|
"bytes"
|
6
6
|
"fmt"
|
7
|
-
|
8
|
-
"github.com/devfile/library/pkg/devfile/
|
9
|
-
"github.com/devfile/library/pkg/devfile/parser"
|
10
|
-
"github.com/devfile/library/pkg/devfile/parser/data/v2/common"
|
7
|
+
"github.com/devfile/library/v2/pkg/devfile/generator"
|
8
|
+
"github.com/devfile/library/v2/pkg/devfile/parser"
|
9
|
+
"github.com/devfile/library/v2/pkg/devfile/parser/data/v2/common"
|
11
10
|
networkingv1 "k8s.io/api/networking/v1"
|
12
11
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
13
12
|
"k8s.io/apimachinery/pkg/runtime"
|
14
13
|
"k8s.io/cli-runtime/pkg/printers"
|
15
|
-
|
16
|
-
|
17
|
-
const (
|
18
|
-
defaultIngressClass = "ingress-nginx"
|
14
|
+
"sigs.k8s.io/yaml"
|
19
15
|
)
|
20
16
|
|
21
17
|
type Devfile struct {
|
22
18
|
devfileObj parser.DevfileObj
|
23
19
|
}
|
24
20
|
|
25
|
-
func (d Devfile) getDeployment(name, namespace string) (runtime.Object, error) {
|
21
|
+
func (d Devfile) getDeployment(name, namespace string, labels, annotations map[string]string, replicas int) (runtime.Object, error) {
|
26
22
|
containers, err := generator.GetContainers(d.devfileObj, common.DevfileOptions{})
|
27
23
|
if err != nil {
|
28
24
|
return nil, err
|
29
25
|
}
|
26
|
+
initContainers, err := generator.GetInitContainers(d.devfileObj)
|
27
|
+
if err != nil {
|
28
|
+
return nil, err
|
29
|
+
}
|
30
|
+
volumes, err := d.getVolumesAndVolumeMounts(containers, initContainers, name)
|
31
|
+
if err != nil {
|
32
|
+
return nil, err
|
33
|
+
}
|
30
34
|
|
31
35
|
deployParams := generator.DeploymentParams{
|
32
|
-
TypeMeta:
|
33
|
-
ObjectMeta:
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
TypeMeta: generator.GetTypeMeta("Deployment", "apps/v1"),
|
37
|
+
ObjectMeta: generator.GetObjectMeta(name, namespace, labels, annotations),
|
38
|
+
InitContainers: initContainers,
|
39
|
+
Containers: containers,
|
40
|
+
Volumes: volumes,
|
41
|
+
PodSelectorLabels: labels,
|
42
|
+
Replicas: pointerTo(int32(replicas)),
|
38
43
|
}
|
39
44
|
|
40
45
|
deployment, err := generator.GetDeployment(d.devfileObj, deployParams)
|
@@ -45,13 +50,11 @@ func (d Devfile) getDeployment(name, namespace string) (runtime.Object, error) {
|
|
45
50
|
return deployment, err
|
46
51
|
}
|
47
52
|
|
48
|
-
func (d Devfile) getService(name, namespace string) (runtime.Object, error) {
|
53
|
+
func (d Devfile) getService(name, namespace string, labels, annotations map[string]string) (runtime.Object, error) {
|
49
54
|
service, err := generator.GetService(d.devfileObj, generator.ServiceParams{
|
50
|
-
TypeMeta:
|
51
|
-
ObjectMeta:
|
52
|
-
SelectorLabels:
|
53
|
-
"name": name,
|
54
|
-
},
|
55
|
+
TypeMeta: generator.GetTypeMeta("Service", "v1"),
|
56
|
+
ObjectMeta: generator.GetObjectMeta(name, namespace, labels, annotations),
|
57
|
+
SelectorLabels: labels,
|
55
58
|
}, common.DevfileOptions{})
|
56
59
|
if err != nil {
|
57
60
|
return nil, err
|
@@ -60,7 +63,7 @@ func (d Devfile) getService(name, namespace string) (runtime.Object, error) {
|
|
60
63
|
return service, err
|
61
64
|
}
|
62
65
|
|
63
|
-
func (d Devfile) getIngress(name, namespace,
|
66
|
+
func (d Devfile) getIngress(name, namespace string, labels, annotations map[string]string, domainSuffix, ingressClass string) (runtime.Object, error) {
|
64
67
|
components, err := d.devfileObj.Data.GetDevfileContainerComponents(common.DevfileOptions{})
|
65
68
|
if err != nil {
|
66
69
|
return nil, err
|
@@ -71,7 +74,7 @@ func (d Devfile) getIngress(name, namespace, domain string) (runtime.Object, err
|
|
71
74
|
|
72
75
|
for _, component := range components {
|
73
76
|
for _, endpoint := range component.Container.Endpoints {
|
74
|
-
domain := fmt.Sprintf("%d-%
|
77
|
+
domain := fmt.Sprintf("%d-%s-%s.%s", endpoint.TargetPort, endpoint.Name, name, domainSuffix)
|
75
78
|
hosts = append(hosts, domain)
|
76
79
|
rules = append(rules, networkingv1.IngressRule{
|
77
80
|
Host: domain,
|
@@ -101,14 +104,21 @@ func (d Devfile) getIngress(name, namespace, domain string) (runtime.Object, err
|
|
101
104
|
return nil, nil
|
102
105
|
}
|
103
106
|
|
107
|
+
// since annotations is a map, it is passed by reference in go
|
108
|
+
// hence to modify it, create a new copy
|
109
|
+
ingressAnnotations := map[string]string{
|
110
|
+
"kubernetes.io/ingress.class": ingressClass,
|
111
|
+
}
|
112
|
+
for k, v := range annotations {
|
113
|
+
ingressAnnotations[k] = v
|
114
|
+
}
|
104
115
|
ingress := &networkingv1.Ingress{
|
105
116
|
TypeMeta: generator.GetTypeMeta("Ingress", "networking.k8s.io/v1"),
|
106
117
|
ObjectMeta: metav1.ObjectMeta{
|
107
|
-
Name:
|
108
|
-
Namespace:
|
109
|
-
|
110
|
-
|
111
|
-
},
|
118
|
+
Name: name,
|
119
|
+
Namespace: namespace,
|
120
|
+
Labels: labels,
|
121
|
+
Annotations: ingressAnnotations,
|
112
122
|
},
|
113
123
|
Spec: networkingv1.IngressSpec{
|
114
124
|
//TLS: []networkingv1.IngressTLS{
|
@@ -124,16 +134,16 @@ func (d Devfile) getIngress(name, namespace, domain string) (runtime.Object, err
|
|
124
134
|
return ingress, nil
|
125
135
|
}
|
126
136
|
|
127
|
-
func (d Devfile) getAll(name, namespace,
|
128
|
-
deployment, err := d.getDeployment(name, namespace)
|
137
|
+
func (d Devfile) getAll(name, namespace string, labels, annotations map[string]string, replicas int, domainSuffix, ingressClass string) ([]runtime.Object, error) {
|
138
|
+
deployment, err := d.getDeployment(name, namespace, labels, annotations, replicas)
|
129
139
|
if err != nil {
|
130
140
|
return nil, err
|
131
141
|
}
|
132
|
-
service, err := d.getService(name, namespace)
|
142
|
+
service, err := d.getService(name, namespace, labels, annotations)
|
133
143
|
if err != nil {
|
134
144
|
return nil, err
|
135
145
|
}
|
136
|
-
ingress, err := d.getIngress(name, namespace,
|
146
|
+
ingress, err := d.getIngress(name, namespace, labels, annotations, domainSuffix, ingressClass)
|
137
147
|
if err != nil {
|
138
148
|
return nil, err
|
139
149
|
}
|
@@ -156,16 +166,17 @@ func (d Devfile) getFlattenedDevfileContent() string {
|
|
156
166
|
return string(d.devfileObj.Ctx.GetDevfileContent())
|
157
167
|
}
|
158
168
|
|
159
|
-
func parseDevfile(content string) (
|
169
|
+
func parseDevfile(content string) (Devfile, error) {
|
160
170
|
parserArgs := parser.ParserArgs{
|
161
171
|
Data: []byte(content),
|
162
172
|
}
|
163
|
-
|
164
|
-
|
165
|
-
|
173
|
+
devfileObj, err := parser.ParseDevfile(parserArgs)
|
174
|
+
return Devfile{
|
175
|
+
devfileObj: devfileObj,
|
176
|
+
}, err
|
166
177
|
}
|
167
178
|
|
168
|
-
func
|
179
|
+
func marshalResources(objs []runtime.Object) (string, error) {
|
169
180
|
printer := printers.YAMLPrinter{}
|
170
181
|
dest := bytes.NewBuffer([]byte{})
|
171
182
|
for _, obj := range objs {
|
@@ -180,6 +191,14 @@ func marshal(objs []runtime.Object) (string, error) {
|
|
180
191
|
return dest.String(), nil
|
181
192
|
}
|
182
193
|
|
194
|
+
func marshalDevfile(devfile string) (string, error) {
|
195
|
+
data, err := yaml.JSONToYAML([]byte(devfile))
|
196
|
+
if err != nil {
|
197
|
+
return "", err
|
198
|
+
}
|
199
|
+
return string(data), nil
|
200
|
+
}
|
201
|
+
|
183
202
|
// since it is not possible to get pointer of a constant directly
|
184
203
|
func pointerTo[T any](v T) *T {
|
185
204
|
return &v
|
data/ext/go.mod
CHANGED
@@ -3,7 +3,9 @@ module gitlab.com/gitlab-org/incubation-engineering/server-runtime/devfilerubyff
|
|
3
3
|
go 1.18
|
4
4
|
|
5
5
|
require (
|
6
|
-
github.com/devfile/library
|
6
|
+
github.com/devfile/library/v2 v2.2.0
|
7
|
+
k8s.io/api v0.26.1
|
8
|
+
k8s.io/apimachinery v0.26.1
|
7
9
|
k8s.io/cli-runtime v0.26.1
|
8
10
|
)
|
9
11
|
|
@@ -17,8 +19,8 @@ require (
|
|
17
19
|
github.com/containerd/containerd v1.5.9 // indirect
|
18
20
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
19
21
|
github.com/devfile/api/v2 v2.2.0 // indirect
|
20
|
-
github.com/devfile/registry-support/index/generator v0.0.0-
|
21
|
-
github.com/devfile/registry-support/registry-library v0.0.0-
|
22
|
+
github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273 // indirect
|
23
|
+
github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba // indirect
|
22
24
|
github.com/docker/cli v20.10.11+incompatible // indirect
|
23
25
|
github.com/docker/distribution v2.7.1+incompatible // indirect
|
24
26
|
github.com/docker/docker v20.10.11+incompatible // indirect
|
@@ -103,9 +105,7 @@ require (
|
|
103
105
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
104
106
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
105
107
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
106
|
-
k8s.io/api v0.26.1 // indirect
|
107
108
|
k8s.io/apiextensions-apiserver v0.25.0 // indirect
|
108
|
-
k8s.io/apimachinery v0.26.1 // indirect
|
109
109
|
k8s.io/client-go v0.26.1 // indirect
|
110
110
|
k8s.io/klog v1.0.0 // indirect
|
111
111
|
k8s.io/klog/v2 v2.80.1 // indirect
|
data/ext/go.sum
CHANGED
@@ -292,13 +292,16 @@ github.com/devfile/api/v2 v2.2.0 h1:3Mwl/dtT508oU4pNt/v4G8vqvjoZqi9LOInXCNwKMoc=
|
|
292
292
|
github.com/devfile/api/v2 v2.2.0/go.mod h1:dN7xFrOVG+iPqn4UKGibXLd5oVsdE8XyK9OEb5JL3aI=
|
293
293
|
github.com/devfile/library v1.2.1-0.20211104222135-49d635cb492f/go.mod h1:uFZZdTuRqA68FVe/JoJHP92CgINyQkyWnM2Qyiim+50=
|
294
294
|
github.com/devfile/library v1.2.1-0.20220308191614-f0f7e11b17de/go.mod h1:GSPfJaBg0+bBjBHbwBE5aerJLH6tWGQu2q2rHYd9czM=
|
295
|
-
github.com/devfile/library
|
296
|
-
github.com/devfile/library
|
295
|
+
github.com/devfile/library/v2 v2.0.1/go.mod h1:paJ0PARAVy0br13VpBEQ4fO3rZVDxWtooQ29+23PNBk=
|
296
|
+
github.com/devfile/library/v2 v2.2.0 h1:M12ui+ONi4oU0ynJwhWvPs7jaNX6KsUI5gBRyAVQQCs=
|
297
|
+
github.com/devfile/library/v2 v2.2.0/go.mod h1:k0dGRv2oJtQkQaCcNSwku2OBM5Xu6fGl1Jsi2fsu/Ps=
|
297
298
|
github.com/devfile/registry-support/index/generator v0.0.0-20220222194908-7a90a4214f3e/go.mod h1:iRPBxs+ZjfLEduVXpCCIOzdD2588Zv9OCs/CcXMcCCY=
|
298
|
-
github.com/devfile/registry-support/index/generator v0.0.0-20220527155645-8328a8a883be h1:tCdIUbJ1eZV/jRa1gjs3dPZsbTjRibDqwRqIK4HCI9k=
|
299
299
|
github.com/devfile/registry-support/index/generator v0.0.0-20220527155645-8328a8a883be/go.mod h1:1fyDJL+fPHtcrYA6yjSVWeLmXmjCNth0d5Rq1rvtryc=
|
300
|
-
github.com/devfile/registry-support/
|
300
|
+
github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273 h1:DXENQSRTEDsk9com38njPg5511DD12HPIgzyFUErnpM=
|
301
|
+
github.com/devfile/registry-support/index/generator v0.0.0-20221018203505-df96d34d4273/go.mod h1:ZJnaSLjTKCvGJhWmYgQoQ1O3g78qBe4Va6ZugLmi4dE=
|
301
302
|
github.com/devfile/registry-support/registry-library v0.0.0-20220627163229-4aa39fcb0c0a/go.mod h1:kmEjH5oO465vh36kcYdZLYeG8edVD6N/ZgzyLs1x7qs=
|
303
|
+
github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba h1:7Ag9guD3qOSzg3PcbSMqTVHDjqZojqb5JoIIonjRjDQ=
|
304
|
+
github.com/devfile/registry-support/registry-library v0.0.0-20221018213054-47b3ffaeadba/go.mod h1:NOtmnbozFn15w/DPD/Urc+KDlNRP4JH5m+KC5GZoAWA=
|
302
305
|
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
303
306
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
304
307
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
@@ -711,6 +714,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
|
711
714
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
712
715
|
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
713
716
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
717
|
+
github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8=
|
714
718
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
715
719
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
716
720
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
data/ext/main.go
CHANGED
@@ -1,113 +1,203 @@
|
|
1
1
|
package main
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
};
|
9
|
-
*/
|
10
|
-
import "C"
|
11
|
-
import "k8s.io/apimachinery/pkg/runtime"
|
3
|
+
import (
|
4
|
+
"fmt"
|
5
|
+
"k8s.io/apimachinery/pkg/util/yaml"
|
6
|
+
"os"
|
7
|
+
"strconv"
|
12
8
|
|
13
|
-
|
9
|
+
"k8s.io/apimachinery/pkg/runtime"
|
10
|
+
)
|
14
11
|
|
15
|
-
|
12
|
+
type Result struct {
|
13
|
+
content string
|
14
|
+
err error
|
15
|
+
}
|
16
16
|
|
17
|
-
func
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
func main() {
|
18
|
+
args := os.Args
|
19
|
+
|
20
|
+
if len(args) <= 1 {
|
21
|
+
fmt.Fprint(os.Stderr, "Function name and devfile are required")
|
22
|
+
os.Exit(1)
|
22
23
|
}
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
fnName := os.Args[1]
|
26
|
+
devfile := os.Args[2]
|
27
|
+
|
28
|
+
var result Result
|
29
|
+
|
30
|
+
switch fnName {
|
31
|
+
case "deployment":
|
32
|
+
result = getDeployment(devfile, args[3], args[4], args[5], args[6], args[7])
|
33
|
+
case "service":
|
34
|
+
result = getService(devfile, args[3], args[4], args[5], args[6])
|
35
|
+
case "ingress":
|
36
|
+
result = getIngress(devfile, args[3], args[4], args[5], args[6], args[7], args[8])
|
37
|
+
case "all":
|
38
|
+
result = getAll(devfile, args[3], args[4], args[5], args[6], args[7], args[8], args[9])
|
39
|
+
case "flatten":
|
40
|
+
result = flatten(devfile)
|
29
41
|
}
|
30
|
-
|
31
|
-
|
42
|
+
|
43
|
+
if result.err != nil {
|
44
|
+
fmt.Fprint(os.Stderr, result.err)
|
45
|
+
os.Exit(1)
|
32
46
|
}
|
33
47
|
|
34
|
-
|
48
|
+
fmt.Print(result.content)
|
35
49
|
}
|
36
50
|
|
37
|
-
func
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
}
|
51
|
+
func unmarshalKeyValuePair(data string) (map[string]string, error) {
|
52
|
+
values := map[string]string{}
|
53
|
+
err := yaml.Unmarshal([]byte(data), &values)
|
54
|
+
if err != nil {
|
55
|
+
return nil, err
|
56
|
+
}
|
57
|
+
return values, err
|
43
58
|
}
|
44
59
|
|
45
|
-
|
46
|
-
|
47
|
-
d, err := InGo(devfile)
|
60
|
+
func getDeployment(devfile, name, namespace, labelsStr, annotationsStr, replicas string) Result {
|
61
|
+
d, err := parseDevfile(devfile)
|
48
62
|
if err != nil {
|
49
|
-
return
|
63
|
+
return Result{"", err}
|
50
64
|
}
|
51
65
|
exists, err := d.hasContainerComponents()
|
52
66
|
if err != nil {
|
53
|
-
return
|
67
|
+
return Result{"", err}
|
54
68
|
}
|
55
69
|
if exists == false {
|
56
|
-
return
|
70
|
+
return Result{"", err}
|
71
|
+
}
|
72
|
+
labels, err := unmarshalKeyValuePair(labelsStr)
|
73
|
+
if err != nil {
|
74
|
+
return Result{"", err}
|
75
|
+
}
|
76
|
+
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
77
|
+
if err != nil {
|
78
|
+
return Result{"", err}
|
57
79
|
}
|
58
|
-
|
59
|
-
|
80
|
+
replicasInt, err := strconv.Atoi(replicas)
|
81
|
+
if err != nil {
|
82
|
+
return Result{"", err}
|
83
|
+
}
|
84
|
+
deployment, err := d.getDeployment(name, namespace, labels, annotations, replicasInt)
|
85
|
+
if err != nil {
|
86
|
+
return Result{"", err}
|
87
|
+
}
|
88
|
+
content, err := marshalResources([]runtime.Object{deployment})
|
89
|
+
if err != nil {
|
90
|
+
return Result{"", err}
|
91
|
+
}
|
92
|
+
return Result{content, nil}
|
60
93
|
}
|
61
94
|
|
62
|
-
|
63
|
-
|
64
|
-
d, err := InGo(devfile)
|
95
|
+
func getService(devfile, name, namespace, labelsStr, annotationsStr string) Result {
|
96
|
+
d, err := parseDevfile(devfile)
|
65
97
|
if err != nil {
|
66
|
-
return
|
98
|
+
return Result{"", err}
|
67
99
|
}
|
68
100
|
exists, err := d.hasContainerComponents()
|
69
101
|
if err != nil {
|
70
|
-
return
|
102
|
+
return Result{"", err}
|
71
103
|
}
|
72
104
|
if exists == false {
|
73
|
-
return
|
105
|
+
return Result{"", err}
|
106
|
+
}
|
107
|
+
labels, err := unmarshalKeyValuePair(labelsStr)
|
108
|
+
if err != nil {
|
109
|
+
return Result{"", err}
|
110
|
+
}
|
111
|
+
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
112
|
+
if err != nil {
|
113
|
+
return Result{"", err}
|
114
|
+
}
|
115
|
+
service, err := d.getService(name, namespace, labels, annotations)
|
116
|
+
if err != nil {
|
117
|
+
return Result{"", err}
|
74
118
|
}
|
75
|
-
|
76
|
-
|
119
|
+
content, err := marshalResources([]runtime.Object{service})
|
120
|
+
if err != nil {
|
121
|
+
return Result{"", err}
|
122
|
+
}
|
123
|
+
return Result{content, nil}
|
77
124
|
}
|
78
125
|
|
79
|
-
|
80
|
-
|
81
|
-
d, err := InGo(devfile)
|
126
|
+
func getIngress(devfile, name, namespace, labelsStr, annotationsStr, domainSuffix, ingressClass string) Result {
|
127
|
+
d, err := parseDevfile(devfile)
|
82
128
|
if err != nil {
|
83
|
-
return
|
129
|
+
return Result{"", err}
|
84
130
|
}
|
85
131
|
exists, err := d.hasContainerComponents()
|
86
132
|
if err != nil {
|
87
|
-
return
|
133
|
+
return Result{"", err}
|
88
134
|
}
|
89
135
|
if exists == false {
|
90
|
-
return
|
136
|
+
return Result{"", err}
|
137
|
+
}
|
138
|
+
labels, err := unmarshalKeyValuePair(labelsStr)
|
139
|
+
if err != nil {
|
140
|
+
return Result{"", err}
|
91
141
|
}
|
92
|
-
|
93
|
-
|
142
|
+
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
143
|
+
if err != nil {
|
144
|
+
return Result{"", err}
|
145
|
+
}
|
146
|
+
ingress, err := d.getIngress(name, namespace, labels, annotations, domainSuffix, ingressClass)
|
147
|
+
if err != nil {
|
148
|
+
return Result{"", err}
|
149
|
+
}
|
150
|
+
content, err := marshalResources([]runtime.Object{ingress})
|
151
|
+
if err != nil {
|
152
|
+
return Result{"", err}
|
153
|
+
}
|
154
|
+
return Result{content, nil}
|
94
155
|
}
|
95
156
|
|
96
|
-
|
97
|
-
|
98
|
-
d, err := InGo(devfile)
|
157
|
+
func getAll(devfile string, name, namespace, labelsStr, annotationsStr, replicas, domainSuffix, ingressClass string) Result {
|
158
|
+
d, err := parseDevfile(devfile)
|
99
159
|
if err != nil {
|
100
|
-
return
|
160
|
+
return Result{"", err}
|
101
161
|
}
|
102
162
|
exists, err := d.hasContainerComponents()
|
103
163
|
if err != nil {
|
104
|
-
return
|
164
|
+
return Result{"", err}
|
105
165
|
}
|
106
166
|
if exists == false {
|
107
|
-
return
|
167
|
+
return Result{"", err}
|
108
168
|
}
|
109
|
-
|
110
|
-
|
169
|
+
labels, err := unmarshalKeyValuePair(labelsStr)
|
170
|
+
if err != nil {
|
171
|
+
return Result{"", err}
|
172
|
+
}
|
173
|
+
annotations, err := unmarshalKeyValuePair(annotationsStr)
|
174
|
+
if err != nil {
|
175
|
+
return Result{"", err}
|
176
|
+
}
|
177
|
+
replicasInt, err := strconv.Atoi(replicas)
|
178
|
+
if err != nil {
|
179
|
+
return Result{"", err}
|
180
|
+
}
|
181
|
+
resources, err := d.getAll(name, namespace, labels, annotations, replicasInt, domainSuffix, ingressClass)
|
182
|
+
if err != nil {
|
183
|
+
return Result{"", err}
|
184
|
+
}
|
185
|
+
content, err := marshalResources(resources)
|
186
|
+
if err != nil {
|
187
|
+
return Result{"", err}
|
188
|
+
}
|
189
|
+
return Result{content, nil}
|
111
190
|
}
|
112
191
|
|
113
|
-
|
192
|
+
func flatten(devfile string) Result {
|
193
|
+
d, err := parseDevfile(devfile)
|
194
|
+
if err != nil {
|
195
|
+
return Result{"", err}
|
196
|
+
}
|
197
|
+
flattenedDevfile := d.getFlattenedDevfileContent()
|
198
|
+
content, err := marshalDevfile(flattenedDevfile)
|
199
|
+
if err != nil {
|
200
|
+
return Result{"", err}
|
201
|
+
}
|
202
|
+
return Result{content, nil}
|
203
|
+
}
|
data/ext/volume.go
ADDED
@@ -0,0 +1,114 @@
|
|
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
|
+
}
|
data/lib/devfile.rb
CHANGED
@@ -1,49 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'open3'
|
4
4
|
|
5
5
|
# Module that works with the Devfile standard
|
6
6
|
module Devfile
|
7
|
-
|
7
|
+
# Set of services to parse a devfile and output k8s manifests
|
8
|
+
class Parser
|
9
|
+
FILE_PATH = File.expand_path('./../bin/devfile', File.dirname(__FILE__))
|
8
10
|
|
9
|
-
|
11
|
+
class << self
|
12
|
+
def get_deployment(devfile, name, namespace, labels, annotations, replicas)
|
13
|
+
stdout, stderr, status = Open3.capture3("#{FILE_PATH} deployment '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}' #{replicas}")
|
10
14
|
|
11
|
-
|
12
|
-
class Result < FFI::Struct
|
13
|
-
layout :resources, :string,
|
14
|
-
:flattenedDevfile, :string,
|
15
|
-
:err, :string
|
15
|
+
raise stderr unless status.success?
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
stdout
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
20
|
+
def get_service(devfile, name, namespace, labels, annotations)
|
21
|
+
stdout, stderr, status = Open3.capture3("#{FILE_PATH} service '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}'")
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def get_deployment(name, namespace, devfile)
|
28
|
-
Devfile.getDeployment(name, namespace, devfile).process
|
23
|
+
raise stderr unless status.success?
|
24
|
+
|
25
|
+
stdout
|
29
26
|
end
|
30
27
|
|
31
|
-
def
|
32
|
-
|
28
|
+
def get_ingress(devfile, name, namespace, labels, annotations, domain_suffix, ingress_class)
|
29
|
+
stdout, stderr, status = Open3.capture3("#{FILE_PATH} ingress '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}' #{domain_suffix} #{ingress_class}")
|
30
|
+
|
31
|
+
raise stderr unless status.success?
|
32
|
+
|
33
|
+
stdout
|
33
34
|
end
|
34
35
|
|
35
|
-
def
|
36
|
-
|
36
|
+
def get_all(devfile, name, namespace, labels, annotations, replicas, domain_suffix, ingress_class)
|
37
|
+
stdout, stderr, status = Open3.capture3(
|
38
|
+
"#{FILE_PATH} all '#{devfile}' #{name} #{namespace} '#{labels}' '#{annotations}' #{replicas} #{domain_suffix} #{ingress_class}"
|
39
|
+
)
|
40
|
+
|
41
|
+
raise stderr unless status.success?
|
42
|
+
|
43
|
+
stdout
|
37
44
|
end
|
38
45
|
|
39
|
-
def
|
40
|
-
|
46
|
+
def flatten(devfile)
|
47
|
+
stdout, stderr, status = Open3.capture3("#{FILE_PATH} flatten '#{devfile}'")
|
48
|
+
|
49
|
+
raise stderr unless status.success?
|
50
|
+
|
51
|
+
stdout
|
41
52
|
end
|
42
53
|
end
|
43
54
|
end
|
44
|
-
|
45
|
-
attach_function 'getDeployment', %i[string string string], Result.by_value
|
46
|
-
attach_function 'getService', %i[string string string], Result.by_value
|
47
|
-
attach_function 'getIngress', %i[string string string string], Result.by_value
|
48
|
-
attach_function 'getAll', %i[string string string string], Result.by_value
|
49
55
|
end
|
metadata
CHANGED
@@ -1,28 +1,27 @@
|
|
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.4.pre.alpha1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Library used to generate kubernetes manifests from a Devfile.
|
14
14
|
email: spatnaik@gitlab.com
|
15
15
|
executables: []
|
16
|
-
extensions:
|
17
|
-
- "./ext/extconf.rb"
|
16
|
+
extensions: []
|
18
17
|
extra_rdoc_files: []
|
19
18
|
files:
|
20
|
-
-
|
19
|
+
- bin/devfile
|
21
20
|
- ext/devfile.go
|
22
|
-
- ext/extconf.rb
|
23
21
|
- ext/go.mod
|
24
22
|
- ext/go.sum
|
25
23
|
- ext/main.go
|
24
|
+
- ext/volume.go
|
26
25
|
- lib/devfile.rb
|
27
26
|
homepage: https://gitlab.com
|
28
27
|
licenses:
|