Compare commits

..

2 Commits

Author SHA1 Message Date
Jeff McCune
a533d4e7d9 testutil: update v1alpha6 platform1 fixture to use struct for components 2025-05-22 17:26:40 -07:00
Jeff McCune
f6c06df979 v1alpha6: define top level platform schema (#435) 2025-05-22 15:29:41 -07:00
73 changed files with 383 additions and 798 deletions

View File

@@ -1,13 +1,18 @@
{
"permissions": {
"allow": [
"Bash(cd:*)",
"Bash(make:*)",
"Bash(holos:*)",
"Bash(cue:*)",
"Bash(grep:*)",
"Bash(cd:*)",
"Bash(mkdir:*)",
"Bash(find:*)",
"Bash(echo:*)",
"Bash(head:*)",
"Bash(git commit:*)",
"Bash(git add:*)",
"Bash(make:*)"
"Bash(git add:*)"
],
"deny": []
}
}
}

View File

@@ -308,6 +308,7 @@
"sysfs",
"systemconnect",
"tablewriter",
"taskset",
"templatable",
"testscript",
"testutil",

View File

@@ -113,3 +113,4 @@ Component: #Helm & {
- Test fixtures: `/internal/testutil/fixtures/`
- Core schemas: `/api/core/` (Abstraction over low level data pipeline tasks)
- Author schemas: `/api/author/` (User facing abstractions over core Schemas)
- Task planning documents are located in the `/tasks/` directory

View File

@@ -1,6 +1,6 @@
FROM registry.k8s.io/kubectl:v1.33.4 AS kubectl
FROM registry.k8s.io/kubectl:v1.31.0 AS kubectl
# https://github.com/GoogleContainerTools/distroless
FROM golang:1.24 AS build
FROM golang:1.23 AS build
WORKDIR /go/src/app
COPY . .
@@ -18,8 +18,8 @@ RUN curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/s
COPY --from=kubectl /bin/kubectl /usr/local/bin/
# Use debian slim instead of distroless to get package management.
FROM public.ecr.aws/docker/library/debian:13-slim AS final
# distroless
FROM gcr.io/distroless/static-debian12 AS final
COPY --from=build \
/go/bin/holos \
/go/bin/kustomize \
@@ -27,12 +27,5 @@ COPY --from=build \
/usr/local/bin/helm \
/bin/
# Extra packages
# git - https://github.com/holos-run/holos/issues/440
RUN apt update && \
apt install -y --no-install-recommends git ca-certificates && \
apt clean && \
rm -rf /var/lib/apt/lists/*
# Usage: docker run -v $(pwd):/app --workdir /app --rm -it quay.io/holos-run/holos holos render platform
CMD ["/bin/holos"]

View File

@@ -136,7 +136,6 @@ unity: ## https://cuelabs.dev/unity/
.PHONY: update-docs
update-docs: ## Update doc examples
HOLOS_UPDATE_SCRIPTS=1 go test -v ./doc/md/...
HOLOS_UPDATE_SCRIPTS=1 go test -v ./doc/website/versioned_docs/...
.PHONY: help
help: ## Display this help menu.

View File

@@ -274,8 +274,8 @@ type Chart struct {
// repository. Holos gets the username and password from the environment
// variables represented by the Auth field.
type Repository struct {
Name string `json:"name,omitempty" yaml:"name,omitempty"`
URL string `json:"url,omitempty" yaml:"url,omitempty"`
Name string `json:"name" yaml:"name"`
URL string `json:"url" yaml:"url"`
Auth Auth `json:"auth,omitempty" yaml:"auth,omitempty"`
}
@@ -382,6 +382,10 @@ type Command struct {
IsStdoutOutput bool `json:"isStdoutOutput,omitempty" yaml:"isStdoutOutput,omitempty"`
}
// NameLabel indicates a field name matching the name of the value. Usually the
// name or metadata.name field of the struct value.
type NameLabel string
// InternalLabel is an arbitrary unique identifier internal to holos itself.
// The holos cli is expected to never write a InternalLabel value to rendered
// output files, therefore use a InternalLabel when the identifier must be
@@ -426,7 +430,7 @@ type Platform struct {
// PlatformSpec represents the platform specification.
type PlatformSpec struct {
// Components represents a collection of holos components to manage.
Components []Component `json:"components" yaml:"components"`
Components map[NameLabel]Component `json:"components" yaml:"components" cue:"{[NAME=string]: name: NAME}"`
}
// Component represents the complete context necessary to produce a [BuildPlan]

View File

@@ -37,6 +37,7 @@ Package core contains schemas for a [Platform](<#Platform>) and [BuildPlan](<#Bu
- [type Kustomization](<#Kustomization>)
- [type Kustomize](<#Kustomize>)
- [type Metadata](<#Metadata>)
- [type NameLabel](<#NameLabel>)
- [type Platform](<#Platform>)
- [type PlatformSpec](<#PlatformSpec>)
- [type Repository](<#Repository>)
@@ -478,6 +479,15 @@ type Metadata struct {
}
```
<a name="NameLabel"></a>
## type NameLabel {#NameLabel}
NameLabel indicates a field name matching the name of the value. Usually the name or metadata.name field of the struct value.
```go
type NameLabel string
```
<a name="Platform"></a>
## type Platform {#Platform}
@@ -511,7 +521,7 @@ PlatformSpec represents the platform specification.
```go
type PlatformSpec struct {
// Components represents a collection of holos components to manage.
Components []Component `json:"components" yaml:"components"`
Components map[NameLabel]Component `json:"components" yaml:"components" cue:"{[NAME=string]: name: NAME}"`
}
```

View File

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

View File

@@ -1 +1 @@
0.105.1
0.104.1

View File

@@ -1,2 +1,3 @@
rendered podinfo in 169.504ms
rendered platform in 169.609583ms
cached podinfo 6.6.2
rendered podinfo in 1.938665041s
rendered platform in 1.938759417s

View File

@@ -9,8 +9,9 @@
|-- platform
| |-- platform.gen.cue
| `-- podinfo.cue
|-- platform.metadata.json
|-- resources.cue
|-- schema.cue
`-- tags.cue
8 directories, 6 files
8 directories, 7 files

View File

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

View File

@@ -1 +1 @@
0.105.1
0.104.1

View File

@@ -1,3 +1,3 @@
[main 67f5363] 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 bef876c] integrate blackbox and prometheus together
3 files changed, 1359 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 9dd00f3] import values
2 files changed, 1826 insertions(+)
[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 112.795875ms
rendered prometheus in 144.441042ms
rendered platform in 144.505625ms
rendered blackbox in 365.936792ms
rendered prometheus in 371.855875ms
rendered platform in 372.109916ms

View File

@@ -1,4 +1,4 @@
[main c523ef0] 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 877.548833ms
rendered prometheus in 882.902333ms
rendered platform in 883.561541ms
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 3aa63f4] 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.106.0
0.104.1

View File

@@ -1 +1 @@
0.105.1
0.104.1

View File

@@ -27,9 +27,9 @@ spec:
- includeSelectors: false
pairs:
app.kubernetes.io/name: httpbin
patches: []
images:
- name: mccutchen/go-httpbin
patches: []
resources:
- resources.gen.yaml
- httpbin.yaml

View File

@@ -1,4 +1,4 @@
[main 2fc33ea] add httpbin
[main 823e136] 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 6d5bbc3] annotate httpbin for prometheus probes
[main 96f5f45] 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 82.637042ms
rendered platform in 82.702458ms
rendered httpbin in 112.916375ms
rendered platform in 112.990333ms

View File

@@ -1,2 +1,2 @@
rendered httpbin in 80.916166ms
rendered platform in 80.992958ms
rendered httpbin in 111.183042ms
rendered platform in 111.265792ms

View File

@@ -1,391 +0,0 @@
# v1alpha6 Build Plan Executor
This document outlines the plan to finalize the v1alpha6 build plan executor for `holos render platform`. The goal is to use the compiler pool to produce a complete set of BuildPlans, then combine them into a topologically sorted DAG for efficient concurrent execution.
## Related Issues
- [#435 v1alpha6 Design](https://github.com/holos-run/holos/issues/435)
- [#389 Concurrent Component Compiler](https://github.com/holos-run/holos/issues/389)
- [#452 Fix concurrent helm invocations](https://github.com/holos-run/holos/issues/452)
## Current State Analysis
### What's Implemented
1. **Compiler Pool** (`internal/compile/compile.go`):
- `compile.Compile()` function spawns a pool of `holos compile` subprocesses
- Producer-consumer pattern with task queue using channels
- Each worker maintains a persistent subprocess with stdin/stdout pipes
- JSON streaming protocol for BuildPlanRequest/BuildPlanResponse
2. **`holos show buildplans`** (`internal/cli/show.go`):
- Uses `compile.Compile()` to produce BuildPlans concurrently
- Displays BuildPlans without executing them
- Validates the compiler pool works correctly
3. **`holos render platform`** (`internal/cli/render/render.go`):
- Spawns individual `holos render component` subprocesses
- Each subprocess independently compiles AND executes its BuildPlan
- Does NOT use the compiler pool
4. **BuildPlan Execution** (`internal/component/v1alpha6/v1alpha6.go`):
- `BuildPlan.Build()` processes artifacts concurrently
- Within each artifact: generators run concurrently, transformers sequentially, validators concurrently
- Worker pool for task execution within a single BuildPlan
### What's Missing
1. **Compiler Pool in `holos render platform`**: The render command still spawns individual subprocesses instead of using the compiler pool.
2. **Unified DAG Execution**: BuildPlans execute independently. No cross-BuildPlan task deduplication or optimization.
3. **Helm Chart Deduplication**: Each component fetches Helm charts independently. Multiple components using the same chart/version fetch redundantly.
4. **Topological Sort**: No dependency analysis or task ordering across BuildPlans.
## Architecture Design
### Phase 1: Compile All BuildPlans
Use the existing compiler pool to compile all BuildPlans before executing any.
```
holos render platform
├─> Platform.Build()
│ └─> Collect all Components
├─> compile.Compile(ctx, concurrency, requests)
│ ├─> Producer: sends BuildPlanRequest per component
│ ├─> N Workers: each runs holos compile subprocess
│ └─> Returns: []BuildPlanResponse with all BuildPlans
└─> Phase 2: Execute BuildPlans
```
### Phase 2: Build Unified Task DAG
Transform all BuildPlans into a single DAG of executable tasks.
```go
// Task represents a single executable unit of work
type Task struct {
ID string // Unique identifier
Kind string // helm-fetch, generator, transformer, validator, write-artifact
BuildPlan string // Which BuildPlan this task belongs to
Artifact string // Which Artifact within the BuildPlan
Inputs []string // Task IDs this depends on
Outputs []string // Output keys this produces
Run func(ctx) error // Execution function
}
// TaskDAG represents the complete dependency graph
type TaskDAG struct {
Tasks map[string]*Task // All tasks by ID
Adjacency map[string][]string // task -> tasks that depend on it
InDegree map[string]int // task -> number of dependencies
}
```
#### Task Types
1. **helm-fetch**: Download a Helm chart to local cache
- Key: `helm-fetch:{repo}:{chart}:{version}`
- Deduplicated across all BuildPlans
2. **generator**: Execute a Generator (Resources, Helm template, File, Command)
- Key: `{buildplan}:{artifact}:gen:{output}`
- helm-fetch tasks depend on generators that use Helm
3. **transformer**: Execute a Transformer (Kustomize, Join, Command)
- Key: `{buildplan}:{artifact}:transform:{output}`
- Sequential within artifact, depends on generators or prior transformers
4. **validator**: Execute a Validator (Command)
- Key: `{buildplan}:{artifact}:validate:{idx}`
- Depends on final transformer output
5. **write-artifact**: Write artifact to filesystem
- Key: `{buildplan}:{artifact}:write`
- Depends on validators completing
### Phase 3: Topological Sort and Execution
Execute tasks using Kahn's algorithm for topological ordering with concurrent execution.
```go
func ExecuteDAG(ctx context.Context, dag *TaskDAG, workers int) error {
g, ctx := errgroup.WithContext(ctx)
ready := make(chan *Task, len(dag.Tasks))
completed := make(chan string, len(dag.Tasks))
// Initialize with tasks that have no dependencies
for id, task := range dag.Tasks {
if dag.InDegree[id] == 0 {
ready <- task
}
}
// Coordinator goroutine
g.Go(func() error {
remaining := len(dag.Tasks)
for remaining > 0 {
select {
case <-ctx.Done():
return ctx.Err()
case id := <-completed:
remaining--
// Decrement in-degree of dependent tasks
for _, depID := range dag.Adjacency[id] {
dag.InDegree[depID]--
if dag.InDegree[depID] == 0 {
ready <- dag.Tasks[depID]
}
}
}
}
close(ready)
return nil
})
// Worker goroutines
for i := 0; i < workers; i++ {
g.Go(func() error {
for task := range ready {
if err := task.Run(ctx); err != nil {
return err
}
completed <- task.ID
}
return nil
})
}
return g.Wait()
}
```
### Helm Chart Deduplication
Extract all Helm chart references, deduplicate, and create fetch tasks.
```go
type ChartKey struct {
Repository string
Name string
Version string
}
func ExtractHelmCharts(plans []BuildPlan) map[ChartKey][]TaskRef {
charts := make(map[ChartKey][]TaskRef)
for _, plan := range plans {
for _, artifact := range plan.Spec.Artifacts {
for _, gen := range artifact.Generators {
if gen.Kind == "Helm" {
key := ChartKey{
Repository: gen.Helm.Chart.Repository.URL,
Name: gen.Helm.Chart.Name,
Version: gen.Helm.Chart.Version,
}
charts[key] = append(charts[key], TaskRef{
BuildPlan: plan.Metadata.Name,
Artifact: artifact.Artifact,
Generator: gen.Output,
})
}
}
}
}
return charts
}
```
## Implementation Plan
### Step 1: Wire Compiler Pool to Render Platform
Modify `internal/cli/render/render.go` to:
1. Collect all components from the Platform
2. Build `[]BuildPlanRequest` for each component
3. Call `compile.Compile()` to get all BuildPlans
4. Execute BuildPlans (initially using existing per-BuildPlan execution)
**Files to modify:**
- `internal/cli/render/render.go`
**Validation:**
- `holos render platform` produces identical output to before
- Compilation is faster due to concurrent pool
### Step 2: Create Task DAG Package
Create new package `internal/dag/` with:
1. Task and TaskDAG types
2. DAG construction from BuildPlans
3. Topological sort execution
4. Shared artifact store across BuildPlans
**Files to create:**
- `internal/dag/dag.go` - Core types and construction
- `internal/dag/execute.go` - DAG execution with worker pool
- `internal/dag/dag_test.go` - Unit tests
### Step 3: Implement Helm Chart Deduplication
1. Extract all Helm chart references before execution
2. Create single fetch task per unique chart
3. Helm generator tasks depend on corresponding fetch task
4. Use file system locking for concurrent safety
**Files to modify:**
- `internal/dag/dag.go` - Add chart extraction and fetch task creation
- `internal/component/v1alpha6/v1alpha6.go` - Refactor helm fetch logic
### Step 4: Integrate DAG Execution into Render Platform
Replace per-BuildPlan execution with unified DAG execution.
**Files to modify:**
- `internal/cli/render/render.go`
- `internal/platform/platform.go`
### Step 5: Update Build Plan Execution to Use Shared Store
Modify BuildPlan execution to:
1. Accept a shared artifact store
2. Support external Helm chart cache
3. Report task completion to coordinator
**Files to modify:**
- `internal/component/v1alpha6/v1alpha6.go`
- `internal/artifact/artifact.go`
## Testing Strategy
### Unit Tests
1. DAG construction from BuildPlans
2. Topological sort correctness
3. Cycle detection
4. Helm chart deduplication
### Integration Tests
1. Render platform with multiple components sharing Helm charts
2. Verify deduplication reduces Helm fetches
3. Verify output matches non-DAG execution
4. Use `holos compare buildplans` to validate equivalence
### Performance Tests
1. Measure compilation time improvement
2. Measure execution time with chart deduplication
3. Benchmark with varying concurrency levels
## Migration Path
1. **v0.106.0**: Wire compiler pool to render platform (Step 1)
2. **v0.107.0**: Introduce DAG package, optional via flag (Steps 2-3)
3. **v0.108.0**: Make DAG execution default, deprecate old path (Steps 4-5)
## Future Considerations
### TaskSet Schema (v1alpha6 Design Goal)
The DAG implementation provides a foundation for the TaskSet schema:
```cue
TaskSet: {
tasks: [string]: Task
}
Task: {
kind: "HelmFetch" | "Generator" | "Transformer" | "Validator" | "Write"
inputs: [...string] // Task IDs
outputs: [...string] // Output keys
// Kind-specific fields
}
```
### Cross-Component Dependencies
Future enhancement to support:
```cue
Component: {
dependsOn: [...string] // Other component names
}
```
### Caching
Consider caching:
1. Compiled BuildPlans (CUE evaluation cache)
2. Generator outputs (content-addressed)
3. Transformer outputs (input-hash based)
## Appendix: Current Code Flow
### `holos show buildplans` (Uses Compiler Pool)
```
show.go:84 showBuildPlans.Run()
├─> p.Select() - Get components matching selectors
├─> Build []BuildPlanRequest from components
├─> compile.Compile(ctx, concurrency, reqs)
│ compile.go:155
│ ├─> Producer goroutine sends requests to channel
│ ├─> N Consumer goroutines run holos compile
│ └─> Returns []BuildPlanResponse
└─> Encode and output BuildPlans
```
### `holos render platform` (Current: Per-Component Subprocess)
```
render.go:49 renderPlatform.Run()
├─> platform.Platform.Build()
│ platform.go
│ └─> For each component (concurrent, limited):
│ └─> PerComponentFunc()
└─> PerComponentFunc() spawns subprocess:
holos render component [path]
└─> component.go
├─> Compile CUE to BuildPlan
└─> BuildPlan.Build() - Execute artifact pipeline
```
### Proposed: `holos render platform` (With Compiler Pool + DAG)
```
render.go renderPlatform.Run()
├─> Collect all components from Platform
├─> compile.Compile(ctx, concurrency, reqs)
│ └─> Returns []BuildPlanResponse
├─> dag.Build(buildPlans)
│ ├─> Extract and deduplicate Helm charts
│ ├─> Create fetch tasks
│ ├─> Create generator tasks (depend on fetch)
│ ├─> Create transformer tasks (depend on generators)
│ ├─> Create validator tasks (depend on transformers)
│ └─> Create write tasks (depend on validators)
└─> dag.Execute(ctx, workers)
├─> Topological sort execution
├─> Fixed worker pool with errgroup
└─> Write artifacts to filesystem
```

View File

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

View File

@@ -1,2 +1,3 @@
rendered podinfo in 290.020792ms
rendered platform in 290.155667ms
cached podinfo 6.6.2
rendered podinfo in 1.938665041s
rendered platform in 1.938759417s

View File

@@ -9,8 +9,9 @@
|-- platform
| |-- platform.gen.cue
| `-- podinfo.cue
|-- platform.metadata.json
|-- resources.cue
|-- schema.cue
`-- tags.cue
8 directories, 6 files
8 directories, 7 files

View File

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

View File

@@ -1,3 +1,3 @@
[main fd30368] 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 e9a22bd] integrate blackbox and prometheus together
3 files changed, 1359 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 dbaf504] import values
2 files changed, 1826 insertions(+)
[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 120.236ms
rendered prometheus in 147.333125ms
rendered platform in 147.385208ms
rendered blackbox in 365.936792ms
rendered prometheus in 371.855875ms
rendered platform in 372.109916ms

View File

@@ -1,4 +1,4 @@
[main c523ef0] 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.023009333s
rendered prometheus in 1.1285565s
rendered platform in 1.128658458s
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 ed5ce22] 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.106.0
0.104.1

View File

@@ -27,9 +27,9 @@ spec:
- includeSelectors: false
pairs:
app.kubernetes.io/name: httpbin
patches: []
images:
- name: mccutchen/go-httpbin
patches: []
resources:
- resources.gen.yaml
- httpbin.yaml

View File

@@ -1,4 +1,4 @@
[main bdb182b] add httpbin
[main 823e136] 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 d557fa2] annotate httpbin for prometheus probes
[main 96f5f45] 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 79.923ms
rendered platform in 79.99475ms
rendered httpbin in 112.916375ms
rendered platform in 112.990333ms

View File

@@ -1,2 +1,2 @@
rendered httpbin in 81.503708ms
rendered platform in 81.573166ms
rendered httpbin in 111.183042ms
rendered platform in 111.265792ms

41
go.mod
View File

@@ -1,29 +1,29 @@
module github.com/holos-run/holos
go 1.24.0
go 1.23.0
toolchain go1.23.6
require (
cuelang.org/go v0.15.1
cuelang.org/go v0.13.0-rc.1
github.com/google/go-cmp v0.7.0
github.com/mattn/go-isatty v0.0.20
github.com/mattn/go-runewidth v0.0.15
github.com/olekukonko/tablewriter v0.0.5
github.com/patrickdappollonio/kubectl-slice v1.4.2
github.com/princjef/gomarkdoc v1.1.0
github.com/rogpeppe/go-internal v1.14.1
github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.19.0
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.6
github.com/stretchr/testify v1.10.0
golang.org/x/sync v0.17.0
golang.org/x/tools v0.38.0
golang.org/x/sync v0.13.0
golang.org/x/tools v0.32.0
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.16.3
sigs.k8s.io/kustomize/kustomize/v5 v5.5.0
)
require (
cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084 // indirect
cuelabs.dev/go/oci/ociregistry v0.0.0-20250304105642-27e071d2c9b1 // indirect
dario.cat/mergo v1.0.1 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
@@ -58,7 +58,7 @@ require (
github.com/docker/go-connections v0.5.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/emicklei/proto v1.14.2 // indirect
github.com/emicklei/proto v1.14.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch v5.9.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
@@ -110,7 +110,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/mitchellh/copystructure v1.2.0 // indirect
@@ -141,7 +140,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-20251016062345-16587c79cd91 // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20250129171521-feedd8250727 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rubenv/sql-migrate v1.7.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
@@ -154,8 +153,9 @@ 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.18.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tetratelabs/wazero v1.9.0 // indirect
github.com/tetratelabs/wazero v1.6.0 // indirect
github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
@@ -168,15 +168,14 @@ require (
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
golang.org/x/mod v0.29.0 // indirect
golang.org/x/net v0.46.0 // indirect
golang.org/x/oauth2 v0.32.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/term v0.36.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/oauth2 v0.29.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/term v0.31.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/grpc v1.65.0 // indirect

75
go.sum
View File

@@ -1,7 +1,7 @@
cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084 h1:4k1yAtPvZJZQTu8DRY8muBo0LHv6TqtrE0AO5n6IPYs=
cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084/go.mod h1:4WWeZNxUO1vRoZWAHIG0KZOd6dA25ypyWuwD3ti0Tdc=
cuelang.org/go v0.15.1 h1:MRnjc/KJE+K42rnJ3a+425f1jqXeOOgq9SK4tYRTtWw=
cuelang.org/go v0.15.1/go.mod h1:NYw6n4akZcTjA7QQwJ1/gqWrrhsN4aZwhcAL0jv9rZE=
cuelabs.dev/go/oci/ociregistry v0.0.0-20250304105642-27e071d2c9b1 h1:Dmbd5Q+ENb2C6carvwrMsrOUwJ9X9qfL5JdW32gYAHo=
cuelabs.dev/go/oci/ociregistry v0.0.0-20250304105642-27e071d2c9b1/go.mod h1:dqrnoZx62xbOZr11giMPrWbhlaV8euHwciXZEy3baT8=
cuelang.org/go v0.13.0-rc.1 h1:0y3LZKA5LpJehVMHTJhjR7jQxBdYZ5fg05htMaKHaJg=
cuelang.org/go v0.13.0-rc.1/go.mod h1:kA/8D9/d32IBp2lISWo90BEJhLyS9tqBcvqw2QAEhEg=
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
@@ -115,8 +115,8 @@ github.com/elazarl/goproxy v1.2.1 h1:njjgvO6cRG9rIqN2ebkqy6cQz2Njkx7Fsfv/zIZqgug
github.com/elazarl/goproxy v1.2.1/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
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.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I=
github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emicklei/proto v1.14.0 h1:WYxC0OrBuuC+FUCTZvb8+fzEHdZMwLEF+OnVfZA3LXU=
github.com/emicklei/proto v1.14.0/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/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
@@ -308,8 +308,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/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
@@ -366,8 +364,6 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/patrickdappollonio/kubectl-slice v1.4.2 h1:U1Jrma4BRK9D1Mbly8oP6uA06/gmOif6KjVQFrPUBzI=
github.com/patrickdappollonio/kubectl-slice v1.4.2/go.mod h1:gt3IidcTPeCcazqcMuXF51VWU5mGsQv6YlNpXxQvPsE=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
@@ -408,8 +404,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-20251016062345-16587c79cd91 h1:s1LvMaU6mVwoFtbxv/rCZKE7/fwDmDY684FfUe4c1Io=
github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY=
github.com/protocolbuffers/txtpbfmt v0.0.0-20250129171521-feedd8250727 h1:A8EM8fVuYc0qbVMw9D6EiKdKTIm1SmLvAWcCc2mipGY=
github.com/protocolbuffers/txtpbfmt v0.0.0-20250129171521-feedd8250727/go.mod h1:VmWrOlMnBZNtToCWzRlZlIXcJqjo0hS5dwQbRD62gL8=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
@@ -441,13 +437,12 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/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/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
@@ -461,8 +456,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
github.com/tetratelabs/wazero v1.6.0 h1:z0H1iikCdP8t+q341xqepY4EWvHEw8Es7tlqiVzlP3g=
github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg=
github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
@@ -500,21 +495,19 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -524,18 +517,18 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY=
golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
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=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
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=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -565,16 +558,16 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -582,8 +575,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
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=

View File

@@ -17,7 +17,6 @@ import (
"github.com/holos-run/holos/internal/cli/command"
"github.com/holos-run/holos/internal/cli/render"
"github.com/holos-run/holos/internal/cli/slice"
"github.com/holos-run/holos/internal/cli/txtar"
cueCmd "cuelang.org/go/cmd/cue/cmd"
@@ -83,9 +82,6 @@ func New(cfg *holos.Config) *cobra.Command {
// Compile
rootCmd.AddCommand(NewCompileCmd())
// Slice - https://github.com/patrickdappollonio/kubectl-slice
rootCmd.AddCommand(slice.NewKubectlSliceCmd())
return rootCmd
}

View File

@@ -66,7 +66,7 @@ func TestShowAlpha6(t *testing.T) {
t.Run("BuildPlans", func(t *testing.T) {
t.Run("EmptyPlatform", func(t *testing.T) {
platformDir := filepath.Join(tempDir, "platform")
platformDir := filepath.Join(tempDir, "fixtures", "v1alpha6", "empty-platform")
h := newHarness()
err := h.Run(ctx, "buildplans", platformDir)
require.NoError(t, err)

View File

@@ -1,22 +0,0 @@
// MIT License
// Copyright (c) 2021 Patrick D'appollonio
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package slice

View File

@@ -1,212 +0,0 @@
package slice
import (
"bytes"
"fmt"
"os"
"strings"
"github.com/patrickdappollonio/kubectl-slice/slice"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
var version = "development"
const (
helpShort = "kubectl-slice allows you to split a YAML into multiple subfiles using a pattern."
helpLong = `kubectl-slice allows you to split a YAML into multiple subfiles using a pattern.
For documentation, available functions, and more, visit: https://github.com/patrickdappollonio/kubectl-slice.`
)
var examples = []string{
"kubectl-slice -f foo.yaml -o ./ --include-kind Pod,Namespace",
"kubectl-slice -f foo.yaml -o ./ --exclude-kind Pod",
"kubectl-slice -f foo.yaml -o ./ --exclude-name *-svc",
"kubectl-slice -f foo.yaml --exclude-name *-svc --stdout",
"kubectl-slice -f foo.yaml --include Pod/* --stdout",
"kubectl-slice -f foo.yaml --exclude deployment/kube* --stdout",
"kubectl-slice -d ./ --recurse -o ./ --include-kind Pod,Namespace",
"kubectl-slice -d ./ --recurse --stdout --include Pod/*",
"kubectl-slice --config config.yaml",
}
func generateExamples([]string) string {
var s bytes.Buffer
for pos, v := range examples {
s.WriteString(fmt.Sprintf(" %s", v))
if pos != len(examples)-1 {
s.WriteString("\n")
}
}
return s.String()
}
func NewKubectlSliceCmd() *cobra.Command {
opts := slice.Options{}
var configFile string
rootCommand := &cobra.Command{
Use: "kubectl-slice",
Short: helpShort,
Long: helpLong,
Version: version,
SilenceUsage: true,
SilenceErrors: true,
Example: generateExamples(examples),
PreRunE: func(cmd *cobra.Command, args []string) error {
return bindCobraAndViper(cmd, configFile)
},
RunE: func(cmd *cobra.Command, args []string) error {
// Bind to the appropriate stdout/stderr
opts.Stdout = cmd.OutOrStdout()
opts.Stderr = cmd.ErrOrStderr()
// If no input file has been provided or it's "-", then
// point the app to stdin
if (opts.InputFile == "" || opts.InputFile == "-") && opts.InputFolder == "" {
opts.InputFile = os.Stdin.Name()
// Check if we're receiving data from the terminal
// or from piped content. Users from piped content
// won't see this message. Users that might have forgotten
// setting the flags correctly will see this message.
if !opts.Quiet {
if fi, err := os.Stdin.Stat(); err == nil && fi.Mode()&os.ModeNamedPipe == 0 {
fmt.Fprintln(opts.Stderr, "Receiving data from the terminal. Press CTRL+D when you're done typing or CTRL+C")
fmt.Fprintln(opts.Stderr, "to exit without processing the content. If you're seeing this by mistake, make")
fmt.Fprintln(opts.Stderr, "sure the command line flags, environment variables or config file are correct.")
}
}
}
// Create a new instance. This will also perform a basic validation.
instance, err := slice.New(opts)
if err != nil {
return fmt.Errorf("validation failed: %w", err)
}
return instance.Execute()
},
}
rootCommand.Flags().StringVarP(&opts.InputFile, "input-file", "f", "", "the input file used to read the initial macro YAML file; if empty or \"-\", stdin is used (exclusive with --input-folder)")
rootCommand.Flags().StringVarP(&opts.InputFolder, "input-folder", "d", "", "the input folder used to read the initial macro YAML files (exclusive with --input-file)")
rootCommand.Flags().StringSliceVar(&opts.InputFolderExt, "extensions", []string{".yaml", ".yml"}, "the extensions to look for in the input folder")
rootCommand.Flags().BoolVarP(&opts.Recurse, "recurse", "r", false, "if true, the input folder will be read recursively (has no effect unless used with --input-folder)")
rootCommand.Flags().StringVarP(&opts.OutputDirectory, "output-dir", "o", "", "the output directory used to output the splitted files")
rootCommand.Flags().StringVarP(&opts.GoTemplate, "template", "t", slice.DefaultTemplateName, "go template used to generate the file name when creating the resource files in the output directory")
rootCommand.Flags().BoolVar(&opts.DryRun, "dry-run", false, "if true, no files are created, but the potentially generated files will be printed as the command output")
rootCommand.Flags().BoolVar(&opts.DebugMode, "debug", false, "enable debug mode")
rootCommand.Flags().BoolVarP(&opts.Quiet, "quiet", "q", false, "if true, no output is written to stdout/err")
rootCommand.Flags().StringSliceVar(&opts.IncludedKinds, "include-kind", nil, "resource kind to include in the output (singular, case insensitive, glob supported)")
rootCommand.Flags().StringSliceVar(&opts.ExcludedKinds, "exclude-kind", nil, "resource kind to exclude in the output (singular, case insensitive, glob supported)")
rootCommand.Flags().StringSliceVar(&opts.IncludedNames, "include-name", nil, "resource name to include in the output (singular, case insensitive, glob supported)")
rootCommand.Flags().StringSliceVar(&opts.ExcludedNames, "exclude-name", nil, "resource name to exclude in the output (singular, case insensitive, glob supported)")
rootCommand.Flags().StringSliceVar(&opts.Included, "include", nil, "resource name to include in the output (format <kind>/<name>, case insensitive, glob supported)")
rootCommand.Flags().StringSliceVar(&opts.Excluded, "exclude", nil, "resource name to exclude in the output (format <kind>/<name>, case insensitive, glob supported)")
rootCommand.Flags().BoolVarP(&opts.StrictKubernetes, "skip-non-k8s", "s", false, "if enabled, any YAMLs that don't contain at least an \"apiVersion\", \"kind\" and \"metadata.name\" will be excluded from the split")
rootCommand.Flags().BoolVar(&opts.SortByKind, "sort-by-kind", false, "if enabled, resources are sorted by Kind, a la Helm, before saving them to disk")
rootCommand.Flags().BoolVar(&opts.OutputToStdout, "stdout", false, "if enabled, no resource is written to disk and all resources are printed to stdout instead")
rootCommand.Flags().StringVarP(&configFile, "config", "c", "", "path to the config file")
rootCommand.Flags().BoolVar(&opts.AllowEmptyKinds, "allow-empty-kinds", false, "if enabled, resources with empty kinds don't produce an error when filtering")
rootCommand.Flags().BoolVar(&opts.AllowEmptyNames, "allow-empty-names", false, "if enabled, resources with empty names don't produce an error when filtering")
rootCommand.Flags().BoolVar(&opts.IncludeTripleDash, "include-triple-dash", false, "if enabled, the typical \"---\" YAML separator is included at the beginning of resources sliced")
rootCommand.Flags().BoolVar(&opts.PruneOutputDir, "prune", false, "if enabled, the output directory will be pruned before writing the files")
rootCommand.Flags().BoolVar(&opts.RemoveFileComments, "remove-comments", false, "if enabled, comments generated by the app are removed from the sliced files (but keep comments from the original file)")
rootCommand.Flags().StringSliceVar(&opts.IncludedGroups, "include-group", nil, "resource kind to include in the output (singular, case insensitive, glob supported)")
rootCommand.Flags().StringSliceVar(&opts.ExcludedGroups, "exclude-group", nil, "resource kind to exclude in the output (singular, case insensitive, glob supported)")
_ = rootCommand.Flags().MarkHidden("debug")
return rootCommand
}
// envVarPrefix is the prefix used for environment variables.
// Using underscores to ensure compatibility with the shell.
const envVarPrefix = "KUBECTL_SLICE"
// skippedFlags is a list of flags that are not bound through
// Viper. These include things like "help", "version", and of
// course, "config", since it doesn't make sense to say where
// the config file is located in the config file itself.
var skippedFlags = [...]string{
"help",
"version",
"config",
}
// bindCobraAndViper binds the settings loaded by Viper
// to the flags defined in Cobra.
func bindCobraAndViper(cmd *cobra.Command, configFileLocation string) error {
v := viper.New()
// If a configuration file has been passed...
if cmd.Flags().Lookup("config").Changed {
// ... then set it as the configuration file
v.SetConfigFile(configFileLocation)
// then read the configuration file
if err := v.ReadInConfig(); err != nil {
return fmt.Errorf("failed to read configuration file: %w", err)
}
}
// Handler for potential error
var err error
// Recurse through all the variables
cmd.Flags().VisitAll(func(flag *pflag.Flag) {
// Skip the flags that are not bound through Viper
for _, v := range skippedFlags {
if v == flag.Name {
return
}
}
// Normalize key names with underscores instead of dashes
nameUnderscored := strings.ReplaceAll(flag.Name, "-", "_")
envVarName := strings.ToUpper(fmt.Sprintf("%s_%s", envVarPrefix, nameUnderscored))
// Bind the flag to the environment variable
if val, found := os.LookupEnv(envVarName); found {
v.Set(nameUnderscored, val)
}
// If the CLI flag hasn't been changed, but the value is set in
// the configuration file, then set the CLI flag to the value
// from the configuration file
if !flag.Changed && v.IsSet(nameUnderscored) {
// Type check for all the supported types
switch val := v.Get(nameUnderscored).(type) {
case string:
_ = cmd.Flags().Set(flag.Name, val)
case []interface{}:
var stringified []string
for _, v := range val {
stringified = append(stringified, fmt.Sprintf("%v", v))
}
_ = cmd.Flags().Set(flag.Name, strings.Join(stringified, ","))
case bool:
_ = cmd.Flags().Set(flag.Name, fmt.Sprintf("%t", val))
case int:
_ = cmd.Flags().Set(flag.Name, fmt.Sprintf("%d", val))
default:
err = fmt.Errorf("unsupported type %T for flag %q", val, nameUnderscored)
return
}
}
})
// If an error occurred, return it
return err
}

View File

@@ -400,6 +400,10 @@ package core
isStdoutOutput?: bool @go(IsStdoutOutput)
}
// NameLabel indicates a field name matching the name of the value. Usually the
// name or metadata.name field of the struct value.
#NameLabel: string
// InternalLabel is an arbitrary unique identifier internal to holos itself.
// The holos cli is expected to never write a InternalLabel value to rendered
// output files, therefore use a InternalLabel when the identifier must be
@@ -448,7 +452,7 @@ package core
// PlatformSpec represents the platform specification.
#PlatformSpec: {
// Components represents a collection of holos components to manage.
components: [...#Component] @go(Components,[]Component)
components: {[string]: #Component} & {[NAME=string]: name: NAME} @go(Components,map[NameLabel]Component)
}
// Component represents the complete context necessary to produce a [BuildPlan]

View File

@@ -10,7 +10,7 @@ import (
components: _
resource: {
metadata: "name": name
spec: "components": [for x in components {x}]
spec: "components": components
}
}

View File

@@ -0,0 +1,10 @@
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
vendor/
node_modules/
tmp/

View File

@@ -0,0 +1,30 @@
package holos
// This component produces a TaskSet at the top level holos field
// The TaskSet structure is to be defined
holos: {
metadata: name: "taskset-example"
// TaskSet structure placeholder - to be defined
// This will represent the new v1alpha6 TaskSet that replaces BuildPlan
taskSet: {
// Example structure for discussion
tasks: {
// Tasks as a struct instead of list for better composition
generateManifests: {
type: "generator"
// Additional fields to be defined
}
transformManifests: {
type: "transformer"
dependsOn: ["generateManifests"]
// Additional fields to be defined
}
validateManifests: {
type: "validator"
dependsOn: ["transformManifests"]
// Additional fields to be defined
}
}
}
}

View File

@@ -0,0 +1,6 @@
@extern(embed)
package holos
import "github.com/holos-run/holos/api/core/v1alpha6:core"
holos: core.#Component @embed(file=typemeta.yaml)

View File

@@ -0,0 +1,2 @@
kind: Component
apiVersion: v1alpha6

View File

@@ -0,0 +1,17 @@
package holos
platform: spec: components: {
TaskSet1: {
name: "TaskSet1"
path: "components/taskset"
// Parameters to pass into the component.
parameters: index: "1"
// In v1alpha5 "component" was ambiguous. We disambiguate in v1alpha6 by
// naming the output of a platform component an "instance"
labels: "app.holos.run/component.instance": name
// The component the instance is derived from.
labels: "app.holos.run/component.path": path
}
}
holos: platform

View File

@@ -0,0 +1,6 @@
@extern(embed)
package holos
import "github.com/holos-run/holos/api/core/v1alpha6:core"
holos: core.#Platform @embed(file=typemeta.yaml)

View File

@@ -0,0 +1,2 @@
kind: Platform
apiVersion: v1alpha6

View File

@@ -0,0 +1,49 @@
package holos
import (
corev1 "k8s.io/api/core/v1"
appsv1 "k8s.io/api/apps/v1"
rbacv1 "k8s.io/api/rbac/v1"
batchv1 "k8s.io/api/batch/v1"
ci "cert-manager.io/clusterissuer/v1"
rgv1 "gateway.networking.k8s.io/referencegrant/v1beta1"
certv1 "cert-manager.io/certificate/v1"
hrv1 "gateway.networking.k8s.io/httproute/v1"
gwv1 "gateway.networking.k8s.io/gateway/v1"
ap "argoproj.io/appproject/v1alpha1"
es "external-secrets.io/externalsecret/v1beta1"
ss "external-secrets.io/secretstore/v1beta1"
)
#Resources: {
[Kind=string]: [InternalLabel=string]: {
kind: Kind
metadata: name: string | *InternalLabel
}
AppProject?: [_]: ap.#AppProject
Certificate?: [_]: certv1.#Certificate
ClusterIssuer?: [_]: ci.#ClusterIssuer
ClusterRole?: [_]: rbacv1.#ClusterRole
ClusterRoleBinding?: [_]: rbacv1.#ClusterRoleBinding
ConfigMap?: [_]: corev1.#ConfigMap
CronJob?: [_]: batchv1.#CronJob
Deployment?: [_]: appsv1.#Deployment
ExternalSecret?: [_]: es.#ExternalSecret
HTTPRoute?: [_]: hrv1.#HTTPRoute
Job?: [_]: batchv1.#Job
Namespace?: [_]: corev1.#Namespace
ReferenceGrant?: [_]: rgv1.#ReferenceGrant
Role?: [_]: rbacv1.#Role
RoleBinding?: [_]: rbacv1.#RoleBinding
Secret?: [_]: corev1.#Secret
SecretStore?: [_]: ss.#SecretStore
Service?: [_]: corev1.#Service
ServiceAccount?: [_]: corev1.#ServiceAccount
StatefulSet?: [_]: appsv1.#StatefulSet
Gateway?: [_]: gwv1.#Gateway & {
spec: gatewayClassName: string | *"istio"
}
}

View File

@@ -0,0 +1,37 @@
package holos
import "github.com/holos-run/holos/api/author/v1alpha6:author"
#ComponentConfig: author.#ComponentConfig & {
Name: _Tags.component.name
Path: _Tags.component.path
Resources: #Resources
// labels is an optional field, guard references to it.
if _Tags.component.labels != _|_ {
Labels: _Tags.component.labels
}
// annotations is an optional field, guard references to it.
if _Tags.component.annotations != _|_ {
Annotations: _Tags.component.annotations
}
}
// https://holos.run/docs/api/author/v1alpha6/#Kubernetes
#Kubernetes: close({
#ComponentConfig
author.#Kubernetes
})
// https://holos.run/docs/api/author/v1alpha6/#Kustomize
#Kustomize: close({
#ComponentConfig
author.#Kustomize
})
// https://holos.run/docs/api/author/v1alpha6/#Helm
#Helm: close({
#ComponentConfig
author.#Helm
})

View File

@@ -0,0 +1,34 @@
package holos
import (
"encoding/json"
"github.com/holos-run/holos/api/core/v1alpha6:core"
)
// Note: tags should have a reasonable default value for cue export.
_Tags: {
// Standardized parameters
component: core.#Component & {
name: string | *"no-name" @tag(holos_component_name, type=string)
path: string | *"no-path" @tag(holos_component_path, type=string)
_labels_json: string | *"" @tag(holos_component_labels, type=string)
_labels: {}
if _labels_json != "" {
_labels: json.Unmarshal(_labels_json)
}
for k, v in _labels {
labels: (k): v
}
_annotations_json: string | *"" @tag(holos_component_annotations, type=string)
_annotations: {}
if _annotations_json != "" {
_annotations: json.Unmarshal(_annotations_json)
}
for k, v in _annotations {
annotations: (k): v
}
}
}

View File

@@ -3,13 +3,11 @@ package helm
import (
"context"
"fmt"
"net/url"
"github.com/holos-run/holos/internal/errors"
"github.com/holos-run/holos/internal/logger"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/registry"
)
// PullChart downloads and caches a Helm chart locally. It handles both OCI and
@@ -34,20 +32,6 @@ func PullChart(ctx context.Context, settings *cli.EnvSettings, chartRef, chartVe
}
actionConfig.RegistryClient = registryClient
chartRefURL, err := url.Parse(chartRef)
if err != nil {
return errors.Format("Failed to parse the Chart: %w", err)
}
// If the chart been pulled is an OCI chart, the repo authentication has to be done ahead of the pull.
if chartRefURL.Scheme == "oci" && username != "" && password != "" {
loginOption := registry.LoginOptBasicAuth(username, password)
err = registryClient.Login(chartRefURL.Host, loginOption)
if err != nil {
return errors.Format("failed to login to registry: %w", err)
}
}
pullClient := action.NewPullWithOpts(action.WithConfig(actionConfig))
pullClient.Untar = true
pullClient.RepoURL = repoURL

View File

@@ -0,0 +1,14 @@
package holos
import "github.com/holos-run/holos/api/author/v1alpha6:author"
// holos represents the field holos render platform evaluates, the resource
// field of the author.#Platform definition constructed from a components
// struct.
holos: platform.resource
platform: author.#Platform & {
components: {
// Empty platform with no components
}
}

View File

@@ -0,0 +1,6 @@
@extern(embed)
package holos
import "github.com/holos-run/holos/api/core/v1alpha6:core"
holos: core.#Platform @embed(file=typemeta.yaml)

View File

@@ -0,0 +1,2 @@
kind: Platform
apiVersion: v1alpha6

View File

@@ -7,8 +7,8 @@ holos: {
"name": "default"
}
"spec": {
"components": [
{
"components": {
"slice": {
"annotations": {
"app.holos.run/description": "slice command transformer"
}
@@ -20,7 +20,7 @@ holos: {
"outputBaseDir": "outputBaseDir"
}
"path": "fixtures/v1alpha6/components/slice"
},
]
}
}
}
}

View File

@@ -1 +1 @@
106
104

View File

@@ -1 +1 @@
0
1