Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit cfb075a

Browse files
committedJun 23, 2025··
[Feature] [Platform] Packer
1 parent 16d9a54 commit cfb075a

24 files changed

+1206
-56
lines changed
 

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- (Feature) (Platform) MetaV1 Integration Service
55
- (Feature) (Platform) Chart Overrides
66
- (Feature) Parallel Executor
7+
- (Feature) (Platform) Packer
78

89
## [1.2.49](https://github.com/arangodb/kube-arangodb/tree/1.2.49) (2025-06-17)
910
- (Maintenance) Optimize go.mod

‎docs/cli/arangodb_operator_platform.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ Available Commands:
4242
Flags:
4343
-h, --help help for registry
4444
--platform.endpoint string Platform Repository URL (default "https://arangodb-platform-prd-chart-registry.s3.amazonaws.com")
45-
--platform.name string Kubernetes Platform Name (name of the ArangoDeployment)
4645
4746
Global Flags:
4847
-n, --namespace string Kubernetes Namespace (default "default")
@@ -190,11 +189,13 @@ Usage:
190189
191190
Available Commands:
192191
dump Dumps the current setup of the platform
192+
export Export the package in the ZIP Format
193+
import Imports the package from the ZIP format
193194
install Installs the specified setup of the platform
195+
merge Merges definitions into single file
194196
195197
Flags:
196-
-h, --help help for package
197-
--platform.name string Kubernetes Platform Name (name of the ArangoDeployment)
198+
-h, --help help for package
198199
199200
Global Flags:
200201
-n, --namespace string Kubernetes Namespace (default "default")
@@ -213,11 +214,11 @@ Usage:
213214
arangodb_operator_platform package dump [flags]
214215
215216
Flags:
216-
-h, --help help for dump
217+
-h, --help help for dump
218+
--platform.name string Kubernetes Platform Name (name of the ArangoDeployment)
217219
218220
Global Flags:
219-
-n, --namespace string Kubernetes Namespace (default "default")
220-
--platform.name string Kubernetes Platform Name (name of the ArangoDeployment)
221+
-n, --namespace string Kubernetes Namespace (default "default")
221222
```
222223
[END_INJECT]: # (arangodb_operator_platform_package_dump_cmd)
223224

@@ -228,15 +229,15 @@ Global Flags:
228229
Installs the specified setup of the platform
229230
230231
Usage:
231-
arangodb_operator_platform package install [flags] package
232+
arangodb_operator_platform package install [flags] ... packages
232233
233234
Flags:
234235
-h, --help help for install
235236
--platform.endpoint string Platform Repository URL (default "https://arangodb-platform-prd-chart-registry.s3.amazonaws.com")
237+
--platform.name string Kubernetes Platform Name (name of the ArangoDeployment)
236238
237239
Global Flags:
238-
-n, --namespace string Kubernetes Namespace (default "default")
239-
--platform.name string Kubernetes Platform Name (name of the ArangoDeployment)
240+
-n, --namespace string Kubernetes Namespace (default "default")
240241
```
241242
[END_INJECT]: # (arangodb_operator_platform_package_install_cmd)
242243

‎go.mod

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ require (
5454
github.com/prometheus/prom2json v1.3.3
5555
github.com/robfig/cron v1.2.0
5656
github.com/rs/zerolog v1.33.0
57-
github.com/spf13/cobra v1.8.1
58-
github.com/spf13/pflag v1.0.5
57+
github.com/spf13/cobra v1.9.1
58+
github.com/spf13/pflag v1.0.6
5959
github.com/stretchr/testify v1.10.0
6060
golang.org/x/sync v0.12.0
6161
golang.org/x/sys v0.31.0
@@ -83,6 +83,7 @@ require (
8383
github.com/golang-jwt/jwt/v5 v5.2.2
8484
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1
8585
github.com/jedib0t/go-pretty/v6 v6.6.5
86+
github.com/regclient/regclient v0.8.3
8687
golang.org/x/oauth2 v0.28.0
8788
google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489
8889
helm.sh/helm/v3 v3.17.3
@@ -124,6 +125,7 @@ require (
124125
github.com/docker/docker-credential-helpers v0.7.0 // indirect
125126
github.com/docker/go-connections v0.5.0 // indirect
126127
github.com/docker/go-metrics v0.0.1 // indirect
128+
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
127129
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
128130
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
129131
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
@@ -167,7 +169,7 @@ require (
167169
github.com/josharian/intern v1.0.0 // indirect
168170
github.com/json-iterator/go v1.1.12 // indirect
169171
github.com/kkdai/maglev v0.2.0 // indirect
170-
github.com/klauspost/compress v1.16.7 // indirect
172+
github.com/klauspost/compress v1.18.0 // indirect
171173
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
172174
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
173175
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
@@ -208,6 +210,7 @@ require (
208210
github.com/stretchr/objx v0.5.2 // indirect
209211
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
210212
github.com/ugorji/go/codec v1.2.11 // indirect
213+
github.com/ulikunitz/xz v0.5.12 // indirect
211214
github.com/x448/float16 v0.8.4 // indirect
212215
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
213216
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect

‎go.sum

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8
980980
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
981981
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
982982
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
983+
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
983984
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
984985
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
985986
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
@@ -1026,6 +1027,8 @@ github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHz
10261027
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
10271028
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
10281029
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
1030+
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
1031+
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
10291032
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
10301033
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
10311034
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
@@ -1399,6 +1402,8 @@ github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw
13991402
github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
14001403
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
14011404
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
1405+
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
1406+
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
14021407
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
14031408
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
14041409
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
@@ -1600,6 +1605,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
16001605
github.com/prometheus/prom2json v1.3.3 h1:IYfSMiZ7sSOfliBoo89PcufjWO4eAR0gznGcETyaUgo=
16011606
github.com/prometheus/prom2json v1.3.3/go.mod h1:Pv4yIPktEkK7btWsrUTWDDDrnpUrAELaOCj+oFwlgmc=
16021607
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
1608+
github.com/regclient/regclient v0.8.3 h1:AFAPu/vmOYGyY22AIgzdBUKbzH+83lEpRioRYJ/reCs=
1609+
github.com/regclient/regclient v0.8.3/go.mod h1:gjQh5uBVZoo/CngchghtQh9Hx81HOMKRRDd5WPcPkbk=
16031610
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
16041611
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
16051612
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
@@ -1652,9 +1659,13 @@ github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cA
16521659
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
16531660
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
16541661
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
1662+
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
1663+
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
16551664
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
16561665
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
16571666
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
1667+
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
1668+
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
16581669
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
16591670
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
16601671
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
@@ -1674,6 +1685,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
16741685
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
16751686
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
16761687
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
1688+
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
1689+
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
16771690
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
16781691
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
16791692
github.com/vektah/gqlparser/v2 v2.4.5/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=

‎pkg/apis/shared/v1/any.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ func FromAny[T any](in Any) (T, error) {
4646
}
4747

4848
func (d Any) MarshalJSON() ([]byte, error) {
49+
if len(d) == 0 {
50+
return []byte("null"), nil
51+
}
4952
ret := make([]byte, len(d))
5053
copy(ret, d)
5154
return ret, nil

‎pkg/logging/wrap.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,13 @@ func JSON(key string, item any) Wrap {
108108
return in.Str(key, string(data))
109109
}
110110
}
111+
112+
func WithElapsed(key string) Wrap {
113+
return WithElapsedCustom(key, time.Now())
114+
}
115+
116+
func WithElapsedCustom(key string, t time.Time) Wrap {
117+
return func(in *zerolog.Event) *zerolog.Event {
118+
return in.Str(key, time.Since(t).String())
119+
}
120+
}

‎pkg/platform/flags.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ package platform
2323
import (
2424
"os"
2525

26+
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
2627
"github.com/arangodb/kube-arangodb/pkg/util"
2728
"github.com/arangodb/kube-arangodb/pkg/util/cli"
2829
"github.com/arangodb/kube-arangodb/pkg/util/errors"
@@ -42,6 +43,13 @@ var (
4243
Description: "Kubernetes Platform Name (name of the ArangoDeployment)",
4344
Default: "",
4445
Persistent: true,
46+
Check: func(in string) error {
47+
if err := sharedApi.IsValidName(in); err != nil {
48+
return errors.Errorf("Invalid deployment name: %s", err.Error())
49+
}
50+
51+
return nil
52+
},
4553
}
4654

4755
flagOutput = cli.Flag[string]{
@@ -104,4 +112,13 @@ var (
104112
return nil
105113
},
106114
}
115+
116+
flagRegistryUseCredentials = cli.Flag[bool]{
117+
Name: "registry.docker.credentials",
118+
Description: "Use Docker Credentials",
119+
Default: false,
120+
Check: func(in bool) error {
121+
return nil
122+
},
123+
}
107124
)

‎pkg/platform/helm.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ package platform
2323
import (
2424
"github.com/spf13/cobra"
2525

26+
"github.com/arangodb/kube-arangodb/pkg/util"
2627
"github.com/arangodb/kube-arangodb/pkg/util/errors"
2728
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
2829
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
@@ -45,3 +46,35 @@ func getHelmClient(cmd *cobra.Command) (helm.Client, error) {
4546
Driver: nil,
4647
})
4748
}
49+
50+
func getHelmPackages(files ...string) (helm.Package, error) {
51+
if len(files) == 0 {
52+
return helm.Package{}, nil
53+
}
54+
55+
pkgs := make([]helm.Package, len(files))
56+
57+
for id := range pkgs {
58+
p, err := util.JsonOrYamlUnmarshalFile[helm.Package](files[id])
59+
if err != nil {
60+
return helm.Package{}, err
61+
}
62+
pkgs[id] = p
63+
}
64+
65+
if len(pkgs) == 1 {
66+
return pkgs[0], nil
67+
}
68+
69+
v, err := helm.NewMergeValues(helm.MergeMaps, pkgs...)
70+
if err != nil {
71+
return helm.Package{}, err
72+
}
73+
74+
p, err := util.JSONRemarshal[helm.Values, helm.Package](v)
75+
if err != nil {
76+
return helm.Package{}, err
77+
}
78+
79+
return p, nil
80+
}

‎pkg/platform/pack/export.go

Lines changed: 406 additions & 0 deletions
Large diffs are not rendered by default.

‎pkg/platform/pack/import.go

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package pack
22+
23+
import (
24+
"archive/zip"
25+
"context"
26+
"errors"
27+
"fmt"
28+
"io"
29+
"os"
30+
"sync"
31+
32+
"github.com/regclient/regclient"
33+
"github.com/regclient/regclient/types/descriptor"
34+
"github.com/regclient/regclient/types/errs"
35+
"github.com/regclient/regclient/types/manifest"
36+
"github.com/regclient/regclient/types/mediatype"
37+
"github.com/regclient/regclient/types/ref"
38+
39+
"github.com/arangodb/kube-arangodb/pkg/logging"
40+
"github.com/arangodb/kube-arangodb/pkg/util"
41+
"github.com/arangodb/kube-arangodb/pkg/util/executor"
42+
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/helm"
43+
)
44+
45+
func Import(ctx context.Context, path string, client *regclient.RegClient, registry string) (Proto, *helm.Package, error) {
46+
out, err := os.Open(path)
47+
if err != nil {
48+
return Proto{}, nil, err
49+
}
50+
51+
stat, err := out.Stat()
52+
if err != nil {
53+
return Proto{}, nil, err
54+
}
55+
56+
in, err := zip.NewReader(out, stat.Size())
57+
if err != nil {
58+
return Proto{}, nil, err
59+
}
60+
61+
i := &importPackageSet{
62+
in: in,
63+
client: client,
64+
registry: registry,
65+
}
66+
67+
data, err := i.Read("proto.yaml")
68+
if err != nil {
69+
return Proto{}, nil, err
70+
}
71+
72+
proto, err := util.JsonOrYamlUnmarshal[Proto](data)
73+
if err != nil {
74+
return Proto{}, nil, err
75+
}
76+
77+
if err := executor.Run(ctx, logger, 8, i.run(proto)); err != nil {
78+
return Proto{}, nil, err
79+
}
80+
81+
return proto, &i.p, nil
82+
}
83+
84+
type importPackageSet struct {
85+
lock sync.Mutex
86+
87+
in *zip.Reader
88+
89+
client *regclient.RegClient
90+
91+
p helm.Package
92+
registry string
93+
}
94+
95+
func (i *importPackageSet) run(p Proto) executor.RunFunc {
96+
return func(ctx context.Context, log logging.Logger, t executor.Thread, h executor.Handler) error {
97+
for k, v := range p.Manifests {
98+
src, err := ref.New(fmt.Sprintf("%s/%s", i.registry, k))
99+
if err != nil {
100+
return err
101+
}
102+
103+
h.RunAsync(ctx, i.importManifest(src, v))
104+
}
105+
106+
type valuesInterface struct {
107+
Images ProtoImages `json:"images,omitempty"`
108+
}
109+
110+
h.WaitForSubThreads(t)
111+
112+
for k, v := range p.Charts {
113+
var pkgS helm.PackageSpec
114+
115+
data, err := i.Read("chart/%s-%s.tgz", k, v.Version)
116+
if err != nil {
117+
return err
118+
}
119+
120+
pkgS.Chart = data
121+
pkgS.Version = v.Version
122+
123+
var versions valuesInterface
124+
125+
versions.Images = map[string]ProtoImage{}
126+
127+
for z, q := range v.Images {
128+
var img = q
129+
130+
img.Registry = util.NewType(i.registry)
131+
132+
versions.Images[z] = img
133+
}
134+
135+
vData, err := helm.NewValues(versions)
136+
if err != nil {
137+
return err
138+
}
139+
140+
pkgS.Overrides = vData
141+
142+
i.withPackage(func(in helm.Package) helm.Package {
143+
if in.Packages == nil {
144+
in.Packages = map[string]helm.PackageSpec{}
145+
}
146+
147+
in.Packages[k] = pkgS
148+
149+
return in
150+
})
151+
}
152+
153+
return nil
154+
}
155+
}
156+
157+
func (i *importPackageSet) importManifest(src ref.Ref, blob string) executor.RunFunc {
158+
return func(ctx context.Context, log logging.Logger, t executor.Thread, h executor.Handler) error {
159+
log = log.Str("manifest", src.CommonName()).Wrap(logging.WithElapsed("duration"))
160+
161+
log.Info("Importing manifest")
162+
defer func() {
163+
log.Info("Imported manifest")
164+
}()
165+
166+
data, err := i.Read("manifests/%s", blob)
167+
if err != nil {
168+
return err
169+
}
170+
171+
m, err := manifest.New(
172+
manifest.WithRaw(data),
173+
manifest.WithRef(src),
174+
)
175+
if err != nil {
176+
return err
177+
}
178+
179+
if manifestIndex, ok := m.(manifest.Indexer); ok && m.IsSet() {
180+
manifests, err := manifestIndex.GetManifestList()
181+
if err != nil {
182+
return err
183+
}
184+
185+
for _, entry := range manifests {
186+
if entry.Platform == nil {
187+
continue
188+
}
189+
190+
switch entry.MediaType {
191+
case mediatype.Docker1Manifest, mediatype.Docker1ManifestSigned,
192+
mediatype.Docker2Manifest, mediatype.Docker2ManifestList,
193+
mediatype.OCI1Manifest, mediatype.OCI1ManifestList:
194+
h.RunAsync(ctx, i.importManifest(src.SetDigest(entry.Digest.String()), entry.Digest.Hex()))
195+
196+
case mediatype.Docker2ImageConfig, mediatype.OCI1ImageConfig,
197+
mediatype.Docker2Layer, mediatype.Docker2LayerGzip, mediatype.Docker2LayerZstd,
198+
mediatype.OCI1Layer, mediatype.OCI1LayerGzip, mediatype.OCI1LayerZstd,
199+
mediatype.BuildkitCacheConfig:
200+
h.RunAsync(ctx, i.importBlob(src, entry))
201+
}
202+
}
203+
}
204+
205+
if manifestIndex, ok := m.(manifest.Imager); ok && m.IsSet() {
206+
cd, err := manifestIndex.GetConfig()
207+
if err != nil {
208+
// docker schema v1 does not have a config object, ignore if it's missing
209+
if !errors.Is(err, errs.ErrUnsupportedMediaType) {
210+
return fmt.Errorf("failed to get config digest for %s: %w", src.CommonName(), err)
211+
}
212+
} else {
213+
h.RunAsync(ctx, i.importBlob(src, cd))
214+
}
215+
216+
layers, err := manifestIndex.GetLayers()
217+
if err != nil {
218+
return err
219+
}
220+
221+
for _, m := range layers {
222+
h.RunAsync(ctx, i.importBlob(src, m))
223+
}
224+
}
225+
226+
h.WaitForSubThreads(t)
227+
228+
if err := i.client.ManifestPut(ctx, src, m); err != nil {
229+
return err
230+
}
231+
232+
return nil
233+
}
234+
}
235+
236+
func (i *importPackageSet) importBlob(src ref.Ref, desc descriptor.Descriptor) executor.RunFunc {
237+
return func(ctx context.Context, log logging.Logger, t executor.Thread, h executor.Handler) error {
238+
log = log.Str("blob", desc.Digest.Hex()).Wrap(logging.WithElapsed("duration")).Int64("size", desc.Size)
239+
240+
log.Info("Importing blob")
241+
defer func() {
242+
log.Info("Imported blob")
243+
}()
244+
245+
// Upload
246+
qs, err := i.Open("blobs/%s", desc.Digest.Hex())
247+
if err != nil {
248+
return err
249+
}
250+
251+
if _, err := i.client.BlobPut(ctx, src, desc, qs); err != nil {
252+
return err
253+
}
254+
255+
return nil
256+
}
257+
}
258+
259+
func (i *importPackageSet) Open(name string, args ...any) (io.Reader, error) {
260+
return i.in.Open(fmt.Sprintf(name, args...))
261+
}
262+
263+
func (i *importPackageSet) Read(name string, args ...any) ([]byte, error) {
264+
reader, err := i.in.Open(fmt.Sprintf(name, args...))
265+
if err != nil {
266+
return nil, err
267+
}
268+
269+
return io.ReadAll(reader)
270+
}
271+
272+
func (i *importPackageSet) withPackage(mod util.ModR[helm.Package]) {
273+
i.lock.Lock()
274+
defer i.lock.Unlock()
275+
276+
i.p = mod(i.p)
277+
}

‎pkg/platform/pack/logger.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package pack
22+
23+
import "github.com/arangodb/kube-arangodb/pkg/logging"
24+
25+
var (
26+
logger = logging.Global().RegisterAndGetLogger("installer-pack", logging.Info)
27+
)

‎pkg/platform/pack/proto.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package pack
22+
23+
import "fmt"
24+
25+
type Proto struct {
26+
Charts ProtoCharts `json:"charts,omitempty"`
27+
28+
Manifests map[string]string `json:"manifests,omitempty"`
29+
}
30+
31+
type ProtoCharts map[string]ProtoChart
32+
33+
type ProtoChart struct {
34+
Version string `json:"version"`
35+
36+
Images ProtoImages `json:"images,omitempty"`
37+
}
38+
39+
type ProtoImages map[string]ProtoImage
40+
41+
type ProtoImage struct {
42+
Registry *string `json:"registry,omitempty"`
43+
Image string `json:"image"`
44+
Tag string `json:"tag"`
45+
Kind string `json:"kind,omitempty"`
46+
}
47+
48+
func (p ProtoImage) IsTest() bool {
49+
return p.Kind == "Test"
50+
}
51+
52+
func (p ProtoImage) GetShortImage() string {
53+
return fmt.Sprintf("%s:%s", p.Image, p.Tag)
54+
}
55+
56+
func (p ProtoImage) GetImage() string {
57+
if p.Registry == nil {
58+
return fmt.Sprintf("%s:%s", p.Image, p.Tag)
59+
}
60+
61+
return fmt.Sprintf("%s/%s:%s", *p.Registry, p.Image, p.Tag)
62+
}

‎pkg/platform/package.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,16 @@ func pkg() (*cobra.Command, error) {
3232
cmd.Use = "package"
3333
cmd.Short = "Release Package related operations"
3434

35-
if err := cli.RegisterFlags(&cmd, flagPlatformName); err != nil {
35+
if err := cli.RegisterFlags(&cmd); err != nil {
3636
return nil, err
3737
}
3838

3939
if err := withRegisterCommand(&cmd,
4040
packageDump,
4141
packageInstall,
42+
packageExport,
43+
packageImport,
44+
packageMerge,
4245
); err != nil {
4346
return nil, err
4447
}

‎pkg/platform/package_dump.go

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
package platform
2222

2323
import (
24-
"encoding/json"
25-
2624
"github.com/spf13/cobra"
2725
"sigs.k8s.io/yaml"
2826

@@ -38,7 +36,7 @@ func packageDump() (*cobra.Command, error) {
3836
cmd.Use = "dump [flags]"
3937
cmd.Short = "Dumps the current setup of the platform"
4038

41-
if err := cli.RegisterFlags(&cmd); err != nil {
39+
if err := cli.RegisterFlags(&cmd, flagPlatformName); err != nil {
4240
return nil, err
4341
}
4442

@@ -68,12 +66,7 @@ func packageDumpRun(cmd *cobra.Command, args []string) error {
6866
return err
6967
}
7068

71-
d, err := json.Marshal(out)
72-
if err != nil {
73-
return err
74-
}
75-
76-
d, err = yaml.JSONToYAML(d)
69+
d, err := yaml.Marshal(out)
7770
if err != nil {
7871
return err
7972
}

‎pkg/platform/package_export.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package platform
22+
23+
import (
24+
"github.com/spf13/cobra"
25+
26+
"github.com/arangodb/kube-arangodb/pkg/platform/pack"
27+
"github.com/arangodb/kube-arangodb/pkg/util/cli"
28+
"github.com/arangodb/kube-arangodb/pkg/util/errors"
29+
)
30+
31+
func packageExport() (*cobra.Command, error) {
32+
var cmd cobra.Command
33+
34+
cmd.Use = "export [flags] package output"
35+
cmd.Short = "Export the package in the ZIP Format"
36+
37+
if err := cli.RegisterFlags(&cmd, flagPlatformEndpoint, flagRegistryUseCredentials); err != nil {
38+
return nil, err
39+
}
40+
41+
cmd.RunE = getRunner().With(packageExportRun).Run
42+
43+
return &cmd, nil
44+
}
45+
46+
func packageExportRun(cmd *cobra.Command, args []string) error {
47+
if len(args) != 2 {
48+
return errors.Errorf("Invalid arguments")
49+
}
50+
51+
pkg, err := getHelmPackages(args[0])
52+
if err != nil {
53+
logger.Err(err).Error("Unable to read the file")
54+
return err
55+
}
56+
57+
out := args[1]
58+
59+
cm, err := getChartManager(cmd)
60+
if err != nil {
61+
return err
62+
}
63+
64+
rc, err := getRegClient(cmd)
65+
if err != nil {
66+
return err
67+
}
68+
69+
return pack.Export(cmd.Context(), out, cm, rc, pkg)
70+
}

‎pkg/platform/package_import.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package platform
22+
23+
import (
24+
"os"
25+
26+
"github.com/spf13/cobra"
27+
"sigs.k8s.io/yaml"
28+
29+
"github.com/arangodb/kube-arangodb/pkg/platform/pack"
30+
"github.com/arangodb/kube-arangodb/pkg/util/cli"
31+
"github.com/arangodb/kube-arangodb/pkg/util/errors"
32+
)
33+
34+
func packageImport() (*cobra.Command, error) {
35+
var cmd cobra.Command
36+
37+
cmd.Use = "import [flags] registry package output"
38+
cmd.Short = "Imports the package from the ZIP format"
39+
40+
if err := cli.RegisterFlags(&cmd, flagRegistryUseCredentials); err != nil {
41+
return nil, err
42+
}
43+
44+
cmd.RunE = getRunner().With(packageImportRun).Run
45+
46+
return &cmd, nil
47+
}
48+
49+
func packageImportRun(cmd *cobra.Command, args []string) error {
50+
if len(args) != 3 {
51+
return errors.Errorf("Invalid arguments")
52+
}
53+
54+
reg := args[0]
55+
dest := args[1]
56+
out := args[2]
57+
58+
rc, err := getRegClient(cmd)
59+
if err != nil {
60+
return err
61+
}
62+
63+
_, pkg, err := pack.Import(cmd.Context(), dest, rc, reg)
64+
if err != nil {
65+
return err
66+
}
67+
68+
data, err := yaml.Marshal(pkg)
69+
if err != nil {
70+
return err
71+
}
72+
73+
return os.WriteFile(out, data, 0644)
74+
}

‎pkg/platform/package_install.go

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
package platform
2222

2323
import (
24-
"os"
2524
"time"
2625

2726
"github.com/spf13/cobra"
@@ -30,7 +29,6 @@ import (
3029

3130
platformApi "github.com/arangodb/kube-arangodb/pkg/apis/platform/v1alpha1"
3231
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
33-
"github.com/arangodb/kube-arangodb/pkg/util"
3432
"github.com/arangodb/kube-arangodb/pkg/util/cli"
3533
"github.com/arangodb/kube-arangodb/pkg/util/constants"
3634
"github.com/arangodb/kube-arangodb/pkg/util/errors"
@@ -41,10 +39,10 @@ import (
4139
func packageInstall() (*cobra.Command, error) {
4240
var cmd cobra.Command
4341

44-
cmd.Use = "install [flags] package"
42+
cmd.Use = "install [flags] ... packages"
4543
cmd.Short = "Installs the specified setup of the platform"
4644

47-
if err := cli.RegisterFlags(&cmd, flagPlatformEndpoint); err != nil {
45+
if err := cli.RegisterFlags(&cmd, flagPlatformEndpoint, flagPlatformName); err != nil {
4846
return nil, err
4947
}
5048

@@ -88,37 +86,36 @@ func packageInstallRun(cmd *cobra.Command, args []string) error {
8886
return errors.Errorf("Invalid arguments")
8987
}
9088

91-
file := args[0]
92-
93-
data, err := os.ReadFile(file)
94-
if err != nil {
95-
logger.Err(err).Error("Unable to read the file")
96-
return err
97-
}
98-
99-
r, err := util.JsonOrYamlUnmarshal[helm.Package](data)
89+
r, err := getHelmPackages(args...)
10090
if err != nil {
101-
logger.Err(err).Error("Unable to read the file")
10291
return err
10392
}
10493

10594
for name, packageSpec := range r.Packages {
106-
def, ok := hm.Get(name)
107-
if !ok {
108-
return errors.Errorf("Unable to get '%s' chart", name)
109-
}
95+
var chart helm.Chart
11096

111-
ver, ok := def.Get(packageSpec.Version)
112-
if !ok {
113-
return errors.Errorf("Unable to get '%s' chart in version `%s`", name, packageSpec.Version)
114-
}
97+
if len(packageSpec.Chart) == 0 {
98+
def, ok := hm.Get(name)
99+
if !ok {
100+
return errors.Errorf("Unable to get '%s' chart", name)
101+
}
115102

116-
chart, err := ver.Get(cmd.Context())
117-
if err != nil {
118-
return errors.Wrapf(err, "Unable to download chart %s-%s", name, ver.Version())
103+
ver, ok := def.Get(packageSpec.Version)
104+
if !ok {
105+
return errors.Errorf("Unable to get '%s' chart in version `%s`", name, packageSpec.Version)
106+
}
107+
108+
c, err := ver.Get(cmd.Context())
109+
if err != nil {
110+
return errors.Wrapf(err, "Unable to download chart %s-%s", name, ver.Version())
111+
}
112+
113+
chart = c
114+
} else {
115+
chart = helm.Chart(packageSpec.Chart)
119116
}
120117

121-
logger := logger.Str("chart", name).Str("version", ver.Version())
118+
logger := logger.Str("chart", name).Str("version", packageSpec.Version)
122119

123120
if c, ok := charts[name]; !ok {
124121
logger.Debug("Installing Chart: %s", name)
@@ -137,15 +134,16 @@ func packageInstallRun(cmd *cobra.Command, args []string) error {
137134
return err
138135
}
139136

140-
logger.Debug("Installed Chart: %s", name)
137+
logger.Info("Installed Chart: %s", name)
141138
} else {
142-
if c.Spec.Definition.SHA256() != chart.SHA256SUM() {
139+
if c.Spec.Definition.SHA256() != chart.SHA256SUM() || !packageSpec.Overrides.Equals(helm.Values(c.Spec.Overrides)) {
143140
c.Spec.Definition = sharedApi.Data(chart)
141+
c.Spec.Overrides = sharedApi.Any(packageSpec.Overrides)
144142
_, err := client.Arango().PlatformV1alpha1().ArangoPlatformCharts(ns).Update(cmd.Context(), c, meta.UpdateOptions{})
145143
if err != nil {
146144
return err
147145
}
148-
logger.Debug("Updated Chart: %s", name)
146+
logger.Info("Updated Chart: %s", name)
149147
}
150148
}
151149
}
@@ -170,7 +168,9 @@ func packageInstallRun(cmd *cobra.Command, args []string) error {
170168
return err
171169
}
172170

173-
mergedData, err := helm.NewMergeValues(helm.MergeMaps, map[string]any{
171+
println(string(chartObject.Overrides))
172+
173+
mergedData, err := helm.NewMergeValues[any](helm.MergeMaps, map[string]any{
174174
"arangodb_platform": map[string]any{
175175
"deployment": map[string]any{
176176
"name": deployment,
@@ -183,8 +183,6 @@ func packageInstallRun(cmd *cobra.Command, args []string) error {
183183

184184
logger.Info("Fetch ArangoPlatformChart")
185185

186-
logger.Info("ArangoPlatformChart Found")
187-
188186
if current, err := hclient.Status(cmd.Context(), name); err != nil {
189187
return err
190188
} else if current == nil {

‎pkg/platform/package_merge.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package platform
22+
23+
import (
24+
"github.com/spf13/cobra"
25+
"sigs.k8s.io/yaml"
26+
27+
"github.com/arangodb/kube-arangodb/pkg/util/cli"
28+
)
29+
30+
func packageMerge() (*cobra.Command, error) {
31+
var cmd cobra.Command
32+
33+
cmd.Use = "merge ... packages"
34+
cmd.Short = "Merges definitions into single file"
35+
36+
if err := cli.RegisterFlags(&cmd); err != nil {
37+
return nil, err
38+
}
39+
40+
cmd.RunE = getRunner().With(packageMergeRun).Run
41+
42+
return &cmd, nil
43+
}
44+
45+
func packageMergeRun(cmd *cobra.Command, args []string) error {
46+
p, err := getHelmPackages(args...)
47+
if err != nil {
48+
return err
49+
}
50+
51+
d, err := yaml.Marshal(p)
52+
if err != nil {
53+
return err
54+
}
55+
56+
return render(cmd, "---\n\n%s", string(d))
57+
}

‎pkg/platform/regclient.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package platform
22+
23+
import (
24+
"github.com/regclient/regclient"
25+
"github.com/spf13/cobra"
26+
)
27+
28+
func getRegClient(cmd *cobra.Command) (*regclient.RegClient, error) {
29+
var flags = make([]regclient.Opt, 0, 1)
30+
31+
if creds, err := flagRegistryUseCredentials.Get(cmd); err != nil {
32+
return nil, err
33+
} else if creds {
34+
flags = append(flags, regclient.WithDockerCreds())
35+
}
36+
37+
return regclient.New(flags...), nil
38+
}

‎pkg/platform/registry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func registry() (*cobra.Command, error) {
3232
cmd.Use = "registry"
3333
cmd.Short = "Registry related operations"
3434

35-
if err := cli.RegisterFlags(&cmd, flagPlatformEndpoint, flagPlatformName); err != nil {
35+
if err := cli.RegisterFlags(&cmd, flagPlatformEndpoint); err != nil {
3636
return nil, err
3737
}
3838

‎pkg/util/closer/multi.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package closer
22+
23+
import shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
24+
25+
type MultiCloser interface {
26+
Close
27+
With(closers ...Close) MultiCloser
28+
}
29+
30+
func NewMultiCloser(closers ...Close) MultiCloser {
31+
return multiCloser(closers)
32+
}
33+
34+
type multiCloser []Close
35+
36+
func (m multiCloser) With(closers ...Close) MultiCloser {
37+
r := make(multiCloser, len(m)+len(closers))
38+
copy(r, m)
39+
copy(r[len(m):], closers)
40+
return r
41+
}
42+
43+
func (m multiCloser) Close() error {
44+
e := make([]error, len(m))
45+
46+
for id := len(m) - 1; id >= 0; id-- {
47+
e[id] = m[id].Close()
48+
}
49+
50+
return shared.WithErrors(e...)
51+
}

‎pkg/util/json.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package util
2222

2323
import (
2424
"encoding/json"
25+
"os"
2526

2627
"sigs.k8s.io/yaml"
2728
)
@@ -41,6 +42,15 @@ func JSONRemarshal[A, B any](in A) (B, error) {
4142
return o, nil
4243
}
4344

45+
func JsonOrYamlUnmarshalFile[T any](path string) (T, error) {
46+
data, err := os.ReadFile(path)
47+
if err != nil {
48+
return Default[T](), err
49+
}
50+
51+
return JsonOrYamlUnmarshal[T](data)
52+
}
53+
4454
func JsonOrYamlUnmarshal[T any](b []byte) (T, error) {
4555
var z T
4656

‎pkg/util/k8sutil/helm/package.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
2828

2929
platformApi "github.com/arangodb/kube-arangodb/pkg/apis/platform/v1alpha1"
30+
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
3031
"github.com/arangodb/kube-arangodb/pkg/util/constants"
3132
"github.com/arangodb/kube-arangodb/pkg/util/errors"
3233
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
@@ -41,6 +42,8 @@ type Package struct {
4142
type PackageSpec struct {
4243
Version string `json:"version"`
4344

45+
Chart sharedApi.Data `json:"chart,omitempty"`
46+
4447
Overrides Values `json:"overrides,omitempty"`
4548
}
4649

‎pkg/util/k8sutil/helm/values.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func NewMergeRawValues(opts ValuesMergeMethod, vs ...Values) (Values, error) {
4545
return o, nil
4646
}
4747

48-
func NewMergeValues(opts ValuesMergeMethod, vs ...any) (Values, error) {
48+
func NewMergeValues[T any](opts ValuesMergeMethod, vs ...T) (Values, error) {
4949
if len(vs) == 0 {
5050
return nil, nil
5151
}

0 commit comments

Comments
 (0)
Please sign in to comment.