project files

svn path=/trunk/boinc/; revision=10517
This commit is contained in:
David Anderson 2006-06-26 22:58:24 +00:00
parent 1234444558
commit 0f9b83a55b
12 changed files with 162 additions and 19 deletions

View File

@ -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

View File

@ -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);

View File

@ -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++) {

View File

@ -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).

View File

@ -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,

View File

@ -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;

View File

@ -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) {

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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$";

View File

@ -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;