mirror of https://github.com/BOINC/boinc.git
client: handle changes to project master URLs
The Einstein@home web site says its master URL is https://einsteinathome.org. But its scheduler replies say the master URL is https://einstein.phys.uwm.edu If you attach to URL1 the client creates a file account_einsteinathome.org.xml Then it does a scheduler RPC and gets a reply saying the master URL is URL2. It then creates a file account_einstein.phys.uwm.edu.xml If you then detach from the project, it deletes the 2nd account file but the first one is still there, so the next time you run the client you're still attached to Einstein@home! To fix this situation: 1) on startup, check for misnamed account files (file name doesn't match master URL in the file). Delete (if there's already a file of the right name) or rename. 2) on scheduler RPC reply with a URL that differs by more than http(s)://, rename the account file and the project directory. Reset the project (remove jobs and other info) since soft links point to the old project dir.
This commit is contained in:
parent
86669cd2c1
commit
1c3d99e3bc
|
@ -323,6 +323,7 @@ int CLIENT_STATE::parse_account_files() {
|
|||
PROJECT* project;
|
||||
FILE* f;
|
||||
int retval;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
DirScanner dir(".");
|
||||
while (dir.scan(name)) {
|
||||
|
@ -345,16 +346,50 @@ int CLIENT_STATE::parse_account_files() {
|
|||
"Couldn't parse account file %s", name.c_str()
|
||||
);
|
||||
delete project;
|
||||
} else {
|
||||
if (lookup_project(project->master_url)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// see if the account file name doesn't match the master URL.
|
||||
// This can happen if a project changes its URL
|
||||
//
|
||||
// If this happens, anything in client_state.xml for the old project
|
||||
// will be ignored.
|
||||
//
|
||||
get_account_filename(project->master_url, path, sizeof(path));
|
||||
if (strcmp(path, name.c_str())) {
|
||||
// if not, see if account file with proper name exists
|
||||
//
|
||||
if (boinc_file_exists(path)) {
|
||||
// yes - delete this file
|
||||
//
|
||||
msg_printf(project, MSG_INFO,
|
||||
"Duplicate account file %s - ignoring", name.c_str()
|
||||
"Misnamed account file %s - deleting", name.c_str()
|
||||
);
|
||||
boinc_delete_file(name.c_str());
|
||||
delete project;
|
||||
continue;
|
||||
} else {
|
||||
projects.push_back(project);
|
||||
// no - rename this file
|
||||
//
|
||||
msg_printf(project, MSG_INFO,
|
||||
"Misnamed account file %s - renaming to %s",
|
||||
name.c_str(), path
|
||||
);
|
||||
boinc_rename(name.c_str(), path);
|
||||
}
|
||||
}
|
||||
|
||||
// shouldn't happen given the above logic, but just in case
|
||||
//
|
||||
if (lookup_project(project->master_url)) {
|
||||
msg_printf(project, MSG_INFO,
|
||||
"Duplicate account file %s - ignoring", name.c_str()
|
||||
);
|
||||
delete project;
|
||||
continue;
|
||||
}
|
||||
|
||||
projects.push_back(project);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -87,15 +87,39 @@ bool CLIENT_STATE::start_new_file_xfer(PERS_FILE_XFER& pfx) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Make a directory for each of the projects in the client state
|
||||
// Make a directory for each of the projects in the client state,
|
||||
// and delete other stuff in projects/
|
||||
//
|
||||
int CLIENT_STATE::make_project_dirs() {
|
||||
unsigned int i;
|
||||
int retval;
|
||||
vector<string> pds;
|
||||
for (i=0; i<projects.size(); i++) {
|
||||
retval = make_project_dir(*projects[i]);
|
||||
PROJECT *p = projects[i];
|
||||
retval = make_project_dir(*p);
|
||||
if (retval) return retval;
|
||||
pds.push_back(p->project_dir());
|
||||
}
|
||||
|
||||
string name;
|
||||
char path[MAXPATHLEN];
|
||||
DirScanner dir("projects");
|
||||
while (dir.scan(name)) {
|
||||
snprintf(path, sizeof(path), "projects/%s", name.c_str());
|
||||
if (std::find(pds.begin(), pds.end(), path) != pds.end()) {
|
||||
continue;
|
||||
}
|
||||
msg_printf(0, MSG_INFO,
|
||||
"%s is not a project dir - removing", path
|
||||
);
|
||||
if (is_dir(path)) {
|
||||
clean_out_dir(path);
|
||||
boinc_rmdir(path);
|
||||
} else {
|
||||
boinc_delete_file(path);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -567,7 +567,9 @@ int CLIENT_STATE::handle_scheduler_reply(
|
|||
// (which comes from the project's config.xml).
|
||||
// - if http -> https transition, use the https: one from now on
|
||||
// - if https -> http transition, keep using the https: one
|
||||
// - otherwise notify the user.
|
||||
// - otherwise switch to the new master URL:
|
||||
// rename and rewrite account file
|
||||
// rename project dir
|
||||
//
|
||||
if (strlen(sr.master_url)) {
|
||||
canonicalize_master_url(sr.master_url, sizeof(sr.master_url));
|
||||
|
@ -587,9 +589,41 @@ int CLIENT_STATE::handle_scheduler_reply(
|
|||
// keep using https://
|
||||
} else {
|
||||
msg_printf(project, MSG_USER_ALERT,
|
||||
_("This project seems to have changed its URL. When convenient, remove the project, then add %s"),
|
||||
sr.master_url
|
||||
_("Master URL changed from %s to %s"),
|
||||
current_url.c_str(), reply_url.c_str()
|
||||
);
|
||||
char path[MAXPATHLEN], path2[MAXPATHLEN], old_project_dir[MAXPATHLEN];
|
||||
|
||||
// rename statistics file
|
||||
//
|
||||
get_statistics_filename(
|
||||
(char*)current_url.c_str(), path, sizeof(path)
|
||||
);
|
||||
get_statistics_filename(
|
||||
(char*)reply_url.c_str(), path2, sizeof(path2)
|
||||
);
|
||||
boinc_rename(path, path2);
|
||||
|
||||
strcpy(old_project_dir, project->project_dir());
|
||||
|
||||
// delete account file and write new one
|
||||
//
|
||||
get_account_filename(project->master_url, path, sizeof(path));
|
||||
boinc_delete_file(path);
|
||||
strcpy(project->master_url, reply_url.c_str());
|
||||
project->write_account_file();
|
||||
|
||||
// rename project dir
|
||||
//
|
||||
strcpy(project->_project_dir, "");
|
||||
strcpy(path2, project->project_dir());
|
||||
boinc_rename(old_project_dir, path2);
|
||||
|
||||
// reset the project (clear jobs etc.).
|
||||
// If any jobs are running, their soft links
|
||||
// point to the old project dir
|
||||
//
|
||||
reset_project(project, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue