mirror of https://github.com/BOINC/boinc.git
parent
1234444558
commit
0f9b83a55b
|
@ -6859,3 +6859,28 @@ David 26 June 2006
|
|||
gui_rpc_client_ops.C
|
||||
sched/
|
||||
server_types.C
|
||||
|
||||
David 26 June 2006
|
||||
- Add support for "project files".
|
||||
These are files that are downloaded to all clients
|
||||
attached to that project,
|
||||
but are not associated with an app version, WU or result.
|
||||
Example: graphics files for use by the BOINC Manager.
|
||||
- Scheduling server: look for "project_files.xml" in project dir.
|
||||
If found, include it verbatim in scheduler replies.
|
||||
Intended to describe "project files"
|
||||
- core client: parse list of project files in scheduler reply
|
||||
or client state file.
|
||||
Create corresponding FILE_INFO and FILE_REF.
|
||||
Write list to client state file.
|
||||
When a project file finishes downloading,
|
||||
create link file(s) for it.
|
||||
|
||||
client/
|
||||
client_types.C,h
|
||||
cs_account.C
|
||||
cs_statefile.C
|
||||
scheduler_op.C
|
||||
sched/
|
||||
main.C,h
|
||||
server_types.C,h
|
||||
|
|
|
@ -86,7 +86,7 @@ static void debug_print_argv(char** argv) {
|
|||
static int make_link(const char *existing, const char *new_link) {
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(new_link, "w");
|
||||
fp = boinc_fopen(new_link, "w");
|
||||
if (!fp) return ERR_FOPEN;
|
||||
fprintf(fp, "<soft_link>%s</soft_link>\n", existing);
|
||||
fclose(fp);
|
||||
|
|
|
@ -89,6 +89,7 @@ void PROJECT::init() {
|
|||
attached_via_acct_mgr = false;
|
||||
strcpy(code_sign_key, "");
|
||||
user_files.clear();
|
||||
project_files.clear();
|
||||
anticipated_debt = 0;
|
||||
wall_cpu_time_this_period = 0;
|
||||
next_runnable_result = NULL;
|
||||
|
@ -260,6 +261,7 @@ int PROJECT::write_state(MIOFILE& out, bool gui_rpc) {
|
|||
" <code_sign_key>\n%s</code_sign_key>\n", code_sign_key
|
||||
);
|
||||
}
|
||||
write_project_files(out);
|
||||
}
|
||||
out.printf(
|
||||
"</project>\n"
|
||||
|
@ -440,6 +442,98 @@ void PROJECT::file_xfer_succeeded(const bool is_upload) {
|
|||
}
|
||||
}
|
||||
|
||||
int PROJECT::parse_project_files(FILE* in) {
|
||||
char buf[256];
|
||||
|
||||
project_files.clear();
|
||||
|
||||
while (fgets(buf, 256, in)) {
|
||||
if (match_tag(buf, "</project_files>")) return 0;
|
||||
if (match_tag(buf, "<file>")) {
|
||||
parse_project_file(in);
|
||||
} else {
|
||||
if (log_flags.unparsed_xml) {
|
||||
msg_printf(0, MSG_ERROR,
|
||||
"APP::parse(): unrecognized: %s\n", buf
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
|
||||
int PROJECT::parse_project_file(FILE* in) {
|
||||
char buf[1024], url[1024];
|
||||
FILE_REF fref;
|
||||
FILE_INFO finfo, *fip;
|
||||
|
||||
while (fgets(buf, 256, in)) {
|
||||
if (match_tag(buf, "</file>")) {
|
||||
if (!strlen(fref.open_name)) {
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
if (!strlen(finfo.name)) {
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
fip = gstate.lookup_file_info(this, finfo.name);
|
||||
if (fip) {
|
||||
fip->merge_info(finfo);
|
||||
fref.file_info = fip;
|
||||
} else {
|
||||
fip = new FILE_INFO;
|
||||
*fip = finfo;
|
||||
fip->is_project_file = true;
|
||||
gstate.file_infos.push_back(fip);
|
||||
fref.file_info = fip;
|
||||
}
|
||||
project_files.push_back(fref);
|
||||
return 0;
|
||||
}
|
||||
if (parse_str(buf, "<open_name>", fref.open_name, sizeof(fref.open_name))) continue;
|
||||
if (parse_str(buf, "<name>", finfo.name, sizeof(finfo.name))) continue;
|
||||
if (parse_str(buf, "<url>", url, sizeof(url))) {
|
||||
finfo.urls.push_back(url);
|
||||
}
|
||||
}
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
|
||||
void PROJECT::write_project_files(MIOFILE& f) {
|
||||
unsigned int i;
|
||||
|
||||
if (!project_files.size()) return;
|
||||
f.printf("<project_files>\n");
|
||||
for (i=0; i<project_files.size(); i++) {
|
||||
FILE_REF& fref = project_files[i];
|
||||
FILE_INFO* fip = fref.file_info;
|
||||
f.printf(
|
||||
" <file>\n"
|
||||
" <name>%s</name>\n"
|
||||
" <open_name>%s</open_name>\n"
|
||||
" </file>\n",
|
||||
fip->name,
|
||||
fref.open_name
|
||||
);
|
||||
}
|
||||
f.printf("</project_files>\n");
|
||||
}
|
||||
|
||||
int PROJECT::link_project_file(FILE_INFO* fip) {
|
||||
char project_dir[256], path[256];
|
||||
unsigned int i;
|
||||
|
||||
get_project_dir(this, project_dir);
|
||||
for (i=0; i<project_files.size(); i++) {
|
||||
FILE_REF& fref = project_files[i];
|
||||
if (fref.file_info != fip) continue;
|
||||
sprintf(path, "%s/%s", project_dir, fref.open_name);
|
||||
FILE* f = boinc_fopen(path, "w");
|
||||
if (!f) continue;
|
||||
fprintf(f, "<soft_link>%s/%s</soft_link>\n", project_dir, fip->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APP::parse(MIOFILE& in) {
|
||||
char buf[256];
|
||||
|
||||
|
@ -488,6 +582,7 @@ FILE_INFO::FILE_INFO() {
|
|||
gzip_when_done = false;
|
||||
signature_required = false;
|
||||
is_user_file = false;
|
||||
is_project_file = false;
|
||||
pers_file_xfer = NULL;
|
||||
result = NULL;
|
||||
project = NULL;
|
||||
|
@ -618,6 +713,7 @@ int FILE_INFO::parse(MIOFILE& in, bool from_server) {
|
|||
else if (match_tag(buf, "<report_on_rpc/>")) report_on_rpc = true;
|
||||
else if (parse_bool(buf, "gzip_when_done", gzip_when_done)) continue;
|
||||
else if (match_tag(buf, "<signature_required/>")) signature_required = true;
|
||||
else if (match_tag(buf, "<is_project_file/>")) is_project_file = true;
|
||||
else if (match_tag(buf, "<persistent_file_xfer>")) {
|
||||
pfxp = new PERS_FILE_XFER;
|
||||
retval = pfxp->parse(in);
|
||||
|
@ -685,6 +781,7 @@ int FILE_INFO::write(MIOFILE& out, bool to_server) {
|
|||
if (report_on_rpc) out.printf(" <report_on_rpc/>\n");
|
||||
if (gzip_when_done) out.printf(" <gzip_when_done/>\n");
|
||||
if (signature_required) out.printf(" <signature_required/>\n");
|
||||
if (is_user_file) out.printf(" <is_user_file/>\n");
|
||||
if (strlen(file_signature)) out.printf(" <file_signature>\n%s</file_signature>\n", file_signature);
|
||||
}
|
||||
for (i=0; i<urls.size(); i++) {
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
// don't report to server even if report_on_rpc is true
|
||||
bool signature_required; // true iff associated with app version
|
||||
bool is_user_file;
|
||||
bool is_project_file;
|
||||
bool gzip_when_done;
|
||||
// for output files: gzip file when done, and append .gz to its name
|
||||
class PERS_FILE_XFER* pers_file_xfer; // nonzero if in the process of being up/downloaded
|
||||
|
@ -228,7 +229,13 @@ public:
|
|||
bool attached_via_acct_mgr;
|
||||
char code_sign_key[MAX_KEY_LEN];
|
||||
std::vector<FILE_REF> user_files;
|
||||
std::vector<FILE_REF> project_files;
|
||||
// files not specific to apps or work - e.g. icons
|
||||
int parse_preferences_for_user_files();
|
||||
int parse_project_files(FILE*);
|
||||
int parse_project_file(FILE*);
|
||||
void write_project_files(MIOFILE&);
|
||||
int link_project_file(FILE_INFO*);
|
||||
|
||||
// Multiply by this when estimating the CPU time of a result
|
||||
// (based on FLOPs estimated and benchmarks).
|
||||
|
|
|
@ -135,16 +135,6 @@ int PROJECT::parse_account(FILE* in) {
|
|||
tentative = true;
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
else if (match_tag(buf, "<deletion_policy_priority/>")) {
|
||||
deletion_policy_priority = true;
|
||||
continue;
|
||||
}
|
||||
else if (match_tag(buf, "<deletion_policy_expire>")) {
|
||||
deletion_policy_expire = true;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
else if (match_tag(buf, "<gui_urls>")) {
|
||||
string foo;
|
||||
retval = copy_element_contents(in, "</gui_urls>", foo);
|
||||
|
@ -152,6 +142,10 @@ int PROJECT::parse_account(FILE* in) {
|
|||
gui_urls = "<gui_urls>\n"+foo+"</gui_urls>\n";
|
||||
continue;
|
||||
}
|
||||
else if (match_tag(buf, "<project_files>")) {
|
||||
parse_project_files(in);
|
||||
continue;
|
||||
}
|
||||
else if (match_tag(buf, "<project_specific>")) {
|
||||
retval = copy_element_contents(
|
||||
in,
|
||||
|
|
|
@ -273,6 +273,13 @@ bool CLIENT_STATE::handle_pers_file_xfers() {
|
|||
if (fip->is_user_file) {
|
||||
active_tasks.request_reread_prefs(fip->project);
|
||||
}
|
||||
|
||||
// if it's a project file, make a link in project dir
|
||||
//
|
||||
if (fip->is_project_file) {
|
||||
PROJECT* p = fip->project;
|
||||
p->link_project_file(fip);
|
||||
}
|
||||
}
|
||||
iter = pers_file_xfers->pers_file_xfers.erase(iter);
|
||||
delete pfx;
|
||||
|
|
|
@ -284,6 +284,9 @@ int CLIENT_STATE::parse_state_file() {
|
|||
delete rp;
|
||||
}
|
||||
}
|
||||
} else if (match_tag(buf, "<project_files>")) {
|
||||
project->parse_project_files(f);
|
||||
continue;
|
||||
} else if (match_tag(buf, "<host_info>")) {
|
||||
retval = host_info.parse(mf);
|
||||
if (retval) {
|
||||
|
|
|
@ -677,14 +677,6 @@ int SCHEDULER_REPLY::parse(FILE* in, PROJECT* project) {
|
|||
}
|
||||
project->gui_urls = "<gui_urls>\n"+foo+"</gui_urls>\n";
|
||||
continue;
|
||||
#if 0
|
||||
} else if (match_tag(buf, "<deletion_policy_priority/>")) {
|
||||
project->deletion_policy_priority = true;
|
||||
continue;
|
||||
} else if (match_tag(buf, "<deletion_policy_expire>")) {
|
||||
project->deletion_policy_expire = true;
|
||||
continue;
|
||||
#endif
|
||||
} else if (match_tag(buf, "<code_sign_key>")) {
|
||||
retval = dup_element_contents(
|
||||
in,
|
||||
|
@ -831,6 +823,8 @@ int SCHEDULER_REPLY::parse(FILE* in, PROJECT* project) {
|
|||
send_file_list = true;
|
||||
} else if (parse_int(buf, "<scheduler_version>", scheduler_version)) {
|
||||
continue;
|
||||
} else if (match_tag(buf, "<project_files>")) {
|
||||
retval = project->parse_project_files(in);
|
||||
} else if (strlen(buf)>1){
|
||||
if (log_flags.unparsed_xml) {
|
||||
msg_printf(0, MSG_ERROR,
|
||||
|
|
|
@ -73,6 +73,7 @@ bool use_files = false; // use disk files for req/reply msgs (for debugging)
|
|||
|
||||
SCHED_CONFIG config;
|
||||
GUI_URLS gui_urls;
|
||||
PROJECT_FILES project_files;
|
||||
key_t sema_key;
|
||||
int g_pid;
|
||||
static bool db_opened=false;
|
||||
|
@ -301,6 +302,7 @@ int main(int argc, char** argv) {
|
|||
log_messages.set_debug_level(config.sched_debug_level);
|
||||
|
||||
gui_urls.init();
|
||||
project_files.init();
|
||||
|
||||
sprintf(path, "%s/code_sign_public", config.key_dir);
|
||||
retval = read_file_malloc(path, code_sign_key);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
extern SCHED_CONFIG config;
|
||||
extern GUI_URLS gui_urls;
|
||||
extern PROJECT_FILES project_files;
|
||||
extern key_t sema_key;
|
||||
extern int g_pid;
|
||||
|
||||
|
|
|
@ -624,6 +624,9 @@ int SCHEDULER_REPLY::write(FILE* fout) {
|
|||
|
||||
gui_urls.get_gui_urls(user, host, team, buf);
|
||||
fputs(buf, fout);
|
||||
if (project_files.text) {
|
||||
fputs(project_files.text, fout);
|
||||
}
|
||||
|
||||
end:
|
||||
fprintf(fout,
|
||||
|
@ -906,4 +909,9 @@ void GUI_URLS::get_gui_urls(USER& user, HOST& host, TEAM& team, char* buf) {
|
|||
}
|
||||
}
|
||||
|
||||
void PROJECT_FILES::init() {
|
||||
text = 0;
|
||||
read_file_malloc("../project_files.xml", text);
|
||||
}
|
||||
|
||||
const char *BOINC_RCSID_ea659117b3 = "$Id$";
|
||||
|
|
|
@ -93,6 +93,11 @@ struct GUI_URLS {
|
|||
void get_gui_urls(USER& user, HOST& host, TEAM& team, char*);
|
||||
};
|
||||
|
||||
struct PROJECT_FILES {
|
||||
char* text;
|
||||
void init();
|
||||
};
|
||||
|
||||
struct IP_RESULT {
|
||||
double report_deadline;
|
||||
double cpu_time_remaining;
|
||||
|
|
Loading…
Reference in New Issue