wireshare

package
v0.5.0 Latest Latest
Warning

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

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

Documentation

Overview

Package wireshare carries a deployment's node-wire authority between the controllers that share it.

WHAT PROBLEM IT SOLVES. An active/passive pair serves one fleet, and a node verifies the control plane against the authority it was given. Promotion is therefore only half a failover: the promoted host has to present a certificate the fleet already trusts, and a host whose ca directory is empty mints a NEW authority instead — after which every node in the fleet drops off at once while the control plane looks perfectly healthy.

IT IS REPLICATION, NOT A SHARED AUTHORITY, AND THE DIFFERENCE IS DELIBERATE. The file layout in internal/wirecert stays the source of truth on each host, with every guard it already has: the publication ORDER that makes each instant of a rotation a state a reader answers correctly, the torn-read repair, the retire guard that took three rounds. Porting that state machine onto a remote key/value store would carry the code and discard the reasoning — cross-key write ordering, per-file durable visibility, O_EXCL and a crash-releasing flock are all properties of a filesystem, and not one of them survives the move.

SO THE STORE IS A CHANNEL. A controller PUBLISHES the authority it holds, and a host that holds NONE adopts it rather than minting one. Nothing here ever replaces a local authority: a host that already has one and disagrees is refused, naming both, because the file it would be writing over is the key every node in the fleet verifies against.

WHAT THAT COSTS, said rather than implied: a rotation on one host reaches the other when somebody asks — `billet ca sync` — or when that host has nothing. Two controllers do not converge on their own, and the operator documentation says so in those words.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoAuthority = errors.New("wireshare: this deployment has published no authority")

ErrNoAuthority means the store holds nothing for this deployment.

AN ORDINARY STATE RATHER THAN A FAULT. A deployment whose first controller has not started yet has published nothing, and a host that finds nothing mints its own and publishes THAT — which is how the first one gets there.

Functions

func Publish

func Publish(ctx context.Context, store Store, stateDir, deployment string) error

Publish writes the authority this host holds into the store.

THE CALLER MUST HOLD wirecert.LockAuthority, because this reads the five files a rotation mutates in sequence and a reader without it can come away with a key from one generation beside a certificate from another — an authority that loads cleanly and verifies nothing, discovered on the day it is adopted.

IT REPLACES, and that is the one place this package overwrites anything. What it is overwriting is a COPY: the authority itself lives in the file layout on each host, and the store's job is to hold whatever the deployment currently has. Refusing to replace would make a rotation unpublishable.

Types

type Adopted

type Adopted int

Adopted says what Adopt did, so a caller can report it without inferring.

const (
	// AdoptedNothing means the store held no authority. The caller mints its own
	// and publishes it.
	AdoptedNothing Adopted = iota
	// AdoptedInstalled means this host had none and now holds the deployment's.
	AdoptedInstalled
	// AdoptedAlreadyHeld means this host already held the same authority.
	AdoptedAlreadyHeld
)

func Adopt

func Adopt(
	ctx context.Context, store Store, stateDir, deployment string, replace bool,
) (Adopted, error)

Adopt gives a host with no authority the one this deployment already uses.

THE CALLER MUST HOLD wirecert.LockAuthority.

THREE ANSWERS AND NOT TWO. "Nothing published" and "already held" are both success and mean opposite things to the caller: the first says this host is the one that has to publish, the second says there is nothing to do. Collapsing them would make a first controller publish nothing and a fleet have no authority in the store at all.

A LOCAL AUTHORITY IS NEVER REPLACED. If this host holds one and it is not the published one, that is refused naming both fingerprints — because the file being written over would be the key every node in the fleet verifies against, and billet cannot tell a host that was left behind by a rotation from a host pointed at the wrong deployment. An operator can, and `billet ca sync --force` is where they say so.

type Store

type Store interface {
	// GetAuthority returns the published document, or ErrNoAuthority.
	GetAuthority(ctx context.Context) ([]byte, error)
	// PutAuthority replaces the published document.
	PutAuthority(ctx context.Context, body []byte) error
}

Store is the identity store, narrowed to the one value this package keeps in it.

AN INTERFACE SO THE RULES ARE TESTABLE WITHOUT AWS, and so nothing here depends on which store a deployment chose. The AWS implementation is one adapter in cmd/billet; a fake is what the tests below use.

Jump to

Keyboard shortcuts

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