]> git.proxmox.com Git - pve-manager.git/blob - PVE/API2Tools.pm
3136e096ee23a12c03cfef0a033f9e68e21ca6b1
[pve-manager.git] / PVE / API2Tools.pm
1 package PVE::API2Tools;
2
3 use strict;
4 use warnings;
5 use PVE::Tools;
6 use Digest::MD5 qw(md5_hex);
7 use URI;
8 use URI::Escape;
9 use PVE::SafeSyslog;
10
11 my $hwaddress;
12
13 sub get_hwaddress {
14
15 return $hwaddress if defined ($hwaddress);
16
17 my $fn = '/etc/ssh/ssh_host_rsa_key.pub';
18 my $sshkey = PVE::Tools::file_get_contents($fn);
19 $hwaddress = uc(md5_hex($sshkey));
20
21 return $hwaddress;
22 }
23
24 sub extract_node_stats {
25 my ($node, $members, $rrd) = @_;
26
27 my $entry = {
28 id => "node/$node",
29 node => $node,
30 type => "node",
31 };
32
33 if (my $d = $rrd->{"pve2-node/$node"}) {
34
35 if (!$members || # no cluster
36 ($members->{$node} && $members->{$node}->{online})) {
37 $entry->{uptime} = ($d->[0] || 0) + 0;
38 $entry->{cpu} = ($d->[5] || 0) + 0;
39 $entry->{mem} = ($d->[8] || 0) + 0;
40 $entry->{disk} = ($d->[12] || 0) + 0;
41 }
42 $entry->{level} = $d->[1];
43 $entry->{maxcpu} = ($d->[4] || 0) + 0;
44 $entry->{maxmem} = ($d->[7] || 0) + 0;
45 $entry->{maxdisk} = ($d->[11] || 0) + 0;
46 }
47
48 return $entry;
49 }
50
51 sub extract_vm_stats {
52 my ($vmid, $data, $rrd) = @_;
53
54 my $entry = {
55 id => "$data->{type}/$vmid",
56 vmid => $vmid + 0,
57 node => $data->{node},
58 type => $data->{type},
59 };
60
61 my $d;
62
63 if ($d = $rrd->{"pve2-vm/$vmid"}) {
64
65 $entry->{uptime} = ($d->[0] || 0) + 0;
66 $entry->{name} = $d->[1];
67 $entry->{status} = $entry->{uptime} ? 'running' : 'stopped';
68 $entry->{maxcpu} = ($d->[3] || 0) + 0;
69 $entry->{cpu} = ($d->[4] || 0) + 0;
70 $entry->{maxmem} = ($d->[5] || 0) + 0;
71 $entry->{mem} = ($d->[6] || 0) + 0;
72 $entry->{maxdisk} = ($d->[7] || 0) + 0;
73 $entry->{disk} = ($d->[8] || 0) + 0;
74 $entry->{netin} = ($d->[9] || 0) + 0;
75 $entry->{netout} = ($d->[10] || 0) + 0;
76 $entry->{diskread} = ($d->[11] || 0) + 0;
77 $entry->{diskwrite} = ($d->[12] || 0) + 0;
78
79 } elsif ($d = $rrd->{"pve2.3-vm/$vmid"}) {
80
81 $entry->{uptime} = ($d->[0] || 0) + 0;
82 $entry->{name} = $d->[1];
83 $entry->{status} = $d->[2];
84 $entry->{template} = $d->[3] + 0;
85
86 $entry->{maxcpu} = ($d->[5] || 0) + 0;
87 $entry->{cpu} = ($d->[6] || 0) + 0;
88 $entry->{maxmem} = ($d->[7] || 0) + 0;
89 $entry->{mem} = ($d->[8] || 0) + 0;
90 $entry->{maxdisk} = ($d->[9] || 0) + 0;
91 $entry->{disk} = ($d->[10] || 0) + 0;
92 $entry->{netin} = ($d->[11] || 0) + 0;
93 $entry->{netout} = ($d->[12] || 0) + 0;
94 $entry->{diskread} = ($d->[13] || 0) + 0;
95 $entry->{diskwrite} = ($d->[14] || 0) + 0;
96 };
97
98 return $entry;
99 };
100
101 sub extract_storage_stats {
102 my ($storeid, $scfg, $node, $rrd) = @_;
103
104 my $entry = {
105 id => "storage/$node/$storeid",
106 storage => $storeid,
107 node => $node,
108 type => 'storage',
109 };
110
111 if (my $d = $rrd->{"pve2-storage/$node/$storeid"}) {
112 $entry->{maxdisk} = ($d->[1] || 0) + 0;
113 $entry->{disk} = ($d->[2] || 0) + 0;
114 }
115
116 return $entry;
117 };
118
119 sub parse_http_proxy {
120 my ($proxyenv) = @_;
121
122 my $uri = URI->new($proxyenv);
123
124 my $scheme = $uri->scheme;
125 my $host = $uri->host;
126 my $port = $uri->port || 3128;
127
128 my ($username, $password);
129
130 if (defined(my $p_auth = $uri->userinfo())) {
131 ($username, $password) = map URI::Escape::uri_unescape($_), split(":", $p_auth, 2);
132 }
133
134 return ("$host:$port", $username, $password);
135 }
136
137 sub run_spiceterm {
138 my ($authpath, $permissions, $vmid, $node, $proxy, $title, $shcmd) = @_;
139
140 my $rpcenv = PVE::RPCEnvironment::get();
141
142 my $authuser = $rpcenv->get_user();
143
144 my $port = PVE::Tools::next_spice_port();
145
146 my ($ticket, undef, $remote_viewer_config) =
147 PVE::AccessControl::remote_viewer_config($authuser, $vmid, $node, $proxy, $title, $port);
148
149 my $timeout = 40;
150
151 my $cmd = ['/usr/bin/spiceterm', '--port', $port, '--addr', '127.0.0.1',
152 '--timeout', $timeout, '--authpath', $authpath,
153 '--permissions', $permissions];
154
155 my $dcconf = PVE::Cluster::cfs_read_file('datacenter.cfg');
156 push @$cmd, '--keymap', $dcconf->{keyboard} if $dcconf->{keyboard};
157
158 push @$cmd, '--', @$shcmd;
159
160 my $realcmd = sub {
161 my $upid = shift;
162
163 syslog ('info', "starting spiceterm $upid - $title\n");
164
165 my $cmdstr = join (' ', @$cmd);
166 syslog ('info', "launch command: $cmdstr");
167
168 eval {
169 foreach my $k (keys %ENV) {
170 next if $k eq 'PATH' || $k eq 'TERM' || $k eq 'USER' || $k eq 'HOME' || $k eq 'LANG' || $k eq 'LANGUAGE' ;
171 delete $ENV{$k};
172 }
173 $ENV{PWD} = '/';
174 $ENV{SPICE_TICKET} = $ticket;
175
176 # run_command sets LC_ALL, so we use system() instead
177 system(@$cmd) == 0 ||
178 die "spiceterm failed\n";
179 };
180 if (my $err = $@) {
181 syslog ('err', $err);
182 }
183
184 return;
185 };
186
187 if ($vmid) {
188 $rpcenv->fork_worker('spiceproxy', $vmid, $authuser, $realcmd);
189 } else {
190 $rpcenv->fork_worker('spiceshell', undef, $authuser, $realcmd);
191 }
192
193 PVE::Tools::wait_for_vnc_port($port);
194
195 return $remote_viewer_config;
196 }
197
198 1;