$form->{title} = "kivitendo / " . $locale->text('Database Administration');
- # Intentionnaly disabled unless fixed to work with the authentication DB.
- $form->{ALLOW_DBBACKUP} = 0; # "$pg_dump_exe" ne "DISABLED";
-
$form->header();
print $form->parse_html_template("admin/dbadmin");
}
print $form->parse_html_template("admin/dbdelete");
}
-sub backup_dataset {
- my $form = $main::form;
- my $locale = $main::locale;
-
- $form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Backup Dataset');
-
- if ($::lx_office_conf{applications}->{pg_dump} eq "DISABLED") {
- $form->error($locale->text('Database backups and restorations are disabled in the configuration.'));
- }
-
- my @dbsources = sort User->dbsources($form);
- $form->{DATABASES} = [ map { { "dbname" => $_ } } @dbsources ];
- $form->{NO_DATABASES} = !scalar @dbsources;
-
- my $username = getpwuid $UID || "unknown-user";
- my $hostname = hostname() || "unknown-host";
- $form->{from} = "kivitendo Admin <${username}\@${hostname}>";
-
- $form->header();
- print $form->parse_html_template("admin/backup_dataset");
-}
-
-sub backup_dataset_start {
- my $form = $main::form;
- my $locale = $main::locale;
-
- $form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Backup Dataset');
-
- my $pg_dump_exe = $::lx_office_conf{applications}->{pg_dump} || "pg_dump";
-
- if ("$pg_dump_exe" eq "DISABLED") {
- $form->error($locale->text('Database backups and restorations are disabled in the configuration.'));
- }
-
- $form->isblank("dbname", $locale->text('The dataset name is missing.'));
- $form->isblank("to", $locale->text('The email address is missing.')) if $form->{destination} eq "email";
-
- my $tmpdir = "/tmp/lx_office_backup_" . Common->unique_id();
- mkdir $tmpdir, 0700 || $form->error($locale->text('A temporary directory could not be created:') . " $ERRNO");
-
- my $pgpass = IO::File->new("${tmpdir}/.pgpass", O_WRONLY | O_CREAT, 0600);
-
- if (!$pgpass) {
- unlink $tmpdir;
- $form->error($locale->text('A temporary file could not be created:') . " $ERRNO");
- }
-
- print $pgpass "$form->{dbhost}:$form->{dbport}:$form->{dbname}:$form->{dbuser}:$form->{dbpasswd}\n";
- $pgpass->close();
-
- $ENV{HOME} = $tmpdir;
-
- my @args = ("-Ft", "-c", "-o", "-h", $form->{dbhost}, "-U", $form->{dbuser});
- push @args, ("-p", $form->{dbport}) if ($form->{dbport});
- push @args, $form->{dbname};
-
- my $cmd = "$pg_dump_exe " . join(" ", map { s/\\/\\\\/g; s/\"/\\\"/g; $_ } @args);
- my $name = "dataset_backup_$form->{dbname}_" . strftime("%Y%m%d", localtime()) . ".tar";
-
- if ($form->{destination} ne "email") {
- my $in = IO::File->new("$cmd |");
-
- if (!$in) {
- unlink "${tmpdir}/.pgpass";
- rmdir $tmpdir;
-
- $form->error($locale->text('The pg_dump process could not be started.'));
- }
-
- print "content-type: application/x-tar\n";
- print "content-disposition: attachment; filename=\"${name}\"\n\n";
-
- while (my $line = <$in>) {
- print $line;
- }
-
- $in->close();
-
- unlink "${tmpdir}/.pgpass";
- rmdir $tmpdir;
-
- } else {
- my $tmp = $tmpdir . "/dump_" . Common::unique_id();
-
- if (system("$cmd > $tmp") != 0) {
- unlink "${tmpdir}/.pgpass", $tmp;
- rmdir $tmpdir;
-
- $form->error($locale->text('The pg_dump process could not be started.'));
- }
-
- my $mail = new Mailer;
-
- map { $mail->{$_} = $form->{$_} } qw(from to cc subject message);
-
- $mail->{charset} = $::lx_office_conf{system}->{dbcharset} || Common::DEFAULT_CHARSET;
- $mail->{attachments} = [ { "filename" => $tmp, "name" => $name } ];
- $mail->send();
-
- unlink "${tmpdir}/.pgpass", $tmp;
- rmdir $tmpdir;
-
- $form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Backup Dataset');
-
- $form->header();
- print $form->parse_html_template("admin/backup_dataset_email_done");
- }
-}
-
-sub restore_dataset {
- my $form = $main::form;
- my $locale = $main::locale;
-
- $form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Restore Dataset');
-
- if ($::lx_office_conf{applications}->{pg_restore} eq "DISABLED") {
- $form->error($locale->text('Database backups and restorations are disabled in the configuration.'));
- }
-
- my $default_charset = $::lx_office_conf{system}->{dbcharset};
- $default_charset ||= Common::DEFAULT_CHARSET;
-
- $form->{DBENCODINGS} = [];
-
- foreach my $encoding (@Common::db_encodings) {
- push @{ $form->{DBENCODINGS} }, { "dbencoding" => $encoding->{dbencoding},
- "label" => $encoding->{label},
- "selected" => $encoding->{charset} eq $default_charset };
- }
-
- $form->header();
- print $form->parse_html_template("admin/restore_dataset");
-}
-
-sub restore_dataset_start {
- my $form = $main::form;
- my $locale = $main::locale;
-
- $form->{title} = "kivitendo " . $locale->text('Database Administration') . " / " . $locale->text('Restore Dataset');
-
- my $pg_restore_exe = $::lx_office_conf{applications}->{pg_restore} || "pg_restore";
-
- if ("$pg_restore_exe" eq "DISABLED") {
- $form->error($locale->text('Database backups and restorations are disabled in the configuration.'));
- }
-
- $form->isblank("new_dbname", $locale->text('The dataset name is missing.'));
- $form->isblank("content", $locale->text('No backup file has been uploaded.'));
-
- # Create temporary directories. Write the backup file contents to a temporary
- # file. Create a .pgpass file with the username and password for the pg_restore
- # utility.
-
- my $tmpdir = "/tmp/lx_office_backup_" . Common->unique_id();
- mkdir $tmpdir, 0700 || $form->error($locale->text('A temporary directory could not be created:') . " $ERRNO");
-
- my $pgpass = IO::File->new("${tmpdir}/.pgpass", O_WRONLY | O_CREAT, 0600);
-
- if (!$pgpass) {
- unlink $tmpdir;
- $form->error($locale->text('A temporary file could not be created:') . " $ERRNO");
- }
-
- print $pgpass "$form->{dbhost}:$form->{dbport}:$form->{new_dbname}:$form->{dbuser}:$form->{dbpasswd}\n";
- $pgpass->close();
-
- $ENV{HOME} = $tmpdir;
-
- my $tmp = $tmpdir . "/dump_" . Common::unique_id();
- my $tmpfile;
-
- if (substr($form->{content}, 0, 2) eq "\037\213") {
- $tmpfile = IO::File->new("| gzip -d > $tmp");
- $tmpfile->binary();
-
- } else {
- $tmpfile = IO::File->new($tmp, O_WRONLY | O_CREAT | O_BINARY, 0600);
- }
-
- if (!$tmpfile) {
- unlink "${tmpdir}/.pgpass";
- rmdir $tmpdir;
-
- $form->error($locale->text('A temporary file could not be created:') . " $ERRNO");
- }
-
- print $tmpfile $form->{content};
- $tmpfile->close();
-
- delete $form->{content};
-
- # Try to connect to the database. Find out if a database with the same name exists.
- # If yes, then drop the existing database. Create a new one with the name and encoding
- # given by the user.
-
- User::dbconnect_vars($form, "template1");
-
- my %myconfig = map { $_ => $form->{$_} } grep /^db/, keys %{ $form };
- my $dbh = $form->dbconnect(\%myconfig) || $form->dberror();
-
- my ($query, $sth);
-
- $form->{new_dbname} =~ s|[^a-zA-Z0-9_\-]||g;
-
- $query = qq|SELECT COUNT(*) FROM pg_database WHERE datname = ?|;
- my ($count) = selectrow_query($form, $dbh, $query, $form->{new_dbname});
- if ($count) {
- do_query($form, $dbh, qq|DROP DATABASE $form->{new_dbname}|);
- }
-
- my $found = 0;
- foreach my $item (@Common::db_encodings) {
- if ($item->{dbencoding} eq $form->{dbencoding}) {
- $found = 1;
- last;
- }
- }
- $form->{dbencoding} = "LATIN9" unless $form->{dbencoding};
-
- do_query($form, $dbh, qq|CREATE DATABASE $form->{new_dbname} ENCODING ? TEMPLATE template0|, $form->{dbencoding});
-
- $dbh->disconnect();
-
- # Spawn pg_restore on the temporary file.
-
- my @args = ("-h", $form->{dbhost}, "-U", $form->{dbuser}, "-d", $form->{new_dbname});
- push @args, ("-p", $form->{dbport}) if ($form->{dbport});
- push @args, $tmp;
-
- my $cmd = "$pg_restore_exe " . join(" ", map { s/\\/\\\\/g; s/\"/\\\"/g; $_ } @args);
-
- my $in = IO::File->new("$cmd 2>&1 |");
-
- if (!$in) {
- unlink "${tmpdir}/.pgpass", $tmp;
- rmdir $tmpdir;
-
- $form->error($locale->text('The pg_restore process could not be started.'));
- }
-
- $English::AUTOFLUSH = 1;
-
- $form->header();
- print $form->parse_html_template("admin/restore_dataset_start_header");
-
- while (my $line = <$in>) {
- print $line;
- }
- $in->close();
-
- $form->{retval} = $CHILD_ERROR >> 8;
- print $form->parse_html_template("admin/restore_dataset_start_footer");
-
- unlink "${tmpdir}/.pgpass", $tmp;
- rmdir $tmpdir;
-}
-
1;