]> git.proxmox.com Git - pve-manager.git/blame - PVE/API2Tools.pm
update descriptions, error messages
[pve-manager.git] / PVE / API2Tools.pm
CommitLineData
19a6b9f1
DM
1package PVE::API2Tools;
2
3use strict;
4use warnings;
a3eff2d9
DM
5use Net::IP;
6
2ba6d822 7use PVE::Tools;
eb6d7497 8use PVE::INotify;
2ba6d822 9use Digest::MD5 qw(md5_hex);
446b9669
DM
10use URI;
11use URI::Escape;
b289829f 12use PVE::SafeSyslog;
2ba6d822
DM
13
14my $hwaddress;
15
16sub get_hwaddress {
17
18 return $hwaddress if defined ($hwaddress);
19
20 my $fn = '/etc/ssh/ssh_host_rsa_key.pub';
21 my $sshkey = PVE::Tools::file_get_contents($fn);
22 $hwaddress = uc(md5_hex($sshkey));
23
24 return $hwaddress;
25}
19a6b9f1 26
16b69b6c
DM
27sub extract_node_stats {
28 my ($node, $members, $rrd) = @_;
29
30 my $entry = {
31 id => "node/$node",
32 node => $node,
33 type => "node",
34 };
35
36 if (my $d = $rrd->{"pve2-node/$node"}) {
37
38 if (!$members || # no cluster
39 ($members->{$node} && $members->{$node}->{online})) {
40 $entry->{uptime} = ($d->[0] || 0) + 0;
41 $entry->{cpu} = ($d->[5] || 0) + 0;
42 $entry->{mem} = ($d->[8] || 0) + 0;
43 $entry->{disk} = ($d->[12] || 0) + 0;
44 }
45 $entry->{level} = $d->[1];
46 $entry->{maxcpu} = ($d->[4] || 0) + 0;
47 $entry->{maxmem} = ($d->[7] || 0) + 0;
48 $entry->{maxdisk} = ($d->[11] || 0) + 0;
49 }
50
51 return $entry;
52}
19a6b9f1
DM
53
54sub extract_vm_stats {
55 my ($vmid, $data, $rrd) = @_;
56
57 my $entry = {
58 id => "$data->{type}/$vmid",
59 vmid => $vmid + 0,
60 node => $data->{node},
61 type => $data->{type},
62 };
63
90c3fae4
DM
64 my $d;
65
66 if ($d = $rrd->{"pve2-vm/$vmid"}) {
19a6b9f1
DM
67
68 $entry->{uptime} = ($d->[0] || 0) + 0;
69 $entry->{name} = $d->[1];
3c353ed2 70 $entry->{status} = $entry->{uptime} ? 'running' : 'stopped';
19a6b9f1
DM
71 $entry->{maxcpu} = ($d->[3] || 0) + 0;
72 $entry->{cpu} = ($d->[4] || 0) + 0;
73 $entry->{maxmem} = ($d->[5] || 0) + 0;
74 $entry->{mem} = ($d->[6] || 0) + 0;
75 $entry->{maxdisk} = ($d->[7] || 0) + 0;
76 $entry->{disk} = ($d->[8] || 0) + 0;
cf497f7d
AD
77 $entry->{netin} = ($d->[9] || 0) + 0;
78 $entry->{netout} = ($d->[10] || 0) + 0;
79 $entry->{diskread} = ($d->[11] || 0) + 0;
80 $entry->{diskwrite} = ($d->[12] || 0) + 0;
3c353ed2 81
90c3fae4 82 } elsif ($d = $rrd->{"pve2.3-vm/$vmid"}) {
3c353ed2
DM
83
84 $entry->{uptime} = ($d->[0] || 0) + 0;
85 $entry->{name} = $d->[1];
86 $entry->{status} = $d->[2];
87 $entry->{template} = $d->[3] + 0;
88
89 $entry->{maxcpu} = ($d->[5] || 0) + 0;
90 $entry->{cpu} = ($d->[6] || 0) + 0;
91 $entry->{maxmem} = ($d->[7] || 0) + 0;
92 $entry->{mem} = ($d->[8] || 0) + 0;
93 $entry->{maxdisk} = ($d->[9] || 0) + 0;
94 $entry->{disk} = ($d->[10] || 0) + 0;
95 $entry->{netin} = ($d->[11] || 0) + 0;
96 $entry->{netout} = ($d->[12] || 0) + 0;
97 $entry->{diskread} = ($d->[13] || 0) + 0;
98 $entry->{diskwrite} = ($d->[14] || 0) + 0;
19a6b9f1
DM
99 };
100
101 return $entry;
102};
103
104sub extract_storage_stats {
105 my ($storeid, $scfg, $node, $rrd) = @_;
106
107 my $entry = {
108 id => "storage/$node/$storeid",
109 storage => $storeid,
110 node => $node,
111 type => 'storage',
112 };
113
114 if (my $d = $rrd->{"pve2-storage/$node/$storeid"}) {
115 $entry->{maxdisk} = ($d->[1] || 0) + 0;
116 $entry->{disk} = ($d->[2] || 0) + 0;
117 }
118
119 return $entry;
120};
121
446b9669
DM
122sub parse_http_proxy {
123 my ($proxyenv) = @_;
124
125 my $uri = URI->new($proxyenv);
126
127 my $scheme = $uri->scheme;
128 my $host = $uri->host;
129 my $port = $uri->port || 3128;
130
131 my ($username, $password);
132
133 if (defined(my $p_auth = $uri->userinfo())) {
134 ($username, $password) = map URI::Escape::uri_unescape($_), split(":", $p_auth, 2);
135 }
136
137 return ("$host:$port", $username, $password);
138}
139
b289829f
DM
140sub run_spiceterm {
141 my ($authpath, $permissions, $vmid, $node, $proxy, $title, $shcmd) = @_;
142
143 my $rpcenv = PVE::RPCEnvironment::get();
144
145 my $authuser = $rpcenv->get_user();
b289829f 146
eb6d7497
WB
147 my $nodename = PVE::INotify::nodename();
148 my $family = PVE::Tools::get_host_address_family($nodename);
149 my $port = PVE::Tools::next_spice_port($family);
eb7cd2ce
DM
150
151 my ($ticket, undef, $remote_viewer_config) =
152 PVE::AccessControl::remote_viewer_config($authuser, $vmid, $node, $proxy, $title, $port);
b289829f 153
14e306a9 154 my $timeout = 40;
b289829f
DM
155
156 my $cmd = ['/usr/bin/spiceterm', '--port', $port, '--addr', '127.0.0.1',
157 '--timeout', $timeout, '--authpath', $authpath,
158 '--permissions', $permissions];
159
160 my $dcconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
161 push @$cmd, '--keymap', $dcconf->{keyboard} if $dcconf->{keyboard};
162
163 push @$cmd, '--', @$shcmd;
164
165 my $realcmd = sub {
166 my $upid = shift;
167
168 syslog ('info', "starting spiceterm $upid - $title\n");
169
170 my $cmdstr = join (' ', @$cmd);
171 syslog ('info', "launch command: $cmdstr");
172
3fa0b222 173 eval {
b289829f 174 foreach my $k (keys %ENV) {
3fa0b222 175 next if $k eq 'PATH' || $k eq 'TERM' || $k eq 'USER' || $k eq 'HOME' || $k eq 'LANG' || $k eq 'LANGUAGE' ;
b289829f
DM
176 delete $ENV{$k};
177 }
178 $ENV{PWD} = '/';
179 $ENV{SPICE_TICKET} = $ticket;
3fa0b222
DM
180
181 # run_command sets LC_ALL, so we use system() instead
182 system(@$cmd) == 0 ||
183 die "spiceterm failed\n";
b289829f
DM
184 };
185 if (my $err = $@) {
186 syslog ('err', $err);
187 }
188
189 return;
190 };
191
192 if ($vmid) {
193 $rpcenv->fork_worker('spiceproxy', $vmid, $authuser, $realcmd);
194 } else {
195 $rpcenv->fork_worker('spiceshell', undef, $authuser, $realcmd);
196 }
eb7cd2ce 197
b289829f
DM
198 PVE::Tools::wait_for_vnc_port($port);
199
eb7cd2ce 200 return $remote_viewer_config;
b289829f
DM
201}
202
a3eff2d9
DM
203sub read_proxy_config {
204
205 my $conffile = "/etc/default/pveproxy";
206
207 # Note: evaluate with bash
208 my $shcmd = ". $conffile;\n";
209 $shcmd .= 'echo \"ALLOW_FROM:\$ALLOW_FROM\";';
210 $shcmd .= 'echo \"DENY_FROM:\$DENY_FROM\";';
211 $shcmd .= 'echo \"POLICY:\$POLICY\";';
212 $shcmd .= 'echo \"CIPHERS:\$CIPHERS\";';
41196653 213 $shcmd .= 'echo \"DHPARAMS:\$DHPARAMS\";';
a3eff2d9
DM
214
215 my $data = -f $conffile ? `bash -c "$shcmd"` : '';
216
217 my $res = {};
218
219 while ($data =~ s/^(.*)\n//) {
220 my ($key, $value) = split(/:/, $1, 2);
221 next if !$value;
222 if ($key eq 'ALLOW_FROM' || $key eq 'DENY_FROM') {
223 my $ips = [];
224 foreach my $ip (split(/,/, $value)) {
225 $ip = "0/0" if $ip eq 'all';
226 push @$ips, Net::IP->new($ip) || die Net::IP::Error() . "\n";
227 }
228 $res->{$key} = $ips;
229 } elsif ($key eq 'POLICY') {
230 die "unknown policy '$value'\n" if $value !~ m/^(allow|deny)$/;
231 $res->{$key} = $value;
232 } elsif ($key eq 'CIPHERS') {
233 $res->{$key} = $value;
41196653
FG
234 } elsif ($key eq 'DHPARAMS') {
235 $res->{$key} = $value;
a3eff2d9
DM
236 } else {
237 # silently skip everythin else?
238 }
239 }
240
241 return $res;
242}
243
19a6b9f1 2441;