mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 16:54:58 +00:00
Compare commits
12 Commits
v0.104.2
...
jeff/v1alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5680049650 | ||
|
|
f4484ffb21 | ||
|
|
8512ca01d1 | ||
|
|
e6f3a6d8d9 | ||
|
|
3d696b958b | ||
|
|
1bf627b5e1 | ||
|
|
df69198cef | ||
|
|
810a7c6649 | ||
|
|
b24e35f46d | ||
|
|
22c65bbc6c | ||
|
|
e913ce6368 | ||
|
|
0abfa660d0 |
@@ -30,7 +30,7 @@ COPY --from=build \
|
||||
# Extra packages
|
||||
# git - https://github.com/holos-run/holos/issues/440
|
||||
RUN apt update && \
|
||||
apt install -y --no-install-recommends git && \
|
||||
apt install -y --no-install-recommends git ca-certificates && \
|
||||
apt clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@@ -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" yaml:"name"`
|
||||
URL string `json:"url" yaml:"url"`
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
URL string `json:"url,omitempty" yaml:"url,omitempty"`
|
||||
Auth Auth `json:"auth,omitempty" yaml:"auth,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
|
||||
-- command.sh --
|
||||
holos --version
|
||||
-- output.txt --
|
||||
0.104.2
|
||||
0.106.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.104.2
|
||||
0.105.1
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rendered podinfo in 585.290958ms
|
||||
rendered platform in 585.384958ms
|
||||
rendered podinfo in 169.504ms
|
||||
rendered platform in 169.609583ms
|
||||
|
||||
@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
|
||||
-- command.sh --
|
||||
holos --version
|
||||
-- output.txt --
|
||||
0.104.2
|
||||
0.106.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.104.2
|
||||
0.105.1
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[main c67d8cb] add blackbox configuration
|
||||
[main 67f5363] add blackbox configuration
|
||||
1 file changed, 15 insertions(+)
|
||||
create mode 100644 config/prometheus/blackbox.cue
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[main b572420] integrate blackbox and prometheus together
|
||||
3 files changed, 1348 insertions(+), 2 deletions(-)
|
||||
[main bef876c] integrate blackbox and prometheus together
|
||||
3 files changed, 1359 insertions(+), 2 deletions(-)
|
||||
create mode 100644 components/prometheus/values.cue.orig
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[main 009417b] import values
|
||||
2 files changed, 1815 insertions(+)
|
||||
[main 9dd00f3] import values
|
||||
2 files changed, 1826 insertions(+)
|
||||
create mode 100644 components/blackbox/values.cue
|
||||
create mode 100644 components/prometheus/values.cue
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
rendered blackbox in 111.012833ms
|
||||
rendered prometheus in 141.3495ms
|
||||
rendered platform in 141.443792ms
|
||||
rendered blackbox in 112.795875ms
|
||||
rendered prometheus in 144.441042ms
|
||||
rendered platform in 144.505625ms
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[main 03338b1] add blackbox and prometheus
|
||||
[main c523ef0] add blackbox and prometheus
|
||||
5 files changed, 1550 insertions(+)
|
||||
create mode 100644 components/blackbox/blackbox.cue
|
||||
create mode 100644 components/prometheus/prometheus.cue
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
rendered prometheus in 976.842666ms
|
||||
rendered blackbox in 1.010637584s
|
||||
rendered platform in 1.010700333s
|
||||
rendered blackbox in 877.548833ms
|
||||
rendered prometheus in 882.902333ms
|
||||
rendered platform in 883.561541ms
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[main 90f970f] render integrated blackbox and prometheus manifests
|
||||
[main 3aa63f4] render integrated blackbox and prometheus manifests
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
|
||||
-- command.sh --
|
||||
holos --version
|
||||
-- output.txt --
|
||||
0.104.2
|
||||
0.106.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.104.2
|
||||
0.105.1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[main 409f74c] add httpbin
|
||||
[main 2fc33ea] add httpbin
|
||||
4 files changed, 113 insertions(+)
|
||||
create mode 100644 components/httpbin/httpbin.cue
|
||||
create mode 100644 components/httpbin/httpbin.yaml
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[main d00077c] annotate httpbin for prometheus probes
|
||||
[main 6d5bbc3] annotate httpbin for prometheus probes
|
||||
2 files changed, 18 insertions(+)
|
||||
create mode 100644 components/httpbin/patches.cue
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rendered httpbin in 76.075042ms
|
||||
rendered platform in 76.152ms
|
||||
rendered httpbin in 82.637042ms
|
||||
rendered platform in 82.702458ms
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rendered httpbin in 75.982958ms
|
||||
rendered platform in 76.07325ms
|
||||
rendered httpbin in 80.916166ms
|
||||
rendered platform in 80.992958ms
|
||||
|
||||
391
doc/plans/v1alpha6-executor.md
Normal file
391
doc/plans/v1alpha6-executor.md
Normal file
@@ -0,0 +1,391 @@
|
||||
# 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
|
||||
```
|
||||
@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
|
||||
-- command.sh --
|
||||
holos --version
|
||||
-- output.txt --
|
||||
0.104.2
|
||||
0.106.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.104.2
|
||||
0.105.1
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rendered podinfo in 188.373167ms
|
||||
rendered platform in 188.466708ms
|
||||
rendered podinfo in 290.020792ms
|
||||
rendered platform in 290.155667ms
|
||||
|
||||
@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
|
||||
-- command.sh --
|
||||
holos --version
|
||||
-- output.txt --
|
||||
0.104.2
|
||||
0.106.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.104.2
|
||||
0.105.1
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[main 7087e1c] add blackbox configuration
|
||||
[main fd30368] add blackbox configuration
|
||||
1 file changed, 15 insertions(+)
|
||||
create mode 100644 config/prometheus/blackbox.cue
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[main da0fb3b] integrate blackbox and prometheus together
|
||||
3 files changed, 1348 insertions(+), 2 deletions(-)
|
||||
[main e9a22bd] integrate blackbox and prometheus together
|
||||
3 files changed, 1359 insertions(+), 2 deletions(-)
|
||||
create mode 100644 components/prometheus/values.cue.orig
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[main c511284] import values
|
||||
2 files changed, 1815 insertions(+)
|
||||
[main dbaf504] import values
|
||||
2 files changed, 1826 insertions(+)
|
||||
create mode 100644 components/blackbox/values.cue
|
||||
create mode 100644 components/prometheus/values.cue
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
rendered blackbox in 110.982334ms
|
||||
rendered prometheus in 143.239167ms
|
||||
rendered platform in 143.288292ms
|
||||
rendered blackbox in 120.236ms
|
||||
rendered prometheus in 147.333125ms
|
||||
rendered platform in 147.385208ms
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[main b01e9d8] add blackbox and prometheus
|
||||
[main c523ef0] add blackbox and prometheus
|
||||
5 files changed, 1550 insertions(+)
|
||||
create mode 100644 components/blackbox/blackbox.cue
|
||||
create mode 100644 components/prometheus/prometheus.cue
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
rendered prometheus in 914.69225ms
|
||||
rendered blackbox in 928.397375ms
|
||||
rendered platform in 928.461334ms
|
||||
rendered blackbox in 1.023009333s
|
||||
rendered prometheus in 1.1285565s
|
||||
rendered platform in 1.128658458s
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[main b751097] render integrated blackbox and prometheus manifests
|
||||
[main ed5ce22] render integrated blackbox and prometheus manifests
|
||||
2 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
@@ -4,4 +4,4 @@ cmp stdout $WORK/output.txt
|
||||
-- command.sh --
|
||||
holos --version
|
||||
-- output.txt --
|
||||
0.104.2
|
||||
0.106.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.104.2
|
||||
0.105.1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[main 1a292da] add httpbin
|
||||
[main bdb182b] add httpbin
|
||||
4 files changed, 113 insertions(+)
|
||||
create mode 100644 components/httpbin/httpbin.cue
|
||||
create mode 100644 components/httpbin/httpbin.yaml
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[main fcd85b9] annotate httpbin for prometheus probes
|
||||
[main d557fa2] annotate httpbin for prometheus probes
|
||||
2 files changed, 18 insertions(+)
|
||||
create mode 100644 components/httpbin/patches.cue
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rendered httpbin in 84.769458ms
|
||||
rendered platform in 84.835458ms
|
||||
rendered httpbin in 79.923ms
|
||||
rendered platform in 79.99475ms
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
rendered httpbin in 78.073167ms
|
||||
rendered platform in 78.155208ms
|
||||
rendered httpbin in 81.503708ms
|
||||
rendered platform in 81.573166ms
|
||||
|
||||
37
go.mod
37
go.mod
@@ -1,29 +1,29 @@
|
||||
module github.com/holos-run/holos
|
||||
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.6
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
cuelang.org/go v0.14.1
|
||||
cuelang.org/go v0.15.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.9.1
|
||||
github.com/spf13/pflag v1.0.7
|
||||
github.com/spf13/cobra v1.10.1
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/spf13/viper v1.19.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/sync v0.16.0
|
||||
golang.org/x/tools v0.35.0
|
||||
golang.org/x/sync v0.17.0
|
||||
golang.org/x/tools v0.38.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-20250715075730-49cab49c8e9d // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20250722084951-074d06050084 // 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
|
||||
@@ -110,6 +110,7 @@ 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
|
||||
@@ -140,7 +141,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-20250627152318-f293424e46b5 // indirect
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20251016062345-16587c79cd91 // 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
|
||||
@@ -153,7 +154,6 @@ 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/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
|
||||
@@ -168,14 +168,15 @@ 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
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.43.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/mod v0.26.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/term v0.33.0 // indirect
|
||||
golang.org/x/text v0.27.0 // 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/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
|
||||
|
||||
68
go.sum
68
go.sum
@@ -1,7 +1,7 @@
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20250715075730-49cab49c8e9d h1:lX0EawyoAu4kgMJJfy7MmNkIHioBcdBGFRSKDZ+CWo0=
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20250715075730-49cab49c8e9d/go.mod h1:4WWeZNxUO1vRoZWAHIG0KZOd6dA25ypyWuwD3ti0Tdc=
|
||||
cuelang.org/go v0.14.1 h1:kxFAHr7bvrCikbtVps2chPIARazVdnRmlz65dAzKyWg=
|
||||
cuelang.org/go v0.14.1/go.mod h1:aSP9UZUM5m2izHAHUvqtq0wTlWn5oLjuv2iBMQZBLLs=
|
||||
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=
|
||||
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=
|
||||
@@ -308,6 +308,8 @@ 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=
|
||||
@@ -364,6 +366,8 @@ 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=
|
||||
@@ -404,8 +408,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-20250627152318-f293424e46b5 h1:WWs1ZFnGobK5ZXNu+N9If+8PDNVB9xAqrib/stUXsV4=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20250627152318-f293424e46b5/go.mod h1:BnHogPTyzYAReeQLZrOxyxzS739DaTNtTvohVdbENmA=
|
||||
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/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=
|
||||
@@ -437,13 +441,13 @@ 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.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||
github.com/spf13/pflag v1.0.7/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/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/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=
|
||||
@@ -496,19 +500,21 @@ 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.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
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.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||
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/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=
|
||||
@@ -518,18 +524,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.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
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/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.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
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=
|
||||
@@ -559,16 +565,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.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||
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/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.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
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/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=
|
||||
@@ -576,8 +582,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.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||
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/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=
|
||||
|
||||
@@ -17,6 +17,7 @@ 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"
|
||||
@@ -82,6 +83,9 @@ func New(cfg *holos.Config) *cobra.Command {
|
||||
// Compile
|
||||
rootCmd.AddCommand(NewCompileCmd())
|
||||
|
||||
// Slice - https://github.com/patrickdappollonio/kubectl-slice
|
||||
rootCmd.AddCommand(slice.NewKubectlSliceCmd())
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
|
||||
22
internal/cli/slice/doc.go
Normal file
22
internal/cli/slice/doc.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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
|
||||
212
internal/cli/slice/slice.go
Normal file
212
internal/cli/slice/slice.go
Normal file
@@ -0,0 +1,212 @@
|
||||
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
|
||||
}
|
||||
@@ -3,11 +3,13 @@ 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
|
||||
@@ -32,6 +34,20 @@ 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
|
||||
|
||||
@@ -1 +1 @@
|
||||
104
|
||||
106
|
||||
|
||||
@@ -1 +1 @@
|
||||
2
|
||||
0
|
||||
|
||||
Reference in New Issue
Block a user