plugins

package
v0.33.16 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2026 License: Apache-2.0 Imports: 45 Imported by: 0

README

d8 plugins

The internal/plugins package manages d8 plugins: standalone binaries published to an OCI registry that d8 installs, updates, and runs as if they were native subcommands. The machinery lives in this package (the Manager); the d8 dist plugins cobra commands are a thin layer on top of it in internal/plugins/cmd (package pluginscmd), one file per command, mounted as a subtree of d8 dist (internal/dist/cmd) - the same machinery/commands split internal/selfupdate / internal/dist/cmd uses.

Why

  • Isolate dependencies and let teams develop plugins independently of d8.
  • Keep d8 itself compact - heavy functionality ships as plugins.
  • Guarantee compatibility: a plugin declares requirements (Kubernetes, Deckhouse, modules, other plugins) and d8 enforces them both at install time and before every run.

Commands

Command What it does
d8 dist plugins install <name> [--version X] [--use-major N] [--force] install a plugin, switch its version, or update it - installing one that is already present updates it to the newest cluster-compatible version within its current major
d8 dist plugins install --all [--force] the same for every installed plugin at once, each within its own major. Rejects --version and --use-major, which pin a single plugin
d8 dist plugins list the plugins installed on disk, plus - only on a transport that can enumerate, i.e. --source - those published in the registry and ready to install
d8 dist plugins versions <name> list all published versions of one plugin (installed one marked; same verb as d8 dist versions). A release is published one tag per platform; those are collapsed into one line per version listing the platforms it was built for
d8 dist plugins contract <name> show a plugin's contract
d8 dist plugins remove <name> remove an installed plugin
d8 <plugin> ... (wrapper) run an installed plugin; auto-installs it on first use

Overriding a built-in command

A handful of top-level commands are overridable: delivery-kit, data, snapshot, iam, network, v, stronghold, package and system. Install a plugin named exactly like one of them and it takes the command over; with no such plugin installed, the built-in implementation serves it. The table lives in overridableCommands (cmd/d8/root.go).

Details worth knowing:

  • Already-installed only. The override never reaches the registry: a plugin that exists upstream but is not installed locally does not displace a built-in, so d8 starts with no network access and no surprises. Auto-install on first use therefore applies only to plugins that are not shadowing a built-in.
  • Canonical names only. A plugin must match the command's own name, never one of its aliases - there is no dk plugin, only delivery-kit. The built-in's aliases carry over to the wrapper, so d8 dk and d8 s keep working after an override.
  • Resolved before flag parsing. Which commands get registered is decided at startup, so --plugins-dir cannot influence it; only the DECKHOUSE_CLI_PATH env var can. Both the configured root and the ~/.deckhouse-cli fallback are searched.
  • Dependency bookkeeping. delivery-kit and package satisfy a plugin's dependency on that name while they ship as built-ins. Once a plugin takes one over, the name drops off that list and the dependency resolves against the real plugin, version constraints included.

Transports

Plugins reach the registry over one of two transports, chosen in InitPluginServices (init.go) by whether the hidden --source flag is set. Both implement pluginSource (source.go) and report which one they are via Transport(), so a message can name the transport instead of leaving it implicit.

They differ in one capability, expressed as the separate pluginCatalog interface:

TransportRPP TransportRegistry
selected by default --source
credentials none (kubeconfig identity) registry login / license
install, update, versions, contract (by exact name) yes yes
enumerate published plugins (pluginCatalog) no yes
cluster-side requirement checks enforced force-skipped

Enumeration is a property of the transport, not a runtime failure. The catalog is the tag list of the deckhouse-cli/plugins repository, and the proxy allowlist (isAllowedCLIImagePath in the Deckhouse repo) admits only deckhouse-cli and deckhouse-cli/plugins/<name>, explicitly refusing the bare deckhouse-cli/plugins path. So rppPluginSource does not implement pluginCatalog and never issues the request; AvailablePlugins returns ErrCatalogUnsupported naming the transport, and d8 dist plugins list prints its installed half as usual.

  • rppPluginSource (rpp_source.go) - TransportRPP, the default and only supported source. Plugins are pulled through the in-cluster registry-packages-proxy using the kubeconfig identity, with no registry credentials on the user side (ADR #386: deckhouse-cli reaches the registry exclusively through the proxy, so every command needs a reachable cluster). See internal/selfupdate/README.md for what RPP is and how authorization works - plugin download is gated by the same d8:registry-packages-proxy:cli-download ClusterRole as self-update, because both travel the /v1/images/ route. The plugin routes are /v1/images/deckhouse-cli/plugins/<name>/{tags,manifests/<ref>,images/<version>}.
  • registryPluginSource (source_legacy.go) - TransportRegistry, a temporary, hidden --source bypass. It pulls straight from a registry repo with go-containerregistry, skipping the proxy and the cluster, and force-sets --skip-cluster-checks. It exists for pre-#386 workflows and is documented for removal (grep marker legacy --source).

What a plugin image contains

  • plugin - the executable, in the image layers;
  • the contract - name, version, description, requested env vars, flags, and requirements (Kubernetes / Deckhouse / modules / plugins) - published as a base64-JSON contract annotation on the image manifest.

The RPP source fetches the raw image manifest over the proxy manifests/<ref> route (a single manifest fetch, no layer pull) and reads the contract from its base64-JSON contract annotation itself. The binary is pulled separately (full image, over the images/<version> route) only when a plugin is installed.

On-disk layout

<plugins-dir>/                       # /opt/deckhouse/lib/deckhouse-cli by default
├── plugins/<name>/
│   ├── v<major>/<name>             # one binary per major version
│   ├── current -> v<major>/<name>  # the active version (atomic symlink swap)
│   └── install.lock                # one install lock per plugin
└── cache/contracts/<name>.json     # contract of the installed version (atomic writes)
  • --plugins-dir / DECKHOUSE_CLI_PATH override the root; if it is not writable, installs fall back to ~/.deckhouse-cli.
  • "Installed" means "has a current symlink" - a leftover directory from a failed install is never treated as an installed plugin.

How install works (InstallPlugin)

  1. Validate the plugin name (a single OCI path component - nothing else may reach filesystem paths or registry routes).
  2. Pick the version (see policy below) and take the per-plugin lock.
  3. If the selected version is already current - nothing to do (--force re-pulls).
  4. Fetch the contract and validate ALL requirements BEFORE any switch - including the fast path that merely repoints current to an already installed version.
  5. Download into a staged file (<binary>.new) - the live binary keeps working for the whole download.
  6. Smoke-test the staged binary (--version, fallback version; only a clean exit is required) - a corrupt or wrong-platform artifact is rejected before it replaces anything.
  7. Atomically swap the new binary in (rename over the live one - the original is untouched on failure), write the contract cache, then atomically repoint current.

A failure at any step leaves the previous version installed and working.

Version selection policy

  • Default pick: the newest stable semver tag whose cluster-side requirements are satisfied AND whose plugin->plugin dependency chain is resolvable - versions are probed newest to oldest and the first that passes both wins (a too-new release, or one whose dependencies cannot be satisfied, does not block updates).
  • Updates stay within the installed major; crossing majors requires an explicit --use-major N. The major is read from disk (the current symlink), so a broken binary cannot drop the pin.
  • Downgrade guard: the implicit path never installs a version older than the installed one - e.g. when the newest tag's contract is temporarily unreadable. Downgrades are explicit only (--version, --use-major).
  • Pre-releases (rc/alpha/beta) are never picked by default; install them via --version.
  • An unreachable cluster or a malformed contract is a hard error, not a silent fallback to an older version.

Requirements enforcement

  • Cluster-side (kubernetes, deckhouse, and modules - mandatory/conditional/anyOf/noneOf, the last forbidding a module): verified against a one-shot cluster snapshot (the requirements/ package) built from three reads - the API-server version, the deckhouse deployment's core.deckhouse.io/version annotation, and a modules.deckhouse.io list. The snapshot is lazy (built only when the plugin declares such requirements, so contract-less plugins install offline), cached once per run, and bounded by a 30s probe timeout. A non-release Deckhouse version (e.g. dev) skips the Deckhouse check with a warning rather than failing.
  • Plugin-to-plugin: a plugin's mandatory dependencies are installed and upgraded automatically (the resolution planner: constraint-aware, newest satisfying version, within each dependency's own major - or across it when --use-major cascades). Conflicts with already-installed plugins skip a candidate during selection. Conditional dependencies are enforced only when that plugin is already installed and are never auto-installed.
  • At runtime: the wrapper re-validates requirements before EVERY plugin run. The gate is skipped for local-only invocations - --help/-h (anywhere before a --), --version/-v or help/completion as the first arg, and cobra's __complete* requests - and when the plugin ships no contract.
  • Escape hatch for air-gapped setups: --skip-cluster-checks / D8_PLUGINS_SKIP_CLUSTER_CHECKS=1 (downgrades the check to a warning).

Running a plugin (the wrapper)

  • All arguments are forwarded verbatim (the wrapper parses no flags itself).
  • Env requested by the contract is injected: KUBECONFIG (the path d8 uses) and PLUGINS_CALLER (the d8 executable); everything else passes through.
  • stdin/stdout/stderr are inherited; the plugin's exact exit code is propagated.
  • On d8's own termination the plugin gets SIGTERM and a grace period, not an instant SIGKILL.

Switches

Need How
install root --plugins-dir / DECKHOUSE_CLI_PATH
identity (rpp + cluster checks) -k/--kubeconfig, --context
RPP endpoint / TLS --rpp-endpoint, --rpp-ca-file
skip TLS verification on both legs (API server and proxy) --insecure-skip-tls-verify
skip cluster-side requirement checks --skip-cluster-checks / D8_PLUGINS_SKIP_CLUSTER_CHECKS=1

Air-gapped delivery

d8 mirror pull mirrors plugins into the images bundle automatically (plugins whose contracts name the mirrored modules, plus their mandatory plugin dependencies; --include-plugin adds more). After d8 mirror push the target registry holds them at deckhouse-cli/plugins/<name>, where the proxy serves them - install/update work as usual. See internal/mirror/README.MD (Plugin Mirroring).

Boundaries and deliberate decisions

  • Enumerating the published plugins works only over TransportRegistry; the proxy allowlist refuses the plugins-repository path, so list reports that half as unsupported and still prints the installed half. See Transports above.
  • Idempotency compares the version reported by the binary itself; a plugin that prints a non-semver banner is re-pulled on every explicit update.
  • Dependency resolution is dry-run during selection (a candidate whose chain cannot be resolved is skipped); the chain is actually installed only for the finally chosen version. Recursion has a cycle guard and a depth cap.
  • Dependencies are only upgraded, never downgraded, to satisfy a constraint.
  • A plugin contract may depend on external modules only (those served from deckhouse/<edition>/modules/<name>), never on modules embedded in the platform image: d8 mirror auto-selects plugins from the mirrored external modules alone, so an embedded-module requirement never triggers selection and, as a secondary requirement, gets the plugin skipped as "not in the bundle".

Package map

File Responsibility
plugins.go the Manager: shared state of the plugin machinery
install.go the install pipeline: lock, staged download, smoke, atomic swap, idempotency
select.go newest-compatible version selection, contract memoization
planner.go plugin-to-plugin dependency resolution: constraint-aware planning, conflict/cycle/depth guards, upgrade-only
update.go UpdateAll (behind install --all), installed-plugin discovery, home-fallback switch
remove.go Remove / RemoveAll
validators.go plugin-to-plugin requirement checks + the Manager glue over requirements/ (snapshot cache, kubeconfig clients, --skip-cluster-checks)
requirements/ cluster-side requirements: the one-shot cluster snapshot (k8s / Deckhouse / modules) and the named checks against it
run.go running an installed plugin: requirement gate, env injection, exec
list.go / versions.go data for the list / versions commands
source.go / rpp_source.go / init.go the pluginSource interface, its default RPP implementation, and source selection
source_legacy.go the hidden --source direct-registry bypass (temporary, pre-#386; force-enables --skip-cluster-checks)
builtins.go built-in command names (delivery-kit, package) that satisfy a same-named plugin dependency by presence - no version check, no registry lookup
layout/ on-disk path layout
flags/ the plugin-specific flag set (--plugins-dir, --skip-cluster-checks); the kubeconfig and rpp-* flags live on the d8 dist root and are inherited
cmd/ the d8 dist plugins ... command tree and the per-plugin wrapper command, one file per command
cmd/errdetect/ maps registry-packages-proxy errors (401/403/404/5xx/endpoint-discovery) to actionable hints

Related: internal/rpp (proxy HTTP client), internal/lockfile (install lock), internal/selfupdate (the same store-and-symlink update pattern for the d8 binary itself).

Documentation

Overview

Package plugins implements the d8-cli plugin system.

A d8 plugin is a standalone binary published to an OCI Registry. It is not part of d8-cli and can be developed independently.

Why plugins exist

  • Isolate dependencies.
  • Enable independent, parallel development.
  • Let different teams own different plugins (delivery, system, ...).
  • Keep d8 itself compact, with only the dependencies it actually needs.

What d8-cli can do with plugins

  • Download them.
  • Validate their dependencies (requirements the plugin declares in its contract).
  • Run them as if they were native subcommands.

Where a plugin lives

A plugin lives in the cluster's OCI registry, reached exclusively through the in-cluster registry-packages-proxy. The image carries the plugin binary in its layers and a contract, published as a manifest annotation, that describes the plugin:

  • name;
  • version;
  • description;
  • environment variables;
  • flags;
  • requirements.

How a plugin invocation works

  1. The user invokes a command through d8.
  2. The parent CLI checks whether the plugin is installed.
  3. If it is not, the image is pulled through the registry-packages-proxy.
  4. The binary is unpacked.
  5. Requirements are validated.
  6. A symlink is pointed at the current major version.
  7. The plugin is exec'd with the forwarded arguments.

On-disk layout

Installed plugins live under the install root: /opt/deckhouse/lib/deckhouse-cli by default (override with --plugins-dir / DECKHOUSE_CLI_PATH; ~/.deckhouse-cli when the default is not writable). Concrete paths:

<root>/plugins/<name>/v<major>/<name>   plugin binary (one per major version)
<root>/plugins/<name>/current           symlink to the active major's binary
<root>/plugins/<name>/install.lock      install lock (one per plugin)
<root>/cache/contracts/<name>.json      cached contract

Versions are kept per major; the `current` symlink selects the active one, so switching is an atomic repoint - the same idea selfupdate uses for d8 itself. Package internal/plugins/layout holds the authoritative path builders.

What the plugin system is made of

  1. Discover - learn what plugins exist and what their contracts declare.
  2. Install - download and place the plugin in the right location with proper validation.
  3. Exec - run the plugin as part of d8 without losing argument context.

Index

Constants

This section is empty.

Variables

View Source
var ErrCatalogUnsupported = errors.New("listing published plugins is not supported by this transport")

ErrCatalogUnsupported means the transport in use cannot enumerate the published plugins. It is a property of the transport, not a runtime failure: the proxy allowlist admits deckhouse-cli and deckhouse-cli/plugins/<name> and refuses the bare deckhouse-cli/plugins path, so over TransportRPP the request is never made. Addressing a plugin by exact name is unaffected - install, update and versions work on every transport.

Functions

func ProvidesEnv added in v0.32.0

func ProvidesEnv(name string) bool

ProvidesEnv reports whether d8 actually injects a value for a contract-requested env var (vs leaving it to pass through from the inherited environment). It is the single source of truth for both injection and help. MODULE_CONFIG_INFO is not yet provided (it needs a defined module mapping in the contract).

func SplitPlatform added in v0.33.15

func SplitPlatform(version *semver.Version) (*semver.Version, string)

SplitPlatform separates a version's platform suffix from the version itself. Plugin images are published one tag per platform, so a single release reaches the registry as v0.0.34-linux-amd64, v0.0.34-darwin-arm64 and so on - the os-arch pair riding at the end of the semver prerelease slot.

A release that is itself a pre-release keeps that identity: v0.0.1-test-linux-amd64 splits into v0.0.1-test and linux/amd64, so its per-platform tags collapse onto the pre-release rather than onto the stable version of the same number. A version whose prerelease carries no platform tail comes back untouched with an empty platform.

func ValidatePluginName added in v0.32.0

func ValidatePluginName(name string) error

ValidatePluginName guards every user-supplied plugin name before it reaches MkdirAll / RemoveAll / registry paths. The rule lives in layout so that mirror applies the same one to catalog and contract names.

Types

type InstallOption added in v0.32.0

type InstallOption func(*installOptions)

func InstallWithForce added in v0.32.0

func InstallWithForce() InstallOption

func InstallWithMajorVersion added in v0.32.0

func InstallWithMajorVersion(majorVersion int) InstallOption

func InstallWithVersion added in v0.32.0

func InstallWithVersion(version string) InstallOption

type Manager added in v0.32.0

type Manager struct {
	// contains filtered or unexported fields
}

Manager is the plugin machinery shared by every `d8 dist plugins ...` subcommand and the per-plugin wrapper command (see internal/plugins/cmd): it installs, updates, removes, lists and runs plugins from the configured source.

func NewManager added in v0.32.0

func NewManager(logger *dkplog.Logger) *Manager

func (*Manager) AvailablePlugins added in v0.33.15

func (m *Manager) AvailablePlugins(ctx context.Context) ([]RemotePluginInfo, error)

AvailablePlugins enumerates the plugins published in the registry, by name.

The catalog is the tag list of the plugins repository, where each plugin has an image tagged with its name; a source that can reach it declares pluginCatalog. Only a failure to enumerate at all is returned as an error - a plugin whose versions cannot be resolved still appears, carrying a Note that says so.

func (*Manager) EnsureInstallRoot added in v0.32.0

func (m *Manager) EnsureInstallRoot() error

EnsureInstallRoot creates <pluginDirectory>/plugins; on permission denied falls back to ~/.deckhouse-cli, updates m.pluginDirectory, and retries.

func (*Manager) InitPluginServices added in v0.32.0

func (m *Manager) InitPluginServices(ctx context.Context) error

InitPluginServices wires m.service to the in-cluster registry-packages-proxy, reaching the proxy by the user's kubeconfig identity. ctx bounds endpoint discovery, so a Ctrl-C during command startup is honored. The proxy is the only plugin source (ADR: deckhouse-cli reaches the registry exclusively through it).

func (*Manager) InstallPlugin added in v0.32.0

func (m *Manager) InstallPlugin(ctx context.Context, pluginName string, opts ...InstallOption) error

InstallPlugin installs or switches to a plugin version. Steps: select the version, validate requirements, lay out plugins/<name>/v<major>, swap the binary in, point `current` at it, cache the contract. Tune behaviour with the InstallWith* options (version, major, force). With no options it installs the newest cluster-compatible version within the installed major. A plugin's mandatory dependencies are always installed/upgraded first.

func (*Manager) InstalledPluginContract added in v0.32.0

func (m *Manager) InstalledPluginContract(pluginName string) (*internal.Plugin, error)

InstalledPluginContract reads the cached contract from <plugin-dir>/cache/contracts/<plugin>.json and converts it to a domain object.

func (*Manager) InstalledPluginNames added in v0.32.0

func (m *Manager) InstalledPluginNames() ([]string, error)

InstalledPluginNames returns the plugins that are actually installed under the plugins root - a directory with a `current` symlink. A leftover directory from a failed install has no symlink and is excluded, so it cannot become an install target for a plugin the user never had.

func (*Manager) InstalledVersionOrNil added in v0.32.0

func (m *Manager) InstalledVersionOrNil(pluginName string) *semver.Version

InstalledVersionOrNil returns the active installed version of the plugin, or nil when the plugin is not installed or its version cannot be probed - best-effort: a version listing then simply carries no "current" marker.

func (*Manager) LatestVersion added in v0.32.0

func (m *Manager) LatestVersion(ctx context.Context, pluginName string) (*semver.Version, error)

LatestVersion lists tags from the registry for a plugin and returns the highest STABLE semver version - the same notion of "latest" that install selection uses (select.go), so `plugins list`/`contract` never advertise a pre-release that a default install would not pick.

func (*Manager) List added in v0.32.0

func (m *Manager) List() []PluginInfo

List returns the plugins installed on disk. For the plugins published in the registry and available to install, see AvailablePlugins.

func (*Manager) PluginContract added in v0.32.0

func (m *Manager) PluginContract(ctx context.Context, pluginName, tag string) (*internal.Plugin, error)

PluginContract fetches a plugin contract, memoizing it per name@tag for the duration of the command. Requirements-aware selection probes several versions' contracts, and the chosen one is fetched again by the install pipeline; the cache keeps that to a single pull per version.

func (*Manager) PublishedVersions added in v0.32.0

func (m *Manager) PublishedVersions(ctx context.Context, pluginName string) ([]PluginVersion, error)

PublishedVersions lists the plugin's published releases, newest first (unparseable tags are dropped). A plugin is published one tag per platform, so the per-platform tags of a release are collapsed into a single entry carrying the platforms it was built for.

func (*Manager) Remove added in v0.32.0

func (m *Manager) Remove(pluginName string) error

Remove deletes an installed plugin from disk: its install directory and the cached contract. It is idempotent (removing a plugin that is not installed is a no-op) and holds the plugin's install lock so it cannot race a concurrent install of the same plugin.

func (*Manager) RemoveAll added in v0.32.0

func (m *Manager) RemoveAll() error

RemoveAll deletes every plugin found under the plugins root, each under its own install lock.

func (*Manager) RunInstalled added in v0.32.0

func (m *Manager) RunInstalled(ctx context.Context, pluginName string, args []string) error

RunInstalled ensures the plugin is installed, enforces its contract requirements, then execs its binary with args. stdin/stdout/stderr are inherited; the contract's requested env vars are injected.

func (*Manager) SetBuiltinCommands added in v0.32.0

func (m *Manager) SetBuiltinCommands(names []string)

SetBuiltinCommands records the d8 built-in command names that satisfy a plugin dependency of the same name. It bridges capabilities that ship as a built-in command but are not yet published as standalone plugins (e.g. delivery-kit): such a dependency counts as satisfied by the command's mere presence, with no on-disk install and no registry lookup.

func (*Manager) SetDirectory added in v0.32.0

func (m *Manager) SetDirectory(dir string)

SetDirectory retargets the manager at another install root. The command layer calls it after flag parsing, so --plugins-dir overrides the directory captured at construction time.

func (*Manager) UpdateAll added in v0.32.0

func (m *Manager) UpdateAll(ctx context.Context, opts ...InstallOption) error

UpdateAll updates every installed plugin to its newest cluster-compatible version within the current major. A per-plugin failure does not stop the others; the failures are reported together in the returned error.

opts are forwarded to every plugin's install, so only options that make sense applied uniformly belong here - the command layer rejects the rest (an exact --version or a --use-major pin cannot mean anything across a whole set).

type PluginInfo added in v0.32.0

type PluginInfo struct {
	Name        string
	Version     string
	Description string
}

PluginInfo is one installed plugin's name, version and description for display.

type PluginVersion added in v0.33.15

type PluginVersion struct {
	Version   *semver.Version
	Platforms []string
}

PluginVersion is one published release: the version with any platform suffix removed, plus the platforms that release was published for. Platforms is empty for a plugin published as a single platform-independent tag.

type RemotePluginInfo added in v0.33.15

type RemotePluginInfo struct {
	Name      string
	Version   string
	Installed bool
	Note      string
}

RemotePluginInfo is one plugin published in the registry: its name, the newest stable version on offer, and whether it is already installed locally. Note says why Version is empty - a plugin that could only be named is still listed, never silently dropped.

type Transport added in v0.33.15

type Transport string

Transport names how the plugin subsystem reaches the registry. The two differ in more than plumbing - see pluginCatalog for the capability that only one of them has - so the transport in use is named in errors rather than left implicit.

const (
	// TransportRPP goes through the in-cluster registry-packages-proxy, authenticated
	// by the caller's kubeconfig identity and needing no registry credentials. It is
	// the default and the only supported transport (ADR #386).
	TransportRPP Transport = "registry-packages-proxy"

	// TransportRegistry talks to a registry repository directly, with credentials,
	// selected by the legacy --source bypass (see source_legacy.go).
	TransportRegistry Transport = "registry"
)

Directories

Path Synopsis
cmd
Package pluginscmd implements the `d8 dist plugins` command tree and the per-plugin wrapper command on top of the internal/plugins machinery.
Package pluginscmd implements the `d8 dist plugins` command tree and the per-plugin wrapper command on top of the internal/plugins machinery.
errdetect
Package errdetect maps registry-packages-proxy failures from `d8 dist plugins` to HelpfulErrors with plugin-specific guidance.
Package errdetect maps registry-packages-proxy failures from `d8 dist plugins` to HelpfulErrors with plugin-specific guidance.
Package flags defines the shared CLI flag set used by the `d8 dist plugins` management subcommands and consumed when building the registry-packages-proxy client and enforcing cluster-side requirements.
Package flags defines the shared CLI flag set used by the `d8 dist plugins` management subcommands and consumed when building the registry-packages-proxy client and enforcing cluster-side requirements.
Package layout centralizes the on-disk filesystem layout used by the d8 plugins subsystem: directory names, suffixes, and helpers that build concrete paths from the install root.
Package layout centralizes the on-disk filesystem layout used by the d8 plugins subsystem: directory names, suffixes, and helpers that build concrete paths from the install root.
Package requirements answers one question: does THIS cluster satisfy a plugin's cluster-side requirements (Kubernetes, Deckhouse and module versions)?
Package requirements answers one question: does THIS cluster satisfy a plugin's cluster-side requirements (Kubernetes, Deckhouse and module versions)?

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL