guest

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2024 License: BSD-2-Clause Imports: 11 Imported by: 0

README

incus-guestapi

 Godoc Reference

A tiny package for communicating with the Incus instance API.

It has a single dependency (nhooyr.io/websocket) to handle real time events. You can use this package directly or as a reference for your own programs.

Install

go get github.com/shellhazard/incus-guestapi@latest

Purpose

By far the most practical reason to use this is for managing application config. You can pull config values on startup then use ListenForEvents to monitor for any changes to the instance configuration in real time - see the example below.

Usage example

Run the below program inside an Incus instance, then try:

incus config set instance-name user.secret_config_key=secretvalue
package main

import (
	"context"
	"log"

	guest "github.com/shellhazard/incus-guestapi"
	"github.com/shellhazard/incus-guestapi/incus"
)

func must[T any](t T, err error) T {
	if err != nil {
		panic(err)
	}
	return t
}

func main() {
	// Make sure we're actually able to use the Incus socket
	if !guest.IsInsideInstance() {
		log.Fatal("failed: not running inside an Incus instance")
	}

	// Create a new API client
	c := guest.NewClient()

	// Retrieve instance state
	info := must(c.Info())
	log.Printf("%+v\n", info)

	// List attached devices
	devices := must(c.Devices())
	log.Printf("%+v\n", devices)

	// List available config keys
	keys := must(c.ListConfig())
	log.Printf("%+v\n", keys)

	// Retrieve the value associated with a key
	value := c.MustConfig("my_config_item")
	log.Printf("my_config_item: %s\n", value)

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// Block listening for config changes, logging them out as they come
	err := c.ListenForEvents(ctx, func(ev *incus.Event) {
		// Take some kind of useful action here, like updating
		// the config struct used by your application.
		log.Printf("key %s updated - old value: %s; new value: %s\n",
			ev.Config.Key,
			ev.Config.OldValue,
			ev.Config.Value,
		)
	}, incus.EventTypeConfig)
	if err != nil {
		log.Printf("unexpected error in event listener %s\n", err)
	}
}

API Support

The API surface is pretty small. That said, I didn't implement anything I didn't see myself using.

  • Instance info (/1.0)
  • List instance config keys (/1.0/config)
  • Retrieve config value (/1.0/config/{key})
  • List instance devices (/1.0)
  • Instance info (/1.0/devices)
  • Retrieve cloud-init metadata (/1.0/meta-data)
  • Export images (/1.0/images/{fingerprint}/export) (requires security.guestapi.images to be set to true)

Documentation

Index

Constants

View Source
const (
	SocketPath = "/dev/incus/sock"

	InstanceInfoPath = "/1.0/1.0"
	ListDevicesPath  = "/1.0/1.0/devices"
	ConfigPath       = "/1.0/1.0/config"
	MetadataPath     = "/1.0/1.0/meta-data"
	EventsPath       = "/1.0/1.0/events"
)

Variables

View Source
var UnexpectedStatusCode = errors.New("unexpected status code")

Functions

func IsInsideInstance

func IsInsideInstance() bool

IsIncus attempts to connect to /dev/incus/sock.

Types

type GuestClient

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

func NewClient

func NewClient() *GuestClient

func (*GuestClient) Config

func (g *GuestClient) Config(key string) (string, error)

Config retrieves the value of the specified instance config key.

As instances only have access to user.* and cloud-init.* configuration, provided keys will be prefixed with `user.` unless explicitly specified.

See: https://linuxcontainers.org/incus/docs/main/dev-incus/#config-key

func (*GuestClient) Devices

func (g *GuestClient) Devices() (map[string]map[string]string, error)

Devices returns a map of devices available to the instance.

See: https://linuxcontainers.org/incus/docs/main/dev-incus/#devices

func (*GuestClient) HasConfig

func (g *GuestClient) HasConfig(key string) (bool, error)

HasConfig checks for the presence of the specified config key.

As instances only have access to user.* and cloud-init.* configuration, provided keys will be prefixed with `user.` unless explicitly specified.

See: https://linuxcontainers.org/incus/docs/main/dev-incus/#config-key

func (*GuestClient) Info

func (g *GuestClient) Info() (*incus.InstanceInfo, error)

Info returns information about the API and instance state.

See: https://linuxcontainers.org/incus/docs/main/dev-incus/#id2

func (*GuestClient) ListConfig

func (g *GuestClient) ListConfig() ([]string, error)

ListConfig returns a slice of all config keys available to the instance.

See: https://linuxcontainers.org/incus/docs/main/dev-incus/#config

func (*GuestClient) ListenForEvents

func (g *GuestClient) ListenForEvents(ctx context.Context, callback func(*incus.Event), events ...incus.EventType) error

ListenForEvents opens a WebSocket connection to the guest events API, blocking the current goroutine. It takes a callback function and an optional list of events to subscribe to. If no events are provided, it will subscribe to all of them.

See the definition for incus.EventType for valid values.

func (*GuestClient) Metadata

func (g *GuestClient) Metadata() (string, error)

Metadata returns the value of the `cloud-init.user-data` config key.

See: https://linuxcontainers.org/incus/docs/main/dev-incus/#meta-data

func (*GuestClient) MustConfig

func (g *GuestClient) MustConfig(key string) string

MustConfig calls Config, panicking if there's any error or the key is empty.

Directories

Path Synopsis
cmd
example command
Package Incus contains API return types.
Package Incus contains API return types.

Jump to

Keyboard shortcuts

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