mirror of
https://github.com/holos-run/holos.git
synced 2026-03-19 00:37:45 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d2984a635 | ||
|
|
032f72b435 | ||
|
|
2380223794 |
@@ -11,6 +11,7 @@
|
||||
"admissionregistration",
|
||||
"alertmanager",
|
||||
"alertmanagers",
|
||||
"anchore",
|
||||
"anthos",
|
||||
"apiextensions",
|
||||
"apimachinery",
|
||||
@@ -75,6 +76,7 @@
|
||||
"deploymentruntimeconfig",
|
||||
"destinationrule",
|
||||
"destinationrules",
|
||||
"devel",
|
||||
"devicecode",
|
||||
"dnsmasq",
|
||||
"dscacheutil",
|
||||
@@ -137,6 +139,7 @@
|
||||
"httproute",
|
||||
"httproutes",
|
||||
"iampolicygenerator",
|
||||
"incpatch",
|
||||
"Infima",
|
||||
"intstr",
|
||||
"isatty",
|
||||
@@ -256,6 +259,7 @@
|
||||
"rolebinding",
|
||||
"rootfs",
|
||||
"ropc",
|
||||
"sboms",
|
||||
"seccomp",
|
||||
"secretargs",
|
||||
"SECRETKEY",
|
||||
|
||||
27
.github/workflows/release.yaml
vendored
27
.github/workflows/release.yaml
vendored
@@ -35,6 +35,9 @@ jobs:
|
||||
with:
|
||||
go-version: stable
|
||||
|
||||
- name: Setup Syft
|
||||
uses: anchore/sbom-action/download-syft@1ca97d9028b51809cf6d3c934c3e160716e1b605 # v0.17.5
|
||||
|
||||
# Necessary to run these outside of goreleaser, otherwise
|
||||
# /home/runner/_work/holos/holos/internal/frontend/node_modules/.bin/protoc-gen-connect-query is not in PATH
|
||||
- name: Install Tools
|
||||
@@ -54,11 +57,31 @@ jobs:
|
||||
- name: Git diff
|
||||
run: git diff
|
||||
|
||||
- name: Run GoReleaser
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
owner: ${{ github.repository_owner }}
|
||||
app-id: ${{ vars.GORELEASER_APP_ID }}
|
||||
private-key: ${{ secrets.GORELEASER_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Run GoReleaser if tag
|
||||
if: github.ref_type == 'tag'
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
version: '~> v2'
|
||||
args: release --clean
|
||||
env:
|
||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Run GoReleaser if branch
|
||||
if: github.ref_type == 'branch' && github.ref == 'refs/heads/release'
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: '~> v2'
|
||||
args: release --clean --nightly
|
||||
env:
|
||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
||||
|
||||
version: 1
|
||||
version: 2
|
||||
|
||||
before:
|
||||
hooks:
|
||||
@@ -25,6 +25,24 @@ builds:
|
||||
- amd64
|
||||
- arm64
|
||||
|
||||
# .goreleaser.yml
|
||||
nightly:
|
||||
# Default: `{{ incpatch .Version }}-{{ .ShortCommit }}-nightly`.
|
||||
# Templates: allowed.
|
||||
version_template: "{{ .Version }}-{{ .ShortCommit }}-devel"
|
||||
|
||||
# Tag name to create if publish_release is enabled.
|
||||
tag_name: devel
|
||||
|
||||
# Whether to publish a release or not.
|
||||
# Only works on GitHub.
|
||||
publish_release: true
|
||||
|
||||
# Whether to delete previous pre-releases for the same `tag_name` when
|
||||
# releasing.
|
||||
# This allows you to keep a single pre-release.
|
||||
keep_single_release: true
|
||||
|
||||
signs:
|
||||
- artifacts: checksum
|
||||
args: ["-u", "code-signing-key@openinfrastructure.co", "--output", "${signature}", "--detach-sign", "${artifact}"]
|
||||
@@ -50,3 +68,39 @@ changelog:
|
||||
exclude:
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
|
||||
source:
|
||||
enabled: true
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}_source_code'
|
||||
|
||||
sboms:
|
||||
- id: source
|
||||
artifacts: source
|
||||
documents:
|
||||
- "{{ .ProjectName }}_{{ .Version }}_sbom.spdx.json"
|
||||
|
||||
brews:
|
||||
- name: holos
|
||||
repository:
|
||||
owner: holos-run
|
||||
name: homebrew-tap
|
||||
branch: main
|
||||
token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
|
||||
directory: Formula
|
||||
homepage: "https://holos.run"
|
||||
description: "Holos CLI"
|
||||
dependencies:
|
||||
- name: helm
|
||||
type: optional
|
||||
- name: kubectl
|
||||
type: optional
|
||||
install: |
|
||||
bin.install "holos"
|
||||
bash_output = Utils.safe_popen_read(bin/"holos", "completion", "bash")
|
||||
(bash_completion/"holos").write bash_output
|
||||
zsh_output = Utils.safe_popen_read(bin/"holos", "completion", "zsh")
|
||||
(zsh_completion/"holos").write zsh_output
|
||||
fish_output = Utils.safe_popen_read(bin/"holos", "completion", "fish")
|
||||
(fish_completion/"holos.fish").write fish_output
|
||||
test: |
|
||||
system "#{bin}/holos version"
|
||||
|
||||
@@ -28,6 +28,10 @@ func TestSchemas_v1alpha5(t *testing.T) {
|
||||
testscript.Run(t, params(filepath.Join("v1alpha5", "schemas")))
|
||||
}
|
||||
|
||||
func TestIssues_v1alpha5(t *testing.T) {
|
||||
testscript.Run(t, params(filepath.Join("v1alpha5", "issues")))
|
||||
}
|
||||
|
||||
func TestCLI(t *testing.T) {
|
||||
testscript.Run(t, params("cli"))
|
||||
}
|
||||
|
||||
38
cmd/holos/tests/v1alpha5/issues/helm-pull-errors.txt
Normal file
38
cmd/holos/tests/v1alpha5/issues/helm-pull-errors.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
# https://github.com/holos-run/holos/issues/332
|
||||
env HOME=$WORK
|
||||
# Mock with a stub helm command
|
||||
env PATH=$WORK/bin:$PATH
|
||||
chmod 755 bin/helm
|
||||
# Initialize the platform
|
||||
exec holos init platform v1alpha5 --force
|
||||
# when helm update returns an error
|
||||
! exec holos render platform ./platform
|
||||
# holos should log the helm error to stderr
|
||||
stderr 'Error: chart "podinfo" matching 0.0.0 not found in podinfo index'
|
||||
-- bin/helm --
|
||||
#! /bin/bash
|
||||
echo 'Error: chart "podinfo" matching 0.0.0 not found in podinfo index' >&2
|
||||
exit 2
|
||||
-- platform/podinfo.cue --
|
||||
package holos
|
||||
|
||||
Platform: Components: podinfo: {
|
||||
name: "podinfo"
|
||||
path: "components/podinfo"
|
||||
}
|
||||
-- components/podinfo/podinfo.cue --
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
holos: HelmChart.BuildPlan
|
||||
|
||||
HelmChart: #Helm & {
|
||||
Name: "podinfo"
|
||||
Chart: {
|
||||
version: "0.0.0"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
274
doc/md/topics/argocd-application.mdx
Normal file
274
doc/md/topics/argocd-application.mdx
Normal file
@@ -0,0 +1,274 @@
|
||||
---
|
||||
slug: argocd-application
|
||||
title: ArgoCD Application
|
||||
description: Configuring an Application for each Component.
|
||||
sidebar_position: 110
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ArgoCD Application
|
||||
|
||||
## Overview
|
||||
|
||||
This topic covers how to mix in an ArgoCD Application to all components. We'll
|
||||
use the `Artifacts` field of [ComponentConfig] defined by the author schema.
|
||||
|
||||
## The Code
|
||||
|
||||
### Generating the structure
|
||||
|
||||
Use `holos` to generate a minimal platform directory structure. Start by
|
||||
creating a blank directory to hold the platform configuration.
|
||||
|
||||
```shell
|
||||
mkdir holos-argocd-application && cd holos-argocd-application
|
||||
```
|
||||
|
||||
```shell
|
||||
holos init platform v1alpha5
|
||||
```
|
||||
|
||||
### Creating a component
|
||||
|
||||
Create a directory for the `podinfo` component. Create an empty file and then
|
||||
add the following CUE configuration to it.
|
||||
|
||||
<Tabs groupId="1D2C6013-3D19-4516-8147-5A6EE214CAFF">
|
||||
<TabItem value="components/podinfo/podinfo.cue" label="Podinfo Helm Chart">
|
||||
```bash
|
||||
mkdir -p components/podinfo
|
||||
touch components/podinfo/podinfo.cue
|
||||
```
|
||||
```bash
|
||||
cat <<EOF >components/podinfo/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
holos: Component.BuildPlan
|
||||
|
||||
Component: #Helm & {
|
||||
Name: "podinfo"
|
||||
Chart: {
|
||||
version: "6.6.2"
|
||||
repository: {
|
||||
name: "podinfo"
|
||||
url: "https://stefanprodan.github.io/podinfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Integrate the `podinfo` component into the platform.
|
||||
|
||||
<Tabs groupId="tutorial-hello-register-podinfo-component">
|
||||
<TabItem value="platform/podinfo.cue" label="Register Podinfo">
|
||||
```bash
|
||||
cat <<EOF >platform/podinfo.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
Platform: Components: podinfo: {
|
||||
name: "podinfo"
|
||||
path: "components/podinfo"
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Adding ArgoCD Application
|
||||
|
||||
Configure Holos to render an [Application] by defining an [Artifact] for it in
|
||||
every BuildPlan holos produces. We're unifying our custom configuration with
|
||||
the existing `#ComponentConfig` defined in `schema.cue`.
|
||||
|
||||
```bash
|
||||
cat <<EOF >argocd-application.cue
|
||||
```
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
import (
|
||||
"path"
|
||||
app "argoproj.io/application/v1alpha1"
|
||||
)
|
||||
|
||||
#ComponentConfig: {
|
||||
Name: _
|
||||
OutputBaseDir: _
|
||||
|
||||
let ArtifactPath = path.Join([OutputBaseDir, "gitops", "\(Name).application.gen.yaml"], path.Unix)
|
||||
let ResourcesPath = path.Join(["deploy", OutputBaseDir, "components", Name], path.Unix)
|
||||
|
||||
Artifacts: "\(Name)-application": {
|
||||
artifact: ArtifactPath
|
||||
generators: [{
|
||||
kind: "Resources"
|
||||
output: artifact
|
||||
resources: Application: (Name): app.#Application & {
|
||||
metadata: name: Name
|
||||
metadata: namespace: "argocd"
|
||||
spec: {
|
||||
destination: server: "https://kubernetes.default.svc"
|
||||
project: "default"
|
||||
source: {
|
||||
path: ResourcesPath
|
||||
repoURL: "https://example.com/example.git"
|
||||
targetRevision: "main"
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
EOF
|
||||
```
|
||||
|
||||
## Inspecting the BuildPlan
|
||||
|
||||
Our customized `#ComponentConfig` results in the following `BuildPlan`.
|
||||
|
||||
:::note
|
||||
The second artifact around line 40 contains the configured `Application`
|
||||
resource.
|
||||
:::
|
||||
|
||||
<Tabs groupId="55075C71-02E8-4222-88C0-2D52C82D18FC">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos cue export --expression holos --out=yaml ./components/podinfo
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```yaml showLineNumbers
|
||||
kind: BuildPlan
|
||||
apiVersion: v1alpha5
|
||||
metadata:
|
||||
name: podinfo
|
||||
spec:
|
||||
artifacts:
|
||||
- artifact: components/podinfo/podinfo.gen.yaml
|
||||
generators:
|
||||
- kind: Helm
|
||||
output: helm.gen.yaml
|
||||
helm:
|
||||
chart:
|
||||
name: podinfo
|
||||
version: 6.6.2
|
||||
release: podinfo
|
||||
repository:
|
||||
name: podinfo
|
||||
url: https://stefanprodan.github.io/podinfo
|
||||
values: {}
|
||||
enableHooks: false
|
||||
- kind: Resources
|
||||
output: resources.gen.yaml
|
||||
resources: {}
|
||||
transformers:
|
||||
- kind: Kustomize
|
||||
inputs:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
output: components/podinfo/podinfo.gen.yaml
|
||||
kustomize:
|
||||
kustomization:
|
||||
labels:
|
||||
- includeSelectors: false
|
||||
pairs: {}
|
||||
resources:
|
||||
- helm.gen.yaml
|
||||
- resources.gen.yaml
|
||||
kind: Kustomization
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
- artifact: gitops/podinfo.application.gen.yaml
|
||||
generators:
|
||||
- kind: Resources
|
||||
output: gitops/podinfo.application.gen.yaml
|
||||
resources:
|
||||
Application:
|
||||
podinfo:
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: deploy/components/podinfo
|
||||
repoURL: https://example.com/example.git
|
||||
targetRevision: main
|
||||
source:
|
||||
component:
|
||||
name: podinfo
|
||||
path: no-path
|
||||
parameters: {}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Rendering manifests
|
||||
|
||||
<Tabs groupId="E150C802-7162-4FBF-82A7-77D9ADAEE847">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```
|
||||
cached podinfo 6.6.2
|
||||
rendered podinfo in 1.938665041s
|
||||
rendered platform in 1.938759417s
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Reviewing the Application
|
||||
|
||||
The Artifact we added to `#ComponentConfig` will produce an ArgoCD Application
|
||||
resource for every component in the platform. The output in this example is
|
||||
located at:
|
||||
|
||||
```txt
|
||||
deploy/gitops/podinfo.application.gen.yaml
|
||||
```
|
||||
```yaml showLineNumbers
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: deploy/components/podinfo
|
||||
repoURL: https://example.com/example.git
|
||||
targetRevision: main
|
||||
```
|
||||
|
||||
[podinfo]: https://github.com/stefanprodan/podinfo
|
||||
[CUE Module]: https://cuelang.org/docs/reference/modules/
|
||||
[CUE Tags]: https://cuelang.org/docs/howto/inject-value-into-evaluation-using-tag-attribute/
|
||||
[Platform]: ../api/author.md#Platform
|
||||
[Component Parameters]: ../topics/component-parameters.mdx
|
||||
[Application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
|
||||
[ComponentConfig]: ../api/author.md#ComponentConfig
|
||||
[Artifact]: ../api/core.md#Artifact
|
||||
@@ -353,6 +353,7 @@ func (b *BuildPlan) helm(
|
||||
stderr := helmOut.Stderr.String()
|
||||
lines := strings.Split(stderr, "\n")
|
||||
for _, line := range lines {
|
||||
log.DebugContext(ctx, line)
|
||||
if strings.HasPrefix(line, "Error:") {
|
||||
err = fmt.Errorf("%s: %w", line, err)
|
||||
}
|
||||
@@ -520,7 +521,15 @@ func (b *BuildPlan) cacheChart(
|
||||
}
|
||||
helmOut, err := util.RunCmd(ctx, "helm", "pull", "--destination", cacheTemp, "--untar=true", "--version", chart.Version, cn)
|
||||
if err != nil {
|
||||
return errors.Wrap(fmt.Errorf("could not run helm pull: %w", err))
|
||||
stderr := helmOut.Stderr.String()
|
||||
lines := strings.Split(stderr, "\n")
|
||||
for _, line := range lines {
|
||||
log.DebugContext(ctx, line)
|
||||
if strings.HasPrefix(line, "Error:") {
|
||||
err = fmt.Errorf("%s: %w", line, err)
|
||||
}
|
||||
}
|
||||
return errors.Format("could not run helm pull: %w", err)
|
||||
}
|
||||
log.Debug("helm pull", "stdout", helmOut.Stdout, "stderr", helmOut.Stderr)
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
0
|
||||
2
|
||||
|
||||
Reference in New Issue
Block a user