Compare commits

..

1 Commits

Author SHA1 Message Date
Gary Larizza
ae4aad4993 Update Cue tutorial to use testscript
PROBLEM:

The "Cue" tutorial has hardcoded code blocks and hasn't been
updated to use the automated testscript workflow.

NOTE: This is slightly more complex than normal because we need
to make sure Timoni is installed when we execute the testscripts
due to the fact that we need to execute `timoni mod vendor crds ...`
and capture the output.

SOLUTION:

* Add Timoni as one of the packages that are installed via `make go-deps`.
* Update the testing GH Action to install all go dependencies before executing the tests.
* Create a test for the Cue tutorial.
* Create a testscript for the Cue test.
* Update the Cue MDX file to load in data from the testscript directory.

OUTCOME:

The code content in the Cue tutorial now comes directly from the
testscript workflow.
2025-01-23 15:49:04 -08:00
68 changed files with 522 additions and 532 deletions

View File

@@ -27,4 +27,4 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.64.5
version: v1.60

View File

@@ -32,20 +32,17 @@ bump: bumppatch
.PHONY: bumppatch
bumppatch: ## Bump the patch version.
scripts/bump patch
HOLOS_UPDATE_SCRIPTS=1 scripts/test
.PHONY: bumpminor
bumpminor: ## Bump the minor version.
scripts/bump minor
scripts/bump patch 0
HOLOS_UPDATE_SCRIPTS=1 scripts/test
.PHONY: bumpmajor
bumpmajor: ## Bump the major version.
scripts/bump major
scripts/bump minor 0
scripts/bump patch 0
HOLOS_UPDATE_SCRIPTS=1 scripts/test
.PHONY: show-version
show-version: ## Print the full version.
@@ -78,12 +75,6 @@ build: ## Build holos executable.
@echo "GOPATH=${GOPATH}"
go build -trimpath -o bin/$(BIN_NAME) -ldflags $(LD_FLAGS) $(REPO_PATH)/cmd/$(BIN_NAME)
.PHONY: debug
debug: ## Build debug executable.
@echo "building ${BIN_NAME}-debug ${VERSION}"
@echo "GOPATH=${GOPATH}"
go build -o bin/$(BIN_NAME)-debug $(REPO_PATH)/cmd/$(BIN_NAME)
linux: ## Build holos executable for tilt.
@echo "building ${BIN_NAME}.linux ${VERSION}"
@echo "GOPATH=${GOPATH}"
@@ -133,6 +124,7 @@ go-deps: ## tool versions pinned in tools.go
go install golang.org/x/tools/cmd/godoc
go install github.com/princjef/gomarkdoc/cmd/gomarkdoc
go install github.com/google/ko
go install github.com/stefanprodan/timoni/cmd/timoni@v0.23.0
# curl https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash
.PHONY: frontend-deps

View File

@@ -190,13 +190,11 @@ type AuthSource struct {
// 1. [Kustomize] - Patch and transform the output from prior generators or
// transformers. See [Introduction to Kustomize].
// 2. [Join] - Concatenate multiple prior outputs into one output.
// 3. [Slice] - Slice an artifact into multiple artifacts using [kubectl-slice].
//
// [Introduction to Kustomize]: https://kubectl.docs.kubernetes.io/guides/config_management/introduction/
// [kubectl-slice]: https://github.com/patrickdappollonio/kubectl-slice
type Transformer struct {
// Kind represents the kind of transformer. Must be Kustomize, or Join.
Kind string `json:"kind" yaml:"kind" cue:"\"Kustomize\" | \"Join\" | \"Slice\""`
Kind string `json:"kind" yaml:"kind" cue:"\"Kustomize\" | \"Join\""`
// Inputs represents the files to transform. The Output of prior Generators
// and Transformers.
Inputs []FilePath `json:"inputs" yaml:"inputs"`
@@ -256,46 +254,12 @@ type Validator struct {
Command Command `json:"command,omitempty" yaml:"command,omitempty"`
}
// Command represents a generic command for use as a Generator, Transformer, or
// Validator. Holos uses the Go template engine to render the Args field using
// data provided by the TaskData field. For example to fill in the fully
// qualified temporary directory used to provide inputs to the task.
// Command represents a command vetting one or more artifacts. Holos appends
// fully qualified input file paths to the end of the args list, then executes
// the command. Inputs are written into a temporary directory prior to
// executing the command and removed afterwards.
type Command struct {
// DisplayName represents a friendly display name for the command.
DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"`
// Args represents the complete command argument vector as a go template.
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
// OutputRef references the source of the output data.
OutputRef OutputRef `json:"outputRef,omitempty" yaml:"outputRef,omitempty"`
// TaskData populated by Holos for template rendering.
TaskData TaskData `json:"taskData,omitempty" yaml:"taskData,omitempty"`
// TODO(jjm): add command environment variable support similar to args.
}
// TaskData represents data values associated with a pipeline task necessary to
// execute the task. For example, the randomly generated temporary directory
// used to read and write artifact files when executing user defined task
// commands. Values of this struct are intended for the Go template engine.
//
// Holos populates this struct as needed. Holos may treat user provided values
// as an error condition.
type TaskData struct {
// TempDir represents the temp directory holos manages for task artifacts.
TempDir string `json:"tempDir,omitempty" yaml:"tempDir,omitempty"`
}
// OutputRef represents a reference to the data source used as the output of a
// task. For example, a Generator output may be sourced from standard output or
// a file path.
type OutputRef struct {
// Kind represents the kind of output produced.
Kind string `json:"kind,omitempty" yaml:"kind,omitempty" cue:"string | *\"Pipe\" | \"Path\""`
// Pipe represents stdout or stderr. Ignored unless kind is Pipe.
Pipe string `json:"pipe,omitempty" yaml:"pipe,omitempty" cue:"string | *\"stdout\" | \"stderr\""`
// Path represents an artifact path relative to the task temp directory.
// Ignored unless kind is Path.
Path string `json:"path,omitempty" yaml:"path,omitempty"`
// TODO(jjm): support jsonpath or cel references to the output data maybe?
}
// InternalLabel is an arbitrary unique identifier internal to holos itself.

View File

@@ -11,11 +11,10 @@ import (
)
func TestMain(m *testing.M) {
holosMain := cmd.MakeMain()
testscript.Main(m, map[string]func(){
"holos": func() { os.Exit(holosMain()) },
"cue": func() { os.Exit(cue.Main()) },
})
os.Exit(testscript.RunMain(m, map[string]func() int{
"holos": cmd.MakeMain(),
"cue": cue.Main,
}))
}
func TestGuides_v1alpha5(t *testing.T) {

View File

@@ -31,6 +31,7 @@ spec:
- kind: Resources
output: resources.gen.yaml
resources: {}
validators: []
transformers:
- kind: Kustomize
inputs:
@@ -38,8 +39,7 @@ spec:
output: components/no-name/no-name.gen.yaml
kustomize:
kustomization:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- resources.gen.yaml
validators: []
kind: Kustomization
apiVersion: kustomize.config.k8s.io/v1beta1

View File

@@ -36,13 +36,11 @@ Package core contains schemas for a [Platform](<#Platform>) and [BuildPlan](<#Bu
- [type Kustomization](<#Kustomization>)
- [type Kustomize](<#Kustomize>)
- [type Metadata](<#Metadata>)
- [type OutputRef](<#OutputRef>)
- [type Platform](<#Platform>)
- [type PlatformSpec](<#PlatformSpec>)
- [type Repository](<#Repository>)
- [type Resource](<#Resource>)
- [type Resources](<#Resources>)
- [type TaskData](<#TaskData>)
- [type Transformer](<#Transformer>)
- [type Validator](<#Validator>)
- [type ValueFile](<#ValueFile>)
@@ -153,18 +151,11 @@ type Chart struct {
<a name="Command"></a>
## type Command {#Command}
Command represents a generic command for use as a Generator, Transformer, or Validator. Holos uses the Go template engine to render the Args field using data provided by the TaskData field. For example to fill in the fully qualified temporary directory used to provide inputs to the task.
Command represents a command vetting one or more artifacts. Holos appends fully qualified input file paths to the end of the args list, then executes the command. Inputs are written into a temporary directory prior to executing the command and removed afterwards.
```go
type Command struct {
// DisplayName represents a friendly display name for the command.
DisplayName string `json:"displayName,omitempty" yaml:"displayName,omitempty"`
// Args represents the complete command argument vector as a go template.
Args []string `json:"args,omitempty" yaml:"args,omitempty"`
// OutputRef references the source of the output data.
OutputRef OutputRef `json:"outputRef,omitempty" yaml:"outputRef,omitempty"`
// TaskData populated by Holos for template rendering.
TaskData TaskData `json:"taskData,omitempty" yaml:"taskData,omitempty"`
}
```
@@ -396,23 +387,6 @@ type Metadata struct {
}
```
<a name="OutputRef"></a>
## type OutputRef {#OutputRef}
OutputRef represents a reference to the data source used as the output of a task. For example, a Generator output may be sourced from standard output or a file path.
```go
type OutputRef struct {
// Kind represents the kind of output produced.
Kind string `json:"kind,omitempty" yaml:"kind,omitempty" cue:"string | *\"Pipe\" | \"Path\""`
// Pipe represents stdout or stderr. Ignored unless kind is Pipe.
Pipe string `json:"pipe,omitempty" yaml:"pipe,omitempty" cue:"string | *\"stdout\" | \"stderr\""`
// Path represents an artifact path relative to the task temp directory.
// Ignored unless kind is Path.
Path string `json:"path,omitempty" yaml:"path,omitempty"`
}
```
<a name="Platform"></a>
## type Platform {#Platform}
@@ -483,20 +457,6 @@ Resources represents Kubernetes resources. Most commonly used to mix resources i
type Resources map[Kind]map[InternalLabel]Resource
```
<a name="TaskData"></a>
## type TaskData {#TaskData}
TaskData represents data values associated with a pipeline task necessary to execute the task. For example, the randomly generated temporary directory used to read and write artifact files when executing user defined task commands. Values of this struct are intended for the Go template engine.
Holos populates this struct as needed. Holos may treat user provided values as an error condition.
```go
type TaskData struct {
// TempDir represents the temp directory holos manages for task artifacts.
TempDir string `json:"tempDir,omitempty" yaml:"tempDir,omitempty"`
}
```
<a name="Transformer"></a>
## type Transformer {#Transformer}
@@ -504,12 +464,11 @@ Transformer combines multiple inputs from prior [Generator](<#Generator>) or [Tr
1. [Kustomize](<#Kustomize>) \- Patch and transform the output from prior generators or transformers. See [Introduction to Kustomize](<https://kubectl.docs.kubernetes.io/guides/config_management/introduction/>).
2. [Join](<#Join>) \- Concatenate multiple prior outputs into one output.
3. \[Slice\] \- Slice an artifact into multiple artifacts using [kubectl\\\-slice](<https://github.com/patrickdappollonio/kubectl-slice>).
```go
type Transformer struct {
// Kind represents the kind of transformer. Must be Kustomize, or Join.
Kind string `json:"kind" yaml:"kind" cue:"\"Kustomize\" | \"Join\" | \"Slice\""`
Kind string `json:"kind" yaml:"kind" cue:"\"Kustomize\" | \"Join\""`
// Inputs represents the files to transform. The Output of prior Generators
// and Transformers.
Inputs []FilePath `json:"inputs" yaml:"inputs"`

View File

@@ -0,0 +1,7 @@
exec bash -c 'bash -euo pipefail $WORK/command.sh 2>&1'
cmp stdout $WORK/output.txt
-- command.sh --
holos --version
-- output.txt --
0.103.0

View File

@@ -0,0 +1,166 @@
# Set $HOME because:
# - Helm uses it for temporary files
# - Git requires it for setting author name/email globally
env HOME=$WORK/.tmp
chmod 0755 $WORK/update.sh
# Configure git author for testscript execution
exec git config --global user.name 'Holos Docs'
exec git config --global user.email 'hello@holos.run'
exec git config --global init.defaultBranch main
# Remove the tutorial directory if it already exists
exec rm -rf holos-cue-tutorial
# Create and change to the tutorial directory, and then initialize the Holos platform
exec bash -c 'bash -euo pipefail mkdir-and-init.sh'
cd holos-cue-tutorial
# Create the components directory, then combine and execute the multiline
# podinfo component header/body/trailer files
exec bash -c 'bash -euo pipefail $WORK/mkdir-components.sh'
exec cat $WORK/podinfo-component-header.sh $WORK/podinfo-component-body.cue $WORK/eof-trailer.sh
stdin stdout
exec bash -xeuo pipefail
# Combine and execute the multiline platform registration header/body/trailer files.
exec cat $WORK/register-components-header.sh $WORK/register-components-body.cue $WORK/eof-trailer.sh
stdin stdout
exec bash -xeuo pipefail
# Render and capture output
# NOTE: The [net] condition will test whether external network access is available
[net] exec bash -c 'bash -euo pipefail $WORK/render.sh 2>&1'
[net] stdin stdout
exec $WORK/update.sh $WORK/register-components-output.txt
# Git init and commit
exec bash -c 'bash -euo pipefail $WORK/git-init.sh'
# Combine and execute the mixin component header/body/trailer files
exec cat $WORK/mixin-component-header.sh $WORK/mixin-component-body.cue $WORK/eof-trailer.sh
stdin stdout
exec bash -xeuo pipefail
# Import CRDs with Timoni
exec bash -c 'bash -euo pipefail $WORK/import-crds.sh 2>&1'
stdin stdout
exec $WORK/update.sh $WORK/timoni-vendor.txt
# Render platform
[net] exec bash -c 'bash -euo pipefail $WORK/render.sh 2>&1'
# Git diff and capture output
exec bash -c 'bash -euo pipefail $WORK/git-diff.sh 2>&1'
stdin stdout
exec $WORK/update.sh $WORK/git.diff
# Clean up the tutorial directory and tmp $HOME directory
cd $WORK
exec rm -rf holos-cue-tutorial
exec rm -rf $HOME
-- update.sh --
#! /bin/bash
set -euo pipefail
[[ -s "$1" ]] && [[ -z "${HOLOS_UPDATE_SCRIPTS:-}" ]] && exit 0
cat > "$1"
-- mkdir-and-init.sh --
mkdir holos-cue-tutorial && cd holos-cue-tutorial
holos init platform v1alpha5
-- mkdir-components.sh --
mkdir -p components/podinfo
-- import-crds.sh --
timoni mod vendor crds -f https://raw.githubusercontent.com/external-secrets/external-secrets/v0.10.5/deploy/crds/bundle.yaml
-- podinfo-component-header.sh --
cat <<EOF > components/podinfo/podinfo.cue
-- podinfo-component-body.cue --
package holos
// export the component build plan to holos
holos: Component.BuildPlan
// Component is a Helm chart
Component: #Helm & {
Name: "podinfo"
Namespace: "default"
// Add metadata.namespace to all resources with kustomize.
KustomizeConfig: Kustomization: namespace: Namespace
Chart: {
version: "6.6.2"
repository: {
name: "podinfo"
url: "https://stefanprodan.github.io/podinfo"
}
}
}
-- eof-trailer.sh --
EOF
-- register-components-header.sh --
cat <<EOF > platform/podinfo.cue
-- register-components-body.cue --
package holos
Platform: Components: podinfo: {
name: "podinfo"
path: "components/podinfo"
}
-- render.sh --
holos render platform
-- git-init.sh --
git init . && git add . && git commit -m initial
-- mixin-component-header.sh --
cat <<EOF > components/podinfo/mixins.cue
-- mixin-component-body.cue --
package holos
// Component fields are unified with podinfo.cue
Component: {
// Concrete values are defined in podinfo.cue
Name: string
Namespace: string
// Resources represents mix-in resources organized as a struct.
Resources: ExternalSecret: (Name): {
// Name is consistent with the component name.
metadata: name: Name
// Namespace is consistent with the component namespace.
metadata: namespace: Namespace
spec: {
// Ensure the target secret name is consistent.
target: name: metadata.name
// Ensure the name in the SecretStore is consistent.
dataFrom: [{extract: {key: metadata.name}}]
refreshInterval: "30s"
secretStoreRef: kind: "SecretStore"
secretStoreRef: name: "default"
}
}
}
-- git-diff.sh --
git diff deploy
-- git.diff --
diff --git a/deploy/components/podinfo/podinfo.gen.yaml b/deploy/components/podinfo/podinfo.gen.yaml
index 6e4aec0..f79e9d0 100644
--- a/deploy/components/podinfo/podinfo.gen.yaml
+++ b/deploy/components/podinfo/podinfo.gen.yaml
@@ -112,3 +112,19 @@ spec:
volumes:
- emptyDir: {}
name: data
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: podinfo
+ namespace: default
+spec:
+ dataFrom:
+ - extract:
+ key: podinfo
+ refreshInterval: 30s
+ secretStoreRef:
+ kind: SecretStore
+ name: default
+ target:
+ name: podinfo

View File

@@ -0,0 +1 @@
holos --version

View File

@@ -0,0 +1 @@
0.103.0

View File

@@ -0,0 +1 @@
EOF

View File

@@ -0,0 +1 @@
git diff deploy

View File

@@ -0,0 +1 @@
git init . && git add . && git commit -m initial

View File

@@ -0,0 +1,24 @@
diff --git a/deploy/components/podinfo/podinfo.gen.yaml b/deploy/components/podinfo/podinfo.gen.yaml
index 6e4aec0..f79e9d0 100644
--- a/deploy/components/podinfo/podinfo.gen.yaml
+++ b/deploy/components/podinfo/podinfo.gen.yaml
@@ -112,3 +112,19 @@ spec:
volumes:
- emptyDir: {}
name: data
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: podinfo
+ namespace: default
+spec:
+ dataFrom:
+ - extract:
+ key: podinfo
+ refreshInterval: 30s
+ secretStoreRef:
+ kind: SecretStore
+ name: default
+ target:
+ name: podinfo

View File

@@ -0,0 +1 @@
timoni mod vendor crds -f https://raw.githubusercontent.com/external-secrets/external-secrets/v0.10.5/deploy/crds/bundle.yaml

View File

@@ -0,0 +1,25 @@
package holos
// Component fields are unified with podinfo.cue
Component: {
// Concrete values are defined in podinfo.cue
Name: string
Namespace: string
// Resources represents mix-in resources organized as a struct.
Resources: ExternalSecret: (Name): {
// Name is consistent with the component name.
metadata: name: Name
// Namespace is consistent with the component namespace.
metadata: namespace: Namespace
spec: {
// Ensure the target secret name is consistent.
target: name: metadata.name
// Ensure the name in the SecretStore is consistent.
dataFrom: [{extract: {key: metadata.name}}]
refreshInterval: "30s"
secretStoreRef: kind: "SecretStore"
secretStoreRef: name: "default"
}
}
}

View File

@@ -0,0 +1 @@
cat <<EOF > components/podinfo/mixins.cue

View File

@@ -0,0 +1,2 @@
mkdir holos-cue-tutorial && cd holos-cue-tutorial
holos init platform v1alpha5

View File

@@ -0,0 +1 @@
mkdir -p components/podinfo

View File

@@ -0,0 +1,19 @@
package holos
// export the component build plan to holos
holos: Component.BuildPlan
// Component is a Helm chart
Component: #Helm & {
Name: "podinfo"
Namespace: "default"
// Add metadata.namespace to all resources with kustomize.
KustomizeConfig: Kustomization: namespace: Namespace
Chart: {
version: "6.6.2"
repository: {
name: "podinfo"
url: "https://stefanprodan.github.io/podinfo"
}
}
}

View File

@@ -0,0 +1 @@
cat <<EOF > components/podinfo/podinfo.cue

View File

@@ -0,0 +1,6 @@
package holos
Platform: Components: podinfo: {
name: "podinfo"
path: "components/podinfo"
}

View File

@@ -0,0 +1 @@
cat <<EOF > platform/podinfo.cue

View File

@@ -0,0 +1,3 @@
cached podinfo 6.6.2
rendered podinfo in 1.938665041s
rendered platform in 1.938759417s

View File

@@ -0,0 +1 @@
holos render platform

View File

@@ -0,0 +1,17 @@
3:20PM INF schemas vendored: external-secrets.io/clusterexternalsecret/v1beta1
3:20PM INF schemas vendored: external-secrets.io/clustersecretstore/v1alpha1
3:20PM INF schemas vendored: external-secrets.io/clustersecretstore/v1beta1
3:20PM INF schemas vendored: external-secrets.io/externalsecret/v1alpha1
3:20PM INF schemas vendored: external-secrets.io/externalsecret/v1beta1
3:20PM INF schemas vendored: external-secrets.io/pushsecret/v1alpha1
3:20PM INF schemas vendored: external-secrets.io/secretstore/v1alpha1
3:20PM INF schemas vendored: external-secrets.io/secretstore/v1beta1
3:20PM INF schemas vendored: generators.external-secrets.io/acraccesstoken/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/ecrauthorizationtoken/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/fake/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/gcraccesstoken/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/githubaccesstoken/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/password/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/uuid/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/vaultdynamicsecret/v1alpha1
3:20PM INF schemas vendored: generators.external-secrets.io/webhook/v1alpha1

View File

@@ -0,0 +1,4 @@
#! /bin/bash
set -euo pipefail
[[ -s "$1" ]] && [[ -z "${HOLOS_UPDATE_SCRIPTS:-}" ]] && exit 0
cat > "$1"

View File

@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
-- command.sh --
holos --version
-- output.txt --
0.104.1
0.103.0

View File

@@ -1 +1 @@
0.104.1
0.103.0

View File

@@ -1,2 +1,2 @@
rendered podinfo in 312.472625ms
rendered platform in 312.557375ms
rendered podinfo in 544.501875ms
rendered platform in 544.608125ms

View File

@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
-- command.sh --
holos --version
-- output.txt --
0.104.1
0.103.0

View File

@@ -1 +1 @@
0.104.1
0.103.0

View File

@@ -1,3 +1,3 @@
[main aa9749e] add blackbox configuration
[main 1adcd08] add blackbox configuration
1 file changed, 15 insertions(+)
create mode 100644 config/prometheus/blackbox.cue
create mode 100644 components/blackbox.cue

View File

@@ -1,3 +1,2 @@
[main 656d4ee] integrate blackbox and prometheus together
3 files changed, 1348 insertions(+), 2 deletions(-)
create mode 100644 components/prometheus/values.cue.orig
[main 4221803] integrate blackbox and prometheus together
2 files changed, 4 insertions(+), 2 deletions(-)

View File

@@ -1,4 +1,4 @@
[main 3788921] import values
[main 52e90ea] import values
2 files changed, 1815 insertions(+)
create mode 100644 components/blackbox/values.cue
create mode 100644 components/prometheus/values.cue

View File

@@ -1,3 +1,3 @@
rendered blackbox in 129.142708ms
rendered prometheus in 165.260375ms
rendered platform in 165.33ms
rendered blackbox in 365.936792ms
rendered prometheus in 371.855875ms
rendered platform in 372.109916ms

View File

@@ -1,4 +1,4 @@
[main 654ae06] add blackbox and prometheus
[main b5df111] add blackbox and prometheus
5 files changed, 1550 insertions(+)
create mode 100644 components/blackbox/blackbox.cue
create mode 100644 components/prometheus/prometheus.cue

View File

@@ -1,3 +1,5 @@
rendered blackbox in 1.096663084s
rendered prometheus in 1.151784875s
rendered platform in 1.151839916s
cached prometheus-blackbox-exporter 9.0.1
rendered blackbox in 3.825430417s
cached prometheus 25.27.0
rendered prometheus in 4.840089667s
rendered platform in 4.840137792s

View File

@@ -1,2 +1,2 @@
[main 9bc0126] render integrated blackbox and prometheus manifests
[main 67efe0d] render integrated blackbox and prometheus manifests
2 files changed, 7 insertions(+), 7 deletions(-)

View File

@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
-- command.sh --
holos --version
-- output.txt --
0.104.1
0.103.0

View File

@@ -1 +1 @@
0.104.1
0.103.0

View File

@@ -13,6 +13,7 @@ spec:
output: httpbin.yaml
file:
source: httpbin.yaml
validators: []
transformers:
- kind: Kustomize
inputs:
@@ -21,8 +22,6 @@ spec:
output: components/no-name/no-name.gen.yaml
kustomize:
kustomization:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
labels:
- includeSelectors: false
pairs:
@@ -33,4 +32,5 @@ spec:
resources:
- resources.gen.yaml
- httpbin.yaml
validators: []
kind: Kustomization
apiVersion: kustomize.config.k8s.io/v1beta1

View File

@@ -1,4 +1,4 @@
[main 823e136] add httpbin
[main f0dd632] add httpbin
4 files changed, 113 insertions(+)
create mode 100644 components/httpbin/httpbin.cue
create mode 100644 components/httpbin/httpbin.yaml

View File

@@ -1,3 +1,3 @@
[main 96f5f45] annotate httpbin for prometheus probes
[main b120712] annotate httpbin for prometheus probes
2 files changed, 18 insertions(+)
create mode 100644 components/httpbin/patches.cue

View File

@@ -1,2 +1,2 @@
rendered httpbin in 112.916375ms
rendered platform in 112.990333ms
rendered httpbin in 132.00525ms
rendered platform in 132.124042ms

View File

@@ -1,2 +1,2 @@
rendered httpbin in 111.183042ms
rendered platform in 111.265792ms
rendered httpbin in 175.057083ms
rendered platform in 175.145292ms

View File

@@ -7,6 +7,7 @@ sidebar_position: 50
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
# CUE
@@ -25,92 +26,69 @@ Key concepts:
## The Code
### Holos Version
Ensure you have a current version of `holos` installed. This document was
tested with the following version.
import HolosVersionCommand from '!!raw-loader!./_cue/script-01-holos-version/command.sh';
import HolosVersionOutput from '!!raw-loader!./_cue/script-01-holos-version/output.txt';
<CodeBlock language="bash">{HolosVersionCommand}</CodeBlock>
<CodeBlock language="txt">{HolosVersionOutput}</CodeBlock>
### Generating the Structure
Use `holos` to generate a minimal platform directory structure. First, create
and navigate into a blank directory. Then, use the `holos generate platform`
command to generate a minimal platform.
```shell
mkdir holos-cue-tutorial && cd holos-cue-tutorial
holos init platform v1alpha5
```
import MkdirAndInit from '!!raw-loader!./_cue/script-02-cue/mkdir-and-init.sh';
<CodeBlock language="bash">{MkdirAndInit}</CodeBlock>
### Creating the Component
Create the directory for the `podinfo` component. Create an empty file, then add
the following CUE configuration to it.
```bash
mkdir -p components/podinfo
```
```bash
cat <<EOF > components/podinfo/podinfo.cue
```
```cue showLineNumbers
package holos
import MkdirComponents from '!!raw-loader!./_cue/script-02-cue/mkdir-components.sh';
import PodinfoHeader from '!!raw-loader!./_cue/script-02-cue/podinfo-component-header.sh';
import PodinfoBody from '!!raw-loader!./_cue/script-02-cue/podinfo-component-body.cue';
import EofTrailer from '!!raw-loader!./_cue/script-02-cue/eof-trailer.sh';
// export the component build plan to holos
holos: Component.BuildPlan
// Component is a Helm chart
Component: #Helm & {
Name: "podinfo"
Namespace: "default"
// Add metadata.namespace to all resources with kustomize.
KustomizeConfig: Kustomization: namespace: Namespace
Chart: {
version: "6.6.2"
repository: {
name: "podinfo"
url: "https://stefanprodan.github.io/podinfo"
}
}
}
```
```bash
EOF
```
<CodeBlock language="bash">{PodinfoHeader}</CodeBlock>
<CodeBlock language="cue" showLineNumbers>{PodinfoBody}</CodeBlock>
<CodeBlock language="bash">{EofTrailer}</CodeBlock>
Register the component with the platform.
```bash
cat <<EOF > platform/podinfo.cue
```
```cue showLineNumbers
package holos
import RegisterHeader from '!!raw-loader!./_cue/script-02-cue/register-components-header.sh';
import RegisterBody from '!!raw-loader!./_cue/script-02-cue/register-components-body.cue';
Platform: Components: podinfo: {
name: "podinfo"
path: "components/podinfo"
}
```
```bash
EOF
```
<CodeBlock language="bash">{RegisterHeader}</CodeBlock>
<CodeBlock language="cue" showLineNumbers>{RegisterBody}</CodeBlock>
<CodeBlock language="bash">{EofTrailer}</CodeBlock>
Render the platform.
import RenderCommand from '!!raw-loader!./_cue/script-02-cue/render.sh';
import RegisterOutput from '!!raw-loader!./_cue/script-02-cue/register-components-output.txt';
<Tabs groupId="tutorial-hello-render-manifests">
<TabItem value="command" label="Command">
```bash
holos render platform
```
<CodeBlock language="bash">{RenderCommand}</CodeBlock>
</TabItem>
<TabItem value="output" label="Output">
```
cached podinfo 6.6.2
rendered podinfo in 1.938665041s
rendered platform in 1.938759417s
```
<CodeBlock language="txt">{RegisterOutput}</CodeBlock>
</TabItem>
</Tabs>
Add and commit the initial configuration.
```bash
git init . && git add . && git commit -m initial
```
import GitInit from '!!raw-loader!./_cue/script-02-cue/git-init.sh';
<CodeBlock language="bash">{GitInit}</CodeBlock>
### Mixing in Resources
@@ -120,39 +98,12 @@ component kind. This field is a convenient wrapper around the core [BuildPlan]
Create the mixins.cue file.
```bash
cat <<EOF > components/podinfo/mixins.cue
```
```cue showLineNumbers
package holos
import MixinHeader from '!!raw-loader!./_cue/script-02-cue/mixin-component-header.sh';
import MixinBody from '!!raw-loader!./_cue/script-02-cue/mixin-component-body.cue';
// Component fields are unified with podinfo.cue
Component: {
// Concrete values are defined in podinfo.cue
Name: string
Namespace: string
// Resources represents mix-in resources organized as a struct.
Resources: ExternalSecret: (Name): {
// Name is consistent with the component name.
metadata: name: Name
// Namespace is consistent with the component namespace.
metadata: namespace: Namespace
spec: {
// Ensure the target secret name is consistent.
target: name: metadata.name
// Ensure the name in the SecretStore is consistent.
dataFrom: [{extract: {key: metadata.name}}]
refreshInterval: "30s"
secretStoreRef: kind: "SecretStore"
secretStoreRef: name: "default"
}
}
}
```
```bash
EOF
```
<CodeBlock language="bash">{MixinHeader}</CodeBlock>
<CodeBlock language="cue" showLineNumbers>{MixinBody}</CodeBlock>
<CodeBlock language="bash">{EofTrailer}</CodeBlock>
:::important
Holos uses CUE to validate mixed in resources against a schema. The `Resources`
@@ -169,32 +120,15 @@ tutorial.
To import your own custom resource definitions, use [Timoni]. We imported the
ExternalSecret CRDs embedded in `holos` using the following command.
import ImportCRDs from '!!raw-loader!./_cue/script-02-cue/import-crds.sh';
import ImportOutput from '!!raw-loader!./_cue/script-02-cue/timoni-vendor.txt';
<Tabs groupId="35B1A1A1-D7DF-4D27-A575-28556E182096">
<TabItem value="command" label="Command">
```bash
timoni mod vendor crds -f https://raw.githubusercontent.com/external-secrets/external-secrets/v0.10.5/deploy/crds/bundle.yaml
```
<CodeBlock language="bash">{ImportCRDs}</CodeBlock>
</TabItem>
<TabItem value="output" label="Output">
```txt
2:22PM INF schemas vendored: external-secrets.io/clusterexternalsecret/v1beta1
2:22PM INF schemas vendored: external-secrets.io/clustersecretstore/v1alpha1
2:22PM INF schemas vendored: external-secrets.io/clustersecretstore/v1beta1
2:22PM INF schemas vendored: external-secrets.io/externalsecret/v1alpha1
2:22PM INF schemas vendored: external-secrets.io/externalsecret/v1beta1
2:22PM INF schemas vendored: external-secrets.io/pushsecret/v1alpha1
2:22PM INF schemas vendored: external-secrets.io/secretstore/v1alpha1
2:22PM INF schemas vendored: external-secrets.io/secretstore/v1beta1
2:22PM INF schemas vendored: generators.external-secrets.io/acraccesstoken/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/ecrauthorizationtoken/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/fake/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/gcraccesstoken/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/githubaccesstoken/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/password/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/uuid/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/vaultdynamicsecret/v1alpha1
2:22PM INF schemas vendored: generators.external-secrets.io/webhook/v1alpha1
```
<CodeBlock language="txt">{ImportOutput}</CodeBlock>
</TabItem>
</Tabs>
@@ -212,42 +146,15 @@ existing [resources.cue] file.
Render the platform with the `ExternalSecret` mixed into the podinfo component.
```shell
holos render platform
```
<CodeBlock language="bash">{RenderCommand}</CodeBlock>
Take a look at the diff to see the mixed in `ExternalSecret`.
```shell
git diff deploy
```
import GitDiff from '!!raw-loader!./_cue/script-02-cue/git-diff.sh';
import DiffOutput from '!!raw-loader!./_cue/script-02-cue/git.diff';
```diff
diff --git a/deploy/components/podinfo/podinfo.gen.yaml b/deploy/components/podinfo/podinfo.gen.yaml
index 6e4aec0..f79e9d0 100644
--- a/deploy/components/podinfo/podinfo.gen.yaml
+++ b/deploy/components/podinfo/podinfo.gen.yaml
@@ -112,3 +112,19 @@ spec:
volumes:
- emptyDir: {}
name: data
+---
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: podinfo
+ namespace: default
+spec:
+ dataFrom:
+ - extract:
+ key: podinfo
+ refreshInterval: 30s
+ secretStoreRef:
+ kind: SecretStore
+ name: default
+ target:
+ name: podinfo
```
<CodeBlock language="bash">{GitDiff}</CodeBlock>
<CodeBlock language="diff">{DiffOutput}</CodeBlock>
We saw how to mix in resources using the `Resources` field of the
[ComponentConfig]. This approach works for every kind of component in Holos,

View File

@@ -0,0 +1,19 @@
package main
import (
"path/filepath"
"testing"
)
// Run these with go test -v to see the verbose names
func TestCue(t *testing.T) {
t.Run("TestCue", func(t *testing.T) {
// Get an ordered list of test script files.
dir := "_cue"
for _, file := range sortedTestScripts(t, filepath.Join(dir, "examples")) {
t.Run("examples", func(t *testing.T) {
runOneScript(t, dir, file)
})
}
})
}

View File

@@ -15,12 +15,10 @@ import (
)
func TestMain(m *testing.M) {
holosMain := cmd.MakeMain()
testscript.Main(m, map[string]func(){
"holos": func() { os.Exit(holosMain()) },
"cue": func() { os.Exit(cue.Main()) },
})
os.Exit(testscript.RunMain(m, map[string]func() int{
"holos": cmd.MakeMain(),
"cue": cue.Main,
}))
}
// Run these with go test -v to see the verbose names

View File

@@ -24,7 +24,7 @@ exec git config user.name 'go test'
-- version.sh --
holos --version
-- version.txt --
0.104.1
0.103.0
-- clone.sh --
git clone https://github.com/holos-run/multi-sources-example.git
cd multi-sources-example

View File

@@ -1 +1 @@
6a882ac5aee7241e0130a59737cc46db5f636a21
f35da50452b346d4eea3f3e59ff5ae6b8c221218

View File

@@ -1 +1 @@
0.104.1
0.103.0

View File

@@ -1,28 +1,4 @@
config:
integration/gpu/config.json:
env: integration-gpu
region: us
type: non-prod
version: prod
chart: 0.1.0
integration/non-gpu/config.json:
env: integration-non-gpu
region: us
type: non-prod
version: qa
chart: 0.2.0
prod/eu/config.json:
env: prod-eu
region: eu
type: prod
version: prod
chart: 0.1.0
prod/us/config.json:
env: prod-us
region: us
type: prod
version: prod
chart: 0.1.0
qa/config.json:
env: qa
region: us
@@ -41,9 +17,33 @@ config:
type: non-prod
version: staging
chart: 0.2.0
prod/eu/config.json:
env: prod-eu
region: eu
type: prod
version: prod
chart: 0.1.0
integration/gpu/config.json:
env: integration-gpu
region: us
type: non-prod
version: prod
chart: 0.1.0
staging/us/config.json:
env: staging-us
region: us
type: non-prod
version: staging
chart: 0.2.0
prod/us/config.json:
env: prod-us
region: us
type: prod
version: prod
chart: 0.1.0
integration/non-gpu/config.json:
env: integration-non-gpu
region: us
type: non-prod
version: qa
chart: 0.2.0

View File

@@ -1,11 +1,11 @@
my-values/common-values.yaml:
replicaCount: 1
my-values/app-version/prod-values.yaml:
imageVersion: "1.0"
my-values/app-version/qa-values.yaml:
imageVersion: "3.0"
my-values/app-version/staging-values.yaml:
imageVersion: "2.0"
my-values/common-values.yaml:
replicaCount: 1
my-values/env-type/non-prod-values.yaml:
replicaCount: 3
environmentType: non-prod

View File

@@ -1,8 +1,8 @@
rendered my-chart 0.1.0 for environment prod-us in 169.0965ms
rendered my-chart 0.1.0 for environment integration-gpu in 169.146375ms
rendered my-chart 0.1.0 for environment prod-eu in 171.797375ms
rendered my-chart 0.2.0 for environment staging-us in 195.439625ms
rendered my-chart 0.2.0 for environment qa in 270.457708ms
rendered my-chart 0.2.0 for environment integration-non-gpu in 270.497166ms
rendered my-chart 0.2.0 for environment staging-eu in 271.18825ms
rendered platform in 271.252916ms
rendered my-chart 0.1.0 for environment integration-gpu in 428.168708ms
rendered my-chart 0.1.0 for environment prod-us in 428.221333ms
rendered my-chart 0.1.0 for environment prod-eu in 428.148834ms
rendered my-chart 0.2.0 for environment qa in 433.4605ms
rendered my-chart 0.2.0 for environment staging-us in 493.320625ms
rendered my-chart 0.2.0 for environment integration-non-gpu in 493.343917ms
rendered my-chart 0.2.0 for environment staging-eu in 493.325917ms
rendered platform in 493.432542ms

View File

@@ -1,8 +1,8 @@
rendered my-chart 0.2.0 for environment staging-eu in 202.936708ms
rendered my-chart 0.2.0 for environment staging-us in 204.292666ms
rendered my-chart 0.1.0 for environment integration-gpu in 205.155833ms
rendered my-chart 0.1.0 for environment prod-us in 207.647458ms
rendered my-chart 0.2.0 for environment qa in 208.1245ms
rendered my-chart 0.1.0 for environment prod-eu in 208.608833ms
rendered my-chart 0.2.0 for environment integration-non-gpu in 212.441042ms
rendered platform in 212.504042ms
rendered my-chart 0.2.0 for environment integration-non-gpu in 204.149958ms
rendered my-chart 0.1.0 for environment prod-us in 205.34475ms
rendered my-chart 0.2.0 for environment staging-eu in 206.376291ms
rendered my-chart 0.1.0 for environment prod-eu in 207.298833ms
rendered my-chart 0.1.0 for environment integration-gpu in 207.896ms
rendered my-chart 0.2.0 for environment staging-us in 210.70825ms
rendered my-chart 0.2.0 for environment qa in 210.695667ms
rendered platform in 210.776584ms

36
go.mod
View File

@@ -10,7 +10,7 @@ require (
connectrpc.com/grpcreflect v1.2.0
connectrpc.com/otelconnect v0.7.0
connectrpc.com/validate v0.1.0
cuelang.org/go v0.12.0
cuelang.org/go v0.11.1
entgo.io/ent v0.13.1
github.com/bufbuild/buf v1.35.1
github.com/choria-io/machine-room v0.0.0-20240417064836-c604da2f005e
@@ -26,17 +26,16 @@ require (
github.com/mattn/go-runewidth v0.0.15
github.com/mennanov/fieldmask-utils v1.1.2
github.com/olekukonko/tablewriter v0.0.5
github.com/patrickdappollonio/kubectl-slice v1.4.1
github.com/princjef/gomarkdoc v1.1.0
github.com/prometheus/client_golang v1.19.1
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a
github.com/rogpeppe/go-internal v1.13.1
github.com/sethvargo/go-retry v0.2.4
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
golang.org/x/net v0.34.0
golang.org/x/sync v0.10.0
golang.org/x/tools v0.29.0
golang.org/x/net v0.30.0
golang.org/x/sync v0.8.0
golang.org/x/tools v0.26.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v3 v3.0.1
@@ -57,7 +56,7 @@ require (
buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.34.2-20240610164129-660609bc46d3.2 // indirect
cel.dev/expr v0.15.0 // indirect
cloud.google.com/go/compute/metadata v0.3.0 // indirect
cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1 // indirect
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 // indirect
dario.cat/mergo v1.0.1 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/AlecAivazis/survey/v2 v2.3.7 // indirect
@@ -147,7 +146,7 @@ require (
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/emicklei/proto v1.13.4 // indirect
github.com/emicklei/proto v1.13.2 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/envoyproxy/go-control-plane v0.12.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
@@ -249,7 +248,6 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/miekg/dns v1.1.58 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
@@ -300,7 +298,7 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20240823084532-8e6b51fa9bef // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
@@ -326,7 +324,7 @@ require (
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/viper v1.19.0 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
@@ -348,7 +346,7 @@ require (
github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 // indirect
github.com/xlab/treeprint v1.2.0 // indirect
github.com/yashtewari/glob-intersection v0.2.0 // indirect
github.com/yuin/goldmark v1.7.8 // indirect
github.com/yuin/goldmark v1.7.4 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zclconf/go-cty v1.8.0 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
@@ -361,16 +359,16 @@ require (
go.uber.org/automaxprocs v1.5.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.32.0 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/oauth2 v0.25.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/term v0.25.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect
google.golang.org/grpc v1.65.0 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect

72
go.sum
View File

@@ -50,10 +50,10 @@ connectrpc.com/otelconnect v0.7.0 h1:ZH55ZZtcJOTKWWLy3qmL4Pam4RzRWBJFOqTPyAqCXkY
connectrpc.com/otelconnect v0.7.0/go.mod h1:Bt2ivBymHZHqxvo4HkJ0EwHuUzQN6k2l0oH+mp/8nwc=
connectrpc.com/validate v0.1.0 h1:r55jirxMK7HO/xZwVHj3w2XkVFarsUM77ZDy367NtH4=
connectrpc.com/validate v0.1.0/go.mod h1:GU47c9/x/gd+u9wRSPkrQOP46gx2rMN+Wo37EHgI3Ow=
cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1 h1:mRwydyTyhtRX2wXS3mqYWzR2qlv6KsmoKXmlz5vInjg=
cuelabs.dev/go/oci/ociregistry v0.0.0-20241125120445-2c00c104c6e1/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg=
cuelang.org/go v0.12.0 h1:q4W5I+RtDIA27rslQyyt6sWkXX0YS9qm43+U1/3e0kU=
cuelang.org/go v0.12.0/go.mod h1:B4+kjvGGQnbkz+GuAv1dq/R308gTkp0sO28FdMrJ2Kw=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 h1:R5wwEcbEZSBmeyg91MJZTxfd7WpBo2jPof3AYjRbxwY=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg=
cuelang.org/go v0.11.1 h1:pV+49MX1mmvDm8Qh3Za3M786cty8VKPWzQ1Ho4gZRP0=
cuelang.org/go v0.11.1/go.mod h1:PBY6XvPUswPPJ2inpvUozP9mebDVTXaeehQikhZPBz0=
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
@@ -336,8 +336,8 @@ github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcej
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/proto v1.13.4 h1:myn1fyf8t7tAqIzV91Tj9qXpvyXXGXk8OS2H6IBSc9g=
github.com/emicklei/proto v1.13.4/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY=
github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -737,8 +737,6 @@ github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 h1:NK3O7S5FRD/wj7ORQ5C3Mx1STpyEMuFe+/F0Lakd1Nk=
github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4/go.mod h1:FqD3ES5hx6zpzDainDaHgkTIqrPaI9uX4CVWqYZoQjY=
github.com/mennanov/fieldmask-utils v1.1.2 h1:f5hd3hYeWdl+q2thiKYyZZmqTqn90uayWG03bca9U+E=
github.com/mennanov/fieldmask-utils v1.1.2/go.mod h1:xRqd9Fjz/gFEDYCQw7pxGouxqLhSPrkOdx2yhEAXEls=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -833,8 +831,6 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/patrickdappollonio/kubectl-slice v1.4.1 h1:JtH3IhvbWpNmIoIaZrHNSA0KpffRsdxh5z5UxeUIMmo=
github.com/patrickdappollonio/kubectl-slice v1.4.1/go.mod h1:XPVl2GUsmGuSInYe+fk58BySbrZpZEwbF9rSoYSMgpc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
@@ -891,8 +887,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA=
github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
github.com/protocolbuffers/txtpbfmt v0.0.0-20240823084532-8e6b51fa9bef h1:ej+64jiny5VETZTqcc1GFVAPEtaSk6U1D0kKC2MS5Yc=
github.com/protocolbuffers/txtpbfmt v0.0.0-20240823084532-8e6b51fa9bef/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@@ -906,8 +902,8 @@ github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfm
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM=
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rubenv/sql-migrate v1.7.0 h1:HtQq1xyTN2ISmQDggnh0c9U3JlP8apWh8YO2jzlXpTI=
@@ -960,8 +956,8 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -1039,8 +1035,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
@@ -1105,8 +1101,8 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1144,8 +1140,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1187,16 +1183,16 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1209,8 +1205,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1280,8 +1276,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -1289,8 +1285,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1305,8 +1301,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1359,8 +1355,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1418,8 +1414,8 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20220531173845-685668d2de03/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To=
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ=
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro=
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc=
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=

View File

@@ -4,7 +4,6 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"github.com/holos-run/holos/internal/errors"
@@ -61,17 +60,6 @@ func (a *MapStore) Get(path string) (data []byte, ok bool) {
func (a *MapStore) Save(dir, path string) error {
fullPath := filepath.Join(dir, path)
msg := fmt.Sprintf("could not save %s", fullPath)
// TODO(jjm): replace slash hack with artifact directory support maybe
if strings.HasSuffix(path, "/") {
for _, key := range a.Keys() {
if strings.HasPrefix(key, path) {
if err := a.Save(dir, key); err != nil {
return errors.Wrap(err)
}
}
}
return nil
}
data, ok := a.Get(path)
if !ok {
return errors.Format("%s: missing %s", msg, path)

View File

@@ -5,7 +5,6 @@ import (
"context"
"encoding/json"
"fmt"
"io/fs"
"log/slog"
"os"
"path/filepath"
@@ -367,10 +366,6 @@ func (t transformersTask) run(ctx context.Context) error {
if err := t.opts.Store.Set(string(transformer.Output), data); err != nil {
return errors.Format("%s: %w", msg, err)
}
case "Slice":
if err := slice(ctx, transformer, t.taskParams); err != nil {
return errors.Wrap(err)
}
default:
return errors.Format("%s: unsupported kind %s", msg, transformer.Kind)
}
@@ -656,80 +651,6 @@ func kustomize(ctx context.Context, t core.Transformer, p taskParams) error {
return nil
}
func slice(ctx context.Context, t core.Transformer, p taskParams) error {
log := logger.FromContext(ctx)
msg := fmt.Sprintf(
"could not transform %s for %s path %s",
t.Output,
p.buildPlanName,
p.opts.Path,
)
// TODO(jjm): replace slash hack with artifact directory support maybe
//
// NOTE: We do not actually store an artifact with a trailing slash into the
// artifact map, this could trigger an infinite recursive loop with the way
// this hack is implemented in the artifact Save() method.
if !strings.HasSuffix(string(t.Output), "/") {
return errors.Format("%s: slice output must end in /", msg)
}
tempDir, err := os.MkdirTemp("", "holos.slice")
if err != nil {
return errors.Wrap(err)
}
defer util.Remove(ctx, tempDir)
// Write the inputs
for _, input := range t.Inputs {
path := string(input)
if err := p.opts.Store.Save(tempDir, path); err != nil {
return errors.Format("%s: %w", msg, err)
}
}
// TODO(jjm): useless?
var tempDirSlice = filepath.Join(tempDir, "slice") // TODO(jjm): hack for expedience
// Execute kubectl-slice for each input file, writing to one output directory.
for _, input := range t.Inputs {
in := filepath.Join(tempDir, string(input))
_, err := util.RunCmdW(
ctx, p.opts.Stderr,
"kubectl-slice", "-f", in, "-o", tempDirSlice)
if err != nil {
return errors.Format("%s: could not run kubectl-slice: %w", msg, err)
}
}
// Store each file located in the output directory as an artifact.
// TODO(jjm): model a directory entry in the artifact map.
err = filepath.WalkDir(tempDirSlice, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if !d.IsDir() {
// artifact key, relative to the output field from the transformer
artifact := filepath.Join(string(t.Output), filepath.Base(path))
log.DebugContext(ctx, fmt.Sprintf("storing: %s to %s", path, artifact), "label", "slice", "artifact", artifact)
// Read the file
data, err := os.ReadFile(path)
if err != nil {
return errors.Format("%s: %w", msg, err)
}
// Store into the artifact map
if err := p.opts.Store.Set(artifact, data); err != nil {
return errors.Format("%s: %w", msg, err)
}
}
return nil
})
if err != nil {
return errors.Format("%s: could not walk slice output dir: %w", msg, err)
}
return nil
}
func validate(ctx context.Context, validator core.Validator, p taskParams) error {
store := p.opts.Store
tempDir, err := os.MkdirTemp("", "holos.validate")

View File

@@ -18,11 +18,10 @@ import (
)
func TestMain(m *testing.M) {
holosMain := cmd.MakeMain()
testscript.Main(m, map[string]func(){
"holos": func() { os.Exit(holosMain()) },
"cue": func() { os.Exit(cue.Main()) },
})
os.Exit(testscript.RunMain(m, map[string]func() int{
"holos": cmd.MakeMain(),
"cue": cue.Main,
}))
}
func RunOneScript(t *testing.T, dir string, file string) {

File diff suppressed because one or more lines are too long

View File

@@ -211,13 +211,11 @@ package core
// 1. [Kustomize] - Patch and transform the output from prior generators or
// transformers. See [Introduction to Kustomize].
// 2. [Join] - Concatenate multiple prior outputs into one output.
// 3. [Slice] - Slice an artifact into multiple artifacts using [kubectl-slice].
//
// [Introduction to Kustomize]: https://kubectl.docs.kubernetes.io/guides/config_management/introduction/
// [kubectl-slice]: https://github.com/patrickdappollonio/kubectl-slice
#Transformer: {
// Kind represents the kind of transformer. Must be Kustomize, or Join.
kind: string & ("Kustomize" | "Join" | "Slice") @go(Kind)
kind: string & ("Kustomize" | "Join") @go(Kind)
// Inputs represents the files to transform. The Output of prior Generators
// and Transformers.
@@ -284,49 +282,12 @@ package core
command?: #Command @go(Command)
}
// Command represents a generic command for use as a Generator, Transformer, or
// Validator. Holos uses the Go template engine to render the Args field using
// data provided by the TaskData field. For example to fill in the fully
// qualified temporary directory used to provide inputs to the task.
// Command represents a command vetting one or more artifacts. Holos appends
// fully qualified input file paths to the end of the args list, then executes
// the command. Inputs are written into a temporary directory prior to
// executing the command and removed afterwards.
#Command: {
// DisplayName represents a friendly display name for the command.
displayName?: string @go(DisplayName)
// Args represents the complete command argument vector as a go template.
args?: [...string] @go(Args,[]string)
// OutputRef references the source of the output data.
outputRef?: #OutputRef @go(OutputRef)
// TaskData populated by Holos for template rendering.
taskData?: #TaskData @go(TaskData)
}
// TaskData represents data values associated with a pipeline task necessary to
// execute the task. For example, the randomly generated temporary directory
// used to read and write artifact files when executing user defined task
// commands. Values of this struct are intended for the Go template engine.
//
// Holos populates this struct as needed. Holos may treat user provided values
// as an error condition.
#TaskData: {
// TempDir represents the temp directory holos manages for task artifacts.
tempDir?: string @go(TempDir)
}
// OutputRef represents a reference to the data source used as the output of a
// task. For example, a Generator output may be sourced from standard output or
// a file path.
#OutputRef: {
// Kind represents the kind of output produced.
kind?: string & (string | *"Pipe" | "Path") @go(Kind)
// Pipe represents stdout or stderr. Ignored unless kind is Pipe.
pipe?: string & (string | *"stdout" | "stderr") @go(Pipe)
// Path represents an artifact path relative to the task temp directory.
// Ignored unless kind is Path.
path?: string @go(Path)
}
// InternalLabel is an arbitrary unique identifier internal to holos itself.

View File

@@ -1,3 +1,7 @@
#! /bin/bash
set -xeuo pipefail
# Necessary to install timoni for testscript execution
make go-deps
go test -coverprofile=coverage.out ./...

View File

@@ -4,5 +4,5 @@ deps:
- remote: buf.build
owner: bufbuild
repository: protovalidate
commit: d39267d9df8f4053bbac6b956a23169f
digest: shake256:bfb2a6f67179429b8fec30ddd03fc42538cc4d2d207e3c89e325de75fd3716335be06114666d2dd0a099eaf37cbc685c5d1b1a347537af74017e780280e64a9c
commit: a3320276596649bcad929ac829d451f4
digest: shake256:a6e5f64fd3fd47e3e8568e9753f59a1566f56c11ec055baf65463d3bca3499f6f16c2d6f5628fa41cfd0f4fa7e72abe65be4efd77d269749492472ed4cc4070d

View File

@@ -6,15 +6,15 @@ package tools
// https://go.dev/wiki/Modules
import (
_ "sigs.k8s.io/kustomize/kustomize/v5"
_ "connectrpc.com/connect/cmd/protoc-gen-connect-go"
_ "cuelang.org/go/cmd/cue"
_ "github.com/bufbuild/buf/cmd/buf"
_ "github.com/fullstorydev/grpcurl/cmd/grpcurl"
_ "github.com/google/ko"
_ "github.com/patrickdappollonio/kubectl-slice"
_ "github.com/princjef/gomarkdoc/cmd/gomarkdoc"
_ "golang.org/x/tools/cmd/godoc"
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
_ "honnef.co/go/tools/cmd/staticcheck"
_ "sigs.k8s.io/kustomize/kustomize/v5"
- "github.com/stefanprodan/timoni/cmd/timoni"
)

View File

@@ -1 +1 @@
104
103

View File

@@ -1 +1 @@
1
0