internal/agent/permanent/permanent.go
Ref: Size: 1.5 KiB History
// Package permanent mints agent errors that no retry can fix. A provisioner or
// the image cache returns one when a create can never succeed as asked — a disk
// that would have to shrink, an image digest that will never match, a vfkit
// binary the host cannot legally run — so the reconcile loop spends its whole
// retry budget at once instead of grinding on a failure that is deterministic.
//
// Only the producer lives here. The consumer-side check does not: reconcile
// matches the Permanent() marker structurally (errors.As against an anonymous
// interface), so nothing imports this package to READ a permanent error, only
// to MINT one. That split is deliberate — what a VMM driver and an image cache
// call permanent have nothing else in common, and the decision to terminal-fail
// stays where the retry budget is spent.
package permanent
import "fmt"
// permanentError carries the marker. It is unexported: callers mint one through
// Errorf and read it back through the structural Permanent() check, never by
// name.
type permanentError struct{ err error }
func (e permanentError) Error() string { return e.err.Error() }
func (e permanentError) Unwrap() error { return e.err }
func (e permanentError) Permanent() bool { return true }
// Errorf returns a permanent error with a formatted message. Wrap a cause with
// %w to keep it in the chain (errors.Is/As still traverse it).
func Errorf(format string, args ...any) error {
return permanentError{err: fmt.Errorf(format, args...)}
}