Revision 7a6602d6
Von Moritz Bunkus vor mehr als 11 Jahren hinzugefügt
bin/mozilla/admin.pl | ||
---|---|---|
126 | 126 |
|
127 | 127 |
$form->{title} = "kivitendo / " . $locale->text('Database Administration'); |
128 | 128 |
|
129 |
# Intentionnaly disabled unless fixed to work with the authentication DB. |
|
130 |
$form->{ALLOW_DBBACKUP} = 0; # "$pg_dump_exe" ne "DISABLED"; |
|
131 |
|
|
132 | 129 |
$form->header(); |
133 | 130 |
print $form->parse_html_template("admin/dbadmin"); |
134 | 131 |
} |
... | ... | |
269 | 266 |
print $form->parse_html_template("admin/dbdelete"); |
270 | 267 |
} |
271 | 268 |
|
272 |
sub backup_dataset { |
|
273 |
my $form = $main::form; |
|
274 |
my $locale = $main::locale; |
|
275 |
|
|
276 |
$form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Backup Dataset'); |
|
277 |
|
|
278 |
if ($::lx_office_conf{applications}->{pg_dump} eq "DISABLED") { |
|
279 |
$form->error($locale->text('Database backups and restorations are disabled in the configuration.')); |
|
280 |
} |
|
281 |
|
|
282 |
my @dbsources = sort User->dbsources($form); |
|
283 |
$form->{DATABASES} = [ map { { "dbname" => $_ } } @dbsources ]; |
|
284 |
$form->{NO_DATABASES} = !scalar @dbsources; |
|
285 |
|
|
286 |
my $username = getpwuid $UID || "unknown-user"; |
|
287 |
my $hostname = hostname() || "unknown-host"; |
|
288 |
$form->{from} = "kivitendo Admin <${username}\@${hostname}>"; |
|
289 |
|
|
290 |
$form->header(); |
|
291 |
print $form->parse_html_template("admin/backup_dataset"); |
|
292 |
} |
|
293 |
|
|
294 |
sub backup_dataset_start { |
|
295 |
my $form = $main::form; |
|
296 |
my $locale = $main::locale; |
|
297 |
|
|
298 |
$form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Backup Dataset'); |
|
299 |
|
|
300 |
my $pg_dump_exe = $::lx_office_conf{applications}->{pg_dump} || "pg_dump"; |
|
301 |
|
|
302 |
if ("$pg_dump_exe" eq "DISABLED") { |
|
303 |
$form->error($locale->text('Database backups and restorations are disabled in the configuration.')); |
|
304 |
} |
|
305 |
|
|
306 |
$form->isblank("dbname", $locale->text('The dataset name is missing.')); |
|
307 |
$form->isblank("to", $locale->text('The email address is missing.')) if $form->{destination} eq "email"; |
|
308 |
|
|
309 |
my $tmpdir = "/tmp/lx_office_backup_" . Common->unique_id(); |
|
310 |
mkdir $tmpdir, 0700 || $form->error($locale->text('A temporary directory could not be created:') . " $ERRNO"); |
|
311 |
|
|
312 |
my $pgpass = IO::File->new("${tmpdir}/.pgpass", O_WRONLY | O_CREAT, 0600); |
|
313 |
|
|
314 |
if (!$pgpass) { |
|
315 |
unlink $tmpdir; |
|
316 |
$form->error($locale->text('A temporary file could not be created:') . " $ERRNO"); |
|
317 |
} |
|
318 |
|
|
319 |
print $pgpass "$form->{dbhost}:$form->{dbport}:$form->{dbname}:$form->{dbuser}:$form->{dbpasswd}\n"; |
|
320 |
$pgpass->close(); |
|
321 |
|
|
322 |
$ENV{HOME} = $tmpdir; |
|
323 |
|
|
324 |
my @args = ("-Ft", "-c", "-o", "-h", $form->{dbhost}, "-U", $form->{dbuser}); |
|
325 |
push @args, ("-p", $form->{dbport}) if ($form->{dbport}); |
|
326 |
push @args, $form->{dbname}; |
|
327 |
|
|
328 |
my $cmd = "$pg_dump_exe " . join(" ", map { s/\\/\\\\/g; s/\"/\\\"/g; $_ } @args); |
|
329 |
my $name = "dataset_backup_$form->{dbname}_" . strftime("%Y%m%d", localtime()) . ".tar"; |
|
330 |
|
|
331 |
if ($form->{destination} ne "email") { |
|
332 |
my $in = IO::File->new("$cmd |"); |
|
333 |
|
|
334 |
if (!$in) { |
|
335 |
unlink "${tmpdir}/.pgpass"; |
|
336 |
rmdir $tmpdir; |
|
337 |
|
|
338 |
$form->error($locale->text('The pg_dump process could not be started.')); |
|
339 |
} |
|
340 |
|
|
341 |
print "content-type: application/x-tar\n"; |
|
342 |
print "content-disposition: attachment; filename=\"${name}\"\n\n"; |
|
343 |
|
|
344 |
while (my $line = <$in>) { |
|
345 |
print $line; |
|
346 |
} |
|
347 |
|
|
348 |
$in->close(); |
|
349 |
|
|
350 |
unlink "${tmpdir}/.pgpass"; |
|
351 |
rmdir $tmpdir; |
|
352 |
|
|
353 |
} else { |
|
354 |
my $tmp = $tmpdir . "/dump_" . Common::unique_id(); |
|
355 |
|
|
356 |
if (system("$cmd > $tmp") != 0) { |
|
357 |
unlink "${tmpdir}/.pgpass", $tmp; |
|
358 |
rmdir $tmpdir; |
|
359 |
|
|
360 |
$form->error($locale->text('The pg_dump process could not be started.')); |
|
361 |
} |
|
362 |
|
|
363 |
my $mail = new Mailer; |
|
364 |
|
|
365 |
map { $mail->{$_} = $form->{$_} } qw(from to cc subject message); |
|
366 |
|
|
367 |
$mail->{charset} = $::lx_office_conf{system}->{dbcharset} || Common::DEFAULT_CHARSET; |
|
368 |
$mail->{attachments} = [ { "filename" => $tmp, "name" => $name } ]; |
|
369 |
$mail->send(); |
|
370 |
|
|
371 |
unlink "${tmpdir}/.pgpass", $tmp; |
|
372 |
rmdir $tmpdir; |
|
373 |
|
|
374 |
$form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Backup Dataset'); |
|
375 |
|
|
376 |
$form->header(); |
|
377 |
print $form->parse_html_template("admin/backup_dataset_email_done"); |
|
378 |
} |
|
379 |
} |
|
380 |
|
|
381 |
sub restore_dataset { |
|
382 |
my $form = $main::form; |
|
383 |
my $locale = $main::locale; |
|
384 |
|
|
385 |
$form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Restore Dataset'); |
|
386 |
|
|
387 |
if ($::lx_office_conf{applications}->{pg_restore} eq "DISABLED") { |
|
388 |
$form->error($locale->text('Database backups and restorations are disabled in the configuration.')); |
|
389 |
} |
|
390 |
|
|
391 |
my $default_charset = $::lx_office_conf{system}->{dbcharset}; |
|
392 |
$default_charset ||= Common::DEFAULT_CHARSET; |
|
393 |
|
|
394 |
$form->{DBENCODINGS} = []; |
|
395 |
|
|
396 |
foreach my $encoding (@Common::db_encodings) { |
|
397 |
push @{ $form->{DBENCODINGS} }, { "dbencoding" => $encoding->{dbencoding}, |
|
398 |
"label" => $encoding->{label}, |
|
399 |
"selected" => $encoding->{charset} eq $default_charset }; |
|
400 |
} |
|
401 |
|
|
402 |
$form->header(); |
|
403 |
print $form->parse_html_template("admin/restore_dataset"); |
|
404 |
} |
|
405 |
|
|
406 |
sub restore_dataset_start { |
|
407 |
my $form = $main::form; |
|
408 |
my $locale = $main::locale; |
|
409 |
|
|
410 |
$form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Restore Dataset'); |
|
411 |
|
|
412 |
my $pg_restore_exe = $::lx_office_conf{applications}->{pg_restore} || "pg_restore"; |
|
413 |
|
|
414 |
if ("$pg_restore_exe" eq "DISABLED") { |
|
415 |
$form->error($locale->text('Database backups and restorations are disabled in the configuration.')); |
|
416 |
} |
|
417 |
|
|
418 |
$form->isblank("new_dbname", $locale->text('The dataset name is missing.')); |
|
419 |
$form->isblank("content", $locale->text('No backup file has been uploaded.')); |
|
420 |
|
|
421 |
# Create temporary directories. Write the backup file contents to a temporary |
|
422 |
# file. Create a .pgpass file with the username and password for the pg_restore |
|
423 |
# utility. |
|
424 |
|
|
425 |
my $tmpdir = "/tmp/lx_office_backup_" . Common->unique_id(); |
|
426 |
mkdir $tmpdir, 0700 || $form->error($locale->text('A temporary directory could not be created:') . " $ERRNO"); |
|
427 |
|
|
428 |
my $pgpass = IO::File->new("${tmpdir}/.pgpass", O_WRONLY | O_CREAT, 0600); |
|
429 |
|
|
430 |
if (!$pgpass) { |
|
431 |
unlink $tmpdir; |
|
432 |
$form->error($locale->text('A temporary file could not be created:') . " $ERRNO"); |
|
433 |
} |
|
434 |
|
|
435 |
print $pgpass "$form->{dbhost}:$form->{dbport}:$form->{new_dbname}:$form->{dbuser}:$form->{dbpasswd}\n"; |
|
436 |
$pgpass->close(); |
|
437 |
|
|
438 |
$ENV{HOME} = $tmpdir; |
|
439 |
|
|
440 |
my $tmp = $tmpdir . "/dump_" . Common::unique_id(); |
|
441 |
my $tmpfile; |
|
442 |
|
|
443 |
if (substr($form->{content}, 0, 2) eq "\037\213") { |
|
444 |
$tmpfile = IO::File->new("| gzip -d > $tmp"); |
|
445 |
$tmpfile->binary(); |
|
446 |
|
|
447 |
} else { |
|
448 |
$tmpfile = IO::File->new($tmp, O_WRONLY | O_CREAT | O_BINARY, 0600); |
|
449 |
} |
|
450 |
|
|
451 |
if (!$tmpfile) { |
|
452 |
unlink "${tmpdir}/.pgpass"; |
|
453 |
rmdir $tmpdir; |
|
454 |
|
|
455 |
$form->error($locale->text('A temporary file could not be created:') . " $ERRNO"); |
|
456 |
} |
|
457 |
|
|
458 |
print $tmpfile $form->{content}; |
|
459 |
$tmpfile->close(); |
|
460 |
|
|
461 |
delete $form->{content}; |
|
462 |
|
|
463 |
# Try to connect to the database. Find out if a database with the same name exists. |
|
464 |
# If yes, then drop the existing database. Create a new one with the name and encoding |
|
465 |
# given by the user. |
|
466 |
|
|
467 |
User::dbconnect_vars($form, "template1"); |
|
468 |
|
|
469 |
my %myconfig = map { $_ => $form->{$_} } grep /^db/, keys %{ $form }; |
|
470 |
my $dbh = $form->dbconnect(\%myconfig) || $form->dberror(); |
|
471 |
|
|
472 |
my ($query, $sth); |
|
473 |
|
|
474 |
$form->{new_dbname} =~ s|[^a-zA-Z0-9_\-]||g; |
|
475 |
|
|
476 |
$query = qq|SELECT COUNT(*) FROM pg_database WHERE datname = ?|; |
|
477 |
my ($count) = selectrow_query($form, $dbh, $query, $form->{new_dbname}); |
|
478 |
if ($count) { |
|
479 |
do_query($form, $dbh, qq|DROP DATABASE $form->{new_dbname}|); |
|
480 |
} |
|
481 |
|
|
482 |
my $found = 0; |
|
483 |
foreach my $item (@Common::db_encodings) { |
|
484 |
if ($item->{dbencoding} eq $form->{dbencoding}) { |
|
485 |
$found = 1; |
|
486 |
last; |
|
487 |
} |
|
488 |
} |
|
489 |
$form->{dbencoding} = "LATIN9" unless $form->{dbencoding}; |
|
490 |
|
|
491 |
do_query($form, $dbh, qq|CREATE DATABASE $form->{new_dbname} ENCODING ? TEMPLATE template0|, $form->{dbencoding}); |
|
492 |
|
|
493 |
$dbh->disconnect(); |
|
494 |
|
|
495 |
# Spawn pg_restore on the temporary file. |
|
496 |
|
|
497 |
my @args = ("-h", $form->{dbhost}, "-U", $form->{dbuser}, "-d", $form->{new_dbname}); |
|
498 |
push @args, ("-p", $form->{dbport}) if ($form->{dbport}); |
|
499 |
push @args, $tmp; |
|
500 |
|
|
501 |
my $cmd = "$pg_restore_exe " . join(" ", map { s/\\/\\\\/g; s/\"/\\\"/g; $_ } @args); |
|
502 |
|
|
503 |
my $in = IO::File->new("$cmd 2>&1 |"); |
|
504 |
|
|
505 |
if (!$in) { |
|
506 |
unlink "${tmpdir}/.pgpass", $tmp; |
|
507 |
rmdir $tmpdir; |
|
508 |
|
|
509 |
$form->error($locale->text('The pg_restore process could not be started.')); |
|
510 |
} |
|
511 |
|
|
512 |
$English::AUTOFLUSH = 1; |
|
513 |
|
|
514 |
$form->header(); |
|
515 |
print $form->parse_html_template("admin/restore_dataset_start_header"); |
|
516 |
|
|
517 |
while (my $line = <$in>) { |
|
518 |
print $line; |
|
519 |
} |
|
520 |
$in->close(); |
|
521 |
|
|
522 |
$form->{retval} = $CHILD_ERROR >> 8; |
|
523 |
print $form->parse_html_template("admin/restore_dataset_start_footer"); |
|
524 |
|
|
525 |
unlink "${tmpdir}/.pgpass", $tmp; |
|
526 |
rmdir $tmpdir; |
|
527 |
} |
|
528 |
|
|
529 | 269 |
1; |
Auch abrufbar als: Unified diff
Admin-Funktionen zum Sichern/Wiederherstellen der Datenbanken entfernt
Diese funktionieren seit der Umstellung von users/members auf
Verwendung der Authentifizierungsdatenbank nicht mehr und sind seitdem
auch auskommentiert. Eine Neuimplementation ist nicht geplant.