]>
git.proxmox.com Git - pve-manager.git/blob - lib/PVE.old/HTMLServices.pm
1 package PVE
::HTMLServices
;
6 use Apache2
::Const
qw(:common);
10 use POSIX
qw(tzset strftime);
11 use Text
::Wrap
qw(wrap);
14 use PVE
::ConfigServer
;
19 $PVE::HTMLServices
::Obj
= bless {
23 index => { proto
=> "index ()" },
24 command
=> { proto
=> "command (upid, did)" },
25 command_abort
=> { "command_abort (upid)" },
26 status
=> { proto
=> "status (cid)" },
27 status_update
=> { proto
=> "status_update (cid)" },
28 vzlist
=> { proto
=> "vzlist (cid)" },
29 vmops
=> { proto
=> "vmops (inactive)" },
30 vmlogview
=> { proto
=> "vmlogview (cid, veid, service)" },
31 viewlog
=> { proto
=> "viewlog (service, filter)" },
32 vmstatus
=> { proto
=> "vmstatus (cid, veid, type)" },
33 hello
=> { proto
=> "hello ()" },
34 servertime
=> { proto
=> "servertime ()" },
40 my($conn, $args) = @_;
43 name
=> "A JSON Example",
54 my ($sec, $min, $hour) = localtime (time());
56 return sprintf ("%02d:%02d:%02d", $hour, $min, $sec);
60 my($conn, $args) = @_;
62 my $cid = $args->{"cid"};
68 my $cvzl = PVE
::Cluster
::vzlist_update
($cid, $conn->{ticket
});
69 die "no data" if !$cvzl;
70 $html = PVE
::HTMLUtils
::create_vzlist_table
($cid, $cvzl->{"CID_$cid"});
78 $html = "Unable to get data for Cluster Node $cid<br>";
79 $status = "<blink><font color=red>Unable to load local cluster table</blink>";
84 status
=> $status || "Online",
89 my($conn, $args) = @_;
91 my $cid = $args->{"cid"};
92 my $verbose = $args->{"verbose"};
96 my $cinfo = PVE
::Cluster
::clusterinfo
();
99 my $rcon = PVE
::ConfigClient
::connect ($conn->{ticket
}, $cinfo, $cid);
100 my $status = $rcon->ping()->result;
101 $html = PVE
::HTMLUtils
::create_host_status
($cinfo, $status, $verbose);
107 syslog
('err', $err);
110 html
=> encode_entities
("ERROR: $err"),
111 status
=> "Unable to get data for Cluster Node $cid<br>",
121 sub ws_status_update
{
122 my($conn, $args) = @_;
124 my $cid = $args->{"cid"};
128 my $cinfo = PVE
::Cluster
::clusterinfo
();
130 my $ni = $cinfo->{"CID_$cid"};
133 my $name = "Node $cid";
138 die "unknown CID '$cid'\n" if !$ni;
141 $role = 'Master' if $role eq 'M';
142 $role = 'Node' if $role eq 'N';
147 my $rcon = PVE
::ConfigClient
::connect ($conn->{ticket
}, $cinfo, $cid);
149 my $status = $rcon->ping()->result;
151 my $state = $status->{insync
} ?
'active' : '<blink><font color=red>nosync</font></blink>';
153 my $mem = int (0.5 + ($status->{meminfo
}->{mbmemused
}*100/$status->{meminfo
}->{mbmemtotal
}));
154 my $disk = int (0.5 + ($status->{hdinfo
}->{root
}->{used
}*100/$status->{hdinfo
}->{root
}->{avail
}));
156 my $cpu = int ($status->{cpu
}*100);
157 my $wait = int ($status->{wait}*100);
159 $html = "<td>$name</td><td>$nodeip</td><td>$role</td><td>$state</td>" .
160 "<td>$status->{uptime}->{uptimestrshort}</td>" .
161 "<td>$status->{uptime}->{avg1}</td>" .
162 "<td>$cpu%</td><td>$wait%</td><td>$mem%</td><td>$disk%</td>";
169 syslog
('err', $err);
170 my $state = "<blink><font color=red>ERROR: " . encode_entities
($err) . "</blink>";
171 return "<td>$name</td><td>$nodeip</td><td>$role</td><td colspan=7>$state</td>";
177 sub ws_json_vmstatus
{
178 my($conn, $args) = @_;
180 my $cid = $args->{"cid"};
181 my $veid = $args->{"veid"};
182 my $type = $args->{"type"};
187 my $cinfo = PVE
::Cluster
::clusterinfo
();
190 my $vzinfo = PVE
::Cluster
::load_vmconfig
($cinfo, $cid, $veid, $type, $conn->{ticket
});
191 $html = PVE
::HTMLUtils
::create_vmstatus
($cid, $veid, $type, $vzinfo);
197 syslog
('err', $err);
198 $html = "Unable to get data for VM $veid<br>";
199 $status = "<blink><font color=red>Unable to load virtual machine config</blink>";
208 sub ws_json_vmlogview
{
209 my($conn, $args) = @_;
211 my $cid = $args->{"cid"};
212 my $veid = $args->{"veid"};
213 my $service = $args->{"service"};
218 my $cinfo = PVE
::Cluster
::clusterinfo
();
221 my $ni = $cinfo->{"CID_$cid"} || die "unknown CID '$cid'";
223 my $rcon = PVE
::ConfigClient
::connect ($conn->{ticket
}, $cinfo, $cid);
224 my $lines = $rcon->vmlogview($cid, $veid, $service)->result;
226 foreach my $line (@$lines) {
227 my $el = encode_entities
($line) . "<br>\n";
228 if ($service eq 'init') {
229 $el =~ s/&\#27;\[0;31m(.*)&\#27;\[0;39m/<font color=red>$1<\/font
>/g
;
230 $el =~ s/&\#27;\[31m(.*)&\#27;\[39;49m/<font color=red>$1<\/font
>/g
;
231 $el =~ s/&\#27;\[33m(.*)&\#27;\[39;49m/<font color=yellow>$1<\/font
>/g
;
232 $el =~ s/&\#27;\[0;32m(.*)&\#27;\[0;39m/<font color=green>$1<\/font
>/g
;
233 $el =~ s/&\#27;\[\d+G//g;
242 syslog
('err', $err);
243 $html = "Unable to get data for Cluster Node $cid<br>";
244 $status = "<blink><font color=red>Unable to load local cluster table</blink>";
249 status
=> $status || "Online",
254 sub syslog_parse_line
{
260 m/^(\S+\s+\S+\s+\S+)\s+(\S+)\s+([^\s\[:]+)(\[(\S+)\])?([^:]*):\s+(.*)$/) {
264 $rec->{prog
} .= " $6" if $6;
269 m/^(\S+\s+\S+\s+\S+)\s+(\S+)\s+(last message repeated \d+ times)$/) {
272 $rec->{prog
} = 'syslog';
278 $rec->{host
} = "unknown";
279 $rec->{prog
} = "unknown";
281 $rec->{text
} = $line;
285 if (lc ($rec->{prog
}) eq '/usr/sbin/cron') {
286 $rec->{prog
} = 'cron';
292 sub ws_json_viewlog
{
293 my($conn, $args) = @_;
297 my $filter = $args->{"filter"};
298 my $service = $args->{"service"} || '';
299 my $trackid = $args->{"trackid"} || '';
301 $filter =~ s
|\\|\\\\|g
;
302 $filter =~ s/\?/\\\?/g;
303 $filter =~ s/\(/\\\(/g;
304 $filter =~ s/\)/\\\)/g;
305 $filter =~ s/\{/\\\{/g;
306 $filter =~ s/\}/\\\}/g;
307 $filter =~ s/\[/\\\[/g;
308 $filter =~ s/\]/\\\]/g;
309 $filter =~ s/\./\\\./g;
310 $filter =~ s/\*/\\\*/g;
311 $filter =~ s/\+/\\\+/g;
313 my $filename= "/var/log/syslog";
317 if ($service eq 'apache') {
318 $filename = "/var/log/apache2/access.log";
324 my $rcon = PVE
::ConfigClient
::connect ($conn->{ticket
});
325 $running = $rcon->check_worker ($trackid)->result;
328 $out .= "<table border=0 cellspacing=3 cellpadding=0 style='font-family:monospace;'>";
330 if ($filename eq '/var/log/syslog') {
334 open (TMP
, "tail -$limit $filename|");
335 while (my $line = <TMP
>) {
336 if (my $rec = syslog_parse_line
($line)) {
337 next if $filter && $line !~ m/$filter/i;
338 next if ($service && ($rec->{prog
} !~ m
"(^$service\/|\/$service$|^$service$)"));
346 foreach my $rec (@$loga) {
347 $out .= "<tr><td nowrap>" . encode_entities
($rec->{date
}) . " </td>";
349 $out .= "<td nowrap>" . encode_entities
($rec->{host
}) . "</td>";
352 $rec->{prog
} =~ s
|^postfix
/||;
354 $out .= "<td nowrap>" . encode_entities
($rec->{prog
}) . "</td>";
355 $out .= "<td align=right nowrap>" . $rec->{pid
} . " </td>";
356 $out .= "<td nowrap>" . encode_entities
($rec->{text
}) . "</td>";
360 open (TMP
, "tail -$limit $filename|");
361 while (my $line = <TMP
>) {
363 next if $filter && $line !~ m/$filter/i;
364 $line = encode_entities
($line);
365 $out .= "<tr><td nowrap>" . $line . "</td></tr>";
369 $out .= "</table>\n";
374 status
=> $running ?
"Update in progress" : "Update finished",
387 my($conn, $args) = @_;
389 my $inactive = $args->{"inactive"};
391 my $vmops = PVE
::Config
::read_file
("vmops");
392 my $out = PVE
::HTMLUtils
::create_vmops_table
($vmops, $inactive);
394 return { html
=> $out, status
=> 'OK' };
397 sub ws_command_abort
{
398 my($conn, $args) = @_;
400 my $upid = $args->{"upid"};
402 my $rcon = PVE
::ConfigClient
::connect ($conn->{ticket
});
403 $rcon->check_worker ($upid, 1);
406 sub ws_json_command
{
407 my($conn, $args) = @_;
411 my $upid = $args->{"upid"};
412 my $jsvar = $args->{"jsvar"};
414 my $upid_hash = PVE
::Utils
::upid_decode
($upid);
416 my $cmdtype = $upid_hash->{type
}; # 'vmops', 'apldownload'
418 if (!$upid_hash || !$upid_hash->{filename
}) {
422 status
=> "got strange parameters $upid"
426 my $filename = $upid_hash->{filename
};
428 my $fh = new IO
::File
$filename, "r";
429 if (!defined ($fh)) {
433 status
=> "unable to open output file '$filename'" };
439 if ($savedid ne $upid) {
440 return { html
=> '', running
=> 0, status
=> "no data"};
446 while (defined ($line = <$fh>)) {
450 next if $line =~ m/^tcgetattr: Inappropriate ioctl for device$/;
453 while (defined ($line) && $line =~ m/^rsync\s+status:/) {
455 if (defined ($line = <$fh>)) {
460 $out .= encode_entities
($stat) . "<br>" if $stat;
462 $out .= encode_entities
($line) . "<br>" if defined ($line);;
467 my $rcon = PVE
::ConfigClient
::connect ($conn->{ticket
});
468 my $running = $rcon->check_worker ($upid)->result;
472 if ($cmdtype eq 'apldownload') {
473 $status = $running ?
"downloading '$upid_hash->{apl}'" : "download finished";
475 $status = $running ?
"executing command" : "command finished";
485 my($conn, $args) = @_;
487 my $obj = $conn->{server
};
489 my $out = "Proxmox Web Service Description<br><br>";
491 foreach my $m (keys %{$obj->{methods
}}) {
492 my $proto = $obj->{methods
}->{$m}->{proto
};
493 $out .= "METHOD: $proto<br>";
502 my $auth_type = $r->ap_auth_type;
505 my $cookie_name = $auth_type->cookie_name ($r);
506 my $cookie = $auth_type->key ($r);
508 my ($username, $group) = split /::/, $cookie;
519 my $pvecfg = PVE
::Config
::read_file
('pvecfg');
520 my $language = $pvecfg->{language
} || 'C';
521 PVE
::I18N
::set_lang
($language);
523 my $path = $r->path_info;
524 if ($path =~ m
'^/?(\w+)(\.htm|\.pl)?$' && $obj->{methods
}->{$1}) {
527 my $cgi = CGI-
>new ($r);
529 my $arglist = $cgi->Vars();
533 if (my $serv = $obj->can ("ws_script_$name")) {
534 my $data = &$serv ($conn, $arglist);
535 my $x = length ($data);
536 $r->content_type ('application/javascript');
537 $r->headers_out->set ("Content-length", "$x");
538 $r->headers_out->set ("Pragma", "no-cache");
541 } elsif (my $serv = $obj->can ("ws_json_$name")) {
542 my $data = &$serv ($conn, $arglist);
543 my $js = to_json
($data, {utf8
=> 1});
544 my $x = length ($js);
545 $r->content_type ('application/json');
546 $r->headers_out->set ("Content-length", "$x");
547 $r->headers_out->set ("Pragma", "no-cache");
550 } elsif (my $serv = $obj->can ("ws_$name")) {
551 my $data = &$serv ($conn, $arglist);
552 my $x = length ($data);
553 $r->content_type ('text/html');
554 $r->headers_out->set ("Content-length", "$x");
555 $r->headers_out->set ("Pragma", "no-cache");