Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"bootstrap/kro": "1.1.0",
"services/dns-mirror": "0.3.1",
"services/github-token-broker": "0.2.1",
"schemas/lab": "0.1.0",
"tools/labctl": "0.2.0"
}
5 changes: 5 additions & 0 deletions schemas/lab/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ This module contains shared CUE schemas for GilmanLab lab tooling.
The CUE definitions are the source of truth. Generated Go types are committed
for Go consumers that need typed access to the same contracts.

Packages:

- `incusos` — IncusOS image build and seed configuration.
- `talos` — Talos Image Factory download and NoCloud config artifact builds.

Validate and regenerate from this directory:

```sh
Expand Down
3 changes: 2 additions & 1 deletion schemas/lab/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ tasks:
test:
command: 'go test ./...'
toolchains: 'system'
deps:
- 'schemas:generate-check'
inputs:
- '**/*.go'
- 'go.mod'
Expand All @@ -71,7 +73,6 @@ tasks:
- 'schemas:format'
- 'schemas:tidy'
- 'schemas:vet'
- 'schemas:generate-check'
- 'schemas:test'
options:
cache: false
Expand Down
33 changes: 33 additions & 0 deletions schemas/lab/talos/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Talos Schema

This package defines the CUE schema for Talos image build configuration. It is
used by platform tooling, including `labctl`, to validate the Image Factory
source, Talos machine configuration delivery, and generated local artifacts for
the temporary bootstrap cluster.

The CUE schema is the source of truth; Go types are generated from `schema.cue`.

## Example

```cue
package images

import talos "github.com/gilmanlab/platform/schemas/lab/talos"

build: talos.#ImageBuild & {
name: "bootstrap-talos-controlplane"
source: {
version: "v1.13.0"
}
config: {
userData: path: "controlplane.yaml"
metaData: localHostname: "bootstrap-controlplane-1"
}
output: {
dir: ".state/images/talos-bootstrap"
format: "img"
bootArtifactName: "talos-bootstrap-amd64.img"
configArtifactName: "talos-bootstrap-cidata.img"
}
}
```
120 changes: 120 additions & 0 deletions schemas/lab/talos/cue_types_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions schemas/lab/talos/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package talos contains generated Go types for the Talos image build schema.
package talos
122 changes: 122 additions & 0 deletions schemas/lab/talos/schema.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package talos

@go(talos)

// NonEmptyString is a required string value that must not be empty.
#NonEmptyString: (string & !="") | error("must be a non-empty string")

// HTTPURL is an HTTP or HTTPS URL.
#HTTPURL: (#NonEmptyString & =~"^https?://") | error("must be an HTTP or HTTPS URL")

// RelativePath is a repository- or config-relative path.
#RelativePath: (#NonEmptyString & !~"^/" & !~"(^|/)\\.\\.(/|$)" & !~"\\\\") |
error("path must be relative and use forward slashes")

// ArtifactName is a local artifact filename, not a path.
#ArtifactName: (#NonEmptyString & !~"/" & !~"\\\\" & =~"\\.img$") |
error("artifact name must be an .img filename")

// SchematicID is an Image Factory schematic ID.
#SchematicID: =~"^[a-f0-9]{64}$" | error("schematic ID must be a 64-character lowercase hex string")

// TalosVersion selects an exact Talos Linux release.
#TalosVersion: =~"^v[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?(\\+[0-9A-Za-z.-]+)?$" |
error("Talos version must be an exact release like v1.13.0")

// Architecture selects the Talos image architecture.
#Architecture: *"amd64" | "amd64" | "arm64" | error("architecture must be amd64 or arm64")

// Platform selects the Talos image platform.
#Platform: *"nocloud" | "nocloud" | error("platform must be nocloud")

// SourceArtifact selects the Image Factory artifact to download.
#SourceArtifact: *"raw.xz" | "raw.xz" | error("source artifact must be raw.xz")

// OutputFormat selects the local artifact format produced by the build.
#OutputFormat: *"img" | "img" | error("format must be img")

// ConfigDelivery selects how the Talos machine configuration is delivered.
#ConfigDelivery: *"nocloud-cidata" | "nocloud-cidata" |
error("config delivery must be nocloud-cidata")

// DNSLabel is a single RFC 1123-style hostname label.
#DNSLabel: (#NonEmptyString & =~"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$") |
error("hostname must be a lowercase DNS label")

// FileInput points at a local file consumed by the build.
#FileInput: {
@go(FileInput)

// Path is a relative path from the build config directory.
path!: #RelativePath
}

// ImageSource describes the Talos Image Factory asset to download.
#ImageSource: {
@go(ImageSource)

// FactoryURL is the Image Factory base URL.
factoryURL: *"https://factory.talos.dev" | #HTTPURL @go(FactoryURL)
// Version is the exact Talos Linux release to download.
version!: #TalosVersion
// SchematicID identifies the Image Factory schematic.
schematicID: *"376567988ad370138ad0c15e58e1dcefd698631a5d546e5f7c7e1a6d167663f3" | #SchematicID @go(SchematicID)
// Platform selects the Talos platform image.
platform: #Platform
// Arch selects the Talos image architecture.
arch: #Architecture
// Artifact selects the compressed Image Factory disk artifact.
artifact: #SourceArtifact
}

// NoCloudMetaData describes the meta-data file in the NoCloud cidata image.
#NoCloudMetaData: {
@go(NoCloudMetaData)

// LocalHostname is the VM hostname advertised through NoCloud.
localHostname!: #DNSLabel @go(LocalHostname)
// InstanceID identifies this NoCloud instance. It defaults to localHostname.
instanceID: *localHostname | #NonEmptyString @go(InstanceID)
}

// MachineConfig describes Talos machine configuration delivery.
#MachineConfig: {
@go(MachineConfig)

// Delivery controls how config files are packaged for Talos.
delivery: #ConfigDelivery
// UserData is the Talos machine config written as NoCloud user-data.
userData!: #FileInput @go(UserData)
// MetaData is the NoCloud meta-data payload.
metaData!: #NoCloudMetaData @go(MetaData)
// NetworkConfig optionally points at a NoCloud network-config file.
networkConfig?: #FileInput @go(NetworkConfig)
}

// ImageOutput describes the local artifacts produced by the build.
#ImageOutput: {
@go(ImageOutput)

// Dir is the output directory for generated artifacts.
dir!: #NonEmptyString
// Format is the local artifact format.
format: #OutputFormat
// BootArtifactName is the Talos boot disk IMG filename.
bootArtifactName!: #ArtifactName @go(BootArtifactName)
// ConfigArtifactName is the NoCloud cidata IMG filename.
configArtifactName!: #ArtifactName @go(ConfigArtifactName)
}

// ImageBuild is the top-level Talos image download and config packaging contract.
#ImageBuild: {
@go(ImageBuild)

// Name is the stable build name used in logs and generated metadata.
name!: #NonEmptyString
// Source describes the upstream Talos image to download.
source!: #ImageSource
// Config describes Talos machine configuration delivery.
config!: #MachineConfig
// Output describes the local artifacts produced by the build.
output!: #ImageOutput
}
11 changes: 11 additions & 0 deletions schemas/lab/talos/schema_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package talos

import _ "embed"

//go:embed schema.cue
var schemaSource string

// SchemaSource returns the CUE source for the Talos schema package.
func SchemaSource() string {
return schemaSource
}
8 changes: 8 additions & 0 deletions tools/labctl/moon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ tasks:
lint:
command: 'bash -lc "if find . -name ''*.go'' -not -path ''./vendor/*'' -print -quit | grep -q .; then go tool golangci-lint run --config .golangci.yml ./...; else echo ''no Go files to lint''; fi"'
toolchains: 'system'
deps:
- 'schemas:generate-check'
inputs:
- '/go.work'
- '/go.work.sum'
Expand All @@ -29,6 +31,8 @@ tasks:
format:
command: 'bash -lc "if find . -name ''*.go'' -not -path ''./vendor/*'' -print -quit | grep -q .; then go tool golangci-lint fmt --config .golangci.yml --diff; else echo ''no Go files to format''; fi"'
toolchains: 'system'
deps:
- 'schemas:generate-check'
inputs:
- '/go.work'
- '/go.work.sum'
Expand All @@ -44,6 +48,8 @@ tasks:
test:
command: 'bash -lc "if find . -name ''*.go'' -not -path ''./vendor/*'' -print -quit | grep -q .; then go test ./...; else echo ''no Go packages to test''; fi"'
toolchains: 'system'
deps:
- 'schemas:generate-check'
inputs:
- '/go.work'
- '/go.work.sum'
Expand Down Expand Up @@ -83,6 +89,8 @@ tasks:
printf "version output: %s\n" "${output}"
[[ "${output}" == "labctl dev" ]]
toolchains: 'system'
deps:
- 'schemas:generate-check'
inputs:
- '/go.work'
- '/go.work.sum'
Expand Down
Loading