ExIncus. Instances
(ex_incus v1.0.0)
Copy Markdown
Manage instances (containers and virtual machines).
Creating and controlling instances
client = ExIncus.Client.new()
# Create + start a container from the public image server
{:ok, _} = ExIncus.Instances.launch(client, "web1", "debian/12")
{:ok, _} = ExIncus.Instances.stop(client, "web1")
{:ok, _} = ExIncus.Instances.start(client, "web1")
{:ok, _} = ExIncus.Instances.delete(client, "web1")Waiting
All state-changing calls are asynchronous on the Incus side; by default
this module waits for the operation to finish (up to timeout: seconds,
default 300). Pass wait: false to get the ExIncus.Operation back
immediately instead.
Config and devices
# Merge config keys (other keys are left alone)
ExIncus.Instances.update_config(client, "web1", %{"limits.memory" => "1GiB"})
# Add or replace a NIC with a static address
ExIncus.Instances.set_device(client, "web1", "eth0", %{
"type" => "nic",
"network" => "incusbr0",
"ipv4.address" => "10.140.100.10"
})Files
ExIncus.Instances.push_file(client, "web1", "/etc/resolv.conf",
"nameserver 10.140.100.1\n", mode: 0o644)
{:ok, content} = ExIncus.Instances.pull_file(client, "web1", "/etc/hostname")Commands
{:ok, result} = ExIncus.Instances.exec(client, "web1", ["uname", "-a"])
result.exit_code #=> 0
result.stdout #=> "Linux web1 ..."
Summary
Functions
Creates an instance from a full InstancesPost params map.
Creates a symlink at link_path pointing to target.
Deletes a (stopped, unless the server allows otherwise) instance.
Deletes a file or empty directory inside the instance.
Runs a command inside the instance and returns an ExIncus.ExecResult.
Freezes (pauses) the instance.
Fetches a single instance.
Fetches a log file by name (e.g. "lxc.log").
Creates (and by default starts) an instance from an image - the equivalent
of incus launch.
Lists instances.
Lists the entries of a directory inside the instance.
Lists available log files (as API URLs).
Creates a directory inside the instance. Options: :uid, :gid, :mode.
Partially updates the instance (PATCH). Supplied "config" and
"devices" entries are merged into the existing ones; entries you don't
mention are kept.
Reads a file from the instance and returns its content as a binary.
Writes a file into the instance, creating or overwriting it.
Removes a device. PATCH can only merge, so this reads the instance and
writes back the full configuration without the device (PUT).
Renames a stopped instance.
Restarts the instance. See set_state/4 for options.
Adds or replaces a single device, leaving other devices untouched.
Changes the runtime state. action is one of :start, :stop,
:restart, :freeze, :unfreeze.
Starts the instance. See set_state/4 for options.
Fetches the runtime state: status, network interfaces and addresses, resource usage, PIDs.
Stops the instance (gracefully; pass force: true to kill). See set_state/4.
Unfreezes the instance.
Replaces the instance configuration (PUT). params must be a full
InstancePut map; for partial changes prefer patch/4 or
update_config/4.
Merges the given keys into the instance config, leaving other keys untouched. Values are stringified (the API only accepts strings).
Types
@type name() :: String.t()
@type result() :: {:ok, term()} | {:error, ExIncus.Error.t()}
Functions
@spec create(ExIncus.Client.t(), map(), keyword()) :: result()
Creates an instance from a full InstancesPost params map.
You are expected to provide the "source" yourself; for the common
image-alias case launch/4 is more convenient.
ExIncus.Instances.create(client, %{
"name" => "web1",
"source" => %{
"type" => "image",
"protocol" => "simplestreams",
"server" => "https://images.linuxcontainers.org",
"alias" => "debian/12"
},
"config" => %{"limits.memory" => "1GiB"},
"profiles" => ["default"]
})
Creates a symlink at link_path pointing to target.
@spec delete(ExIncus.Client.t(), name(), keyword()) :: result()
Deletes a (stopped, unless the server allows otherwise) instance.
@spec delete_file(ExIncus.Client.t(), name(), String.t(), keyword()) :: result()
Deletes a file or empty directory inside the instance.
@spec exec(ExIncus.Client.t(), name(), [String.t()] | String.t(), keyword()) :: {:ok, ExIncus.ExecResult.t() | ExIncus.Operation.t()} | {:error, ExIncus.Error.t()}
Runs a command inside the instance and returns an ExIncus.ExecResult.
The command is run non-interactively. Output is recorded on the server and
fetched (then deleted) once the command finishes. A non-zero exit code is
still {:ok, result}; check result.exit_code.
{:ok, %{exit_code: 0, stdout: out}} =
ExIncus.Instances.exec(client, "web1", ["cat", "/etc/os-release"])Options
:environment- map of environment variables:user/:group- numeric uid/gid to run as:cwd- working directory:record_output- capture stdout/stderr (defaulttrue):cleanup_logs- delete the recorded output from the server after fetching it (defaulttrue):wait/:timeout- operation waiting; withwait: falseyou get the runningExIncus.Operationand no output handling
@spec freeze(ExIncus.Client.t(), name(), keyword()) :: result()
Freezes (pauses) the instance.
@spec get(ExIncus.Client.t(), name(), keyword()) :: result()
Fetches a single instance.
@spec get_log(ExIncus.Client.t(), name(), String.t(), keyword()) :: {:ok, binary()} | {:error, ExIncus.Error.t()}
Fetches a log file by name (e.g. "lxc.log").
Creates (and by default starts) an instance from an image - the equivalent
of incus launch.
image is either an alias string resolved against the public image server
(https://images.linuxcontainers.org), or a full source map which is passed through
untouched.
Options
:server/:protocol- override the image remote (protocol defaults to"simplestreams"):config,:devices,:profiles,:type("container"or"virtual-machine"),:ephemeral,:description- instance fields:start- start after creation (defaulttrue):wait/:timeout- operation waiting, as everywhere else
Examples
ExIncus.Instances.launch(client, "web1", "debian/12")
# From a local image alias instead of the public server:
ExIncus.Instances.launch(client, "web2", %{"type" => "image", "alias" => "my-golden"},
config: %{"limits.cpu" => "2"})
@spec list( ExIncus.Client.t(), keyword() ) :: result()
Lists instances.
Returns full objects by default. Options: recursion: (0 = URLs only,
1 = objects, 2 = objects incl. runtime state), filter: (server-side
filter expression, e.g. "status eq Running"), project:.
@spec list_files(ExIncus.Client.t(), name(), String.t(), keyword()) :: {:ok, [String.t()]} | {:error, ExIncus.Error.t()}
Lists the entries of a directory inside the instance.
@spec logs(ExIncus.Client.t(), name(), keyword()) :: result()
Lists available log files (as API URLs).
@spec mkdir(ExIncus.Client.t(), name(), String.t(), keyword()) :: result()
Creates a directory inside the instance. Options: :uid, :gid, :mode.
@spec patch(ExIncus.Client.t(), name(), map(), keyword()) :: result()
Partially updates the instance (PATCH). Supplied "config" and
"devices" entries are merged into the existing ones; entries you don't
mention are kept.
@spec pull_file(ExIncus.Client.t(), name(), String.t(), keyword()) :: {:ok, binary()} | {:error, ExIncus.Error.t()}
Reads a file from the instance and returns its content as a binary.
Writes a file into the instance, creating or overwriting it.
ExIncus.Instances.push_file(client, "web1", "/etc/resolv.conf",
"nameserver 10.140.100.1\n", uid: 0, gid: 0, mode: 0o644)Options
:uid/:gid- numeric owner (defaults to root on the server side):mode- file mode, as an integer (0o644) or octal string ("0644"):append- append to the file instead of overwriting
@spec remove_device(ExIncus.Client.t(), name(), String.t(), keyword()) :: result()
Removes a device. PATCH can only merge, so this reads the instance and
writes back the full configuration without the device (PUT).
@spec rename(ExIncus.Client.t(), name(), name(), keyword()) :: result()
Renames a stopped instance.
@spec restart(ExIncus.Client.t(), name(), keyword()) :: result()
Restarts the instance. See set_state/4 for options.
Adds or replaces a single device, leaving other devices untouched.
ExIncus.Instances.set_device(client, "web1", "eth0", %{
"type" => "nic",
"network" => "incusbr0",
"ipv4.address" => "10.140.100.10"
})Note the device entry is replaced as a whole, so include every key the device needs, not just the changed one.
@spec set_state(ExIncus.Client.t(), name(), atom(), keyword()) :: result()
Changes the runtime state. action is one of :start, :stop,
:restart, :freeze, :unfreeze.
Options
:force- kill instead of graceful shutdown (stop/restart):action_timeout- seconds the server allows the action to take before giving up (thetimeoutfield of the API request):stateful- store/restore runtime state (start/stop):wait/:timeout- operation waiting
@spec start(ExIncus.Client.t(), name(), keyword()) :: result()
Starts the instance. See set_state/4 for options.
@spec state(ExIncus.Client.t(), name(), keyword()) :: result()
Fetches the runtime state: status, network interfaces and addresses, resource usage, PIDs.
@spec stop(ExIncus.Client.t(), name(), keyword()) :: result()
Stops the instance (gracefully; pass force: true to kill). See set_state/4.
@spec unfreeze(ExIncus.Client.t(), name(), keyword()) :: result()
Unfreezes the instance.
@spec update(ExIncus.Client.t(), name(), map(), keyword()) :: result()
Replaces the instance configuration (PUT). params must be a full
InstancePut map; for partial changes prefer patch/4 or
update_config/4.
@spec update_config(ExIncus.Client.t(), name(), map(), keyword()) :: result()
Merges the given keys into the instance config, leaving other keys untouched. Values are stringified (the API only accepts strings).
ExIncus.Instances.update_config(client, "web1", %{"boot.autostart" => true})