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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b5ccb630f8c382fdec4a27c4d68f09f10630fd51f517e2cde323cfc02bfef22
4
- data.tar.gz: e4933a597caaeb4ea040b8045a623e4e359912dbb8da5fc229ae7c51d5af7e17
3
+ metadata.gz: 68fe0dafd8b89c774342888d1a56ee69357492ef1f7c800695c2cf0e160fc40d
4
+ data.tar.gz: ed969d122de436b5d6ad9dec8385e92623921f888ee7ab7b29d882c3abb5dc6b
5
5
  SHA512:
6
- metadata.gz: d414b0f161daccc339bc8f95fa145c935aaa0b3b2ac950ce4f3046e517a58a8c9903fd5c7c3485b9aa8ce4a08055fd710892412609ece2e9300940d5b03b7f38
7
- data.tar.gz: 458502ef4f3178ab10d54c982c438baa17b2848b3ab881e5508e74658cc1a9348dfc88e1220db5c3741d9e503745ee9a661909834fc06b0949e5718e07b1d5a0
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/generator"
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: generator.GetTypeMeta("Deployment", "apps/v1"),
33
- ObjectMeta: generator.GetObjectMeta(name, namespace, map[string]string{}, make(map[string]string)),
34
- Containers: containers,
35
- PodSelectorLabels: map[string]string{
36
- "name": name,
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: generator.GetTypeMeta("Service", "v1"),
51
- ObjectMeta: generator.GetObjectMeta(name, namespace, map[string]string{}, map[string]string{}),
52
- SelectorLabels: map[string]string{
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, domain string) (runtime.Object, error) {
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-%v", endpoint.TargetPort, domain)
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: name,
108
- Namespace: namespace,
109
- Annotations: map[string]string{
110
- "kubernetes.io/ingress.class": defaultIngressClass,
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, domain string) ([]runtime.Object, error) {
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, domain)
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) (parser.DevfileObj, error) {
169
+ func parseDevfile(content string) (Devfile, error) {
160
170
  parserArgs := parser.ParserArgs{
161
171
  Data: []byte(content),
162
172
  }
163
-
164
- devfile, err := parser.ParseDevfile(parserArgs)
165
- return devfile, err
173
+ devfileObj, err := parser.ParseDevfile(parserArgs)
174
+ return Devfile{
175
+ devfileObj: devfileObj,
176
+ }, err
166
177
  }
167
178
 
168
- func marshal(objs []runtime.Object) (string, error) {
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 v1.3.0
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-20220527155645-8328a8a883be // indirect
21
- github.com/devfile/registry-support/registry-library v0.0.0-20220627163229-4aa39fcb0c0a // indirect
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 v1.3.0 h1:bkPcX4RXR0Cr0aJXBvcc04SfEyKJ1gkgNNM1XTCA7Y8=
296
- github.com/devfile/library v1.3.0/go.mod h1:BbP/cww/WsTcQZ86d2Kd215ku7o7q6wkucP2WigVqmE=
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/registry-library v0.0.0-20220627163229-4aa39fcb0c0a h1:nBOmXUYleKlyYnzbbAgYEaYn4V3ZgXEQ3PN7NlZ8f2k=
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
- struct result {
5
- char *resources;
6
- char *flattenedDevfile;
7
- char *err;
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
- func main() {}
9
+ "k8s.io/apimachinery/pkg/runtime"
10
+ )
14
11
 
15
- // START C Compatibility
12
+ type Result struct {
13
+ content string
14
+ err error
15
+ }
16
16
 
17
- func NewResult(objs []runtime.Object, flattenedDevfile string, err error) C.struct_result {
18
- if err != nil {
19
- return C.struct_result{
20
- err: C.CString(err.Error()),
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
- resources, err := marshal(objs)
25
- r := C.struct_result{
26
- resources: C.CString(resources),
27
- flattenedDevfile: C.CString(flattenedDevfile),
28
- err: nil,
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
- if err != nil {
31
- r.err = C.CString(err.Error())
42
+
43
+ if result.err != nil {
44
+ fmt.Fprint(os.Stderr, result.err)
45
+ os.Exit(1)
32
46
  }
33
47
 
34
- return r
48
+ fmt.Print(result.content)
35
49
  }
36
50
 
37
- func InGo(devfile *C.char) (Devfile, error) {
38
- rawContent := C.GoString(devfile)
39
- devfileObj, err := parseDevfile(rawContent)
40
- return Devfile{
41
- devfileObj: devfileObj,
42
- }, err
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
- //export getDeployment
46
- func getDeployment(name *C.char, namespace *C.char, devfile *C.char) C.struct_result {
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 NewResult(nil, "", err)
63
+ return Result{"", err}
50
64
  }
51
65
  exists, err := d.hasContainerComponents()
52
66
  if err != nil {
53
- return NewResult(nil, "", err)
67
+ return Result{"", err}
54
68
  }
55
69
  if exists == false {
56
- return NewResult([]runtime.Object{nil}, "", err)
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
- deployment, err := d.getDeployment(C.GoString(name), C.GoString(namespace))
59
- return NewResult([]runtime.Object{deployment}, d.getFlattenedDevfileContent(), err)
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
- //export getService
63
- func getService(name *C.char, namespace *C.char, devfile *C.char) C.struct_result {
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 NewResult(nil, "", err)
98
+ return Result{"", err}
67
99
  }
68
100
  exists, err := d.hasContainerComponents()
69
101
  if err != nil {
70
- return NewResult(nil, "", err)
102
+ return Result{"", err}
71
103
  }
72
104
  if exists == false {
73
- return NewResult([]runtime.Object{nil}, "", err)
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
- service, err := d.getService(C.GoString(name), C.GoString(namespace))
76
- return NewResult([]runtime.Object{service}, d.getFlattenedDevfileContent(), err)
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
- //export getIngress
80
- func getIngress(name *C.char, namespace *C.char, devfile *C.char, domain *C.char) C.struct_result {
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 NewResult(nil, "", err)
129
+ return Result{"", err}
84
130
  }
85
131
  exists, err := d.hasContainerComponents()
86
132
  if err != nil {
87
- return NewResult(nil, "", err)
133
+ return Result{"", err}
88
134
  }
89
135
  if exists == false {
90
- return NewResult([]runtime.Object{nil}, "", err)
136
+ return Result{"", err}
137
+ }
138
+ labels, err := unmarshalKeyValuePair(labelsStr)
139
+ if err != nil {
140
+ return Result{"", err}
91
141
  }
92
- ingress, err := d.getIngress(C.GoString(name), C.GoString(namespace), C.GoString(domain))
93
- return NewResult([]runtime.Object{ingress}, d.getFlattenedDevfileContent(), err)
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
- //export getAll
97
- func getAll(name *C.char, namespace *C.char, devfile *C.char, domain *C.char) C.struct_result {
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 NewResult(nil, "", err)
160
+ return Result{"", err}
101
161
  }
102
162
  exists, err := d.hasContainerComponents()
103
163
  if err != nil {
104
- return NewResult(nil, "", err)
164
+ return Result{"", err}
105
165
  }
106
166
  if exists == false {
107
- return NewResult([]runtime.Object{nil}, "", err)
167
+ return Result{"", err}
108
168
  }
109
- resources, err := d.getAll(C.GoString(name), C.GoString(namespace), C.GoString(domain))
110
- return NewResult(resources, d.getFlattenedDevfileContent(), err)
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
- // END C Compatibility
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 'ffi'
3
+ require 'open3'
4
4
 
5
5
  # Module that works with the Devfile standard
6
6
  module Devfile
7
- extend FFI::Library
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
- ffi_lib File.expand_path('./devfile.so', File.dirname(__FILE__))
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
- # Result from go containing an error and the result
12
- class Result < FFI::Struct
13
- layout :resources, :string,
14
- :flattenedDevfile, :string,
15
- :err, :string
15
+ raise stderr unless status.success?
16
16
 
17
- def process
18
- raise self[:err] if self[:err]
17
+ stdout
18
+ end
19
19
 
20
- [self[:resources], self[:flattenedDevfile]]
21
- end
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
- # Set of services to parse a devfile and output k8s manifests
25
- class Parser
26
- class << self
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 get_service(name, namespace, devfile)
32
- Devfile.getService(name, namespace, devfile).process
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 get_ingress(name, namespace, devfile, domain)
36
- Devfile.getIngress(name, namespace, devfile, domain).process
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 get_all(name, namespace, devfile, domain)
40
- Devfile.getAll(name, namespace, devfile, domain).process
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.2.pre.alpha1
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-02-20 00:00:00.000000000 Z
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
- - "./ext/extconf.rb"
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:
data/ext/extconf.rb DELETED
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- makefile_contents = "all:\n\techo \"Starting...\"\n\ninstall:\n\tgo build -buildmode=c-shared -o ../lib/devfile.so\n\n"
4
-
5
- File.write('Makefile', makefile_contents)