Skip to content

Commit

Permalink
build: pass platform component labels and annotations to BuildPlan
Browse files Browse the repository at this point in the history
Without this patch the BuildPlan resulting from a Platform that has
components with labels and annotations does not have the labels or
annotations of the source component.

Holos should copy the labels and annotations defined on each of the
Platform.spec.components to the resulting BuildPlan so end users can see
clearly where a BuildPlan originated from, and filter with selectors the
intermediate output BuildPlan the same way we filter with selectors the
original Platform spec components list.

Result:

```
holos init platform v1alpha5 --force
holos show buildplans  | head
```

```yaml
kind: BuildPlan
apiVersion: v1alpha5
metadata:
  name: podinfo
  labels:
    app.holos.run/cluster: local
    app.holos.run/name: podinfo
  annotations:
    app.holos.run/description: podinfo for cluster local
```
  • Loading branch information
jeffmccune committed Nov 20, 2024
1 parent 791c0a9 commit 864d7d4
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 8 deletions.
5 changes: 5 additions & 0 deletions api/author/v1alpha5/definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ type ComponentConfig struct {
// Name represents the BuildPlan metadata.name field. Used to construct the
// fully rendered manifest file path.
Name string
// Labels represent the BuildPlan metadata.labels field.
Labels map[string]string
// Annotations represent the BuildPlan metadata.annotations field.
Annotations map[string]string

// Path represents the path to the component producing the BuildPlan.
Path string
// Parameters are useful to reuse a component with various parameters.
Expand Down
2 changes: 1 addition & 1 deletion cmd/holos/tests/v1alpha5/issues/helm-pull-errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ chmod 755 bin/helm
# Initialize the platform
exec holos init platform v1alpha5 --force
# when helm update returns an error
! exec holos render platform ./platform
! exec holos render platform
# holos should log the helm error to stderr
stderr 'Error: chart "podinfo" matching 0.0.0 not found in podinfo index'
-- bin/helm --
Expand Down
52 changes: 52 additions & 0 deletions cmd/holos/tests/v1alpha5/issues/holos-show.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty1
labels:
app.holos.run/name: empty1-label
annotations:
app.holos.run/description: empty1-annotation empty test case
spec:
artifacts:
- artifact: components/empty1/empty1.gen.yaml
Expand All @@ -112,6 +116,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty2
labels:
app.holos.run/name: empty2-label
annotations:
app.holos.run/description: empty2-annotation empty test case
spec:
artifacts:
- artifact: components/empty2/empty2.gen.yaml
Expand All @@ -137,6 +145,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty3
labels:
app.holos.run/name: empty3-label
annotations:
app.holos.run/description: empty3-annotation empty test case
spec:
artifacts:
- artifact: components/empty3/empty3.gen.yaml
Expand All @@ -162,6 +174,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty4
labels:
app.holos.run/name: empty4-label
annotations:
app.holos.run/description: empty4-annotation empty test case
spec:
artifacts:
- artifact: components/empty4/empty4.gen.yaml
Expand All @@ -187,6 +203,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty1
labels:
app.holos.run/name: empty1-label
annotations:
app.holos.run/description: empty1-annotation empty test case
spec:
artifacts:
- artifact: components/empty1/empty1.gen.yaml
Expand All @@ -212,6 +232,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty2
labels:
app.holos.run/name: empty2-label
annotations:
app.holos.run/description: empty2-annotation empty test case
spec:
artifacts:
- artifact: components/empty2/empty2.gen.yaml
Expand All @@ -237,6 +261,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty1
labels:
app.holos.run/name: empty1-label
annotations:
app.holos.run/description: empty1-annotation empty test case
spec:
artifacts:
- artifact: components/empty1/empty1.gen.yaml
Expand All @@ -262,6 +290,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty2
labels:
app.holos.run/name: empty2-label
annotations:
app.holos.run/description: empty2-annotation empty test case
spec:
artifacts:
- artifact: components/empty2/empty2.gen.yaml
Expand All @@ -287,6 +319,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty4
labels:
app.holos.run/name: empty4-label
annotations:
app.holos.run/description: empty4-annotation empty test case
spec:
artifacts:
- artifact: components/empty4/empty4.gen.yaml
Expand All @@ -312,6 +348,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty1
labels:
app.holos.run/name: empty1-label
annotations:
app.holos.run/description: empty1-annotation empty test case
spec:
artifacts:
- artifact: components/empty1/empty1.gen.yaml
Expand All @@ -337,6 +377,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty2
labels:
app.holos.run/name: empty2-label
annotations:
app.holos.run/description: empty2-annotation empty test case
spec:
artifacts:
- artifact: components/empty2/empty2.gen.yaml
Expand All @@ -362,6 +406,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty3
labels:
app.holos.run/name: empty3-label
annotations:
app.holos.run/description: empty3-annotation empty test case
spec:
artifacts:
- artifact: components/empty3/empty3.gen.yaml
Expand All @@ -387,6 +435,10 @@ kind: BuildPlan
apiVersion: v1alpha5
metadata:
name: empty4
labels:
app.holos.run/name: empty4-label
annotations:
app.holos.run/description: empty4-annotation empty test case
spec:
artifacts:
- artifact: components/empty4/empty4.gen.yaml
Expand Down
5 changes: 5 additions & 0 deletions doc/md/api/author.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ type ComponentConfig struct {
// Name represents the BuildPlan metadata.name field. Used to construct the
// fully rendered manifest file path.
Name string
// Labels represent the BuildPlan metadata.labels field.
Labels map[string]string
// Annotations represent the BuildPlan metadata.annotations field.
Annotations map[string]string

// Path represents the path to the component producing the BuildPlan.
Path string
// Parameters are useful to reuse a component with various parameters.
Expand Down
29 changes: 26 additions & 3 deletions internal/builder/v1alpha5/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package v1alpha5
import (
"bytes"
"context"
"encoding/json"
"fmt"
"log/slog"
"os"
Expand Down Expand Up @@ -60,15 +61,37 @@ func (c *Component) Describe() string {
return c.Component.Name
}

func (c *Component) Tags() []string {
tags := make([]string, 0, len(c.Component.Parameters)+2)
func (c *Component) Tags() ([]string, error) {
size := 2 +
len(c.Component.Parameters) +
len(c.Component.Labels) +
len(c.Component.Annotations)

tags := make([]string, 0, size)
for k, v := range c.Component.Parameters {
tags = append(tags, k+"="+v)
}
// Inject holos component metadata tags.
tags = append(tags, "holos_component_name="+c.Component.Name)
tags = append(tags, "holos_component_path="+c.Component.Path)
return tags

if len(c.Component.Labels) > 0 {
labels, err := json.Marshal(c.Component.Labels)
if err != nil {
return nil, err
}
tags = append(tags, "holos_component_labels="+string(labels))
}

if len(c.Component.Annotations) > 0 {
annotations, err := json.Marshal(c.Component.Annotations)
if err != nil {
return nil, err
}
tags = append(tags, "holos_component_annotations="+string(annotations))
}

return tags, nil
}

func (c *Component) WriteTo() string {
Expand Down
5 changes: 4 additions & 1 deletion internal/cli/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ func makePlatformRenderFunc(w io.Writer, prefixArgs []string) builder.BuildFunc
case <-ctx.Done():
return errors.Wrap(ctx.Err())
default:
tags := component.Tags()
tags, err := component.Tags()
if err != nil {
return errors.Wrap(err)
}
args := make([]string, 0, 10+len(prefixArgs)+(len(tags)*2))
args = append(args, prefixArgs...)
args = append(args, "render", "component")
Expand Down
6 changes: 5 additions & 1 deletion internal/cli/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ func makeBuildFunc(encoder holos.OrderedEncoder, opts holos.BuildOpts) builder.B
case <-ctx.Done():
return errors.Wrap(ctx.Err())
default:
inst, err := builder.LoadInstance(component.Path(), component.Tags())
tags, err := component.Tags()
if err != nil {
return errors.Wrap(err)
}
inst, err := builder.LoadInstance(component.Path(), tags)
if err != nil {
return errors.Wrap(err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ import "github.com/holos-run/holos/api/core/v1alpha5:core"
// fully rendered manifest file path.
Name: string

// Labels represent the BuildPlan metadata.labels field.
Labels: {[string]: string} @go(,map[string]string)

// Annotations represent the BuildPlan metadata.annotations field.
Annotations: {[string]: string} @go(,map[string]string)

// Path represents the path to the component producing the BuildPlan.
Path: string

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import (
// https://holos.run/docs/next/api/author/#Kubernetes
#Kubernetes: {
Name: _
Labels: _
Annotations: _
Path: _
Parameters: _
Resources: _
Expand Down Expand Up @@ -84,13 +86,21 @@ import (

BuildPlan: {
metadata: name: Name
if len(Labels) != 0 {
metadata: labels: Labels
}
if len(Annotations) != 0 {
metadata: annotations: Annotations
}
spec: artifacts: [for x in Artifacts {x}]
}
}

// https://holos.run/docs/next/api/author/#Helm
#Helm: {
Name: _
Labels: _
Annotations: _
Path: _
Parameters: _
Resources: _
Expand Down Expand Up @@ -170,6 +180,12 @@ import (

BuildPlan: {
metadata: name: Name
if len(Labels) != 0 {
metadata: labels: Labels
}
if len(Annotations) != 0 {
metadata: annotations: Annotations
}
spec: artifacts: [for x in Artifacts {x}]
}
}
10 changes: 10 additions & 0 deletions internal/generate/platforms/v1alpha5/schema.cue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ import "github.com/holos-run/holos/api/author/v1alpha5:author"
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/v1alpha5/#Kubernetes
Expand Down
24 changes: 23 additions & 1 deletion internal/generate/platforms/v1alpha5/tags.cue
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
package holos

import "github.com/holos-run/holos/api/core/v1alpha5:core"
import (
"encoding/json"

"github.com/holos-run/holos/api/core/v1alpha5: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
}
}
}
2 changes: 1 addition & 1 deletion internal/holos/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Platform interface {
type Component interface {
Describe() string
Path() string
Tags() []string
Tags() ([]string, error)
WriteTo() string
Labels() Labels
}
Expand Down

0 comments on commit 864d7d4

Please sign in to comment.