mirror of
https://github.com/haiwen/seafile.git
synced 2025-01-09 04:17:30 +08:00
Fix a few bugs related to deleting repos on server.
Server: - Delete entries from Branch and RepoHead tables; - Restore entries to Branch and RepoHead tables from repo trash. - When client checks head commit, return DELTED if no entry in Repo table. - When client checks upload/download permission, return DELETED if repo doesn't exist. Client: - Handle repo DELETED situation in upload/download thread.
This commit is contained in:
parent
ba7373372d
commit
91928b9396
@ -37,6 +37,7 @@
|
||||
#define HTTP_NOT_FOUND 404
|
||||
#define HTTP_NO_QUOTA 443
|
||||
#define HTTP_REPO_DELETED 444
|
||||
#define HTTP_REPO_CORRUPTED 445
|
||||
#define HTTP_INTERNAL_SERVER_ERROR 500
|
||||
|
||||
#define RESET_BYTES_INTERVAL_MSEC 1000
|
||||
@ -907,6 +908,10 @@ handle_http_errors (HttpTxTask *task, int status)
|
||||
task->error = HTTP_TASK_ERR_SERVER;
|
||||
else if (status == HTTP_NO_QUOTA)
|
||||
task->error = HTTP_TASK_ERR_NO_QUOTA;
|
||||
else if (status == HTTP_REPO_DELETED)
|
||||
task->error = HTTP_TASK_ERR_REPO_DELETED;
|
||||
else if (status == HTTP_REPO_CORRUPTED)
|
||||
task->error = HTTP_TASK_ERR_REPO_CORRUPTED;
|
||||
else
|
||||
task->error = HTTP_TASK_ERR_UNKNOWN;
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ enum HttpTaskError {
|
||||
HTTP_TASK_ERR_WRITE_LOCAL_DATA,
|
||||
HTTP_TASK_ERR_NO_QUOTA,
|
||||
HTTP_TASK_ERR_FILES_LOCKED,
|
||||
HTTP_TASK_ERR_REPO_DELETED,
|
||||
HTTP_TASK_ERR_REPO_CORRUPTED,
|
||||
HTTP_TASK_ERR_UNKNOWN,
|
||||
N_HTTP_TASK_ERROR,
|
||||
};
|
||||
|
@ -1288,6 +1288,24 @@ remove_blocks_done (void *vtask)
|
||||
transition_sync_state (task, SYNC_STATE_DONE);
|
||||
}
|
||||
|
||||
static void
|
||||
on_repo_deleted_on_server (SyncTask *task, SeafRepo *repo)
|
||||
{
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_NOREPO);
|
||||
|
||||
seaf_warning ("repo %s(%.8s) not found on server\n",
|
||||
repo->name, repo->id);
|
||||
|
||||
if (!seafile_session_config_get_allow_repo_not_found_on_server(seaf)) {
|
||||
seaf_message ("remove repo %s(%.8s) since it's deleted on relay\n",
|
||||
repo->name, repo->id);
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
"repo.deleted_on_relay",
|
||||
repo->name);
|
||||
seaf_repo_manager_del_repo (seaf->repo_mgr, repo);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_sync_status (SyncTask *task)
|
||||
{
|
||||
@ -1339,21 +1357,8 @@ update_sync_status (SyncTask *task)
|
||||
/* If repo doesn't exist on relay and we have "master",
|
||||
* it was deleted on relay. In this case we remove this repo.
|
||||
*/
|
||||
else {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_NOREPO);
|
||||
|
||||
seaf_warning ("repo %s(%.8s) not found on server\n",
|
||||
repo->name, repo->id);
|
||||
|
||||
if (!seafile_session_config_get_allow_repo_not_found_on_server(seaf)) {
|
||||
seaf_debug ("remove repo %s(%.8s) since it's deleted on relay\n",
|
||||
repo->name, repo->id);
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
"repo.deleted_on_relay",
|
||||
repo->name);
|
||||
seaf_repo_manager_del_repo (seaf->repo_mgr, repo);
|
||||
}
|
||||
}
|
||||
else
|
||||
on_repo_deleted_on_server (task, repo);
|
||||
} else {
|
||||
/* branch deleted on relay */
|
||||
if (info->branch_deleted_on_relay) {
|
||||
@ -1457,19 +1462,7 @@ update_sync_status_v2 (SyncTask *task)
|
||||
if (info->repo_corrupted) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_REPO_CORRUPT);
|
||||
} else if (info->deleted_on_relay) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_NOREPO);
|
||||
|
||||
seaf_warning ("repo %s(%.8s) not found on server\n",
|
||||
repo->name, repo->id);
|
||||
|
||||
if (!seafile_session_config_get_allow_repo_not_found_on_server(seaf)) {
|
||||
seaf_message ("remove repo %s(%.8s) since it's deleted on relay\n",
|
||||
repo->name, repo->id);
|
||||
seaf_mq_manager_publish_notification (seaf->mq_mgr,
|
||||
"repo.deleted_on_relay",
|
||||
repo->name);
|
||||
seaf_repo_manager_del_repo (seaf->repo_mgr, repo);
|
||||
}
|
||||
on_repo_deleted_on_server (task, repo);
|
||||
} else {
|
||||
/* If local head is the same as remote head, already in sync. */
|
||||
if (strcmp (local->commit_id, info->head_commit) == 0) {
|
||||
@ -2817,6 +2810,8 @@ on_repo_http_fetched (SeafileSession *seaf,
|
||||
}
|
||||
} else if (tx_task->error == HTTP_TASK_ERR_FILES_LOCKED) {
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_FILES_LOCKED);
|
||||
} else if (tx_task->error == HTTP_TASK_ERR_REPO_DELETED) {
|
||||
on_repo_deleted_on_server (task, task->repo);
|
||||
} else
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_FETCH);
|
||||
}
|
||||
@ -2864,6 +2859,8 @@ on_repo_http_uploaded (SeafileSession *seaf,
|
||||
send_sync_error_notification (task->repo, "sync.quota_full");
|
||||
task->repo->quota_full_notified = 1;
|
||||
}
|
||||
} else if (tx_task->error == HTTP_TASK_ERR_REPO_DELETED) {
|
||||
on_repo_deleted_on_server (task, task->repo);
|
||||
} else
|
||||
seaf_sync_manager_set_task_error (task, SYNC_ERROR_UPLOAD);
|
||||
}
|
||||
|
@ -523,6 +523,16 @@ get_check_permission_cb (evhtp_request_t *req, void *arg)
|
||||
const char *token;
|
||||
SeafRepo *repo = NULL;
|
||||
|
||||
repo = seaf_repo_manager_get_repo_ex (seaf->repo_mgr, repo_id);
|
||||
if (!repo) {
|
||||
evhtp_send_reply (req, SEAF_HTTP_RES_REPO_DELETED);
|
||||
goto out;
|
||||
}
|
||||
if (repo->is_corrupted || repo->repaired) {
|
||||
evhtp_send_reply (req, SEAF_HTTP_RES_REPO_CORRUPTED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
int token_status = validate_token (htp_server, req, repo_id, &username, TRUE);
|
||||
if (token_status != EVHTP_RES_OK) {
|
||||
evhtp_send_reply (req, token_status);
|
||||
@ -538,12 +548,6 @@ get_check_permission_cb (evhtp_request_t *req, void *arg)
|
||||
goto out;
|
||||
}
|
||||
|
||||
repo = seaf_repo_manager_get_repo (seaf->repo_mgr, repo_id);
|
||||
if (!repo || repo->repaired) {
|
||||
evhtp_send_reply (req, SEAF_HTTP_RES_REPO_CORRUPTED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ip = get_client_ip_addr (req);
|
||||
if (!ip) {
|
||||
evhtp_send_reply (req, EVHTP_RES_SERVERR);
|
||||
@ -659,16 +663,31 @@ get_head_commit_cb (evhtp_request_t *req, void *arg)
|
||||
HttpServer *htp_server = arg;
|
||||
char **parts = g_strsplit (req->uri->path->full + 1, "/", 0);
|
||||
char *repo_id = parts[1];
|
||||
gboolean db_err = FALSE, exists = TRUE;
|
||||
int token_status;
|
||||
char commit_id[41];
|
||||
char *sql;
|
||||
|
||||
int token_status = validate_token (htp_server, req, repo_id, NULL, FALSE);
|
||||
sql = "SELECT 1 FROM Repo WHERE repo_id=?";
|
||||
exists = seaf_db_statement_exists (seaf->db, sql, &db_err, 1, "string", repo_id);
|
||||
if (!exists) {
|
||||
if (db_err) {
|
||||
seaf_warning ("DB error when check repo existence.\n");
|
||||
evbuffer_add_printf (req->buffer_out,
|
||||
"{\"is_corrupted\": 1}");
|
||||
evhtp_send_reply (req, EVHTP_RES_OK);
|
||||
goto out;
|
||||
}
|
||||
evhtp_send_reply (req, SEAF_HTTP_RES_REPO_DELETED);
|
||||
goto out;
|
||||
}
|
||||
|
||||
token_status = validate_token (htp_server, req, repo_id, NULL, FALSE);
|
||||
if (token_status != EVHTP_RES_OK) {
|
||||
evhtp_send_reply (req, token_status);
|
||||
goto out;
|
||||
}
|
||||
|
||||
char commit_id[41];
|
||||
char *sql;
|
||||
|
||||
commit_id[0] = 0;
|
||||
|
||||
sql = "SELECT commit_id FROM Branch WHERE name='master' AND repo_id=?";
|
||||
|
@ -128,7 +128,8 @@ send_repo_branch_info (void *vprocessor)
|
||||
|
||||
commit_id[0] = 0;
|
||||
|
||||
sql = "SELECT commit_id FROM Branch WHERE name='master' AND repo_id=?";
|
||||
sql = "SELECT commit_id FROM Repo r, Branch b "
|
||||
"WHERE name='master' AND r.repo_id=? AND r.repo_id = b.repo_id";
|
||||
if (seaf_db_statement_foreach_row (seaf->db, sql,
|
||||
get_branch, commit_id,
|
||||
1, "string", priv->repo_id) < 0) {
|
||||
|
@ -566,7 +566,15 @@ del_repo:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Repo branches are not removed at this point. */
|
||||
/* remove branch */
|
||||
GList *p;
|
||||
GList *branch_list = seaf_branch_manager_get_branch_list (seaf->branch_mgr, repo_id);
|
||||
for (p = branch_list; p; p = p->next) {
|
||||
SeafBranch *b = (SeafBranch *)p->data;
|
||||
seaf_repo_manager_branch_repo_unmap (mgr, b);
|
||||
seaf_branch_manager_del_branch (seaf->branch_mgr, repo_id, b->name);
|
||||
}
|
||||
seaf_branch_list_free (branch_list);
|
||||
|
||||
seaf_db_statement_query (mgr->seaf->db, "DELETE FROM RepoOwner WHERE repo_id = ?",
|
||||
1, "string", repo_id);
|
||||
@ -2140,7 +2148,7 @@ seaf_repo_manager_get_repo_from_trash (SeafRepoManager *mgr,
|
||||
char *sql;
|
||||
int rc;
|
||||
|
||||
sql = "SELECT repo_id, repo_name, head_id, owner_id, size FROM RepoTrash "
|
||||
sql = "SELECT repo_id, repo_name, head_id, owner_id, size, del_time FROM RepoTrash "
|
||||
"WHERE repo_id = ?";
|
||||
rc = seaf_db_statement_foreach_row (mgr->seaf->db, sql,
|
||||
collect_trash_repo, &trash_repos,
|
||||
@ -2171,16 +2179,6 @@ seaf_repo_manager_del_repo_from_trash (SeafRepoManager *mgr,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* remove branch */
|
||||
GList *p;
|
||||
GList *branch_list = seaf_branch_manager_get_branch_list (seaf->branch_mgr, repo_id);
|
||||
for (p = branch_list; p; p = p->next) {
|
||||
SeafBranch *b = (SeafBranch *)p->data;
|
||||
seaf_repo_manager_branch_repo_unmap (mgr, b);
|
||||
seaf_branch_manager_del_branch (seaf->branch_mgr, repo_id, b->name);
|
||||
}
|
||||
seaf_branch_list_free (branch_list);
|
||||
|
||||
seaf_db_statement_query (mgr->seaf->db,
|
||||
"DELETE FROM RepoTrash WHERE repo_id = ?",
|
||||
1, "string", repo_id);
|
||||
@ -2287,6 +2285,39 @@ seaf_repo_manager_restore_repo_from_trash (SeafRepoManager *mgr,
|
||||
}
|
||||
}
|
||||
|
||||
exists = seaf_db_trans_check_for_existence (trans,
|
||||
"SELECT 1 FROM Branch WHERE repo_id=?",
|
||||
&db_err, 1, "string", repo_id);
|
||||
if (!exists) {
|
||||
ret = seaf_db_trans_query (trans,
|
||||
"INSERT INTO Branch VALUES ('master', ?, ?)",
|
||||
2, "string", repo_id,
|
||||
"string", seafile_trash_repo_get_head_id(repo));
|
||||
if (ret < 0) {
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL,
|
||||
"DB error: Insert Branch.");
|
||||
seaf_db_rollback (trans);
|
||||
seaf_db_trans_close (trans);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
exists = seaf_db_trans_check_for_existence (trans,
|
||||
"SELECT 1 FROM RepoHead WHERE repo_id=?",
|
||||
&db_err, 1, "string", repo_id);
|
||||
if (!exists) {
|
||||
ret = seaf_db_trans_query (trans,
|
||||
"INSERT INTO RepoHead VALUES (?, 'master')",
|
||||
1, "string", repo_id);
|
||||
if (ret < 0) {
|
||||
g_set_error (error, SEAFILE_DOMAIN, SEAF_ERR_GENERAL,
|
||||
"DB error: Set RepoHead.");
|
||||
seaf_db_rollback (trans);
|
||||
seaf_db_trans_close (trans);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = seaf_db_trans_query (trans,
|
||||
"DELETE FROM RepoTrash WHERE repo_id = ?",
|
||||
1, "string", repo_id);
|
||||
|
Loading…
Reference in New Issue
Block a user