devfile 0.0.2.pre.alpha1 → 0.0.4.pre.alpha1
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 +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:
|