hoststatus

package
v2.22.1 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2026 License: GPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Package hoststatus reads the state of the machine Core runs on: its network links, Bluetooth adapter, storage, displays and controllers, and asks the operating system to reboot, shut down or suspend it.

Every reader here is the generic one for its operating system. A platform that knows better supplies its own through the provider interfaces in the platforms package.

Index

Constants

View Source
const (
	RoleMedia = "media"
	RoleData  = "data"
)
View Source
const (
	ConnectionUSB       = "usb"
	ConnectionBluetooth = "bluetooth"
	ConnectionUnknown   = "unknown"
)
View Source
const (
	BatteryLevelEmpty  = "empty"
	BatteryLevelLow    = "low"
	BatteryLevelMedium = "medium"
	BatteryLevelFull   = "full"
)

Variables

View Source
var (
	// ErrBluetoothNoAdapter means the Bluetooth stack is running but has no
	// adapter to use.
	ErrBluetoothNoAdapter = errors.New("no bluetooth adapter")
	// ErrBluetoothNotPowered means the adapter is off. Core never turns it on
	// by itself.
	ErrBluetoothNotPowered = errors.New("bluetooth adapter is powered off")
	// ErrBluetoothNotFound means the stack does not know the device.
	ErrBluetoothNotFound = errors.New("bluetooth device not found")
	// ErrBluetoothPinRequired means the device asked for a PIN or passkey,
	// which Core has no way to show or enter.
	ErrBluetoothPinRequired = errors.New("bluetooth device requires a PIN or passkey")
	// ErrBluetoothRejected means the device or the stack refused the pairing.
	ErrBluetoothRejected = errors.New("bluetooth pairing was rejected")
	// ErrBluetoothTimeout means the device stopped answering.
	ErrBluetoothTimeout = errors.New("bluetooth device did not answer")
)
View Source
var (
	// ErrUnsupported means the platform has no way to answer at all.
	ErrUnsupported = errors.New("not supported on this platform")
	// ErrNotPermitted means the platform could act but the operating system
	// refuses this process.
	ErrNotPermitted = errors.New("not permitted by the operating system")
)
View Source
var DefaultConnectivityURLs = []string{
	"http://connectivitycheck.gstatic.com/generate_204",
	"http://cp.cloudflare.com/generate_204",
	"http://edge-http.microsoft.com/captiveportal/generate_204",
}

DefaultConnectivityURLs are plain-HTTP endpoints that answer 204 with no body. They are run by different operators so that one being blocked on a network does not read as the internet being down. Plain HTTP is deliberate: it is what lets a captive portal answer in the internet's place and be recognised.

PowerActions lists every action in a stable order.

Functions

func BatteryLevel

func BatteryLevel(percent int) string

BatteryLevel names the coarse level a charge percentage falls in.

func ConnectorName

func ConnectorName(entry string) (string, bool)

ConnectorName returns the connector half of a /sys/class/drm entry named "card<N>-<connector>".

func ControllerDisplayName added in v2.22.0

func ControllerDisplayName(vendorID, productID string) string

ControllerDisplayName returns the model name for a controller's vendor and product IDs, or the empty string when the model is not known. IDs are matched without regard to case.

func FilesystemID

func FilesystemID(path string) (id, mountPoint string, err error)

FilesystemID identifies the filesystem holding path, so two directories on the same one are counted once, and reports where it is mounted.

The device number alone is not enough: every subvolume of a btrfs filesystem has its own, though they all share one pool of space. Where the mount is backed by a block device or a network share, that is the identity.

func IsBluetoothGamepad added in v2.22.0

func IsBluetoothGamepad(device *BluetoothDevice) bool

IsBluetoothGamepad reports whether a device identifies itself as a gamepad or joystick: by its Class of Device, its low energy appearance, the icon the stack derived from either, or failing those a HID profile and a name that says controller.

func MountSource

func MountSource(mountInfo, path string) (source, mountPoint string, ok bool)

MountSource returns what is mounted at the deepest mount point holding path, and that mount point, from the contents of /proc/self/mountinfo. The source is a block device or a network share for a mount that has one behind it; for a mount such as tmpfs it names a kind of filesystem and not one instance of it.

func NormalizeBluetoothAddress added in v2.22.0

func NormalizeBluetoothAddress(address string) (string, bool)

NormalizeBluetoothAddress returns address in upper case when it is a colon-separated six-octet address, and false otherwise.

func ParseDefaultRouteInterface

func ParseDefaultRouteInterface(routes string) string

ParseDefaultRouteInterface returns the interface carrying the default route with the lowest metric from the contents of /proc/net/route, or "" when there is none.

func ParseHardwarePorts

func ParseHardwarePorts(output string) map[string]LinkType

ParseHardwarePorts reads the kind of link behind each device from the output of `networksetup -listallhardwareports`.

func ParseModalias added in v2.22.0

func ParseModalias(modalias string) (vendorID, productID string)

ParseModalias reads the vendor and product IDs from a device's modalias, such as "usb:v054Cp09CCd0100" or "bluetooth:v000Fp1200d1436". Both come back as four lowercase hex digits, or empty when the modalias is not in that form.

func ParseRouteDefaultInterface

func ParseRouteDefaultInterface(output string) string

ParseRouteDefaultInterface reads the interface from the output of `route -n get default`.

Types

type Availability

type Availability string

Availability is whether a section or an action can be used on this device.

const (
	Unsupported  Availability = "unsupported"
	Supported    Availability = "supported"
	NotPermitted Availability = "notPermitted"
)

type BlueZ added in v2.22.0

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

BlueZ manages Bluetooth devices through bluetoothd.

func NewBlueZ added in v2.22.0

func NewBlueZ() *BlueZ

NewBlueZ returns a controller that connects to the system bus the first time it is used.

func (*BlueZ) Batteries added in v2.22.0

func (b *BlueZ) Batteries(ctx context.Context) (map[string]int, error)

Batteries reports the charge of every device that exposes BlueZ's battery interface, keyed by lower-case address. BlueZ has no charging state there.

func (*BlueZ) Connect added in v2.22.0

func (b *BlueZ) Connect(ctx context.Context, address string) error

Connect connects the device's profiles. It waits as long as ctx allows.

func (*BlueZ) Pair added in v2.22.0

func (b *BlueZ) Pair(ctx context.Context, address string) error

Pair bonds with the device. The agent answering the stack's questions is registered for this attempt only: on systems where something else already runs an agent, Core must not stand in for it any longer than that.

func (*BlueZ) Read added in v2.22.0

func (b *BlueZ) Read(ctx context.Context) (BluetoothReading, error)

Read reports the adapter's state and every device it knows.

func (*BlueZ) Remove added in v2.22.0

func (b *BlueZ) Remove(ctx context.Context, address string) error

Remove unpairs the device and forgets it.

func (*BlueZ) StartDiscovery added in v2.22.0

func (b *BlueZ) StartDiscovery(ctx context.Context) error

StartDiscovery starts Core's discovery session.

func (*BlueZ) StopDiscovery added in v2.22.0

func (b *BlueZ) StopDiscovery(ctx context.Context) error

StopDiscovery ends Core's discovery session. Ending one that is not running is not an error.

func (*BlueZ) Trust added in v2.22.0

func (b *BlueZ) Trust(ctx context.Context, address string) error

Trust lets the device reconnect by itself.

func (*BlueZ) Watch added in v2.22.0

func (b *BlueZ) Watch(ctx context.Context, onChange func())

Watch reports BlueZ's changes until ctx ends, resubscribing when the bus connection is lost.

type Bluetooth

type Bluetooth struct {
	// Powered is nil when the adapter's power state cannot be read.
	Powered *bool
	Present bool
}

Bluetooth is the adapter's state. Core only ever reads it.

type BluetoothController added in v2.22.0

type BluetoothController interface {
	Read(ctx context.Context) (BluetoothReading, error)
	// StartDiscovery and StopDiscovery start and end this process's own
	// discovery session. Other programs' sessions are left alone.
	StartDiscovery(ctx context.Context) error
	StopDiscovery(ctx context.Context) error
	// Pair bonds with the device, answering the stack's questions without
	// user input while the attempt lasts. It blocks until the device answers
	// or ctx ends.
	Pair(ctx context.Context, address string) error
	Trust(ctx context.Context, address string) error
	Connect(ctx context.Context, address string) error
	// Remove unpairs the device and forgets it.
	Remove(ctx context.Context, address string) error
	// Watch calls onChange whenever the stack reports a change, until ctx
	// ends. onChange must not block.
	Watch(ctx context.Context, onChange func())
}

BluetoothController manages Bluetooth devices. Every method returns ErrUnsupported when the stack is not running and ErrBluetoothNoAdapter when it has no adapter.

type BluetoothDevice added in v2.22.0

type BluetoothDevice struct {
	// Address is the device's address in upper case, colon separated.
	Address string
	// Name is empty when the device has not said what it is called.
	Name string
	// VendorID and ProductID come from the device's modalias: four lowercase
	// hex digits, or empty.
	VendorID  string
	ProductID string
	Icon      string
	UUIDs     []string
	// Class is the Class of Device of a classic device, or zero.
	Class uint32
	// Appearance is a low energy device's appearance value, or zero.
	Appearance uint16
	Paired     bool
	Connected  bool
	Trusted    bool
	// InRange means the current discovery has heard from the device.
	InRange bool
}

BluetoothDevice is one remote device the Bluetooth stack knows about.

type BluetoothReading added in v2.22.0

type BluetoothReading struct {
	Devices     []BluetoothDevice
	Powered     bool
	Discovering bool
}

BluetoothReading is the adapter and the devices it knows.

type Connector

type Connector struct {
	Name      string
	Connected bool
	Enabled   bool
}

Connector is one display output from /sys/class/drm.

type Controller

type Controller struct {
	Battery *ControllerBattery
	// ID identifies the controller only for as long as it stays connected.
	ID   string
	Name string
	// VendorID and ProductID are four lowercase hex digits, or empty.
	VendorID   string
	ProductID  string
	Connection string
	// Address is the controller's hardware address in lower case, as the
	// kernel reports it, or empty. A Bluetooth controller's is its Bluetooth
	// address. It is never sent to clients.
	Address string
}

Controller is one physical game controller.

type ControllerBattery

type ControllerBattery struct {
	// Percent is nil when the hardware reports only a coarse level.
	Percent *int
	Level   string
	// ChargeState is empty when the hardware does not say.
	ChargeState power.ChargeState
}

ControllerBattery is a controller's own battery.

type DefaultOptions

type DefaultOptions struct {
	Executor command.Executor
	// VirtualGamepadSlots returns the controller slots held by gamepads Core
	// itself created, on systems that number controllers. May be nil.
	VirtualGamepadSlots func() []int
	// VirtualInputName is the name of the input device Core creates, which
	// must never be reported as a controller.
	VirtualInputName string
}

DefaultOptions is what the generic readers need to know about Core itself.

type DiskUsage

type DiskUsage struct {
	Total uint64
	// Free is every unallocated byte; Available is the part of it the calling
	// user may use.
	Free      uint64
	Available uint64
}

DiskUsage is the size of a filesystem and how much of it is free.

func DiskUsageOf

func DiskUsageOf(path string) (DiskUsage, error)

DiskUsageOf reports the size of the filesystem holding path.

type Display

type Display struct {
	// Docked is nil on a device with no built-in panel, where the question
	// has no meaning.
	Docked            *bool
	InternalPanel     bool
	InternalActive    bool
	ExternalConnected bool
	ExternalActive    bool
}

Display is what the device is showing its picture on.

func ClassifyDisplay

func ClassifyDisplay(connectors []Connector) Display

ClassifyDisplay turns a set of connectors into the facts a client lays its interface out from. A device with a built-in panel is docked while an external display is being driven.

type ExecPowerControl

type ExecPowerControl struct {
	Executor command.Executor
	// Commands maps each action the device supports to the program and
	// arguments that perform it.
	Commands map[PowerAction][]string
	// Permitted reports whether this process may run the commands. Nil means
	// it always may.
	Permitted func() bool
}

ExecPowerControl carries out power actions by running a command, for systems where that is the interface the operating system offers.

func (*ExecPowerControl) PowerActions

func (*ExecPowerControl) PreparePowerAction

func (c *ExecPowerControl) PreparePowerAction(_ context.Context, action PowerAction) (func() error, error)

type InputModalias

type InputModalias struct {
	Keys    []uint16
	Bus     uint16
	Vendor  uint16
	Product uint16
}

InputModalias is the identity an input device announces in its sysfs modalias.

func ParseInputModalias

func ParseInputModalias(alias string) (InputModalias, bool)

ParseInputModalias reads an input device modalias of the form "input:b0005v054Cp0CE6e8100-e0,1,3,k130,131,ra0,1,mlsfw". The key list is read from here rather than from capabilities/key because that bitmap's word width depends on the architecture.

func (InputModalias) Connection

func (m InputModalias) Connection() string

Connection names how the device is attached.

func (InputModalias) IsGamepad

func (m InputModalias) IsGamepad() bool

IsGamepad reports whether the device has controller buttons and is not a keyboard that happens to expose a few of them.

type Interface

type Interface struct {
	Name string
	Type LinkType
	// Addresses excludes loopback and link-local addresses.
	Addresses []string
	Up        bool
}

Interface is one network link.

type InternetState

type InternetState string

InternetState is how far beyond the local network the device can reach. The empty value means it has not been determined.

const (
	InternetFull InternetState = "full"
	// InternetPortal means something answered in place of the internet, as a
	// hotel or cafe sign-in page does.
	InternetPortal InternetState = "portal"
	InternetNone   InternetState = "none"
)

type LinkType

type LinkType string

LinkType is the kind of network link an interface is.

const (
	LinkWifi  LinkType = "wifi"
	LinkWired LinkType = "wired"
	LinkOther LinkType = "other"
	// LinkNone is the device-level answer when no interface carries a
	// default route.
	LinkNone LinkType = "none"
)

type LinuxBluetooth

type LinuxBluetooth struct {
	Fs afero.Fs

	SysRoot string
	// contains filtered or unexported fields
}

LinuxBluetooth reads the adapter's state. It never changes it.

func (*LinuxBluetooth) Read

func (r *LinuxBluetooth) Read() (Bluetooth, error)

Read reports whether an adapter exists and, where that can be learned without disturbing it, whether it is powered.

type LinuxControllers

type LinuxControllers struct {
	Fs afero.Fs
	// Resolve returns the real device path behind a sysfs class entry.
	Resolve func(path string) (string, error)
	// Batteries returns the charge BlueZ reads from Bluetooth devices' own
	// battery service, keyed by lower-case address. It covers pads whose
	// kernel driver adds no battery, such as the Xbox Wireless Controller over
	// Bluetooth LE. It may be nil.
	Batteries   func() map[string]int
	InputRoot   string
	PowerRoot   string
	VirtualName string
}

LinuxControllers lists physical game controllers from the kernel's input class.

func (*LinuxControllers) Read

func (r *LinuxControllers) Read() ([]Controller, error)

Read reports connected controllers. Devices created in software are left out, which covers Core's own virtual gamepad and the ones a game launcher presents in place of the real hardware.

type LinuxDisplay

type LinuxDisplay struct {
	Fs      afero.Fs
	DRMRoot string
}

LinuxDisplay reads display outputs from the kernel's DRM class.

func (*LinuxDisplay) Read

func (r *LinuxDisplay) Read() (Display, error)

Read reports which outputs are connected and driven.

type LinuxNetwork

type LinuxNetwork struct {
	Fs         afero.Fs
	Interfaces func() ([]RawInterface, error)

	ProcRoute string
	SysNet    string
	// contains filtered or unexported fields
}

LinuxNetwork reads links from sysfs and the routing table from procfs.

func (*LinuxNetwork) Read

func (r *LinuxNetwork) Read() (Network, error)

Read reports the device's links and which one carries the default route.

type LinuxPowerControl

type LinuxPowerControl struct {
	Fallback PowerController
	// contains filtered or unexported fields
}

LinuxPowerControl asks the login manager to change the machine's power state, which is what lets an unprivileged service do it where the distribution's policy allows. Systems without a login manager fall back to running the commands directly.

func NewLinuxPowerControl

func NewLinuxPowerControl(
	executor command.Executor,
	lookPath func(string) (string, error),
	euid func() int,
) *LinuxPowerControl

NewLinuxPowerControl returns a controller that runs reboot and poweroff as the fallback. lookPath finds a program, and euid is the effective user ID.

func (*LinuxPowerControl) PowerActions

func (c *LinuxPowerControl) PowerActions(ctx context.Context) map[PowerAction]Availability

func (*LinuxPowerControl) PreparePowerAction

func (c *LinuxPowerControl) PreparePowerAction(ctx context.Context, action PowerAction) (func() error, error)

type LinuxSystem

type LinuxSystem struct {
	Fs         afero.Fs
	Hostname   func() (string, error)
	ModelPaths []string
}

LinuxSystem reads what the machine calls itself.

func (*LinuxSystem) Read

func (r *LinuxSystem) Read() (System, error)

Read reports the hostname and hardware model.

type Network

type Network struct {
	// Type and Interface describe the link holding the default route.
	Type      LinkType
	Interface string
	// Internet is filled in by the reader only when InternetAuthoritative is
	// set; otherwise the caller decides it by probing.
	Internet   InternetState
	Interfaces []Interface
	// InternetAuthoritative means the operating system or the embedding host
	// already checks reachability and Internet is its answer.
	InternetAuthoritative bool
}

Network is the device's links and which of them carries its traffic.

type NoPowerControl

type NoPowerControl struct{}

NoPowerControl is the controller for a device that supports no power action.

func (NoPowerControl) PowerActions

func (NoPowerControl) PreparePowerAction

func (NoPowerControl) PreparePowerAction(context.Context, PowerAction) (func() error, error)

type PowerAction

type PowerAction string

PowerAction is a request to change the machine's power state.

const (
	PowerReboot   PowerAction = "reboot"
	PowerShutdown PowerAction = "shutdown"
	PowerSuspend  PowerAction = "suspend"
)

type PowerController

type PowerController interface {
	// PowerActions reports which actions this device can carry out for this
	// process. An action missing from the map is unsupported.
	PowerActions(ctx context.Context) map[PowerAction]Availability
	// PreparePowerAction checks that the action can go ahead and returns the
	// function that performs it. Refusals are reported here, with
	// ErrUnsupported or ErrNotPermitted, because by the time commit runs the
	// caller has already been answered.
	PreparePowerAction(ctx context.Context, action PowerAction) (commit func() error, err error)
}

PowerController carries out power actions.

type Prober

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

Prober decides whether the device can reach the internet by asking known endpoints for an answer nothing else would give.

func NewProber

func NewProber(urls []string, transport http.RoundTripper) *Prober

NewProber returns a prober over urls. transport may be nil for the default.

func (*Prober) Probe

func (p *Prober) Probe(ctx context.Context) InternetState

Probe asks each endpoint in turn and stops at the first that proves the internet is there. The empty state is returned when ctx ends first.

type RawInterface

type RawInterface struct {
	Name      string
	Addresses []net.IP
	Loopback  bool
	Up        bool
}

RawInterface is a network interface as the operating system lists it, before Core decides what kind of link it is.

func ListRawInterfaces

func ListRawInterfaces() ([]RawInterface, error)

ListRawInterfaces lists the machine's interfaces and their addresses.

type Readers

type Readers struct {
	Power        func() (power.Detail, error)
	Network      func() (Network, error)
	Bluetooth    func() (Bluetooth, error)
	Storage      func(roots []StorageRoot) ([]Volume, error)
	Display      func() (Display, error)
	Controllers  func() ([]Controller, error)
	System       func() (System, error)
	PowerControl PowerController
	// BluetoothControl is nil when Core cannot manage Bluetooth devices here.
	BluetoothControl BluetoothController
}

Readers is one reader per section. A nil reader, or one returning ErrUnsupported, means the device does not have that section.

func NewDefaults

func NewDefaults(opts DefaultOptions) Readers

NewDefaults returns the generic readers for Linux.

type StorageReader

type StorageReader struct {
	Usage func(path string) (DiskUsage, error)
	// FilesystemID returns the filesystem's identity and, where it is known,
	// its mount point.
	FilesystemID func(path string) (id, mountPoint string, err error)
	// IsEmpty reports whether a directory holds nothing. It is optional.
	IsEmpty func(path string) bool
	// Resolve follows the symlinks in a path, as FilesystemID does before it
	// names a mount point. It is optional.
	Resolve func(path string) (string, error)
}

StorageReader reports the filesystems a set of directories live on.

func NewStorageReader

func NewStorageReader() *StorageReader

NewStorageReader returns a reader over the real filesystem.

func (*StorageReader) Read

func (r *StorageReader) Read(roots []StorageRoot) ([]Volume, error)

Read returns one volume per distinct filesystem, in the order its first root was given, named by its mount point where that is known. A root that cannot be read, such as a share that is not mounted, is left out.

type StorageRoot

type StorageRoot struct {
	Path string
	Role string
}

StorageRoot is a directory whose filesystem should be reported.

type System

type System struct {
	Hostname string
	Model    string
}

System is what the device is.

type Volume

type Volume struct {
	// Path is where the filesystem is mounted, or the first root found on it
	// when that is not known.
	Path  string
	Roles []string
	Total uint64
	// Free is the space available to the user Core runs as.
	Free uint64
	Used uint64
}

Volume is one filesystem holding at least one storage root.

Jump to

Keyboard shortcuts

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