Skip to content
backup.inc.php 98.2 KiB
Newer Older
Jorge Muñoz's avatar
Jorge Muñoz committed
        if (!empty($backup_format)) {
            $app->system->web_folder_protection($web_root, false);
            $user_mode = $backup_mode == 'userzip';

            $archives = self::getReposArchives($backup_format, $backup_repos_path, $password);
            if (in_array($backup_archive, $archives) && $web_root != '' && $web_root != '/' && !stristr($full_filename, '..') && !stristr($full_filename, 'etc')) {
Jorge Muñoz's avatar
Jorge Muñoz committed
                $success = false;
                $retval = 0;
                switch ($backup_format) {
                    case "borg":
                        $password_cmd = self::getPasswordCommand($backup_format, $password);
                        $command = 'cd ? && ' . $password_cmd . 'borg extract ?';
                        $app->system->exec_safe($command, $web_root, $full_archive_path);
                        $retval = $app->system->last_exec_retcode();
                        $success = ($retval == 0 || $retval == 1);
                        break;
                }
                if ($success) {
                    $app->log('Restored web backup ' . $full_archive_path, LOGLEVEL_DEBUG);
                    $result = true;
                } else {
                    $app->log('Failed to restore web backup ' . $full_archive_path . ', exit code ' . $retval, LOGLEVEL_ERROR);
                }
            }
            $app->system->web_folder_protection($web_root, true);
        } else {
            $app->log('Failed to restore web backup ' . $full_archive_path . ', backup format not recognized.', LOGLEVEL_DEBUG);
        }
        return $result;
    }
    public static function deleteBackup($backup_format, $backup_password, $backup_dir, $filename, $backup_mode, $backup_type, $domain_id) {
        global $app, $conf;
        $server_id = $conf['server_id'];
        $success = false;

        if (empty($backup_format) || $backup_format == 'default') {
            $backup_format = 'borg';
        }

        if(self::formatIsRepos($backup_format, $backup_type)) {
            $backup_archive = $filename;
            $backup_repos_folder = self::getBackupReposFolder($backup_format, $backup_type);
            if ($backup_type != 'web') {
                preg_match('@^(manual-)?db_(?P<db>.+)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}$@', $backup_archive, $matches);
                if (!isset($matches['db']) || empty($matches['db'])) {
                    $app->log('Failed to detect database name during restore of ' . $backup_archive, LOGLEVEL_ERROR);
Jorge Muñoz's avatar
Jorge Muñoz committed
                    return false;
                }
                $db_name = $matches['db'];
                $backup_repos_folder .= '_' . $db_name;
            }
            $backup_repos_path = $backup_dir . DIRECTORY_SEPARATOR . $backup_repos_folder;
            $success = self::deleteArchive($backup_format, $backup_repos_path, $backup_archive, $password);
        } else {
            if(file_exists($backup_dir.'/'.$filename) && !stristr($backup_dir.'/'.$filename, '..') && !stristr($backup_dir.'/'.$filename, 'etc')) {
                $success = unlink($backup_dir.'/'.$filename);
            } else {
                $success = true;
            }
        }
        if ($success) {
            $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename = ?";
            $app->db->query($sql, $server_id, $domain_id, $filename);
            if($app->db->dbHost != $app->dbmaster->dbHost)
                $app->dbmaster->query($sql, $server_id, $domain_id, $filename);
            $app->log($sql . ' - ' . json_encode([$server_id, $domain_id, $filename]), LOGLEVEL_DEBUG);
        }
        return $success;
    }

    protected static function formatIsRepos($backup_format, $backup_type)
    {
        switch ($backup_type) {
            case 'web': case 'mysql': case 'mongodb':
                return in_array($backup_format, ['borg']);
                break;
        }
        return false;
    }
    public static function downloadBackup($backup_format, $password, $backup_dir, $filename, $backup_mode, $backup_type, $domain)
    {
        global $app;
        if (self::formatIsRepos($backup_format, $backup_type)) {
Jorge Muñoz's avatar
Jorge Muñoz committed
            if ($backup_type == 'web') {
                $backup_repos_folder = self::getBackupReposFolder($backup_format, 'web');
                $filename .= '.tar.gz';
            } else {
                preg_match('@^(manual-)?db_(?P<db>.+)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}$@', $backup_archive, $matches);
                if (!isset($matches['db']) || empty($matches['db'])) {
                    $app->log('Failed to detect database name during restore of ' . $backup_archive, LOGLEVEL_ERROR);
Jorge Muñoz's avatar
Jorge Muñoz committed
                    return false;
                }
Jorge Muñoz's avatar
Jorge Muñoz committed
                $backup_repos_folder = self::getBackupReposFolder($backup_format, $backup_type) . '_' . $db_name;
                if ($backup_type == 'mysql') {
                    $filename .= '.sql.gz';
                } else {
                    $filename .= '.tar.gz';
                }
            }
            $backup_repos_path = $backup_dir . DIRECTORY_SEPARATOR . $backup_repos_folder;
            $full_archive_path = $backup_repos_path . '::' . $backup_archive;
Jorge Muñoz's avatar
Jorge Muñoz committed
            $archives = self::getReposArchives($backup_format, $backup_repos_path, $password);
            if ( $archives === FALSE || ! in_array($backup_archive, $archives)) {
Jorge Muñoz's avatar
Jorge Muñoz committed
                $app->log('Failed to find archive ' . $full_archive_path . ' for download', LOGLEVEL_ERROR);
                return false;
            }
            $app->log('Extracting ' . $backup_type . ' backup from repository archive '.$full_archive_path. ' to ' . $domain['document_root'].'/backup/' . $filename, LOGLEVEL_DEBUG);
            switch ($backup_format) {
                case 'borg':
                    $password_cmd = self::getPasswordCommand($backup_format, $password);
                    if ($backup_type != 'mysql') {
                        $command = $password_cmd . 'borg export-tar ? ?';
                    } else {
                        $command = $password_cmd . 'borg extract --stdout ? stdin | gzip -c > ?';
                    }
                    $app->system->exec_safe(
                        $command,
                        $full_archive_path,
                        $domain['document_root'].'/backup/' . $filename
                    );
                    if ($app->system->last_exec_retcode() != 0) {
                        $app->log('Copy of archive ' . $full_archive_path . ' failed', LOGLEVEL_ERROR);
                        return false;
                    }
                    break;
                default:
                    $app->log('Download of archive ' . $full_archive_path . ' failed because format ' . $backup_format . ' is unknown', LOGLEVEL_ERROR);
                    return false;
            }
        }
        //* Copy the backup file to the backup folder of the website
        elseif(file_exists($backup_dir.'/'.$filename) && file_exists($domain['document_root'].'/backup/') && !stristr($backup_dir.'/'.$filename, '..') && !stristr($backup_dir.'/'.$filename, 'etc')) {
            copy($backup_dir.'/'.$filename, $domain['document_root'].'/backup/'.$filename);
        }
        chgrp($domain['document_root'].'/backup/'.$filename, $domain['system_group']);
        chown($domain['document_root'].'/backup/'.$filename, $domain['system_user']);
        chmod($domain['document_root'].'/backup/'.$filename,0600);
        $app->log('Ready '.$domain['document_root'].'/backup/'.$filename, LOGLEVEL_DEBUG);
        return true;
    }

/** END **/
}