platform

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2023 License: Apache-2.0 Imports: 39 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInitramfsEmergency is the marker error returned upon node blocking in emergency mode in initramfs.
	ErrInitramfsEmergency = errors.New("entered emergency.target in initramfs")
)

Functions

func CheckMachine

func CheckMachine(ctx context.Context, m Machine) error

CheckMachine tests a machine for various error conditions such as ssh being available and no systemd units failing at the time ssh is reachable. It also ensures the remote system is running Container Linux by CoreOS or Red Hat CoreOS.

func CopyDirToMachine

func CopyDirToMachine(inputdir string, m Machine, destdir string) error

CopyDirToMachine synchronizes the local contents of inputdir to the remote destdir.

func GenerateFakeKey

func GenerateFakeKey() (string, error)

GenerateFakeKey generates a SSH key pair, returns the public key, and discards the private key. This is useful for droplets that don't need a public key, since DO & Azure insists on requiring one.

func GetMachineBootId

func GetMachineBootId(m Machine) (string, error)

func InstallFile

func InstallFile(in io.Reader, m Machine, to string) error

InstallFile copies data from in to the path to on m.

func Manhole

func Manhole(m Machine) (err error)

Manhole connects os.Stdin, os.Stdout, and os.Stderr to an interactive shell session on the Machine m. Manhole blocks until the shell session has ended. If os.Stdin does not refer to a TTY, Manhole returns immediately with a nil error.

func ReadFile

func ReadFile(m Machine, path string) (io.ReadCloser, error)

ReadFile returns a io.ReadCloser that streams the requested file. The caller should close the reader when finished.

func RebootMachine

func RebootMachine(m Machine, j *Journal) error

RebootMachine will reboot a given machine, provided the machine's journal.

func StartMachine

func StartMachine(m Machine, j *Journal) error

StartMachine will start a given machine, provided the machine's journal.

func StartMachineAfterReboot

func StartMachineAfterReboot(m Machine, j *Journal, oldBootId string) error

func StartReboot

func StartReboot(m Machine) error

Reboots a machine, stopping ssh first. Afterwards run CheckMachine to verify the system is back and operational.

func TransferFile

func TransferFile(src Machine, srcPath string, dst Machine, dstPath string) error

Copy a file between two machines in a cluster.

func WaitForMachineReboot

func WaitForMachineReboot(m Machine, j *Journal, timeout time.Duration, oldBootId string) error

WaitForMachineReboot will wait for the machine to reboot, i.e. it is assumed an action which will cause a reboot has already been initiated. Note the timeout here is for how long to wait for the machine to seemingly go *offline*, not for how long it takes to get back online. Journal.Start() has its own timeouts for that.

func WriteJSONInfo

func WriteJSONInfo(m Machine, w io.Writer) error

Types

type BaseCluster

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

func NewBaseCluster

func NewBaseCluster(bf *BaseFlight, rconf *RuntimeConfig) (*BaseCluster, error)

func (*BaseCluster) AddMach

func (bc *BaseCluster) AddMach(m Machine)

func (*BaseCluster) AllocateMachineSerial

func (bc *BaseCluster) AllocateMachineSerial() uint

func (*BaseCluster) ConsoleOutput

func (bc *BaseCluster) ConsoleOutput() map[string]string

func (*BaseCluster) DelMach

func (bc *BaseCluster) DelMach(m Machine)

func (*BaseCluster) Destroy

func (bc *BaseCluster) Destroy()

Destroy destroys each machine in the cluster.

func (*BaseCluster) Distribution

func (bc *BaseCluster) Distribution() string

func (*BaseCluster) EarlyRelease

func (bc *BaseCluster) EarlyRelease()

func (*BaseCluster) JournalOutput

func (bc *BaseCluster) JournalOutput() map[string]string

func (*BaseCluster) Keys

func (bc *BaseCluster) Keys() ([]*agent.Key, error)

func (*BaseCluster) Machines

func (bc *BaseCluster) Machines() []Machine

func (*BaseCluster) Name

func (bc *BaseCluster) Name() string

func (*BaseCluster) PasswordSSHClient

func (bc *BaseCluster) PasswordSSHClient(ip string, user string, password string) (*ssh.Client, error)

func (*BaseCluster) Platform

func (bc *BaseCluster) Platform() Name

func (*BaseCluster) RenderUserData

func (bc *BaseCluster) RenderUserData(userdata *platformConf.UserData, ignitionVars map[string]string) (*platformConf.Conf, error)

func (*BaseCluster) RuntimeConf

func (bc *BaseCluster) RuntimeConf() RuntimeConfig

func (*BaseCluster) SSH

func (bc *BaseCluster) SSH(m Machine, cmd string) ([]byte, []byte, error)

SSH executes the given command, cmd, on the given Machine, m. It returns the stdout and stderr of the command and an error. Leading and trailing whitespace is trimmed from each.

func (*BaseCluster) SSHClient

func (bc *BaseCluster) SSHClient(ip string) (*ssh.Client, error)

func (*BaseCluster) SSHOnTestFailure

func (bc *BaseCluster) SSHOnTestFailure() bool

func (*BaseCluster) UserSSHClient

func (bc *BaseCluster) UserSSHClient(ip, user string) (*ssh.Client, error)

type BaseFlight

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

func NewBaseFlight

func NewBaseFlight(opts *Options, platform Name) (*BaseFlight, error)

func NewBaseFlightWithDialer

func NewBaseFlightWithDialer(opts *Options, platform Name, dialer network.Dialer) (*BaseFlight, error)

func (*BaseFlight) AddCluster

func (bf *BaseFlight) AddCluster(c Cluster)

func (*BaseFlight) Clusters

func (bf *BaseFlight) Clusters() []Cluster

func (*BaseFlight) DelCluster

func (bf *BaseFlight) DelCluster(c Cluster)

func (*BaseFlight) Destroy

func (bf *BaseFlight) Destroy()

Destroy destroys each Cluster in the Flight and closes the SSH agent.

func (*BaseFlight) Keys

func (bf *BaseFlight) Keys() ([]*agent.Key, error)

func (*BaseFlight) Name

func (bf *BaseFlight) Name() string

func (*BaseFlight) Platform

func (bf *BaseFlight) Platform() Name

type Cluster

type Cluster interface {
	// Platform returns the name of the platform.
	Platform() Name

	// Name returns a unique name for the Cluster.
	Name() string

	// NewMachine creates a new CoreOS machine.
	NewMachine(userdata *conf.UserData) (Machine, error)

	// NewMachineWithOptions creates a new CoreOS machine as defined by the given options.
	NewMachineWithOptions(userdata *conf.UserData, options MachineOptions) (Machine, error)

	// Machines returns a slice of the active machines in the Cluster.
	Machines() []Machine

	// Destroy terminates each machine in the cluster and frees any other
	// associated resources. It should log any failures; since they are not
	// actionable, it does not return an error
	Destroy()

	// ConsoleOutput returns a map of console output from destroyed
	// cluster machines.
	ConsoleOutput() map[string]string

	// JournalOutput returns a map of journal output from destroyed
	// cluster machines.
	JournalOutput() map[string]string

	// Distribution returns the Distribution
	Distribution() string

	// SSHOnTestFailure returns whether the cluster should Manhole into
	// a machine when a MustSSH call fails
	SSHOnTestFailure() bool
}

Cluster represents a cluster of machines within a single Flight.

type Disk

type Disk struct {
	Size          string   // disk image size in bytes, optional suffixes "K", "M", "G", "T" allowed.
	BackingFile   string   // raw disk image to use.
	BackingFormat string   // qcow2, raw, etc.  If unspecified will be autodetected.
	Channel       string   // virtio (default), nvme
	DeviceOpts    []string // extra options to pass to qemu -device. "serial=XXXX" makes disks show up as /dev/disk/by-id/virtio-<serial>
	DriveOpts     []string // extra options to pass to -drive
	SectorSize    int      // if not 0, override disk sector size
	NbdDisk       bool     // if true, the disks should be presented over nbd:unix socket
	MultiPathDisk bool     // if true, present multiple paths
	// contains filtered or unexported fields
}

Disk holds the details of a virtual disk.

func ParseDisk

func ParseDisk(spec string) (*Disk, error)

type Flight

type Flight interface {
	// NewCluster creates a new Cluster.
	NewCluster(rconf *RuntimeConfig) (Cluster, error)

	// Name returns a unique name for the Flight.
	Name() string

	// Platform returns the name of the platform.
	Platform() Name

	// Clusters returns a slice of the active Clusters.
	Clusters() []Cluster

	// ConfigTooLarge returns true iff the config is too
	// large for the platform
	ConfigTooLarge(ud conf.UserData) bool

	// Destroy terminates each cluster and frees any other associated
	// resources.  It should log any failures; since they are not
	// actionable, it does not return an error.
	Destroy()
}

Flight represents a group of Clusters within a single platform.

type HostForwardPort

type HostForwardPort struct {
	Service   string
	HostPort  int
	GuestPort int
}

HostForwardPort contains details about port-forwarding for the VM.

type HostMount

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

A directory mounted from the host into the guest, via 9p or virtiofs

type Install

type Install struct {
	CosaBuild       *util.LocalBuild
	Builder         *QemuBuilder
	Insecure        bool
	Native4k        bool
	MultiPathDisk   bool
	PxeAppendRootfs bool
	NmKeyfiles      map[string]string
	// contains filtered or unexported fields
}

func (*Install) InstallViaISOEmbed

func (inst *Install) InstallViaISOEmbed(kargs []string, liveIgnition, targetIgnition conf.Conf, outdir string, offline, minimal bool) (*InstalledMachine, error)

func (*Install) PXE

func (inst *Install) PXE(kargs []string, liveIgnition, ignition conf.Conf, offline bool) (*InstalledMachine, error)

type InstalledMachine

type InstalledMachine struct {
	Tempdir                 string
	QemuInst                *QemuInstance
	BootStartedErrorChannel chan error
}

func (*InstalledMachine) Destroy

func (inst *InstalledMachine) Destroy() error

type Journal

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

Journal manages recording the journal of a Machine.

func NewJournal

func NewJournal(dir string) (*Journal, error)

NewJournal creates a Journal recorder that will log to "journal.txt" and "journal-raw.txt.gz" inside the given output directory.

func (*Journal) Destroy

func (j *Journal) Destroy()

func (*Journal) Read

func (j *Journal) Read() ([]byte, error)

There is no guarantee that anything is returned if called before Destroy

func (*Journal) Start

func (j *Journal) Start(ctx context.Context, m Machine, oldBootId string) error

Start begins/resumes streaming the system journal to journal.txt.

type Machine

type Machine interface {
	// ID returns the plaform-specific machine identifier.
	ID() string

	// IgnitionError returns an error if the machine failed in Ignition
	IgnitionError() error

	// IP returns the machine's public IP.
	IP() string

	// PrivateIP returns the machine's private IP.
	PrivateIP() string

	// RuntimeConf returns the cluster's runtime configuration.
	RuntimeConf() RuntimeConfig

	// SSHClient establishes a new SSH connection to the machine.
	SSHClient() (*ssh.Client, error)

	// PasswordSSHClient establishes a new SSH connection using the provided credentials.
	PasswordSSHClient(user string, password string) (*ssh.Client, error)

	// SSH runs a single command over a new SSH connection.
	SSH(cmd string) ([]byte, []byte, error)

	// Start sets up the journal and performs sanity checks via platform.StartMachine().
	Start() error

	// Reboot restarts the machine and waits for it to come back.
	Reboot() error

	// WaitForReboot waits for the machine to restart and waits for it to come back.
	WaitForReboot(time.Duration, string) error

	// Destroy terminates the machine and frees associated resources. It should log
	// any failures; since they are not actionable, it does not return an error.
	Destroy()

	// ConsoleOutput returns the machine's console output if available,
	// or an empty string.  Only expected to be valid after Destroy().
	ConsoleOutput() string

	// JournalOutput returns the machine's journal output if available,
	// or an empty string.  Only expected to be valid after Destroy().
	JournalOutput() string
}

Machine represents a Container Linux instance.

func NewMachines

func NewMachines(c Cluster, userdata *conf.UserData, n int, options MachineOptions) ([]Machine, error)

NewMachines spawns n instances in cluster c, with each instance passed the same userdata.

type MachineOptions

type MachineOptions struct {
	MultiPathDisk             bool
	AdditionalDisks           []string
	MinMemory                 int
	MinDiskSize               int
	AdditionalNics            int
	AppendKernelArgs          string
	AppendFirstbootKernelArgs string
	SkipStartMachine          bool // Skip platform.StartMachine on machine bringup
}

type Name

type Name string

Name is a unique identifier for a platform.

type Options

type Options struct {
	BaseName       string
	Distribution   string
	SystemdDropins []SystemdDropin
	Stream         string

	CosaWorkdir   string
	CosaBuildId   string
	CosaBuildArch string

	UseWarnExitCode77 bool

	AppendButane   string
	AppendIgnition string

	// OSContainer is an image pull spec that can be given to the pivot service
	// in RHCOS machines to perform machine content upgrades.
	// When specified additional files & units will be automatically generated
	// inside of RenderUserData
	OSContainer string

	SSHOnTestFailure bool

	ExtendTimeoutPercent uint
}

Options contains the base options for all clusters.

type QEMUMachine

type QEMUMachine interface {
	// Embedding the Machine interface
	Machine

	// RemovePrimaryBlockDevice removes the primary device from a given qemu
	// instance and sets the secondary device as primary.
	RemovePrimaryBlockDevice() error
}

QEMUMachine represents a qemu instance.

type QOMBlkDev

type QOMBlkDev struct {
	Return []struct {
		Device     string `json:"device"`
		DevicePath string `json:"qdev"`
		Removable  bool   `json:"removable"`
		Inserted   struct {
			BackingFileDepth int    `json:"backing_file_depth"`
			NodeName         string `json:"node-name"`
		} `json:"inserted"`
	} `json:"return"`
}

type QOMDev

type QOMDev struct {
	Return []struct {
		Name string `json:"name"`
		Type string `json:"type"`
	} `json:"return"`
}

QOMDev is a QMP monitor, for interactions with a QEMU instance.

type QemuBuilder

type QemuBuilder struct {
	// ConfigFile is a path to Ignition configuration
	ConfigFile string
	// ForceConfigInjection is useful for booting `metal` images directly
	ForceConfigInjection bool

	// File to which to redirect the serial console
	ConsoleFile string

	// MemoryMiB defaults to 1024 on most architectures, others it may be 2048
	MemoryMiB int
	// Processors < 0 means to use host count, unset means 1, values > 1 are directly used
	Processors int
	UUID       string
	Firmware   string
	Swtpm      bool
	Pdeathsig  bool
	Argv       []string

	// AppendKernelArgs are appended to the bootloader config
	AppendKernelArgs string

	// AppendFirstbootKernelArgs are written to /boot/ignition
	AppendFirstbootKernelArgs string

	Hostname string

	InheritConsole bool

	UsermodeNetworking bool

	RestrictNetworking bool
	// contains filtered or unexported fields
}

QemuBuilder is a configurator that can then create a qemu instance

func NewMetalQemuBuilderDefault

func NewMetalQemuBuilderDefault() *QemuBuilder

NewMetalQemuBuilderDefault returns a QEMU builder instance with some defaults set up for bare metal.

func NewQemuBuilder

func NewQemuBuilder() *QemuBuilder

NewQemuBuilder creates a new build for QEMU with default settings.

func (*QemuBuilder) AddAdditionalNics

func (builder *QemuBuilder) AddAdditionalNics(additionalNics int)

func (*QemuBuilder) AddBootDisk

func (builder *QemuBuilder) AddBootDisk(disk *Disk) error

AddBootDisk sets the instance to boot only from the target disk

func (*QemuBuilder) AddDisk

func (builder *QemuBuilder) AddDisk(disk *Disk) error

AddDisk adds a secondary disk for the instance.

func (*QemuBuilder) AddDisksFromSpecs

func (builder *QemuBuilder) AddDisksFromSpecs(specs []string) error

AddDisksFromSpecs adds multiple secondary disks from their specs.

func (*QemuBuilder) AddFd

func (builder *QemuBuilder) AddFd(fd *os.File) string

AddFd appends a file descriptor that will be passed to qemu, returning a "/dev/fdset/<num>" argument that one can use with e.g. -drive file=/dev/fdset/<num>.

func (*QemuBuilder) AddIso

func (builder *QemuBuilder) AddIso(path string, bootindexStr string, asDisk bool) error

AddIso adds an ISO image, optionally configuring its boot index If asDisk is set, attach the ISO as a disk drive (as though it was copied to a USB stick) and overwrite the El Torito signature in the image (to force QEMU's UEFI firmware to boot via the hybrid ESP).

func (*QemuBuilder) AddPrimaryDisk

func (builder *QemuBuilder) AddPrimaryDisk(disk *Disk) error

AddPrimaryDisk sets up the primary disk for the instance.

func (*QemuBuilder) Append

func (builder *QemuBuilder) Append(args ...string)

Append appends additional arguments for QEMU.

func (*QemuBuilder) Close

func (builder *QemuBuilder) Close()

Close drops all resources owned by the builder.

func (*QemuBuilder) EnableUsermodeNetworking

func (builder *QemuBuilder) EnableUsermodeNetworking(h []HostForwardPort, usernetAddr string)

EnableUsermodeNetworking configure forwarding for all requested ports, via usermode network helpers.

func (*QemuBuilder) Exec

func (builder *QemuBuilder) Exec() (*QemuInstance, error)

Exec tries to run a QEMU instance with the given settings.

func (*QemuBuilder) MountHost

func (builder *QemuBuilder) MountHost(source, dest string, readonly bool)

MountHost sets up a mount point from the host to guest. Note that virtiofs does not currently support read-only mounts (which is really surprising!). We do mount it read-only by default in the guest, however.

func (*QemuBuilder) SerialPipe

func (builder *QemuBuilder) SerialPipe() (*os.File, error)

SerialPipe reads the serial console output into a pipe

func (*QemuBuilder) SetArchitecture

func (builder *QemuBuilder) SetArchitecture(arch string) error

SetArchitecture enables qemu full emulation for the target architecture.

func (*QemuBuilder) SetConfig

func (builder *QemuBuilder) SetConfig(config *conf.Conf)

SetConfig injects Ignition; this can be used in place of ConfigFile.

func (*QemuBuilder) SetNetbootP

func (builder *QemuBuilder) SetNetbootP(filename, dir string)

func (*QemuBuilder) SetSecureExecution

func (builder *QemuBuilder) SetSecureExecution(gpgkey string, hostkey string, config *conf.Conf) error

SetSecureExecution enables qemu confidential guest support and adds hostkey to ignition config.

func (*QemuBuilder) TempFile

func (builder *QemuBuilder) TempFile(pattern string) (*os.File, error)

Small wrapper around os.CreateTemp() to avoid leaking our tempdir to others.

func (*QemuBuilder) VirtioChannelRead

func (builder *QemuBuilder) VirtioChannelRead(name string) (*os.File, error)

VirtioChannelRead allocates a virtio-serial channel that will appear in the guest as /dev/virtio-ports/<name>. The guest can write to it, and the host can read.

func (*QemuBuilder) VirtioJournal

func (builder *QemuBuilder) VirtioJournal(config *conf.Conf, queryArguments string) (*os.File, error)

VirtioJournal configures the OS and VM to stream the systemd journal (post-switchroot) over a virtio-serial channel.

  • The first parameter is a poitner to the configuration of the target VM.
  • The second parameter is an optional queryArguments to filter the stream - see `man journalctl` for more information.
  • The return value is a file stream which will be newline-separated JSON.

type QemuInstance

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

QemuInstance holds an instantiated VM through its lifecycle.

func (*QemuInstance) Destroy

func (inst *QemuInstance) Destroy()

Destroy kills the instance and associated sidecar processes.

func (*QemuInstance) Kill

func (inst *QemuInstance) Kill() error

Kill kills the VM instance.

func (*QemuInstance) Pid

func (inst *QemuInstance) Pid() int

Pid returns the PID of QEMU process.

func (*QemuInstance) RemovePrimaryBlockDevice

func (inst *QemuInstance) RemovePrimaryBlockDevice() (err2 error)

RemovePrimaryBlockDevice deletes the primary device from a qemu instance and sets the secondary device as primary. It expects that all block devices with device name disk-<N> are mirrors.

func (*QemuInstance) SSHAddress

func (inst *QemuInstance) SSHAddress() (string, error)

SSHAddress returns the IP address with the forwarded port (host-side).

func (*QemuInstance) Signaled

func (inst *QemuInstance) Signaled() bool

Signaled returns whether QEMU process was signaled.

func (*QemuInstance) SwitchBootOrder

func (inst *QemuInstance) SwitchBootOrder() (err2 error)

SwitchBootOrder tweaks the boot order for the instance. Currently effective on aarch64: switches the boot order to boot from disk on reboot. For s390x and aarch64, bootindex is used to boot from the network device (boot once is not supported). For s390x, the boot ordering was not a problem as it would always read from disk first. For aarch64, the bootindex needs to be switched to boot from disk before a reboot

func (*QemuInstance) Wait

func (inst *QemuInstance) Wait() error

Wait for the qemu process to exit

func (*QemuInstance) WaitAll

func (inst *QemuInstance) WaitAll(ctx context.Context) error

WaitAll wraps the process exit as well as WaitIgnitionError, returning an error if either fail.

func (*QemuInstance) WaitIgnitionError

func (inst *QemuInstance) WaitIgnitionError(ctx context.Context) (string, error)

WaitIgnitionError will only return if the instance failed inside the initramfs. The resulting string will be a newline-delimited stream of JSON strings, as returned by `journalctl -o json`.

type QemuMachineOptions

type QemuMachineOptions struct {
	MachineOptions
	HostForwardPorts    []HostForwardPort
	DisablePDeathSig    bool
	OverrideBackingFile string
}

QemuMachineOptions is specialized MachineOption struct for QEMU.

type RuntimeConfig

type RuntimeConfig struct {
	OutputDir string

	NoSSHKeyInUserData bool                // don't inject SSH key into Ignition/cloud-config
	NoSSHKeyInMetadata bool                // don't add SSH key to platform metadata
	NoInstanceCreds    bool                // don't grant credentials (AWS instance profile, GCP service account) to the instance
	AllowFailedUnits   bool                // don't fail CheckMachine if a systemd unit has failed
	WarningsAction     conf.WarningsAction // what to do on Ignition or Butane validation warnings

	// InternetAccess is true if the cluster should be Internet connected
	InternetAccess bool
	EarlyRelease   func()

	// whether a Manhole into a machine should be created on detected failure
	SSHOnTestFailure bool
}

RuntimeConfig contains cluster-specific configuration.

type SystemdDropin

type SystemdDropin struct {
	Unit     string
	Name     string
	Contents string
}

SystemdDropin is a userdata type agnostic struct representing a systemd dropin

Directories

Path Synopsis
api
aws
do
esx
machine
aws
do
esx

Jump to

Keyboard shortcuts

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