Add a stateful Proxmox API console and broad handler coverage beyond the
initial QEMU slice, backed by imported contracts for majors 6–9. - Implement durable handlers for access/auth, cluster, LXC, storage, HA, firewall, Ceph, SDN, ACME, notifications, pools, mapping, and node ops - Serve an interactive Web UI with catalog browsing, demo seed controls, and OpenAPI/help surfaces - Bundle PVE 6.4-15, 7.4-16, and 8.4.5 contract revisions alongside 9.2.3 - Support in-memory runtime contract Apply (POST /ui/api/contract/apply) so /version and /api2 routes follow the selected major until restart - Expand seed profiles (including demo-cluster), migrations 007–008, TLS gateway config, Compose/Makefile tooling, and compatibility evidence - Tighten .gitignore for macOS, hidden directories (.*/), and local secrets
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use HTTP::Tiny;
|
||||
use JSON qw(decode_json encode_json);
|
||||
|
||||
sub uri_escape {
|
||||
my ($value) = @_;
|
||||
$value =~ s/([^A-Za-z0-9\-\._~])/sprintf('%%%02X', ord($1))/eg;
|
||||
return $value;
|
||||
}
|
||||
|
||||
my $base = $ENV{PVE_BASE} // 'http://localhost:8006/api2/json';
|
||||
my $node = $ENV{PVE_NODE} // 'pve01';
|
||||
my $vmid = $ENV{PVE_VMID} // '115';
|
||||
my $token = $ENV{PVE_API_TOKEN} // 'root@pam!automation=automation-secret';
|
||||
my $auth = "PVEAPIToken=$token";
|
||||
my $http = HTTP::Tiny->new(timeout => 60);
|
||||
|
||||
sub api {
|
||||
my ($method, $path, $body) = @_;
|
||||
my %opts = (headers => { Authorization => $auth });
|
||||
if (defined $body) {
|
||||
$opts{headers}{'Content-Type'} = 'application/x-www-form-urlencoded';
|
||||
$opts{content} = $body;
|
||||
}
|
||||
my $res = $http->request($method, "$base$path", \%opts);
|
||||
die "$method $path failed: $res->{status} $res->{content}\n" unless $res->{success};
|
||||
my $json = decode_json($res->{content});
|
||||
return $json->{data};
|
||||
}
|
||||
|
||||
sub wait_task {
|
||||
my ($upid) = @_;
|
||||
my $deadline = time + 120;
|
||||
while (time < $deadline) {
|
||||
my $status = api('GET', "/nodes/$node/tasks/" . uri_escape($upid) . '/status');
|
||||
return if ref $status eq 'HASH' && ($status->{status} // '') eq 'stopped';
|
||||
select(undef, undef, undef, 0.5);
|
||||
}
|
||||
die "timeout waiting for $upid\n";
|
||||
}
|
||||
|
||||
print "version: ", encode_json(api('GET', '/version')), "\n";
|
||||
my $upid = api('POST', "/nodes/$node/qemu", "vmid=$vmid&name=perl-$vmid&cores=1&memory=512");
|
||||
wait_task($upid);
|
||||
$upid = api('POST', "/nodes/$node/qemu/$vmid/status/start");
|
||||
wait_task($upid);
|
||||
print "status: ", encode_json(api('GET', "/nodes/$node/qemu/$vmid/status/current")), "\n";
|
||||
$upid = api('POST', "/nodes/$node/qemu/$vmid/status/stop");
|
||||
wait_task($upid);
|
||||
$upid = api('DELETE', "/nodes/$node/qemu/$vmid");
|
||||
wait_task($upid);
|
||||
print "ok\n";
|
||||
Reference in New Issue
Block a user