Skip to content

Generate config docs/json-schema from structs, add "k0sctl validate" and "k0sctl docs"#1029

Draft
kke wants to merge 3 commits into
mainfrom
config-doc
Draft

Generate config docs/json-schema from structs, add "k0sctl validate" and "k0sctl docs"#1029
kke wants to merge 3 commits into
mainfrom
config-doc

Conversation

@kke

@kke kke commented Feb 19, 2026

Copy link
Copy Markdown
Contributor

Config docs no longer live in the README.md and instead end up in docs/configuration.md.

  • k0sctl validate allows validating a config.
  • k0sctl docs outputs the config docs so you don't have to open a browser.
  • Config docs are generated from structs, not written and synced manually.

kke added 2 commits February 19, 2026 13:39
Signed-off-by: Kimmo Lehto <klehto@mirantis.com>
Signed-off-by: Kimmo Lehto <klehto@mirantis.com>
Signed-off-by: Kimmo Lehto <klehto@mirantis.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR moves k0sctl configuration documentation/schema generation to be derived from the Go config structs, and exposes that documentation (and config validation) via CLI subcommands.

Changes:

  • Add an internal schema/doc generator (internal/schemagen) that emits docs/k0sctl-schema.json and docs/configuration.md.
  • Add k0sctl docs command to display the embedded configuration documentation (Markdown) or JSON Schema.
  • Enrich config structs with field comments and jsonschema tags to drive generated docs/schema output.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/uploadfile.go Adds documentation comments + jsonschema metadata for file upload config fields.
pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/spec.go Adds doc comments and jsonschema-required markers for spec fields.
pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/options.go Adds doc comments and jsonschema defaults/enums for options.
pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/k0s.go Adds doc comments and jsonschema defaults/enums for k0s settings.
pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster/host.go Adds doc comments and jsonschema required/enums/defaults for host fields.
pkg/apis/k0sctl.k0sproject.io/v1beta1/cluster.go Adds doc comments and jsonschema required/defaults for top-level Cluster config.
internal/schemagen/rig_schemas.go Provides hand-written JSON schema for external rig connection structs.
internal/schemagen/preamble.md Adds a generated-doc preamble and example config used in docs output.
internal/schemagen/markdown.go Renders Markdown field reference from generated JSON schema.
internal/schemagen/main.go Implements the schema/doc generation entrypoint (go run ./internal/schemagen).
internal/schemagen/appendix.md Adds an appendix with connection types, hooks, uploads, tokens, etc.
docs/k0sctl-schema.json Generated JSON Schema committed to the repo for editor validation.
docs/configuration.md Generated Markdown reference committed to the repo for user docs.
docs/docs.go Embeds generated docs/schema into the binary for k0sctl docs.
cmd/root.go Registers new CLI commands (validate, docs) in the root command list.
cmd/docs.go Implements k0sctl docs command and terminal rendering logic.
cmd/apply.go Minor formatting-only diff (blank line removal).
README.md Updates README to link to generated docs/schema and documents k0sctl validate.
Makefile Adds docs and check-docs targets for generating/verifying docs outputs.
go.mod Adds schema/doc generation and terminal markdown rendering dependencies.
go.sum Updates dependency checksums for newly introduced modules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/root.go
Comment on lines 48 to +52
Commands: []*cli.Command{
versionCommand,
applyCommand,
validateCommand,
docsCommand,

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateCommand is referenced in the command list, but there is no definition of validateCommand in the cmd package in this PR state. This will fail to compile. Add the missing validate command implementation (e.g. cmd/validate.go) or remove the reference until it's included.

Copilot uses AI. Check for mistakes.
Comment thread cmd/docs.go
Comment on lines +32 to +38
md := string(k0sctldocs.ConfigurationMD)

outFile, isTerminal := ctx.App.Writer.(*os.File)
if isTerminal {
fi, err := outFile.Stat()
if err != nil || (fi.Mode()&os.ModeCharDevice) == 0 {
isTerminal = false

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outFile, isTerminal := ctx.App.Writer.(*os.File) will panic if ctx.App.Writer is not an *os.File (e.g. when NewK0sctl is used with a bytes.Buffer in tests or other integrations). Use a safe type assertion (outFile, ok := ...) and treat non-*os.File writers as non-terminals.

Copilot uses AI. Check for mistakes.
Comment on lines +132 to +156
// injectDefaults walks the schema definitions and copies `default` values from
// Go struct tags (already parsed by the reflector into Extras) into the Default
// field.
func injectDefaults(schema *jsonschema.Schema) {
if schema.Definitions != nil {
for _, def := range schema.Definitions {
injectDefaultsInSchema(def)
}
}
injectDefaultsInSchema(schema)
}

func injectDefaultsInSchema(s *jsonschema.Schema) {
if s == nil {
return
}
if s.Properties != nil {
for pair := s.Properties.Oldest(); pair != nil; pair = pair.Next() {
injectDefaultsInSchema(pair.Value)
}
}
if s.Items != nil {
injectDefaultsInSchema(s.Items)
}
}

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

injectDefaults/injectDefaultsInSchema is documented as copying default values from the reflector's Extras into Schema.Default, but the current implementation only recurses and never reads Extras or sets Default. As a result, defaults expressed via default:"..." struct tags won't appear in the generated schema/docs (e.g. Spec.K0s.DynamicConfig has default:"false" but no schema default). Either implement the default extraction/parsing or remove/update this logic and rely solely on explicit jsonschema:"default=..." tags.

Copilot uses AI. Check for mistakes.
Comment on lines 39 to +42
PermMode any `yaml:"perm,omitempty"`
DirPermMode any `yaml:"dirPerm,omitempty"`
// Permission mode for directories created by k0sctl during upload.
DirPermMode any `yaml:"dirPerm,omitempty" jsonschema:"default=0755"`
// Owner user name for the uploaded file(s) and created directories. Must already

Copilot AI Feb 19, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DirPermMode is documented/tagged with a JSON Schema default of 0755, but because the field type is any and there is no runtime defaulting in UnmarshalYAML, DirPermMode/DirPermString remain unset when the user omits dirPerm. This also results in the generated docs/k0sctl-schema.json lacking a default for dirPerm. Consider changing the type to a concrete type (e.g. string or int) and/or applying an explicit default during unmarshalling so both behavior and generated schema/docs match the documented default.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants