-
Notifications
You must be signed in to change notification settings - Fork 55
feat: add llms.txt for better LLM usage #492
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
rothgar
wants to merge
1
commit into
siderolabs:main
Choose a base branch
from
rothgar:llm.txt
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,186 @@ | ||
| # Talos Linux Image Factory | ||
|
|
||
| The Image Factory builds and serves customized Talos Linux boot artifacts. Artifacts are parameterized by a **schematic** (a hash-identified YAML document describing customizations) and a **Talos Linux version**. The official instance is at `https://factory.talos.dev` (HTTP/OCI) and `https://pxe.talos.dev` (PXE). | ||
|
|
||
| ## Core Concepts | ||
|
|
||
| **Schematic**: A YAML document that describes image customizations. Submitting one returns a stable SHA-256 ID. The same customizations always produce the same ID. The well-known default schematic (no customizations) has ID `376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba`. | ||
|
|
||
| **Version**: A Talos Linux release version string, e.g. `v1.5.0`. Use `GET /versions` to list available versions. | ||
|
|
||
| **Model**: The combination of a schematic ID and a Talos version. From a model you can derive any artifact type. | ||
|
|
||
| ## Typical Workflow | ||
|
|
||
| 1. POST a schematic → get back an ID | ||
| 2. GET `/versions` to find a version to target | ||
| 3. GET `/image/:schematic/:version/:path` to download an artifact | ||
|
|
||
| ## HTTP API (`https://factory.talos.dev`) | ||
|
|
||
| **Authentication**: The official public instance (`factory.talos.dev`) does not require authentication. Self-hosted deployments may enable an auth provider, in which case all schematic and image endpoints require credentials (HTTP Basic Auth via htpasswd). If you receive a `401 Unauthorized`, check the deployment's authentication configuration. The `/versions`, `/version/:version/extensions/official`, `/version/:version/overlays/official`, `/secureboot/signing-cert.pem`, and `/oci/cosign/signing-key.pub` endpoints are typically public even when auth is enabled. | ||
|
|
||
| ### POST /schematics | ||
|
|
||
| Create a schematic. Request body is YAML (or JSON). Returns `{"id": "<sha256>", "schematic": "<canonical-yaml>"}`. | ||
|
|
||
| ```yaml | ||
| customization: | ||
| extraKernelArgs: # optional | ||
| - vga=791 | ||
| meta: # optional, initial Talos META | ||
| - key: 0xa | ||
| value: "{}" | ||
| systemExtensions: | ||
| officialExtensions: # optional | ||
| - siderolabs/gvisor | ||
| - siderolabs/amd-ucode | ||
| secureboot: # optional, SecureBoot images only | ||
| includeWellKnownCertificates: true | ||
| enrollKeys: force # off | manual | if-safe | force | ||
| bootloader: sd-boot # optional: auto | sd-boot | dual-boot | grub | ||
| embeddedMachineConfiguration: | # optional, YAML machine config docs | ||
| apiVersion: v1alpha1 | ||
| kind: HostnameConfig | ||
| hostname: my-host | ||
| diskImage: # optional, disk images only | ||
| sectorSize: 4096 | ||
| overlay: # optional, for SBC/overlay targets | ||
| image: ghcr.io/siderolabs/sbc-raspberry-pi | ||
| name: rpi_generic | ||
| options: | ||
| data: "mydata" | ||
| ``` | ||
|
|
||
| ### GET /schematics/:schematic | ||
|
|
||
| Retrieve schematic YAML by ID. Returns 404 if not found. | ||
|
|
||
| ### GET /versions | ||
|
|
||
| List available Talos Linux versions. Returns a JSON array of version strings. | ||
|
|
||
| ```json | ||
| ["v1.5.0","v1.5.1","v1.5.2"] | ||
| ``` | ||
|
|
||
| ### GET /version/:version/extensions/official | ||
|
|
||
| List official system extensions for a version. Returns array of `{name, ref, digest}`. | ||
|
|
||
| ### GET /version/:version/overlays/official | ||
|
|
||
| List official overlays (e.g. SBC support) for a version. Returns array of `{name, image, ref, digest}`. | ||
|
|
||
| ### GET /image/:schematic/:version/:path | ||
|
|
||
| Download a boot artifact. `:path` values: | ||
|
|
||
| | Path pattern | Description | | ||
| |---|---| | ||
| | `kernel-<arch>` | Raw kernel (e.g. `kernel-amd64`) | | ||
| | `cmdline-<platform>-<arch>[-secureboot]` | Kernel command line | | ||
| | `initramfs-<arch>.xz` | Initramfs (with extensions) | | ||
| | `<platform>-<arch>[-secureboot].iso` | ISO image | | ||
| | `<platform>-<arch>[-secureboot]-uki.efi` | UEFI UKI image | | ||
| | `installer-<arch>[-secureboot].tar` | Metal installer OCI tar | | ||
| | `<platform>-installer-<arch>[-secureboot].tar` | Platform-specific installer | | ||
| | `metal-<arch>[-secureboot].raw.xz` | Raw disk image (metal) | | ||
| | `aws-<arch>.raw.xz` | Raw disk image for AWS AMI import | | ||
| | `gcp-<arch>.raw.tar.gz` | Raw disk image for GCE import | | ||
|
|
||
| `<arch>` is `amd64` or `arm64`. `<platform>` examples: `metal`, `aws`, `gcp`, `azure`, `vmware`. | ||
|
|
||
| Append `.sha256` or `.sha512` to any path to get a checksum file (Enterprise only). | ||
|
|
||
| ### GET /talosctl/:version | ||
|
|
||
| List `talosctl` binary download URLs for a version (available from v1.11.0+). | ||
|
|
||
| ### GET /talosctl/:version/:path | ||
|
|
||
| Download a `talosctl` binary. `:path` example: `talosctl-linux-amd64`. | ||
|
|
||
| ### GET /secureboot/signing-cert.pem | ||
|
|
||
| Returns the PEM-encoded SecureBoot signing certificate for manual UEFI enrollment. | ||
|
|
||
| ## PXE API (`https://pxe.talos.dev`) | ||
|
|
||
| ### GET /pxe/:schematic/:version/:path | ||
|
|
||
| Returns an iPXE script that boots Talos Linux. `:path` is `<platform>-<arch>[-secureboot]`, e.g. `metal-amd64`. | ||
|
|
||
| Example iPXE chain URL to embed in firmware: | ||
| ``` | ||
| chain --replace --autofree https://pxe.talos.dev/pxe/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.5.0/metal-${buildarch} | ||
| ``` | ||
|
|
||
| ## OCI Registry API (`factory.talos.dev`) | ||
|
|
||
| Pull installer images directly with `docker`/`crane`/`skopeo`: | ||
|
|
||
| ``` | ||
| # Legacy form | ||
| docker pull factory.talos.dev/installer/<schematic>:<version> | ||
| docker pull factory.talos.dev/installer-secureboot/<schematic>:<version> | ||
|
|
||
| # Current form (preferred) | ||
| docker pull factory.talos.dev/metal-installer/<schematic>:<version> | ||
| docker pull factory.talos.dev/aws-installer/<schematic>:<version> | ||
|
|
||
| # latest tag resolves to latest stable (non-prerelease) version | ||
| docker pull factory.talos.dev/metal-installer/<schematic>:latest | ||
| ``` | ||
|
|
||
| ### GET /oci/cosign/signing-key.pub | ||
|
|
||
| Returns the PEM-encoded public key used to sign installer images. Verify with: | ||
|
|
||
| ```shell | ||
| cosign verify --offline --insecure-ignore-tlog --insecure-ignore-sct \ | ||
| --key signing-key.pub factory.talos.dev/metal-installer/<schematic>:<version> | ||
| ``` | ||
|
|
||
| ## Enterprise-Only APIs | ||
|
|
||
| Requires Talos Enterprise Image Factory. Available from Talos v1.11.0+. | ||
|
|
||
| ### GET /spdx/:schematic/:version/:arch | ||
|
|
||
| Returns an SPDX 2.3 JSON SBOM for the given schematic and version. | ||
|
|
||
| ### GET /vex/:version/vex.json | ||
|
|
||
| Returns a VEX JSON document for vulnerability suppression. | ||
|
|
||
| ### GET /scans/:schematic/:version/:arch/:report | ||
|
|
||
| Returns a vulnerability scan report. `:report` suffix: `.json`, `.table`, `.sarif`, `.cdx`. | ||
|
|
||
| ## Examples | ||
|
|
||
| Download a default metal AMD64 ISO for Talos v1.7.0: | ||
| ```shell | ||
| curl -LO https://factory.talos.dev/image/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba/v1.7.0/metal-amd64.iso | ||
| ``` | ||
|
|
||
| Create a schematic with an extension and download its installer image: | ||
| ```shell | ||
| # 1. Create schematic | ||
| curl -s -X POST https://factory.talos.dev/schematics \ | ||
| -H 'Content-Type: application/yaml' \ | ||
| --data-binary 'customization: | ||
| systemExtensions: | ||
| officialExtensions: | ||
| - siderolabs/gvisor' | ||
| # Returns: {"id":"<id>","schematic":"..."} | ||
|
|
||
| # 2. Pull installer | ||
| docker pull factory.talos.dev/metal-installer/<id>:v1.7.0 | ||
| ``` | ||
|
|
||
| List extensions available for a version: | ||
| ```shell | ||
| curl https://factory.talos.dev/version/v1.7.0/extensions/official | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
|
||
| package http | ||
|
|
||
| import ( | ||
| "context" | ||
| "net/http" | ||
|
|
||
| "github.com/julienschmidt/httprouter" | ||
| ) | ||
|
|
||
| // handleLLMsTxt serves the llms.txt file describing the Image Factory API for LLM agents. | ||
| func (f *Frontend) handleLLMsTxt(_ context.Context, w http.ResponseWriter, _ *http.Request, _ httprouter.Params) error { | ||
| w.Header().Set("Content-Type", "text/plain; charset=utf-8") | ||
| _, err := w.Write(getLLMsTxt()) | ||
|
|
||
| return err | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| // This Source Code Form is subject to the terms of the Mozilla Public | ||
| // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
|
|
||
| package http_test | ||
|
|
||
| import ( | ||
| "net/http" | ||
| "net/http/httptest" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| "go.uber.org/zap" | ||
|
|
||
| frontendhttp "github.com/siderolabs/image-factory/internal/frontend/http" | ||
| ) | ||
|
|
||
| func TestHandleLLMsTxt(t *testing.T) { | ||
| frontend := frontendhttp.NewTestFrontend(zap.NewNop()) | ||
|
|
||
| w := httptest.NewRecorder() | ||
| r := httptest.NewRequestWithContext(t.Context(), http.MethodGet, "/llms.txt", nil) | ||
|
|
||
| frontend.WrapHandler(frontend.HandleLLMsTxt())(w, r, nil) | ||
|
|
||
| resp := w.Result() | ||
| require.Equal(t, http.StatusOK, resp.StatusCode) | ||
| assert.Equal(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) | ||
| assert.NotEmpty(t, w.Body.Bytes()) | ||
| assert.Contains(t, w.Body.String(), "factory.talos.dev") | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we render this on build? This is technically just a docs/API.md with some minor changes, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's just a raw text endpoint. I'm not sure what the difference would be with rendering on build vs embedding. Happy to do it a different way, I just wanted something that was easier for discovery and usage.