Getting Started - FreshPerf/PVE4J GitHub Wiki

Getting Started with PVE4J

This guide will help you get up and running with PVE4J quickly.

Prerequisites

  • Java 21 or higher
  • A Proxmox VE server (version 8.x or 9.x recommended)
  • An API token or username/password for authentication

Installation

Gradle

implementation 'fr.freshperf:pve4j:0.2.0'

Maven

<dependency>
    <groupId>fr.freshperf</groupId>
    <artifactId>pve4j</artifactId>
    <version>0.2.0</version>
</dependency>

Creating Your First Client

PVE4J supports two authentication methods: API tokens and username/password.

Using API Token

import fr.freshperf.pve4j.Proxmox;
import fr.freshperf.pve4j.SecurityConfig;

public class ProxmoxExample {
    public static void main(String[] args) {
        // For production with valid SSL certificate
        Proxmox proxmox = Proxmox.create(
            "pve.example.com",
            8006,
            "root@pam!mytoken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
        );
        
        // For development with self-signed certificate
        Proxmox proxmoxDev = Proxmox.create(
            "192.168.1.100",
            8006,
            "root@pam!mytoken=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            SecurityConfig.insecure()
        );
    }
}

Using Username/Password

import fr.freshperf.pve4j.Proxmox;
import fr.freshperf.pve4j.SecurityConfig;
import fr.freshperf.pve4j.throwable.ProxmoxAPIError;

public class ProxmoxExample {
    public static void main(String[] args) {
        try {
            // Simple authentication with default PAM realm
            Proxmox proxmox = Proxmox.createWithPassword(
                "pve.example.com",
                8006,
                "root",
                "your-password"
            );
            
            // With custom realm and insecure config for development
            Proxmox proxmoxDev = Proxmox.createWithPassword(
                "192.168.1.100",
                8006,
                "admin",
                "password",
                "pve",  // realm
                SecurityConfig.insecure()
            );
        } catch (ProxmoxAPIError | InterruptedException e) {
            System.err.println("Authentication failed: " + e.getMessage());
        }
    }
}

Your First API Call

Let's retrieve the Proxmox version:

import fr.freshperf.pve4j.Proxmox;
import fr.freshperf.pve4j.entities.PveVersion;
import fr.freshperf.pve4j.throwable.ProxmoxAPIError;

public class GetVersion {
    public static void main(String[] args) {
        Proxmox proxmox = Proxmox.create("192.168.1.100", 8006, "your-token");
        
        try {
            PveVersion version = proxmox.getVersion().execute();
            System.out.println("Proxmox VE Version: " + version.getVersion());
            System.out.println("Release: " + version.getRelease());
            System.out.println("Repo ID: " + version.getRepoid());
        } catch (ProxmoxAPIError | InterruptedException e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Common Operations

List All Nodes

import fr.freshperf.pve4j.entities.nodes.PveNodesIndex;
import java.util.List;

try {
    List<PveNodesIndex> nodes = proxmox.getNodes().getIndex().execute();
    
    for (PveNodesIndex node : nodes) {
        System.out.println("Node: " + node.getNode());
        System.out.println("Status: " + node.getStatus());
        System.out.println("CPU: " + node.getCpu());
        System.out.println("Memory: " + node.getMem() + " / " + node.getMaxmem());
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

List All VMs in Cluster

import fr.freshperf.pve4j.entities.cluster.resources.PveClusterResources;
import java.util.List;

try {
    List<PveClusterResources> vms = proxmox.getCluster()
            .getResources("vm")
            .execute();
    
    for (PveClusterResources vm : vms) {
        System.out.println("VMID: " + vm.getVmid());
        System.out.println("Name: " + vm.getName());
        System.out.println("Status: " + vm.getStatus());
        System.out.println("Node: " + vm.getNode());
        System.out.println("---");
    }
} catch (ProxmoxAPIError | InterruptedException e) {
    e.printStackTrace();
}

Start a Virtual Machine

import fr.freshperf.pve4j.entities.PveTask;

try {
    PveTask task = proxmox.getNodes()
            .get("pve-node-01")
            .getQemu()
            .get(100)
            .start()
            .waitForCompletion(proxmox)
            .execute();
    
    System.out.println("VM started successfully!");
    System.out.println("Task UPID: " + task.getUpid());
} catch (ProxmoxAPIError | InterruptedException e) {
    System.err.println("Failed to start VM: " + e.getMessage());
}

Exception Handling

All API calls can throw two types of exceptions:

  1. ProxmoxAPIError - For API-related errors (HTTP errors, parsing failures, etc.)
  2. InterruptedException - For thread interruption during requests
try {
    // Your API calls here
} catch (ProxmoxAPIError e) {
    System.err.println("Proxmox API Error: " + e.getMessage());
    System.err.println("Status Code: " + e.getStatusCode());
    System.err.println("Response: " + e.getResponseBody());
} catch (InterruptedException e) {
    System.err.println("Request was interrupted");
    Thread.currentThread().interrupt();
}

Next Steps

Troubleshooting

SSL Certificate Errors

If you get SSL certificate errors with a self-signed certificate:

Proxmox proxmox = Proxmox.create(
    "192.168.1.100",
    8006,
    "your-token",
    SecurityConfig.insecure()  // Disables SSL verification
);

Warning: Only use SecurityConfig.insecure() in development environments.

Connection Refused

If you get connection refused errors:

  1. Verify the Proxmox host and port are correct
  2. Ensure the Proxmox API is accessible from your network
  3. Check firewall rules on both client and server

Authentication Errors

If you get 401 Unauthorized errors:

  1. Verify your API token is correct and not expired
  2. Check that the token has appropriate permissions
  3. Ensure the token format is correct: USER@REALM!TOKENID=SECRET
  4. If using password auth, verify your username, password and realm

Support

⚠️ **GitHub.com Fallback** ⚠️