Skip to main content

Arcane Mage - Fluxnode Provisioning Library and Tools

Introduction

This is experimental software. There may be rough edges. If you spot something that is not quite right - please open an issue.

Arcane Mage is a Python library and suite of tools for automating Fluxnode installation and configuration. It can be used as a standalone CLI/TUI application or imported as a library for custom automation workflows.

Features:

  • Fully automated A to Z Proxmox installs, including Secure Boot key enrollment
  • Async Proxmox VE API client with token and password authentication
  • Pydantic-validated configuration models loadable from YAML
  • Custom async FAT12 writer for config disk image creation
  • Yescrypt password hashing for Linux shadow-compatible hashes
  • TUI (Textual) and CLI (Typer) interfaces with rich-formatted output
  • TPM 2.0 keyring backend for headless Linux credential storage

Installation

Install uv - https://docs.astral.sh/uv/getting-started/installation/

# Library only (for use as a dependency)
uv add arcane-mage

# With CLI support
uv add "arcane-mage[cli]"

# With TUI support (includes CLI)
uv add "arcane-mage[tui]"

# Install as a standalone tool
uv tool install "arcane-mage[tui]"

# Run once without installing
uvx --with "arcane-mage[tui]" arcane-mage

Library Usage

arcane-mage exposes a public API for programmatic Fluxnode provisioning:

from arcane_mage import (
    ArcaneOsConfigGroup,
    Provisioner,
    ProxmoxApi,
    TIER_CONFIG,
    get_latest_iso_version,
)

Loading Configuration

Node configurations are defined in YAML and loaded into Pydantic-validated models:

from arcane_mage import ArcaneOsConfigGroup

# Load from the default fluxnodes.yaml
group = ArcaneOsConfigGroup.from_fs()

# Load from a specific file
group = ArcaneOsConfigGroup.from_fs(Path("my_nodes.yaml"))

for node in group:
    print(node.fluxnode.identity.flux_id)

See the examples directory for sample YAML configurations.

Connecting to Proxmox

from arcane_mage import ProxmoxApi

# Parse and connect with a token string
token = ProxmoxApi.parse_token("automation@pam!arcane=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
if token:
    api = ProxmoxApi.from_token("https://pve.local:8006", token)
    print(token.user)      # "automation@pam"
    print(token.username)   # "automation"

# Password authentication
creds = ProxmoxApi.parse_user_pass("automation:secret")
if creds:
    api = await ProxmoxApi.from_user_pass("https://pve.local:8006", creds)

# Use as an async context manager
async with api:
    version = await api.get_api_version("pve1")
    vms = await api.get_vms("pve1")

Provisioning Nodes

from arcane_mage import ArcaneOsConfigGroup, Provisioner, ProxmoxApi

token = ProxmoxApi.parse_token("automation@pam!arcane=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
api = ProxmoxApi.from_token(url, token)

async with api:
    provisioner = Provisioner(api)

    group = ArcaneOsConfigGroup.from_fs()
    for node in group:
        success = await provisioner.provision_node(
            node,
            callback=lambda ok, msg: print(f"{'OK' if ok else 'FAIL'}: {msg}"),
        )

The provisioner handles the full workflow: API validation, storage checks, VM config generation, FAT12 config disk creation, EFI upload, VM creation, and cleanup.

Discovery

Match existing VMs on a hypervisor against your configuration:

discovery = await provisioner.discover_nodes(group)
if discovery:
    for node in discovery.nodes:
        print(node.fluxnode.identity.flux_id)

Other Utilities

from arcane_mage import HashedPassword, TIER_CONFIG, get_latest_iso_version

# Yescrypt password hashing (Linux shadow-compatible)
hashed = HashedPassword("my_password").hash()

# Hardware tier specs (cumulus, nimbus, stratus)
print(TIER_CONFIG["cumulus"])  # {'memory_mb': 8192, 'scsi_gb': 220, 'cpu_cores': 4}

# Fetch latest FluxOS ISO version
version = await get_latest_iso_version()

CLI Usage

Launch the interactive TUI:

arcane-mage tui
arcane-mage tui -c my_nodes.yaml

Stored Hypervisors

Hypervisors added via the TUI are stored in ~/.fluxnode_creator.yaml with credentials in your system keyring. Use --hypervisor / -H to reference them by name instead of passing --url and --token:

arcane-mage ping -H pve1
arcane-mage validate -H pve1 -c my_nodes.yaml
arcane-mage provision -H pve1 -c my_nodes.yaml --start

Commands

Test connectivity and authentication:

arcane-mage ping -H pve1

Provision nodes:

arcane-mage provision -H pve1 -c my_nodes.yaml --start

Pre-flight validation (checks API, storage, ISO, network without provisioning):

arcane-mage validate -H pve1 -c my_nodes.yaml

Check which configured nodes are already provisioned:

arcane-mage status -H pve1 -c my_nodes.yaml

Deprovision (stop and delete) VMs:

# From config file
arcane-mage deprovision -H pve1 -c my_nodes.yaml

# Target a specific VM by name or ID
arcane-mage deprovision -H pve1 --vm-name mynode
arcane-mage deprovision -H pve1 --vm-id 105

# Skip confirmation
arcane-mage deprovision -H pve1 --vm-name mynode --force

Authentication

All commands that connect to Proxmox also accept explicit credentials:

arcane-mage ping \
    --url https://pve.local:8006 \
    --token 'automation@pam!arcane=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

Or via environment variables:

export ARCANE_MAGE_URL=https://pve.local:8006
export ARCANE_MAGE_TOKEN='automation@pam!arcane=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
arcane-mage validate -c my_nodes.yaml

Or pipe the token via stdin:

cat /path/to/token | arcane-mage provision -c my_nodes.yaml

Credential resolution order: --token > stdin > ARCANE_MAGE_TOKEN env var > --hypervisor stored credential.

JSON Output

All Proxmox commands support --json for machine-readable output (useful for Ansible):

arcane-mage validate -H pve1 -c my_nodes.yaml --json
arcane-mage status -H pve1 -c my_nodes.yaml --json

Run the following for help:

arcane-mage --help
arcane-mage provision --help

Configuration

Node configurations are defined in YAML. See docs/configuration.md for the full schema reference and examples/ for ready-to-use templates.

Proxmox Setup

See docs/proxmox-setup.md for hypervisor setup instructions (user, API token, storage, permissions).

Credential Storage

Arcane Mage uses your system's secure keyring to store API credentials, with a built-in TPM 2.0 backend for headless Linux servers. See docs/keyring.md for details and troubleshooting.

Metadata

Release files for arcane-mage 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for arcane-mage 2.1.0
File Size Uploaded
arcane_mage-2.1.0.tar.gz 482.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for arcane-mage 2.1.0
File Interpreter ABI Platform
arcane_mage-2.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 600.4 kB

Release files / arcane_mage-2.1.0.tar.gz

Download URL arcane_mage-2.1.0.tar.gz
Size 482.0 kB
Tags Source
SHA-256 checksum
How to use checksums
5ea0b3c994505ec2d84b8149900fd1a0f24a7af45446ddcc5248b1da9e44768c
BLAKE2b-256 checksum
How to use checksums
e8c15c32ce761eaff537b876ea557fa7bf4ee0276dc900de399f3df005e1da3a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / arcane_mage-2.1.0-py3-none-any.whl

Download URL arcane_mage-2.1.0-py3-none-any.whl
Size 118.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4a61a8c7cd352f9f652f68c96144ecb4fb3315adeccd25fc5c5dd041e13c8988
BLAKE2b-256 checksum
How to use checksums
17ba314123d28a2686fc5524ec42c3e22bc55e5641dfb56a83d4bbf776ea4fb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

2.2.1

2 release files

2.2.0

2 release files

This release

2.1.0 This release

2 release files

2.0.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page