Exosphere objects

The primary low level objects used by Exosphere are Host and Inventory objects.

They provide the main functionality to interact with the hosts and perform operations on them.

class exosphere.objects.Host(name: str, ip: str, port: int = 22, username: str | None = None, description: str | None = None, connect_timeout: int | None = None, sudo_policy: str | None = None)

Bases: object

Host object representing a remote system.

This object can be used to query the host for information, perform operations on it as well as manage its state.

The host will be marked as offline until the first discovery operation is performed. Errors in processing will update this status automatically.

__init__(name: str, ip: str, port: int = 22, username: str | None = None, description: str | None = None, connect_timeout: int | None = None, sudo_policy: str | None = None) None

Create a new Host Object

Note: The parameters of the Host object can and will be affected by the process of reloading them from cache! See: exosphere.inventory.Inventory.load_or_create_host

Keep in mind the need to verify this process if you make changes to the constructor signature or default values.

Intended to be serializable!

Parameters:
  • name – Name of the host

  • ip – IP address or FQDN of the host

  • port – Port number for SSH connection (default is 22)

  • username – SSH username (optional, will use current if not provided)

  • description – Optional description for the host

  • connect_timeout – Connection timeout in seconds (optional)

  • sudo_policy – Sudo policy for package manager operations (skip, nopasswd)

close(clear: bool = False) None

Close the SSH connection if one exists.

Explicitly close the Connection object. Subsequent calls to connection property will recreate it if necessary.

This should be called when done with batch operations on the host or when cleaning up on exit.

You can use the clear parameter to also clear the internal connection object after closing it, if you want to ensure it is not reused.

Parameters:

clear – If True, sets the internal connection object to None after closing.

property connection: Connection

Establish a connection to the host using Fabric. This method sets up the connection object for further operations.

Connection objects are recycled if already created.

If you work with Host objects directly, make sure to call host.close() when done with operations (such as discover, refresh_updates, etc) to avoid leaving ssh connections open.

If you don’t, all connections will be closed automatically on program exit.

Returns:

Fabric Connection object

property connection_last_used: float | None

Get the timestamp of the last use of the connection.

“last used” here is defined as the last time anything requested the Connection object through the property for this host.

Property access is thread-safe, and will reset the timestamp to None if the connection is no longer active.

Returns:

Timestamp of last use in seconds since epoch, or None if connection has never been used.

discover() None

Synchronize host information with remote system. Attempts to detect the platform details, such as operating system, version, flavor, and package manager.

Online status is also updated in the process.

from_state(state: HostState) None

Update the Host object from a HostState dataclass instance. Useful for loading state from disk or cache.

Parameters:

state – HostState instance to load state from

property is_connected: bool

Check if the host has an active SSH connection.

Returns:

True if connection exists and is connected, False otherwise

property is_stale: bool

Check if the host is staled based on refresh timestamp

A host is considered stale if it has not been refreshed within the “stale_threshold” value in seconds set in the configuration. Default is 86400 seconds (24 hours).

Returns:

True if the host is stale, False otherwise

ping(raise_on_error: bool = False, close_connection: bool = True) bool

Check if the host is reachable by executing a simple command.

Can optionally raise an exception, which will contain much deeper details about the connection failure.

As such, with raise_on_error set to True, ping() can be used to verify authentication and connectivity in general.

Parameters:
  • raise_on_error – Whether to raise an exception on failure

  • close_connection – Whether to close the connection after pinging. This has no effect if SSH pipelining is enabled, as the connection will be managed by the Reaper Thread.

Returns:

True if the host is reachable, False otherwise

refresh_updates() None

Refresh the list of available updates on the host. This method retrieves the list of available updates and populates the updates attribute.

property security_updates: list[Update]

Get a list of security updates available on the host.

Returns:

List of security updates

sync_repos() None

Sync the package repositories on the host.

Will invoke the concrete package manager provider implementation associated during initial host sync.

This is the equivalent of your ‘apt-get update’ or similar

to_dict() dict

Convert the Host object to a dictionary representation. Useful for serialization or reporting

Note: Only includes informational fields, does not include configuration or connection details.

Any datetime fields are represented as ISO 8601 strings in UTC. They explicitly follow what JavaScript’s Date.toJSON() produces for maximum compatibility.

Returns:

Dictionary representation of the Host object

to_state() HostState

Convert the Host object to a HostState dataclass instance. Useful for serialization to disk or caching.

Returns:

HostState instance representing the current state of the Host

class exosphere.inventory.Inventory(config: Configuration)

Bases: object

Inventory and state management

Handles reading the inventory from file and creating the Host objects.

Also handles dispatching tasks to the Host objects, via a parallelized ThreadPoolExecutor.

Convenience methods for discovery, repo sync, updates refresh and ping are provided, and are all parallelized using Threads.

Runtime errors are generally non-fatal, but will be logged. The Host objects themselves usually handle their own failure cases and will log errors as appropriate, on top of flagging themselves as offline if they are unable to perform their tasks.

clear_state() None

Clear the current state of the inventory This will remove the cache file and re-init the inventory.

close_all(clear: bool = False) None

Close all SSH connections for all hosts in the inventory.

Invokes the close method on each Host object, closing the ssh connection if one exists.

It will be re-established on next request.

Parameters:

clear – If True, clears the connection object on each host after closing it by setting it to None.

discover_all() None

Discover all hosts in the inventory.

get_host(name: str) Host | None

Get a Host object by name from the inventory

If the host is not found, it returns None and logs an error message. If the inventory was properly loaded, there a unicity constraint on host names, so you can reasonably expect to not have to deal with duplicates.

Parameters:

name – The name of the host to retrieve, e.g. “webserver1”

Returns:

The Host object if found, None otherwise

init_all() None

Setup the inventory by creating Host objects from the configuration.

Existing state will be cleared in the process.

load_or_create_host(name: str, host_cfg: dict[str, Any], cache: DiskCache) Host

Attempt to load a host from the cache, or create a new one if that fails in any meaningful way.

Is also responsible for binding the host configuration parameters to the Host object ones, and will log a warning if invalid parameters are found in the configuration dictionary.

Invalid parameters will be ignored.

The new host’s other configuration properties will be updated if they have changed from config since (i.e. ip address, port etc)

Parameters:
  • name – The name of the host to load or create

  • host_cfg – The configuration dictionary for the host

  • cache – The DiskCache instance to use for loading the host

Returns:

An instance of Host

ping_all() None

Ping all hosts in the inventory.

This method will call the ping method on each Host object in the inventory and log whether each host is online or offline.

refresh_updates_all() None

Refresh the list of available updates on all hosts in the inventory.

This method will call the refresh_updates method on each Host object in the inventory.

run_task(host_method: str, hosts: list[Host] | None = None) Generator[tuple[Host, Any, Exception | None], None, None]

Run a method on specified hosts in the inventory. If none are specified, run on all hosts.

Uses a ThreadPoolExecutor to run the provided method concurrently, and returns a generator that can be safely iterated over to process the results as the tasks complete.

Parameters:
  • host_method – The method to run on each host

  • hosts – Optional list of Host objects to run the method on. If unspecified, runs on all hosts in the inventory.

Returns:

A generator yielding tuples of (host, result, exception)

save_state() None

Save the current state of inventory hosts to the cache file.

sync_repos_all() None

Sync the package repositories on all hosts in the inventory.

This method will call the sync_repos method on each Host object in the inventory.