Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9d892eee3 | ||
|
|
4c77eba72b | ||
|
|
a8ae56b08b | ||
|
|
b04837ede2 | ||
|
|
559c8bc79f | ||
|
|
a30335b171 | ||
|
|
108831747a | ||
|
|
c714a2b61e | ||
|
|
1cba383dc1 | ||
|
|
265d5773b8 | ||
|
|
44f8779136 | ||
|
|
4127804092 | ||
|
|
8f424cfabe | ||
|
|
699148abdd |
@@ -13,6 +13,7 @@
|
||||
"authroutes",
|
||||
"buildplan",
|
||||
"cainjector",
|
||||
"CAROOT",
|
||||
"clsx",
|
||||
"clusterissuer",
|
||||
"cookiesecret",
|
||||
@@ -57,6 +58,7 @@
|
||||
"libnss",
|
||||
"loadbalancer",
|
||||
"mattn",
|
||||
"mindmap",
|
||||
"mktemp",
|
||||
"Multicluster",
|
||||
"mxcl",
|
||||
@@ -67,6 +69,7 @@
|
||||
"otelconnect",
|
||||
"Parentspanid",
|
||||
"pflag",
|
||||
"pipefail",
|
||||
"PKCE",
|
||||
"platformconnect",
|
||||
"podinfo",
|
||||
@@ -83,6 +86,7 @@
|
||||
"spanid",
|
||||
"spiffe",
|
||||
"startupapicheck",
|
||||
"stefanprodan",
|
||||
"structpb",
|
||||
"systemconnect",
|
||||
"tablewriter",
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
// plate code and generating component build plans in a consistent manner.
|
||||
package v1alpha3
|
||||
|
||||
import core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
import (
|
||||
core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
//go:generate ../../../hack/gendoc
|
||||
|
||||
@@ -97,3 +100,51 @@ type ArgoConfig struct {
|
||||
// main.
|
||||
TargetRevision string `cue:"string | *\"main\""`
|
||||
}
|
||||
|
||||
// Cluster represents a cluster managed by the Platform.
|
||||
type Cluster struct {
|
||||
// Name represents the cluster name, for example "east1", "west1", or
|
||||
// "management".
|
||||
Name string `json:"name"`
|
||||
// Primary represents if the cluster is marked as the primary among a set of
|
||||
// candidate clusters. Useful for promotion of database leaders.
|
||||
Primary bool `json:"primary" cue:"true | *false"`
|
||||
}
|
||||
|
||||
// Fleet represents a named collection of similarly configured Clusters. Useful
|
||||
// to segregate workload clusters from their management cluster.
|
||||
type Fleet struct {
|
||||
Name string `json:"name"`
|
||||
// Clusters represents a mapping of Clusters by their name.
|
||||
Clusters map[string]Cluster `json:"clusters" cue:"{[Name=_]: name: Name}"`
|
||||
}
|
||||
|
||||
// StandardFleets represents the standard set of Clusters in a Platform
|
||||
// segmented into Fleets by their purpose. The management Fleet contains a
|
||||
// single Cluster, for example a GKE autopilot cluster with no workloads
|
||||
// deployed for reliability and cost efficiency. The workload Fleet contains
|
||||
// all other Clusters which contain workloads and sync Secrets from the
|
||||
// management cluster.
|
||||
type StandardFleets struct {
|
||||
// Workload represents a Fleet of zero or more workload Clusters.
|
||||
Workload Fleet `json:"workload" cue:"{name: \"workload\"}"`
|
||||
// Management represents a Fleet with one Cluster named management.
|
||||
Management Fleet `json:"management" cue:"{name: \"management\", clusters: management: _}"`
|
||||
}
|
||||
|
||||
// Platform is a convenience structure to produce a core Platform specification
|
||||
// value in the Output field. Useful to collect components at the root of the
|
||||
// Platform configuration tree as a struct, which are automatically converted
|
||||
// into a list for the core Platform spec output.
|
||||
type Platform struct {
|
||||
// Name represents the Platform name.
|
||||
Name string `cue:"string | *\"holos\""`
|
||||
// Components is a structured map of components to manage by their name.
|
||||
Components map[string]core.PlatformSpecComponent
|
||||
// Model represents the Platform model holos gets from from the
|
||||
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
|
||||
Model structpb.Struct `cue:"{...}"`
|
||||
// Output represents the core Platform spec for the holos cli to iterate over
|
||||
// and render each listed Component, injecting the Model.
|
||||
Output core.Platform
|
||||
}
|
||||
|
||||
5
doc/md/api.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# API Reference
|
||||
|
||||
<DocCardList />
|
||||
5
doc/md/api/core.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Core API
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,3 +0,0 @@
|
||||
# Core API
|
||||
|
||||
- [v1alpha2](v1alpha2)
|
||||
5
doc/md/api/schema.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Schema API
|
||||
|
||||
<DocCardList />
|
||||
@@ -11,7 +11,11 @@ Package v1alpha3 contains CUE definitions intended as convenience wrappers aroun
|
||||
## Index
|
||||
|
||||
- [type ArgoConfig](<#ArgoConfig>)
|
||||
- [type Cluster](<#Cluster>)
|
||||
- [type Fleet](<#Fleet>)
|
||||
- [type Helm](<#Helm>)
|
||||
- [type Platform](<#Platform>)
|
||||
- [type StandardFleets](<#StandardFleets>)
|
||||
|
||||
|
||||
<a name="ArgoConfig"></a>
|
||||
@@ -40,6 +44,35 @@ type ArgoConfig struct {
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Cluster"></a>
|
||||
## type Cluster {#Cluster}
|
||||
|
||||
Cluster represents a cluster managed by the Platform.
|
||||
|
||||
```go
|
||||
type Cluster struct {
|
||||
// Name represents the cluster name, for example "east1", "west1", or
|
||||
// "management".
|
||||
Name string `json:"name"`
|
||||
// Primary represents if the cluster is marked as the primary among a set of
|
||||
// candidate clusters. Useful for promotion of database leaders.
|
||||
Primary bool `json:"primary" cue:"true | *false"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Fleet"></a>
|
||||
## type Fleet {#Fleet}
|
||||
|
||||
Fleet represents a named collection of similarly configured Clusters. Useful to segregate workload clusters from their management cluster.
|
||||
|
||||
```go
|
||||
type Fleet struct {
|
||||
Name string `json:"name"`
|
||||
// Clusters represents a mapping of Clusters by their name.
|
||||
Clusters map[string]Cluster `json:"clusters" cue:"{[Name=_]: name: Name}"`
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Helm"></a>
|
||||
## type Helm {#Helm}
|
||||
|
||||
@@ -98,4 +131,38 @@ type Helm struct {
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Platform"></a>
|
||||
## type Platform {#Platform}
|
||||
|
||||
Platform is a convenience structure to produce a core Platform specification value in the Output field. Useful to collect components at the root of the Platform configuration tree as a struct, which are automatically converted into a list for the core Platform spec output.
|
||||
|
||||
```go
|
||||
type Platform struct {
|
||||
// Name represents the Platform name.
|
||||
Name string `cue:"string | *\"holos\""`
|
||||
// Components is a structured map of components to manage by their name.
|
||||
Components map[string]core.PlatformSpecComponent
|
||||
// Model represents the Platform model holos gets from from the
|
||||
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
|
||||
Model structpb.Struct `cue:"{...}"`
|
||||
// Output represents the core Platform spec for the holos cli to iterate over
|
||||
// and render each listed Component, injecting the Model.
|
||||
Output core.Platform
|
||||
}
|
||||
```
|
||||
|
||||
<a name="StandardFleets"></a>
|
||||
## type StandardFleets {#StandardFleets}
|
||||
|
||||
StandardFleets represents the standard set of Clusters in a Platform segmented into Fleets by their purpose. The management Fleet contains a single Cluster, for example a GKE autopilot cluster with no workloads deployed for reliability and cost efficiency. The workload Fleet contains all other Clusters which contain workloads and sync Secrets from the management cluster.
|
||||
|
||||
```go
|
||||
type StandardFleets struct {
|
||||
// Workload represents a Fleet of zero or more workload Clusters.
|
||||
Workload Fleet `json:"workload" cue:"{name: \"workload\"}"`
|
||||
// Management represents a Fleet with one Cluster named management.
|
||||
Management Fleet `json:"management" cue:"{name: \"management\", clusters: management: _}"`
|
||||
}
|
||||
```
|
||||
|
||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
||||
|
||||
|
Before Width: | Height: | Size: 934 KiB After Width: | Height: | Size: 934 KiB |
|
Before Width: | Height: | Size: 703 KiB After Width: | Height: | Size: 703 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 728 KiB After Width: | Height: | Size: 728 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1014 KiB After Width: | Height: | Size: 1014 KiB |
|
Before Width: | Height: | Size: 854 KiB After Width: | Height: | Size: 854 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 624 KiB After Width: | Height: | Size: 624 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
@@ -671,10 +671,10 @@ foundation of a software development platform that:
|
||||
|
||||
Dive deeper with the following resources that build on the foundation you have now.
|
||||
|
||||
1. Explore the [Rendering Process](/docs/design/rendering) in Holos.
|
||||
1. Explore the [Rendering Process](/docs/concepts#rendering) in Holos.
|
||||
2. Dive deeper into the [Platform Manifests](./platform-manifests) rendered in this guide.
|
||||
3. Deploy [ArgoCD](/docs/guides/argocd) onto the foundation you built.
|
||||
4. Deploy [Backstage](/docs/guides/backstage) as a portal to the integrated platform components.
|
||||
3. Deploy [ArgoCD](../argocd) onto the foundation you built.
|
||||
4. Deploy [Backstage](../backstage) as a portal to the integrated platform components.
|
||||
|
||||
## Clean-Up
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This document provides an example of how Holos uses CUE and Helm to unify and
|
||||
render the platform configuration. It refers to the manifests rendered in the
|
||||
[Try Holos Locally](/docs/guides/try-holos/) guide.
|
||||
Try Holos Locally guide.
|
||||
|
||||
Take a moment to review the manifests `holos` rendered to build the platform.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This document captures notes on locally developing Holos.
|
||||
|
||||
Follow the steps in [Try Holos Locally](/docs/guides/try-holos), but take care
|
||||
Follow the steps in [Try Holos Locally](../guides/try-holos), but take care
|
||||
to select `Develop` tabs when creating the k3d cluster so you have a local
|
||||
registry to push to.
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# Rendering
|
||||
|
||||
:::tip
|
||||
|
||||
This document provides a brief overview of the rendering process, a core design
|
||||
element in Holos.
|
||||
|
||||
:::
|
||||
|
||||
Holos uses the Kubernetes resource model to manage configuration. The `holos`
|
||||
command line interface is the primary method you'll use to manage your platform.
|
||||
Holos uses CUE to provide a unified configuration model of the platform. This
|
||||
unified configuration is built up from components packaged with Helm, Kustomize,
|
||||
CUE, or any other tool that can produce Kubernetes resource manifests as output.
|
||||
|
||||
This process can be thought of as a data **rendering pipeline**. The key
|
||||
concept is that `holos` will always produce fully rendered output, but delegates
|
||||
the _application_ of the configuration to other tools like `kubectl apply`,
|
||||
ArgoCD, or Flux.
|
||||
|
||||
```mermaid
|
||||
---
|
||||
title: Figure 2 - Render Pipeline
|
||||
---
|
||||
graph LR
|
||||
PS[<a href="/docs/api/core/v1alpha2#PlatformSpec">PlatformSpec</a>]
|
||||
BP[<a href="/docs/api/core/v1alpha2#BuildPlan">BuildPlan</a>]
|
||||
HC[<a href="/docs/api/core/v1alpha2#HolosComponent">HolosComponent</a>]
|
||||
|
||||
H[<a href="/docs/api/core/v1alpha2#HelmChart">HelmChart</a>]
|
||||
K[<a href="/docs/api/core/v1alpha2#KustomizeBuild">KustomizeBuild</a>]
|
||||
O[<a href="/docs/api/core/v1alpha2#KubernetesObjects">KubernetesObjects</a>]
|
||||
|
||||
P[<a href="/docs/api/core/v1alpha2#Kustomize">Kustomize</a>]
|
||||
Y[Kubernetes <br>Resources]
|
||||
G[GitOps <br>Resource]
|
||||
|
||||
C[Kube API Server]
|
||||
|
||||
PS --> BP --> HC
|
||||
HC --> H --> P
|
||||
HC --> K --> P
|
||||
HC --> O --> P
|
||||
|
||||
P --> Y --> C
|
||||
P --> G --> C
|
||||
```
|
||||
5
doc/md/guides.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Guides
|
||||
|
||||
<DocCardList />
|
||||
95
doc/md/guides/expose-a-service.mdx
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
description: Use Holos to expose a Service with the Gateway API.
|
||||
slug: /guides/expose-a-service
|
||||
sidebar_position: 300
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Expose a Service
|
||||
|
||||
In this guide, you'll learn how to expose a service with Holos using the Gateway
|
||||
API.
|
||||
|
||||
:::warning TODO
|
||||
Complete this section once the steps are complete.
|
||||
:::
|
||||
|
||||
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
|
||||
and Component.
|
||||
|
||||
## What you'll need {#requirements}
|
||||
|
||||
:::warning TODO
|
||||
Complete this section once the steps are complete.
|
||||
:::
|
||||
|
||||
You'll need the following tools installed to complete this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the Platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos Components that
|
||||
wrap upstream Helm charts.
|
||||
|
||||
Optionally, if you'd like to apply the rendered manifests to a real Cluster,
|
||||
first complete the [localhost Guide](../local-cluster).
|
||||
|
||||
## Create a Git Repository
|
||||
|
||||
Start by initializing an empty Git repository. Holos operates on local files
|
||||
stored in a Git repository.
|
||||
|
||||
<Tabs groupId="init">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir expose-a-service
|
||||
cd expose-a-service
|
||||
git init
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
Initialized empty Git repository in /expose-a-service/.git/
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This guide assumes you will run commands from the root directory of the Git
|
||||
repository unless stated otherwise.
|
||||
|
||||
## Generate the Platform {#Generate-Platform}
|
||||
|
||||
Start by generating a platform used as the basis for our guides.
|
||||
|
||||
```bash
|
||||
holos generate platform guide
|
||||
```
|
||||
|
||||
Commit the generated platform config to the repository.
|
||||
|
||||
<Tabs groupId="commit-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate platform guide - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main (root-commit) 0b17b7f] holos generate platform guide - 0.93.3
|
||||
213 files changed, 72349 insertions(+)
|
||||
...
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Manage httpbin {#manage-httpbin}
|
||||
|
||||
The platform you generated is currently empty. Run the following command to
|
||||
generate a Holos Component for the
|
||||
[httpbin](https://github.com/mccutchen/go-httpbin) service.
|
||||
|
||||
httpbin is a simple backend service useful for end-to-end testing. In this
|
||||
guide, we use httpbin as a example of a service your organization develops and
|
||||
deploy onto your Platform.
|
||||
196
doc/md/guides/local-cluster.mdx
Normal file
@@ -0,0 +1,196 @@
|
||||
---
|
||||
description: Build a local Cluster to use with these guides.
|
||||
slug: /guides/local-cluster
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Local Cluster
|
||||
|
||||
In this guide you'll set up a Cluster on your local host to apply and explore
|
||||
the configuration described in our other guides. After completing this guide
|
||||
you'll have a standard Kubernetes API server with proper DNS and TLS
|
||||
certificates. You'll be able to easily reset the cluster to a known good state
|
||||
to iterate on your own Platform.
|
||||
|
||||
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
|
||||
and Component.
|
||||
|
||||
## What you'll need {#requirements}
|
||||
|
||||
You'll need the following tools installed to complete this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos components that wrap upstream Helm charts.
|
||||
3. [k3d](https://k3d.io/#installation) - to provide a k8s api server.
|
||||
4. [OrbStack](https://docs.orbstack.dev/install) or [Docker](https://docs.docker.com/get-docker/) - to use k3d.
|
||||
5. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the k8s api server.
|
||||
6. [mkcert](https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installation) - to make trusted TLS certificates.
|
||||
7. [jq](https://jqlang.github.io/jq/download/) - to fiddle with JSON output.
|
||||
|
||||
## Configure DNS {#configure-dns}
|
||||
|
||||
Configure your machine to resolve `*.holos.localhost` to your loopback
|
||||
interface. This is necessary for requests to reach the workload cluster. Save
|
||||
this script to a file and execute it.
|
||||
|
||||
```bash showLineNumbers
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
brew install dnsmasq
|
||||
|
||||
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
|
||||
# Refer to https://holos.run/docs/tutorial/local/k3d/
|
||||
address=/holos.localhost/127.0.0.1
|
||||
EOF
|
||||
|
||||
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
|
||||
echo "dnsmasq already configured"
|
||||
else
|
||||
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
|
||||
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
dscacheutil -flushcache
|
||||
echo "dnsmasq configured"
|
||||
fi
|
||||
|
||||
sudo mkdir -p /etc/resolver
|
||||
sudo tee /etc/resolver/holos.localhost <<EOF
|
||||
domain holos.localhost
|
||||
nameserver 127.0.0.1
|
||||
EOF
|
||||
sudo killall -HUP mDNSResponder
|
||||
|
||||
echo "all done."
|
||||
```
|
||||
|
||||
## Create the Cluster {#create-the-cluster}
|
||||
|
||||
The Workload Cluster is where your applications and services will be deployed.
|
||||
In production this is usually an EKS, GKE, or AKS cluster.
|
||||
|
||||
:::tip
|
||||
|
||||
Holos supports all compliant Kubernetes clusters. Holos was developed and tested
|
||||
on GKE, EKS, Talos, k3s, and Kubeadm clusters.
|
||||
|
||||
:::
|
||||
|
||||
Create a local registry to speed up image builds and pulls.
|
||||
|
||||
```bash
|
||||
k3d registry create registry.holos.localhost --port 5100
|
||||
```
|
||||
|
||||
Create the workload cluster configured to use the local registry.
|
||||
|
||||
```bash
|
||||
k3d cluster create workload \
|
||||
--registry-use k3d-registry.holos.localhost:5100 \
|
||||
--port "443:443@loadbalancer" \
|
||||
--k3s-arg "--disable=traefik@server:0"
|
||||
```
|
||||
|
||||
Traefik is disabled because Istio provides the same functionality.
|
||||
|
||||
## Setup Root CA {#setup-root-ca}
|
||||
|
||||
Platforms most often use cert-manager to issue tls certificates. The browser
|
||||
and tools we're using need to trust these certificates to work together.
|
||||
Generate a local, trusted root certificate authority with the following script.
|
||||
|
||||
Admin access is necessary for `mkcert` to manage the certificate into your trust
|
||||
stores.
|
||||
|
||||
```bash
|
||||
sudo -v
|
||||
```
|
||||
|
||||
Manage the local CA and copy the CA key to the workload cluster so that cert
|
||||
manager can manage trusted certificates.
|
||||
|
||||
Save this script to a file and execute it to configure a trusted certificate
|
||||
authority.
|
||||
|
||||
```bash showLineNumbers
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkcert --install
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
# Create the local CA Secret with ca.crt, tls.crt, tls.key
|
||||
|
||||
mkdir local-ca
|
||||
cd local-ca
|
||||
CAROOT="$(mkcert -CAROOT)"
|
||||
cp -p "${CAROOT}/rootCA.pem" ca.crt
|
||||
cp -p "${CAROOT}/rootCA.pem" tls.crt
|
||||
cp -p "${CAROOT}/rootCA-key.pem" tls.key
|
||||
kubectl create secret generic --from-file=. --dry-run=client -o yaml local-ca > ../local-ca.yaml
|
||||
cd ..
|
||||
|
||||
echo 'type: kubernetes.io/tls' >> local-ca.yaml
|
||||
kubectl apply --server-side=true -f- <<EOF
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
EOF
|
||||
kubectl apply -n cert-manager --server-side=true -f local-ca.yaml
|
||||
|
||||
```
|
||||
|
||||
:::warning
|
||||
|
||||
Take care to run the local-ca script each time you create the workload cluster
|
||||
so that Certificates are issued correctly.
|
||||
|
||||
:::
|
||||
|
||||
## Clean Up {#clean-up}
|
||||
|
||||
If you'd like to clean up the resources you created in this guide, remove them
|
||||
with:
|
||||
|
||||
```bash
|
||||
k3d cluster delete workload
|
||||
```
|
||||
|
||||
## Reset {#reset}
|
||||
|
||||
If you'd like to reset to a known good state, execute the [Clean Up](#clean-up)
|
||||
section, then [Create the Cluster](#create-the-cluster) and the [Setup Root
|
||||
CA](#setup-root-ca) tasks.
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you have a real cluster, apply and explore the manifests Holos renders
|
||||
in the [Quickstart](/docs/quickstart) guide.
|
||||
724
doc/md/guides/quickstart.mdx
Normal file
@@ -0,0 +1,724 @@
|
||||
---
|
||||
description: Try Holos with this quick start guide.
|
||||
slug: /quickstart
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Quickstart
|
||||
|
||||
In this guide, you'll experience how Holos makes the process of operating a
|
||||
Platform safer, easier, and more consistent. We'll use Holos to manage a
|
||||
vendor-provided Helm chart as a Component. Next, we'll mix in our own custom
|
||||
resources to manage the Component with GitOps. Finally, you'll see how Holos
|
||||
makes it safer and easier to maintain software over time by surfacing the exact
|
||||
changes that will be applied when upgrading the vendor's chart to a new version,
|
||||
before they are actually made.
|
||||
|
||||
The [Concepts](/docs/concepts) page defines capitalized terms such as Platform
|
||||
and Component.
|
||||
|
||||
## What you'll need {#requirements}
|
||||
|
||||
You'll need the following tools installed to complete this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the Platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos Components that
|
||||
wrap upstream Helm charts.
|
||||
|
||||
Optionally, if you'd like to apply the rendered manifests to a real Cluster,
|
||||
first complete the [Local Cluster Guide](/docs/guides/local-cluster).
|
||||
|
||||
## Install Holos
|
||||
|
||||
Install Holos with the following command or other methods listed on the
|
||||
[Installation](/docs/install/) page.
|
||||
|
||||
```bash
|
||||
go install github.com/holos-run/holos/cmd/holos@latest
|
||||
```
|
||||
|
||||
## Create a Git Repository
|
||||
|
||||
Start by initializing an empty Git repository. Holos operates on local files
|
||||
stored in a Git repository.
|
||||
|
||||
<Tabs groupId="init">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir holos-quickstart
|
||||
cd holos-quickstart
|
||||
git init
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
Initialized empty Git repository in /holos-quickstart/.git/
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This guide assumes you will run commands from the root directory of the Git
|
||||
repository unless stated otherwise.
|
||||
|
||||
## Generate the Platform {#Generate-Platform}
|
||||
|
||||
Generate the Platform code in the repository root. A Platform refers to the
|
||||
entire set of software holistically integrated to provide a software development
|
||||
platform for your organization. In this guide, the Platform will include a
|
||||
single Component to demonstrate how the concepts fit together.
|
||||
|
||||
```bash
|
||||
holos generate platform quickstart
|
||||
```
|
||||
|
||||
Commit the generated platform config to the repository.
|
||||
|
||||
<Tabs groupId="commit-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate platform quickstart - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main (root-commit) 0b17b7f] holos generate platform quickstart
|
||||
213 files changed, 72349 insertions(+)
|
||||
...
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Generate a Component {#generate-component}
|
||||
|
||||
The platform you generated is currently empty. Run the following command to
|
||||
generate the CUE code that defines a Helm Component.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component podinfo --component-version 6.6.1
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The --component-version 6.6.1 flag intentionally installs an older release.
|
||||
You'll see how Holos assists with software upgrades later in this guide.
|
||||
|
||||
The generate component command creates two files: a leaf file,
|
||||
`components/podinfo/podinfo.gen.cue`, and a root file, `podinfo.gen.cue`. Holos
|
||||
leverages the fact that [order is
|
||||
irrelevant](https://cuelang.org/docs/tour/basics/order-irrelevance/) in CUE to
|
||||
register the component with the Platform by adding a file to the root of the Git
|
||||
repository. The second file defines the component in the leaf component
|
||||
directory.
|
||||
|
||||
<Tabs groupId="podinfo-files">
|
||||
<TabItem value="components/podinfo/podinfo.gen.cue" label="Leaf">
|
||||
`components/podinfo/podinfo.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "podinfo"
|
||||
Version: "6.6.1"
|
||||
Namespace: "default"
|
||||
|
||||
Repo: name: "podinfo"
|
||||
Repo: url: "https://stefanprodan.github.io/podinfo"
|
||||
|
||||
Values: {}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="podinfo.gen.cue" label="Root">
|
||||
`podinfo.gen.cue`
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Manage podinfo on workload clusters only
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/podinfo": {
|
||||
path: "components/podinfo"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
In this example, we provide the minimal information needed to manage the Helm
|
||||
chart: the name, version, Kubernetes namespace for deployment, and the chart
|
||||
repository location.
|
||||
|
||||
This chart deploys cleanly without any values provided, but we include an empty
|
||||
Values struct to show how Holos improves consistency and safety in Helm by
|
||||
leveraging the strong type-checking in CUE. You can safely pass shared values,
|
||||
such as the organization’s domain name, to all Components across all clusters in
|
||||
the Platform by defining them at the root of the configuration.
|
||||
|
||||
Commit the generated component config to the repository.
|
||||
|
||||
<Tabs groupId="commit-component">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate component podinfo - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main cc0e90c] holos generate component podinfo
|
||||
2 files changed, 24 insertions(+)
|
||||
create mode 100644 components/podinfo/podinfo.gen.cue
|
||||
create mode 100644 podinfo.gen.cue
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Render the Component
|
||||
|
||||
You can render individual components without adding them to a Platform, which is
|
||||
helpful when developing a new component.
|
||||
|
||||
<Tabs groupId="render-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
cached
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
First, the command caches the Helm chart locally to speed up subsequent
|
||||
renderings. Then, the command runs Helm to produce the output and writes it into
|
||||
the deploy directory.
|
||||
|
||||
<Tabs groupId="tree-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
└── components
|
||||
└── podinfo
|
||||
└── podinfo.gen.yaml
|
||||
|
||||
5 directories, 1 file
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The component deploys to one cluster named `default`. In practice, the same
|
||||
component is often deployed to multiple clusters, such as `east` and `west` to
|
||||
provide redundancy and increase availability.
|
||||
|
||||
:::tip
|
||||
This example is equivalent to running `helm template` on the chart and saving
|
||||
the output to a file. Holos simplifies this task, making it safer and more
|
||||
consistent when managing many charts.
|
||||
:::
|
||||
|
||||
## Mix in an ArgoCD Application
|
||||
|
||||
We've seen how Holos works with Helm, but we haven't yet explored how Holos
|
||||
makes it easier to consistently and safely manage all of the software in a
|
||||
Platform.
|
||||
|
||||
Holos allows you to easily mix in resources that differentiate your Platform.
|
||||
We'll use this feature to mix in an ArgoCD [Application][application] to manage
|
||||
the podinfo Component with GitOps. We'll define this configuration in a way that
|
||||
can be automatically and consistently reused across all future Components added
|
||||
to the Platform.
|
||||
|
||||
Create a new file named `argocd.cue` in the root of your Git repository with the
|
||||
following contents:
|
||||
|
||||
<Tabs groupId="argocd-config">
|
||||
<TabItem value="command" label="argocd.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
RepoURL: "https://example.com/holos-quickstart.git"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
If you plan to apply the rendered output to a real cluster, change the
|
||||
`example.com` RepoURL to the URL of the Git repository you created in this
|
||||
guide. You don't need to change the example if you're just exploring Holos by
|
||||
inspecting the rendered output without applying it to a live cluster.
|
||||
:::
|
||||
|
||||
With this file in place, render the component again.
|
||||
|
||||
<Tabs groupId="render-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
wrote deploy file
|
||||
rendered gitops/podinfo
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Holos uses the locally cached chart to improve performance and reliability. It
|
||||
then renders the Helm template output along with an ArgoCD Application resource
|
||||
for GitOps.
|
||||
|
||||
:::tip
|
||||
By defining the ArgoCD configuration at the root, we again take advantage of the
|
||||
fact that [order is
|
||||
irrelevant](https://cuelang.org/docs/tour/basics/order-irrelevance/) in CUE.
|
||||
:::
|
||||
|
||||
Defining the configuration at the root ensures all future leaf Components take
|
||||
the ArgoCD configuration and render an Application manifest for GitOps
|
||||
management.
|
||||
|
||||
<Tabs groupId="tree-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
├── components
|
||||
│ └── podinfo
|
||||
│ └── podinfo.gen.yaml
|
||||
└── gitops
|
||||
└── podinfo.application.gen.yaml
|
||||
|
||||
6 directories, 2 files
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Notice the new `podinfo.application.gen.yaml` file created by enabling ArgoCD in
|
||||
the Helm component. The Application resource in the file looks like this:
|
||||
|
||||
<Tabs groupId="podinfo-application">
|
||||
<TabItem value="file" label="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/clusters/default/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
Holos generates a similar Application resource for every additional Component
|
||||
added to your Platform.
|
||||
:::
|
||||
|
||||
Finally, add and commit the results to your Platform's Git repository.
|
||||
|
||||
<Tabs groupId="commit-argo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos render component ./components/podinfo --cluster-name=default"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main f95cef1] holos render component ./components/podinfo --cluster-name=default
|
||||
3 files changed, 134 insertions(+)
|
||||
create mode 100644 argocd.cue
|
||||
create mode 100644 deploy/clusters/default/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/default/gitops/podinfo.application.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
In this section, we learned how Holos simplifies mixing resources into
|
||||
Components, like an ArgoCD Application. Holos ensures consistency by managing an
|
||||
Application resource for every Component added to the Platform through the
|
||||
configuration you define in `argocd.cue` at the root of the repository.
|
||||
|
||||
## Define Workload Clusters {#workload-clusters}
|
||||
|
||||
We've generated a Component to manage podinfo and integrated it with our
|
||||
Platform, but rendering the Platform doesn't render podinfo. Podinfo isn't
|
||||
rendered because we haven't assigned any Clusters to the workload Fleet.
|
||||
|
||||
Define two new clusters, `east` and `west`, and assign them to the workload
|
||||
Fleet. Create a new file named `clusters.cue` in the root of your Git repository
|
||||
with the following contents:
|
||||
|
||||
<Tabs groupId="clusters">
|
||||
<TabItem value="clusters.cue" label="clusters.cue">
|
||||
```cue showLineNumbers
|
||||
package holos
|
||||
|
||||
// Define two workload clusters for disaster recovery.
|
||||
#Fleets: workload: clusters: {
|
||||
// In CUE _ indicates values are defined elsewhere.
|
||||
east: _
|
||||
west: _
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This example shows how Holos simplifies configuring multiple clusters with
|
||||
similar configuration by grouping them into a Fleet.
|
||||
|
||||
:::tip
|
||||
Fleets help segment a group of Clusters into one leader and multiple followers
|
||||
by designating one cluster as the primary. Holos makes it safer, easier, and
|
||||
more consistent to reconfigure which cluster is the primary. The primary can be
|
||||
set to automatically restore persistent data from backups, while non-primary
|
||||
clusters can be configured to automatically replicate from the primary.
|
||||
|
||||
Automatic database backup, restore, and streaming replication is an advanced
|
||||
topic enabled by Cloud Native PG and CUE. Check back for a guide on this and
|
||||
other Day 2 operations topics.
|
||||
:::
|
||||
|
||||
## Render the Platform {#render-platform}
|
||||
|
||||
Render the Platform to render the podinfo Component for each of the workload
|
||||
clusters.
|
||||
|
||||
<Tabs groupId="render-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered components/podinfo for cluster west in 99.480792ms
|
||||
rendered components/podinfo for cluster east in 99.882667ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The render platform command iterates over every Cluster in the Fleet and renders
|
||||
each Component assigned to the Fleet. Notice the two additional subdirectories
|
||||
created under the deploy directory, one for each cluster: `east` and `west`.
|
||||
|
||||
<Tabs groupId="tree-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
├── default
|
||||
│ ├── components
|
||||
│ │ └── podinfo
|
||||
│ │ └── podinfo.gen.yaml
|
||||
│ └── gitops
|
||||
│ └── podinfo.application.gen.yaml
|
||||
# highlight-next-line
|
||||
├── east
|
||||
│ ├── components
|
||||
│ │ └── podinfo
|
||||
│ │ └── podinfo.gen.yaml
|
||||
│ └── gitops
|
||||
│ └── podinfo.application.gen.yaml
|
||||
# highlight-next-line
|
||||
└── west
|
||||
├── components
|
||||
│ └── podinfo
|
||||
│ └── podinfo.gen.yaml
|
||||
└── gitops
|
||||
└── podinfo.application.gen.yaml
|
||||
|
||||
14 directories, 6 files
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Holos ensures consistency and safety by defining the ArgoCD Application once,
|
||||
with strong type checking, at the configuration root.
|
||||
|
||||
New Application resources are automatically generated for the `east` and `west`
|
||||
workload Clusters.
|
||||
|
||||
<Tabs groupId="applications">
|
||||
<TabItem value="east" label="east">
|
||||
`deploy/clusters/east/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:
|
||||
# highlight-next-line
|
||||
path: ./deploy/clusters/east/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="west" label="west">
|
||||
`deploy/clusters/west/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:
|
||||
# highlight-next-line
|
||||
path: ./deploy/clusters/west/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="default" label="default">
|
||||
`deploy/clusters/default/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:
|
||||
# highlight-next-line
|
||||
path: ./deploy/clusters/default/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Add and commit the rendered Platform and workload Clusters.
|
||||
|
||||
<Tabs groupId="commit-render-platform">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos render platform ./platform - $(holos --version)"
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
[main 5aebcf5] holos render platform ./platform - 0.93.2
|
||||
5 files changed, 263 insertions(+)
|
||||
create mode 100644 clusters.cue
|
||||
create mode 100644 deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/east/gitops/podinfo.application.gen.yaml
|
||||
create mode 100644 deploy/clusters/west/components/podinfo/podinfo.gen.yaml
|
||||
create mode 100644 deploy/clusters/west/gitops/podinfo.application.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Upgrade a Helm Chart
|
||||
|
||||
Holos is designed to ease the burden of Day 2 operations. With Holos, upgrading
|
||||
software, integrating new software, and making safe platform-wide configuration
|
||||
changes become easier.
|
||||
|
||||
Let's upgrade the podinfo Component to see how this works in practice. First,
|
||||
update the Component version field to the latest upstream Helm chart version.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos generate component podinfo --component-version 6.6.2
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Remove the cached chart version.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
rm -rf components/podinfo/vendor
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Now re-render the Platform.
|
||||
|
||||
<Tabs groupId="render-platform2">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
rendered components/podinfo for cluster east in 327.10475ms
|
||||
rendered components/podinfo for cluster west in 327.796541ms
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Notice we're still using the upstream chart without modifying it. The Holos
|
||||
component wraps around the chart to mix in additional resources and integrate
|
||||
the component with the broader Platform.
|
||||
|
||||
## Visualize the Changes
|
||||
|
||||
Holos makes it easier to see exactly what changes are made and which resources
|
||||
will be applied to the API server. By design, Holos operates on local files,
|
||||
leaving the task of applying them to ecosystem tools like `kubectl` and ArgoCD.
|
||||
This allows platform operators to inspect changes during code review, or before
|
||||
committing the change at all.
|
||||
|
||||
For example, using `git diff`, we see that the only functional change when
|
||||
upgrading this Helm chart is the deployment of a new container image tag to each
|
||||
cluster. Additionally, we can roll out this change gradually by applying it to
|
||||
the east cluster first, then to the west cluster, limiting the potential blast
|
||||
radius of a problematic change.
|
||||
|
||||
<Tabs groupId="git-diff">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
git diff deploy/clusters/east
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```diff showLineNumbers
|
||||
diff --git a/deploy/clusters/east/components/podinfo/podinfo.gen.yaml b/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
index 7cc3332..8c1647d 100644
|
||||
--- a/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
+++ b/deploy/clusters/east/components/podinfo/podinfo.gen.yaml
|
||||
@@ -5,9 +5,9 @@ kind: Service
|
||||
metadata:
|
||||
name: podinfo
|
||||
labels:
|
||||
- helm.sh/chart: podinfo-6.6.1
|
||||
+ helm.sh/chart: podinfo-6.6.2
|
||||
app.kubernetes.io/name: podinfo
|
||||
- app.kubernetes.io/version: "6.6.1"
|
||||
+ app.kubernetes.io/version: "6.6.2"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
type: ClusterIP
|
||||
@@ -29,9 +29,9 @@ kind: Deployment
|
||||
metadata:
|
||||
name: podinfo
|
||||
labels:
|
||||
- helm.sh/chart: podinfo-6.6.1
|
||||
+ helm.sh/chart: podinfo-6.6.2
|
||||
app.kubernetes.io/name: podinfo
|
||||
- app.kubernetes.io/version: "6.6.1"
|
||||
+ app.kubernetes.io/version: "6.6.2"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
spec:
|
||||
replicas: 1
|
||||
@@ -53,7 +53,7 @@ spec:
|
||||
terminationGracePeriodSeconds: 30
|
||||
containers:
|
||||
- name: podinfo
|
||||
# highlight-next-line
|
||||
- image: "ghcr.io/stefanprodan/podinfo:6.6.1"
|
||||
# highlight-next-line
|
||||
+ image: "ghcr.io/stefanprodan/podinfo:6.6.2"
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- ./podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
Holos is designed to surface the _fully rendered_ manifests intended for the
|
||||
Kubernetes API server, making it easier to see and reason about platform-wide
|
||||
configuration changes.
|
||||
:::
|
||||
|
||||
## Recap {#recap}
|
||||
|
||||
In this quickstart guide, we learned how Holos makes it easier, safer, and more
|
||||
consistent to manage a Platform composed of multiple Clusters and upstream Helm
|
||||
charts.
|
||||
|
||||
We covered how to:
|
||||
|
||||
1. Generate a Git repository for the Platform config.
|
||||
2. Wrap the unmodified upstream podinfo Helm chart into a Component.
|
||||
3. Render an individual Component.
|
||||
4. Mix-in your Platform's unique resources to all Components. For example, ArgoCD Application resources.
|
||||
5. Define multiple similar, but not identical, workload clusters.
|
||||
6. Render the manifests for the entire Platform with the `holos render platform` command.
|
||||
7. Upgrade a Helm chart to the latest version as an important Day 2 task.
|
||||
8. Visualize and surface the details of planned changes Platform wide.
|
||||
|
||||
## Dive Deeper
|
||||
|
||||
If you'd like to dive deeper, check out the [Schema API][schema] and [Core
|
||||
API][core] reference docs. The main difference between the schema and core
|
||||
packages is that the schema is used by users to write refined CUE, while the
|
||||
core package is what the schema produces for `holos` to execute. Users rarely
|
||||
need to interact with the Core API when on the happy path, but can use the core
|
||||
package as an escape hatch when the happy path doesn't go where you want.
|
||||
|
||||
|
||||
[application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
|
||||
[schema]: /docs/api/schema/v1alpha3/
|
||||
[core]: /docs/api/core/v1alpha3/
|
||||
10
doc/md/introduction.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
description: Holos Documentation
|
||||
slug: /
|
||||
---
|
||||
|
||||
# Introduction
|
||||
|
||||
:::warning TODO
|
||||
See [introduction](https://github.com/facebook/docusaurus/blob/main/website/docs/introduction.mdx?plain=1)
|
||||
:::
|
||||
@@ -1,311 +0,0 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Quickstart Guide
|
||||
|
||||
This guide shows you the basics of how Holos. You'll deploy a Helm chart to
|
||||
Kubernetes using a Component to see how Holos makes the process safer, easier,
|
||||
and more consistent.
|
||||
|
||||
## What you'll need {#Requirements}
|
||||
|
||||
You'll need the following tools installed to complete this guide.
|
||||
|
||||
1. [holos](/docs/install) - to build the platform.
|
||||
2. [helm](https://helm.sh/docs/intro/install/) - to render Holos components that wrap upstream Helm charts.
|
||||
3. [k3d](https://k3d.io/#installation) - to provide a Kubernetes API server.
|
||||
4. [OrbStack](https://docs.orbstack.dev/install) or [Docker](https://docs.docker.com/get-docker/) - to use k3d.
|
||||
5. [kubectl](https://kubernetes.io/docs/tasks/tools/) - to interact with the k8s api server.
|
||||
|
||||
## Install Holos
|
||||
|
||||
Install Holos with the following command or other methods listed on the
|
||||
[Installation](/docs/install/) page.
|
||||
|
||||
```bash
|
||||
go install github.com/holos-run/holos/cmd/holos@latest
|
||||
```
|
||||
|
||||
## Git repository
|
||||
|
||||
Start by initializing an empty Git repository. Holos is designed to operate
|
||||
against local files in a Git repository.
|
||||
|
||||
<Tabs groupId="init">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir holos-quickstart
|
||||
cd holos-quickstart
|
||||
git init
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
Initialized empty Git repository in /holos-quickstart/.git/
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
This guide assumes commands are run from the root directory of this Git
|
||||
repository unless otherwise stated.
|
||||
|
||||
## Generate the Platform {#Generate-Platform}
|
||||
|
||||
Generate the Platform code in the repository root. A Platform refers to all of
|
||||
the software and services integrated together to provide your organization's
|
||||
software development platform. In this guide the platform will contain a single
|
||||
Component to demonstrate how the concepts fit together.
|
||||
|
||||
```bash
|
||||
holos generate platform quickstart
|
||||
```
|
||||
|
||||
Commit the generated platform config to the repository.
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "holos generate platform quickstart - $(holos --version)"
|
||||
```
|
||||
|
||||
## Create a Component
|
||||
|
||||
The platform you generated is empty. Rendering the platform succeeds, but does
|
||||
nothing because there are no Components listed in the Platform spec:
|
||||
|
||||
```cue
|
||||
package holos
|
||||
|
||||
import core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
|
||||
core.#Platform & {
|
||||
metadata: name: "quickstart"
|
||||
}
|
||||
```
|
||||
|
||||
<Tabs groupId="render">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render platform ./platform
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```bash
|
||||
# No output is produced, the Platform contains no Components.
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Generate the CUE code definition for a Component that wraps the podinfo Helm
|
||||
chart.
|
||||
|
||||
<Tabs groupId="gen-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
mkdir -p components
|
||||
(cd components && holos generate component helm podinfo)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
generated component
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The HelmChart Component is defined in the `components/podinfo/podinfo.cue` file, for example:
|
||||
|
||||
```cue
|
||||
package holos
|
||||
|
||||
// Produce a helm chart build plan.
|
||||
(#Helm & Chart).Output
|
||||
|
||||
let Chart = {
|
||||
Name: "podinfo"
|
||||
Version: "6.6.2"
|
||||
Namespace: "default"
|
||||
|
||||
Repo: name: "podinfo"
|
||||
Repo: url: "https://stefanprodan.github.io/podinfo"
|
||||
|
||||
Values: {}
|
||||
}
|
||||
```
|
||||
|
||||
In this example we're providing the minimal information about the Helm chart we
|
||||
want to manage in this Component. The name, version, Kubernetes namespace to
|
||||
deploy into, and the chart repository location.
|
||||
|
||||
This chart deploys cleanly with no values provided, but we include an empty
|
||||
struct to illustrate how Holos improves the consistency and safety of Helm
|
||||
values by taking advantage the strong type checking in CUE. Shared values, such
|
||||
as the organization domain name, can safely be passed to all Components across
|
||||
all clusters in the Platform.
|
||||
|
||||
## Render the Component
|
||||
|
||||
Individual components can be rendered without needing to be included in a
|
||||
Platform spec, useful when developing a new component.
|
||||
|
||||
<Tabs groupId="render-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
cached
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
First, the command caches the helm chart locally to speed up subsequent
|
||||
renderings. Then the command executes helm to produce the output which is
|
||||
written into the deploy directory.
|
||||
|
||||
<Tabs groupId="tree-podinfo">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
└── components
|
||||
└── podinfo
|
||||
└── podinfo.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The component is deployed to one cluster named default. The same component is
|
||||
often deployed to multiple clusters, for example east and west for reliability.
|
||||
|
||||
This example is equivalent to executing `helm template` on the chart.
|
||||
|
||||
## Mix in an ArgoCD Application
|
||||
|
||||
So far we've seen how Holos is a convenient wrapper around Helm, but we haven't
|
||||
yet seen how it makes it easier to consistently and safely manage all of the
|
||||
software that goes into a platform. We'll mix in an ArgoCD
|
||||
[Application][application] resource to manage the podinfo Component with GitOps.
|
||||
We'll define this configuration in a way that is automatically and consistently
|
||||
re-used across all Components added to the Platform in the future, including
|
||||
Components which are not Helm charts.
|
||||
|
||||
Create a new file named `argocd.cue` in the root of your git repository with the
|
||||
following contents:
|
||||
|
||||
<Tabs groupId="argocd-config">
|
||||
<TabItem value="command" label="File: argocd.cue">
|
||||
```cue
|
||||
package holos
|
||||
|
||||
#ArgoConfig: {
|
||||
Enabled: true
|
||||
RepoURL: "https://example.com/holos-quickstart.git"
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="note" label="Note">
|
||||
If you plan to apply the rendered output to a real cluster, change the RepoURL
|
||||
to the url of the git repository you created in this guide. It is sufficient to
|
||||
keep the example URL if you're getting a feel for Holos and inspecting the
|
||||
rendered output without applying it to a live cluster.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
With this file in place, render the component again.
|
||||
|
||||
<Tabs groupId="render-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
holos render component ./components/podinfo --cluster-name=default
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
wrote deploy file
|
||||
rendered gitops/podinfo
|
||||
rendered podinfo
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The render command uses the cached chart this time around. Then, the helm
|
||||
template output is rendered along with an additional ArgoCD Application resource
|
||||
for GitOps in the `podinfo.application.gen.yaml` file.
|
||||
|
||||
<Tabs groupId="tree-podinfo-argocd">
|
||||
<TabItem value="command" label="Command">
|
||||
```bash
|
||||
tree deploy
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="output" label="Output">
|
||||
```txt
|
||||
deploy
|
||||
└── clusters
|
||||
└── default
|
||||
├── components
|
||||
│ └── podinfo
|
||||
│ └── podinfo.gen.yaml
|
||||
└── gitops
|
||||
└── podinfo.application.gen.yaml
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The Application resource looks like:
|
||||
|
||||
<Tabs groupId="podinfo-application">
|
||||
<TabItem value="file" label="podinfo.application.gen.yaml">
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
project: default
|
||||
source:
|
||||
path: ./deploy/clusters/default/components/podinfo
|
||||
repoURL: https://example.com/holos-quickstart.git
|
||||
targetRevision: main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
|
||||
Holos will generate a similar Application resource for all additional Components
|
||||
added to your Platform.
|
||||
|
||||
:::
|
||||
|
||||
In this section we learned how Holos provides a simple way to add an ArgoCD
|
||||
Application resource for the podinfo Component. Holos further provides
|
||||
consistency by creating a similar Application resource for every subsequent
|
||||
Component added to the platform in the future, all by defining the configuration
|
||||
of ArgoCD in a single place.
|
||||
|
||||
[application]: https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/
|
||||
|
||||
|
||||
## Quickstart Recap {#quickstart-recap}
|
||||
|
||||
In this guide we learned how to:
|
||||
|
||||
1. Install Holos.
|
||||
2. Generate a Git repository for the Platform config.
|
||||
3. Create a Component that wraps the upstream podinfo Helm Chart without modifications.
|
||||
4. Render individual components.
|
||||
5. Mix in an ArgoCD Application resource to every Component in the Platform.
|
||||
5
doc/md/start.md
Normal file
@@ -0,0 +1,5 @@
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
# Get Started
|
||||
|
||||
<DocCardList />
|
||||
@@ -1,9 +1,14 @@
|
||||
# Comparison with other tools
|
||||
---
|
||||
description: Compare Holos with other tools in the ecosystem.
|
||||
slug: /comparison
|
||||
sidebar_position: 300
|
||||
---
|
||||
|
||||
# Comparison
|
||||
|
||||
:::tip
|
||||
|
||||
Holos is designed to complement and improve, not replace, existing tools in the cloud native ecosystem.
|
||||
|
||||
Holos is designed to complement and improve, not replace, existing tools in the
|
||||
cloud native ecosystem.
|
||||
:::
|
||||
|
||||
## Helm
|
||||
@@ -30,13 +35,13 @@ TODO
|
||||
|
||||
## Timoni
|
||||
|
||||
| Aspect | Timoni | Holos | Comment |
|
||||
| -- | -- | -- | -- |
|
||||
| Language | CUE | CUE | Like Holos, Timoni is also built on CUE. |
|
||||
| Artifact | OCI Image | Plain YAML Files | The Holos Authors find plain files easier to work with and reason about than OCI images. |
|
||||
| Outputs to | OCI Image Repository | Local Git repository | Holos is designed for use with existing GitOps tools. |
|
||||
| Concept | Module | Component | A Timoni Module is analogous to a Holos Component. |
|
||||
| Concept | Bundle | Platform | A Timoni Bundle is somewhat similar, but smaller in scope to a Holos Platform. |
|
||||
| Aspect | Timoni | Holos | Comment |
|
||||
| ---------- | -------------------- | -------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| Language | CUE | CUE | Like Holos, Timoni is also built on CUE. |
|
||||
| Artifact | OCI Image | Plain YAML Files | The Holos Authors find plain files easier to work with and reason about than OCI images. |
|
||||
| Outputs to | OCI Image Repository | Local Git repository | Holos is designed for use with existing GitOps tools. |
|
||||
| Concept | Module | Component | A Timoni Module is analogous to a Holos Component. |
|
||||
| Concept | Bundle | Platform | A Timoni Bundle is somewhat similar, but smaller in scope to a Holos Platform. |
|
||||
|
||||
:::important
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
description: Learn the concepts and domain language Holos uses.
|
||||
slug: /concepts
|
||||
sidebar_position: 200
|
||||
---
|
||||
|
||||
# Concepts
|
||||
|
||||
## Introduction
|
||||
@@ -23,21 +29,34 @@ platform engineers.
|
||||
- [Platform](<#platform>) - A collection of Components integrated into a software development platform.
|
||||
- [Model](<#model>) - Structured data included in the Platform specification, available to all Components. For example, your organization's domain name.
|
||||
- [Rendering](<#rendering>) - Holos is a tool that makes the process of rendering Kubernetes manifests safer, easier, and consistent.
|
||||
- [Cluster](<#cluster>) - A Kubernetes cluster. Components are rendered for and applied to a Cluster.
|
||||
- [Fleet](<#fleet>) - A collection of Clusters with a similar purpose. A Platform is typically composed of two Fleets, one for management the second for workloads.
|
||||
|
||||
```mermaid
|
||||
graph BT
|
||||
graph TB
|
||||
Platform[<a href="#platform">Platform</a>]
|
||||
Component[<a href="#component">Components</a>]
|
||||
Cluster[<a href="#cluster">Cluster</a>]
|
||||
Fleet[<a href="#fleet">Fleet</a>]
|
||||
Component[<a href="#component">Component</a>]
|
||||
Helm[<a href="#component">Helm</a>]
|
||||
Kustomize[<a href="#component">Kustomize</a>]
|
||||
CUE[<a href="#component">CUE</a>]
|
||||
|
||||
Component --> Platform
|
||||
Cluster --> Platform
|
||||
Fleet --> Cluster
|
||||
Component --> Fleet
|
||||
Helm --> Component
|
||||
Kustomize --> Component
|
||||
CUE --> Component
|
||||
```
|
||||
|
||||
:::tip
|
||||
This graph is organized as a tree. We often say configuration at the root
|
||||
defines the broad Platform. Configuration at a leaf defines a Component of the
|
||||
Platform. The concept of a tree also reflects the filesystem organization of
|
||||
the configuration.
|
||||
:::
|
||||
|
||||
<!--
|
||||
|
||||
```mermaid
|
||||
@@ -336,6 +355,16 @@ graph LR
|
||||
FS --> kubectl --> C
|
||||
```
|
||||
|
||||
## Cluster
|
||||
|
||||
A Cluster represents a Kubernetes cluster. One component may be reused across
|
||||
multiple different Clusters.
|
||||
|
||||
## Fleet
|
||||
|
||||
A Fleet represents a group of Clusters that share a similar purpose. A Platform
|
||||
typically has two Fleets, one for management and one for workloads.
|
||||
|
||||
[krm]: https://docs.google.com/document/d/1RmHXdLhNbyOWPW_AtnnowaRfGejw-qlKQIuLKQWlwzs/view#heading=h.sa6p0aye4ide
|
||||
[Platform]: /docs/api/core/v1alpha2/#Platform
|
||||
[BuildPlan]: /docs/api/core/v1alpha2/#BuildPlan
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
description: Install the Holos executable.
|
||||
slug: /install
|
||||
sidebar_position: 100
|
||||
---
|
||||
|
||||
# Installation
|
||||
|
||||
Holos is distributed as a single file executable.
|
||||
@@ -41,12 +41,7 @@ const config: Config = {
|
||||
[
|
||||
'@docusaurus/plugin-client-redirects',
|
||||
{
|
||||
redirects: [
|
||||
{
|
||||
from: "/docs/tutorial/local/k3d/",
|
||||
to: "/docs/guides/try-holos/",
|
||||
},
|
||||
],
|
||||
redirects: [],
|
||||
},
|
||||
],
|
||||
],
|
||||
@@ -98,19 +93,14 @@ const config: Config = {
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'quickstart/index',
|
||||
docId: 'guides/quickstart',
|
||||
position: 'left',
|
||||
label: 'Try Holos',
|
||||
},
|
||||
{ to: '/docs', label: 'Docs', position: 'left' },
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'concepts',
|
||||
position: 'left',
|
||||
label: 'Docs',
|
||||
},
|
||||
{
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'api',
|
||||
docId: 'api',
|
||||
position: 'left',
|
||||
label: 'API',
|
||||
},
|
||||
@@ -135,7 +125,7 @@ const config: Config = {
|
||||
title: 'Docs',
|
||||
items: [
|
||||
{
|
||||
label: 'Get Started',
|
||||
label: 'Quickstart',
|
||||
to: '/docs/quickstart',
|
||||
},
|
||||
{
|
||||
@@ -144,11 +134,11 @@ const config: Config = {
|
||||
},
|
||||
{
|
||||
label: 'Documentation',
|
||||
to: '/docs/intro',
|
||||
to: '/docs',
|
||||
},
|
||||
{
|
||||
label: 'API Reference',
|
||||
to: '/docs/api/core/v1alpha2',
|
||||
to: '/docs/api',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -12,30 +12,63 @@ import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
|
||||
*/
|
||||
const sidebars: SidebarsConfig = {
|
||||
doc: [
|
||||
'quickstart/index',
|
||||
'concepts',
|
||||
'install',
|
||||
'comparison',
|
||||
],
|
||||
api: [
|
||||
'introduction',
|
||||
{
|
||||
label: 'Schema',
|
||||
type: 'category',
|
||||
collapsed: false,
|
||||
items: [
|
||||
'api/schema/v1alpha3',
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Core API',
|
||||
label: 'Getting Started',
|
||||
type: 'category',
|
||||
collapsed: true,
|
||||
link: { type: 'doc', id: 'start' },
|
||||
items: [
|
||||
'api/core/v1alpha3',
|
||||
'api/core/v1alpha2',
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'start',
|
||||
},
|
||||
],
|
||||
},
|
||||
'cli',
|
||||
{
|
||||
label: 'Guides',
|
||||
type: 'category',
|
||||
collapsed: false,
|
||||
link: { type: 'doc', id: 'guides' },
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'guides',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'API Reference',
|
||||
type: 'category',
|
||||
collapsed: true,
|
||||
link: { type: 'doc', id: 'api' },
|
||||
items: [
|
||||
{
|
||||
label: 'Schema API',
|
||||
type: 'category',
|
||||
link: { type: 'doc', id: 'api/schema' },
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'api/schema',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Core API',
|
||||
type: 'category',
|
||||
link: { type: 'doc', id: 'api/core' },
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'api/core',
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* Enable wrapping by default for mobile */
|
||||
pre code {
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-link-color: #268bd2;
|
||||
|
||||
38
doc/website/static/scripts/local-ca
Executable file
@@ -0,0 +1,38 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
mkcert --install
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
# Create the local CA Secret with ca.crt, tls.crt, tls.key
|
||||
|
||||
mkdir local-ca
|
||||
cd local-ca
|
||||
CAROOT="$(mkcert -CAROOT)"
|
||||
cp -p "${CAROOT}/rootCA.pem" ca.crt
|
||||
cp -p "${CAROOT}/rootCA.pem" tls.crt
|
||||
cp -p "${CAROOT}/rootCA-key.pem" tls.key
|
||||
kubectl create secret generic --from-file=. --dry-run=client -o yaml local-ca > ../local-ca.yaml
|
||||
cd ..
|
||||
|
||||
echo 'type: kubernetes.io/tls' >> local-ca.yaml
|
||||
kubectl apply --server-side=true -f- <<EOF
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
kubernetes.io/metadata.name: cert-manager
|
||||
name: cert-manager
|
||||
spec:
|
||||
finalizers:
|
||||
- kubernetes
|
||||
EOF
|
||||
kubectl apply -n cert-manager --server-side=true -f local-ca.yaml
|
||||
38
doc/website/static/scripts/local-dns
Normal file
@@ -0,0 +1,38 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
tmpdir="$(mktemp -d)"
|
||||
finish() {
|
||||
[[ -d "$tmpdir" ]] && rm -rf "$tmpdir"
|
||||
}
|
||||
trap finish EXIT
|
||||
cd "$tmpdir"
|
||||
|
||||
brew install dnsmasq
|
||||
|
||||
cat <<EOF >"$(brew --prefix)/etc/dnsmasq.d/holos.localhost.conf"
|
||||
# Refer to https://holos.run/docs/tutorial/local/k3d/
|
||||
address=/holos.localhost/127.0.0.1
|
||||
EOF
|
||||
|
||||
if [[ -r /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist ]]; then
|
||||
echo "dnsmasq already configured"
|
||||
else
|
||||
sudo cp "$(brew list dnsmasq | grep 'dnsmasq.plist$')" \
|
||||
/Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl unload /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
|
||||
dscacheutil -flushcache
|
||||
echo "dnsmasq configured"
|
||||
fi
|
||||
|
||||
sudo mkdir -p /etc/resolver
|
||||
sudo tee /etc/resolver/holos.localhost <<EOF
|
||||
domain holos.localhost
|
||||
nameserver 127.0.0.1
|
||||
EOF
|
||||
sudo killall -HUP mDNSResponder
|
||||
|
||||
echo "all done."
|
||||
@@ -52,33 +52,13 @@ func NewComponent() *cobra.Command {
|
||||
cmd := command.New("component")
|
||||
cmd.Short = "generate a component from an embedded schematic"
|
||||
|
||||
cmd.AddCommand(NewCueComponent())
|
||||
cmd.AddCommand(NewHelmComponent())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewHelmComponent() *cobra.Command {
|
||||
cmd := command.New("helm")
|
||||
cmd.Short = "generate a helm component from a schematic"
|
||||
|
||||
for _, name := range generate.HelmComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("helm", name))
|
||||
for _, name := range generate.Components("v1alpha3") {
|
||||
cmd.AddCommand(makeSchematicCommand("v1alpha3", name))
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCueComponent() *cobra.Command {
|
||||
cmd := command.New("cue")
|
||||
cmd.Short = "generate a cue component from a schematic"
|
||||
|
||||
for _, name := range generate.CueComponents() {
|
||||
cmd.AddCommand(makeSchematicCommand("cue", name))
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func makeSchematicCommand(kind, name string) *cobra.Command {
|
||||
cmd := command.New(name)
|
||||
cfg, err := generate.NewSchematic(filepath.Join("components", kind), name)
|
||||
|
||||
@@ -81,22 +81,10 @@ func (s *Schematic) FlagSet() *flag.FlagSet {
|
||||
return fs
|
||||
}
|
||||
|
||||
// CueComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func CueComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "cue"))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
dirs := make([]string, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
dirs = append(dirs, entry.Name())
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// HelmComponents returns a slice of embedded component schematics or nil if there are none.
|
||||
func HelmComponents() []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, "helm"))
|
||||
// Components returns a slice of embedded component schematics or nil if there
|
||||
// are none.
|
||||
func Components(name string) []string {
|
||||
entries, err := fs.ReadDir(components, filepath.Join(componentsRoot, name))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -131,8 +119,8 @@ func makeRenderFunc[T any](log *slog.Logger, path string, cfg T) func([]byte) *b
|
||||
func GenerateComponent(ctx context.Context, kind string, name string, cfg *Schematic) error {
|
||||
// use name from args to build the source path
|
||||
path := filepath.Join(componentsRoot, kind, name)
|
||||
// use cfg.Name from flags to build the destination path
|
||||
dstPath := filepath.Join(getCwd(ctx), cfg.Name)
|
||||
// write to the current directory.
|
||||
dstPath := filepath.Join(getCwd(ctx))
|
||||
log := logger.FromContext(ctx).With("name", cfg.Name, "path", dstPath)
|
||||
log.DebugContext(ctx, "mkdir")
|
||||
if err := os.MkdirAll(dstPath, os.ModePerm); err != nil {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package holos
|
||||
|
||||
// Manage podinfo on workload clusters only
|
||||
for Cluster in #Fleets.workload.clusters {
|
||||
#Platform: Components: "\(Cluster.name)/podinfo": {
|
||||
path: "components/podinfo"
|
||||
cluster: Cluster.name
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,10 @@
|
||||
// plate code and generating component build plans in a consistent manner.
|
||||
package v1alpha3
|
||||
|
||||
import core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
import (
|
||||
core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
// Helm provides a BuildPlan via the Output field which contains one HelmChart
|
||||
// from package core. Useful as a convenience wrapper to render a HelmChart
|
||||
@@ -92,3 +95,57 @@ import core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
// main.
|
||||
TargetRevision: string & (string | *"main")
|
||||
}
|
||||
|
||||
// Cluster represents a cluster managed by the Platform.
|
||||
#Cluster: {
|
||||
// Name represents the cluster name, for example "east1", "west1", or
|
||||
// "management".
|
||||
name: string @go(Name)
|
||||
|
||||
// Primary represents if the cluster is marked as the primary among a set of
|
||||
// candidate clusters. Useful for promotion of database leaders.
|
||||
primary: bool & (true | *false) @go(Primary)
|
||||
}
|
||||
|
||||
// Fleet represents a named collection of similarly configured Clusters. Useful
|
||||
// to segregate workload clusters from their management cluster.
|
||||
#Fleet: {
|
||||
name: string @go(Name)
|
||||
|
||||
// Clusters represents a mapping of Clusters by their name.
|
||||
clusters: {[string]: #Cluster} & {[Name=_]: name: Name} @go(Clusters,map[string]Cluster)
|
||||
}
|
||||
|
||||
// StandardFleets represents the standard set of Clusters in a Platform
|
||||
// segmented into Fleets by their purpose. The management Fleet contains a
|
||||
// single Cluster, for example a GKE autopilot cluster with no workloads
|
||||
// deployed for reliability and cost efficiency. The workload Fleet contains
|
||||
// all other Clusters which contain workloads and sync Secrets from the
|
||||
// management cluster.
|
||||
#StandardFleets: {
|
||||
// Workload represents a Fleet of zero or more workload Clusters.
|
||||
workload: #Fleet & {name: "workload"} @go(Workload)
|
||||
|
||||
// Management represents a Fleet with one Cluster named management.
|
||||
management: #Fleet & {name: "management", clusters: management: _} @go(Management)
|
||||
}
|
||||
|
||||
// Platform is a convenience structure to produce a core Platform specification
|
||||
// value in the Output field. Useful to collect components at the root of the
|
||||
// Platform configuration tree as a struct, which are automatically converted
|
||||
// into a list for the core Platform spec output.
|
||||
#Platform: {
|
||||
// Name represents the Platform name.
|
||||
Name: string & (string | *"holos")
|
||||
|
||||
// Components is a structured map of components to manage by their name.
|
||||
Components: {[string]: core.#PlatformSpecComponent} @go(,map[string]core.PlatformSpecComponent)
|
||||
|
||||
// Model represents the Platform model holos gets from from the
|
||||
// PlatformService.GetPlatform rpc method and provides to CUE using a tag.
|
||||
Model: structpb.#Struct & {...}
|
||||
|
||||
// Output represents the core Platform spec for the holos cli to iterate over
|
||||
// and render each listed Component, injecting the Model.
|
||||
Output: core.#Platform
|
||||
}
|
||||
|
||||
@@ -199,3 +199,12 @@ import (
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Platform: {
|
||||
Name: _
|
||||
Model: _
|
||||
Components: [string]: _
|
||||
Output: metadata: name: Name
|
||||
Output: spec: model: Model
|
||||
Output: spec: components: [for c in Components {c}]
|
||||
}
|
||||
|
||||
8
internal/generate/platforms/guide/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
vendor/
|
||||
1
internal/generate/platforms/guide/platform.config.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
3
internal/generate/platforms/guide/platform.gen.cue
Normal file
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform: Name: "guide"
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform.Output
|
||||
5
internal/generate/platforms/guide/readme.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Holos
|
||||
|
||||
Generated for use with [Holos Guides][guides].
|
||||
|
||||
[guides]: https://holos.run/docs/guides/
|
||||
15
internal/generate/platforms/guide/schema.gen.cue
Normal file
@@ -0,0 +1,15 @@
|
||||
package holos
|
||||
|
||||
import schema "github.com/holos-run/holos/api/schema/v1alpha3"
|
||||
|
||||
#Helm: schema.#Helm & {
|
||||
ArgoConfig: #ArgoConfig
|
||||
}
|
||||
|
||||
#ArgoConfig: schema.#ArgoConfig & {
|
||||
ClusterName: _ClusterName
|
||||
}
|
||||
|
||||
#Fleets: schema.#StandardFleets
|
||||
|
||||
#Platform: schema.#Platform
|
||||
14
internal/generate/platforms/guide/tags.gen.cue
Normal file
@@ -0,0 +1,14 @@
|
||||
package holos
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
dto "github.com/holos-run/holos/service/gen/holos/object/v1alpha1:object"
|
||||
)
|
||||
|
||||
// _ClusterName is the --cluster-name flag value provided by the holos cli.
|
||||
_ClusterName: string @tag(cluster, type=string)
|
||||
|
||||
// _PlatformConfig represents all of the data passed from holos to cue, used to
|
||||
// carry the platform and project models.
|
||||
_PlatformConfig: dto.#PlatformConfig & json.Unmarshal(_PlatformConfigJSON)
|
||||
_PlatformConfigJSON: string | *"{}" @tag(platform_config, type=string)
|
||||
@@ -1,7 +0,0 @@
|
||||
package holos
|
||||
|
||||
import core "github.com/holos-run/holos/api/core/v1alpha3"
|
||||
|
||||
core.#Platform & {
|
||||
metadata: name: "quickstart"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform.Output
|
||||
@@ -0,0 +1,3 @@
|
||||
package holos
|
||||
|
||||
#Platform: Name: "quickstart"
|
||||
@@ -9,3 +9,7 @@ import schema "github.com/holos-run/holos/api/schema/v1alpha3"
|
||||
#ArgoConfig: schema.#ArgoConfig & {
|
||||
ClusterName: _ClusterName
|
||||
}
|
||||
|
||||
#Fleets: schema.#StandardFleets
|
||||
|
||||
#Platform: schema.#Platform
|
||||
|
||||
@@ -1 +1 @@
|
||||
1
|
||||
3
|
||||
|
||||