]> git.proxmox.com Git - qemu-server.git/blob - PVE/API2/Qemu/Agent.pm
b046d2d66dc567ee0e24bf4392e5fa3dda9c42c8
[qemu-server.git] / PVE / API2 / Qemu / Agent.pm
1 package PVE::API2::Qemu::Agent;
2
3 use strict;
4 use warnings;
5
6 use PVE::RESTHandler;
7 use PVE::JSONSchema qw(get_standard_option);
8 use PVE::QemuServer;
9
10 use base qw(PVE::RESTHandler);
11
12 # list of commands
13 # will generate one api endpoint per command
14 # needs a 'method' property and optionally a 'perms' property (default VM.Monitor)
15 my $guest_agent_commands = {
16 'ping' => {
17 method => 'POST',
18 },
19 'get-time' => {
20 method => 'POST',
21 },
22 'info' => {
23 method => 'POST',
24 },
25 'fsfreeze-status' => {
26 method => 'POST',
27 },
28 'fsfreeze-freeze' => {
29 method => 'POST',
30 },
31 'fsfreeze-thaw' => {
32 method => 'POST',
33 },
34 'fstrim' => {
35 method => 'POST',
36 },
37 'network-get-interfaces' => {
38 method => 'POST',
39 },
40 'get-vcpus' => {
41 method => 'POST',
42 },
43 'get-fsinfo' => {
44 method => 'POST',
45 },
46 'get-memory-blocks' => {
47 method => 'POST',
48 },
49 'get-memory-block-info' => {
50 method => 'POST',
51 },
52 'suspend-hybrid' => {
53 method => 'POST',
54 },
55 'suspend-ram' => {
56 method => 'POST',
57 },
58 'suspend-disk' => {
59 method => 'POST',
60 },
61 'shutdown' => {
62 method => 'POST',
63 },
64 };
65
66 __PACKAGE__->register_method({
67 name => 'index',
68 path => '',
69 proxyto => 'node',
70 method => 'GET',
71 description => "Qemu Agent command index.",
72 permissions => {
73 user => 'all',
74 },
75 parameters => {
76 additionalProperties => 1,
77 properties => {
78 node => get_standard_option('pve-node'),
79 vmid => get_standard_option('pve-vmid', {
80 completion => \&PVE::QemuServer::complete_vmid_running }),
81 },
82 },
83 returns => {
84 type => 'array',
85 items => {
86 type => "object",
87 properties => {},
88 },
89 links => [ { rel => 'child', href => '{name}' } ],
90 description => "Returns the list of Qemu Agent commands",
91 },
92 code => sub {
93 my ($param) = @_;
94
95 my $result = [];
96
97 for my $cmd (sort keys %$guest_agent_commands) {
98 push @$result, { name => $cmd };
99 }
100
101 return $result;
102 }});
103
104 sub register_command {
105 my ($class, $command, $method, $perm) = @_;
106
107 die "no method given\n" if !$method;
108 die "no command given\n" if !defined($command);
109
110 my $permission;
111
112 if (ref($perm) eq 'HASH') {
113 $permission = $perm;
114 } else {
115 $perm //= 'VM.Monitor';
116 $permission = { check => [ 'perm', '/vms/{vmid}', [ $perm ]]};
117 }
118
119 my $parameters = {
120 additionalProperties => 0,
121 properties => {
122 node => get_standard_option('pve-node'),
123 vmid => get_standard_option('pve-vmid', {
124 completion => \&PVE::QemuServer::complete_vmid_running }),
125 command => {
126 type => 'string',
127 description => "The QGA command.",
128 enum => [ sort keys %$guest_agent_commands ],
129 },
130 },
131 };
132
133 my $description = "Execute Qemu Guest Agent commands.";
134 my $name = 'agent';
135
136 if ($command ne '') {
137 $description = "Execute $command.";
138 $name = $command;
139 delete $parameters->{properties}->{command};
140 }
141
142 __PACKAGE__->register_method({
143 name => $name,
144 path => $command,
145 method => $method,
146 protected => 1,
147 proxyto => 'node',
148 description => $description,
149 permissions => $permission,
150 parameters => $parameters,
151 returns => {
152 type => 'object',
153 description => "Returns an object with a single `result` property.",
154 },
155 code => sub {
156 my ($param) = @_;
157
158 my $vmid = $param->{vmid};
159
160 my $conf = PVE::QemuConfig->load_config ($vmid); # check if VM exists
161
162 die "No Qemu Guest Agent\n" if !defined($conf->{agent});
163 die "VM $vmid is not running\n" if !PVE::QemuServer::check_running($vmid);
164
165 my $cmd = $param->{command} // $command;
166 my $res = PVE::QemuServer::vm_mon_cmd($vmid, "guest-$cmd");
167
168 return { result => $res };
169 }});
170 }
171
172 # old {vmid}/agent POST endpoint, here for compatibility
173 __PACKAGE__->register_command('', 'POST');
174
175 for my $cmd (sort keys %$guest_agent_commands) {
176 my $props = $guest_agent_commands->{$cmd};
177 __PACKAGE__->register_command($cmd, $props->{method}, $props->{perms});
178 }
179
180 1;