+ if (!$class) {
+ chomp $result;
+ return if $result =~ m/^\s*$/;
+ print "$result\n";
+ return;
+ }
+
+ if (($class eq 'HASH') && !scalar(keys %$result)) { # empty hash
+ return;
+ }
+
+ print to_json($result, { pretty => 1, canonical => 1, utf8 => 1});
+};
+
+sub param_mapping {
+ my ($name) = @_;
+
+ my $ssh_key_map = ['sshkeys', sub {
+ return URI::Escape::uri_escape(file_get_contents($_[0]));
+ }];
+ my $cipassword_map = PVE::CLIHandler::get_standard_mapping('pve-password', { name => 'cipassword' });
+ my $password_map = PVE::CLIHandler::get_standard_mapping('pve-password');
+ my $mapping = {
+ 'update_vm' => [$ssh_key_map, $cipassword_map],
+ 'create_vm' => [$ssh_key_map, $cipassword_map],
+ 'set-user-password' => [$password_map],
+ };
+
+ return $mapping->{$name};
+}
+
+our $cmddef = {
+ list=> [ "PVE::API2::Qemu", 'vmlist', [], { %node }, sub {
+ my $vmlist = shift;
+ exit 0 if (!scalar(@$vmlist));
+
+ printf "%10s %-20s %-10s %-10s %12s %-10s\n",
+ qw(VMID NAME STATUS MEM(MB) BOOTDISK(GB) PID);
+
+ foreach my $rec (sort { $a->{vmid} <=> $b->{vmid} } @$vmlist) {
+ printf "%10s %-20s %-10s %-10s %12.2f %-10s\n", $rec->{vmid}, $rec->{name},
+ $rec->{qmpstatus} || $rec->{status},
+ ($rec->{maxmem} || 0)/(1024*1024),
+ ($rec->{maxdisk} || 0)/(1024*1024*1024),
+ $rec->{pid} || 0;
+ }
+ }],
+
+ create => [ "PVE::API2::Qemu", 'create_vm', ['vmid'], { %node }, $upid_exit ],
+ destroy => [ "PVE::API2::Qemu", 'destroy_vm', ['vmid'], { %node }, $upid_exit ],
+ clone => [ "PVE::API2::Qemu", 'clone_vm', ['vmid', 'newid'], { %node }, $upid_exit ],
+
+ migrate => [ "PVE::API2::Qemu", 'migrate_vm', ['vmid', 'target'], { %node }, $upid_exit ],
+ 'remote-migrate' => [ __PACKAGE__, 'remote_migrate_vm', ['vmid', 'target-vmid', 'target-endpoint'], { %node }, $upid_exit ],
+
+ set => [ "PVE::API2::Qemu", 'update_vm', ['vmid'], { %node } ],
+
+ config => [ "PVE::API2::Qemu", 'vm_config', ['vmid'], { %node }, sub {
+ my $config = shift;
+ foreach my $k (sort (keys %$config)) {
+ next if $k eq 'digest';
+ my $v = $config->{$k};
+ if ($k eq 'description') {
+ $v = PVE::Tools::encode_text($v);
+ }
+ print "$k: $v\n";
+ }
+ }],
+
+ pending => [ "PVE::API2::Qemu", 'vm_pending', ['vmid'], { %node }, \&PVE::GuestHelpers::format_pending ],
+ showcmd => [ __PACKAGE__, 'showcmd', ['vmid']],
+
+ status => [ __PACKAGE__, 'status', ['vmid']],
+
+ # FIXME: for 8.0 move to command group snapshot { create, list, destroy, rollback }
+ snapshot => [ "PVE::API2::Qemu", 'snapshot', ['vmid', 'snapname'], { %node } , $upid_exit ],
+ delsnapshot => [ "PVE::API2::Qemu", 'delsnapshot', ['vmid', 'snapname'], { %node } , $upid_exit ],
+ listsnapshot => [ "PVE::API2::Qemu", 'snapshot_list', ['vmid'], { %node }, \&PVE::GuestHelpers::print_snapshot_tree],
+ rollback => [ "PVE::API2::Qemu", 'rollback', ['vmid', 'snapname'], { %node } , $upid_exit ],
+
+ template => [ "PVE::API2::Qemu", 'template', ['vmid'], { %node }],
+
+ # FIXME: should be in a power command group?
+ start => [ "PVE::API2::Qemu", 'vm_start', ['vmid'], { %node } , $upid_exit ],
+ stop => [ "PVE::API2::Qemu", 'vm_stop', ['vmid'], { %node }, $upid_exit ],
+ reset => [ "PVE::API2::Qemu", 'vm_reset', ['vmid'], { %node }, $upid_exit ],
+ shutdown => [ "PVE::API2::Qemu", 'vm_shutdown', ['vmid'], { %node }, $upid_exit ],
+ reboot => [ "PVE::API2::Qemu", 'vm_reboot', ['vmid'], { %node }, $upid_exit ],
+ suspend => [ "PVE::API2::Qemu", 'vm_suspend', ['vmid'], { %node }, $upid_exit ],
+ resume => [ "PVE::API2::Qemu", 'vm_resume', ['vmid'], { %node }, $upid_exit ],
+
+ sendkey => [ "PVE::API2::Qemu", 'vm_sendkey', ['vmid', 'key'], { %node } ],