mirror of https://github.com/BOINC/boinc.git
parent
f1a858b6ff
commit
c0813dcd55
|
@ -2023,3 +2023,50 @@ David Sept 28 2002
|
|||
server_types.C,h
|
||||
tools/
|
||||
add.C
|
||||
|
||||
David Oct 3 2002
|
||||
- Changed the PHP framework for testing to facilitate
|
||||
multi-project, multi-host tests (all on one machine).
|
||||
See doc/test.html for details.
|
||||
- NOTE: the BOINC-related environment variables have changed.
|
||||
There are no longer any project-specific variables
|
||||
(e.g. database name, shmem key)
|
||||
- NOTE: the server programs now expect a configuration file
|
||||
in their directory.
|
||||
- TODO: enhance the testing framework to allow projects with
|
||||
multiple scheduling servers or data servers
|
||||
- TODO: enhance the testing framework to allow specification
|
||||
of failure and recovery of servers
|
||||
|
||||
- changed things so a NULL in the DB won't crash db_mysql.C
|
||||
- parse_int() can now handle hex
|
||||
- "add" now takes args for DB name/passwd
|
||||
- "create_work" now takes args for DB name/passwd,
|
||||
upload/download URL, download dir
|
||||
|
||||
db/
|
||||
db_mysql.C
|
||||
mysql_util.C
|
||||
doc/
|
||||
data_server_setup.html
|
||||
sched_server_setup.html
|
||||
test.html
|
||||
web_site.html
|
||||
html_user/
|
||||
index.html
|
||||
lib/
|
||||
md5_file.C
|
||||
parse.C
|
||||
sched/
|
||||
Makefile.in
|
||||
config.C,h (new)
|
||||
feeder.C
|
||||
file_upload_handler.C
|
||||
main.C
|
||||
validate.C
|
||||
validate_test.C
|
||||
tools/
|
||||
add.C
|
||||
backend_lib.C,h
|
||||
create_work.C
|
||||
process_result_template.C
|
||||
|
|
|
@ -25,15 +25,15 @@
|
|||
|
||||
#include "db.h"
|
||||
|
||||
#define TYPE_PROJECT 1
|
||||
#define TYPE_PLATFORM 2
|
||||
#define TYPE_PROJECT 1
|
||||
#define TYPE_PLATFORM 2
|
||||
#define TYPE_APP 3
|
||||
#define TYPE_APP_VERSION 4
|
||||
#define TYPE_USER 5
|
||||
#define TYPE_TEAM 6
|
||||
#define TYPE_HOST 7
|
||||
#define TYPE_WORKUNIT 8
|
||||
#define TYPE_RESULT 9
|
||||
#define TYPE_USER 5
|
||||
#define TYPE_TEAM 6
|
||||
#define TYPE_HOST 7
|
||||
#define TYPE_WORKUNIT 8
|
||||
#define TYPE_RESULT 9
|
||||
|
||||
char* table_name[] = {
|
||||
"",
|
||||
|
@ -230,6 +230,11 @@ void struct_to_str(void* vp, char* q, int type) {
|
|||
}
|
||||
}
|
||||
|
||||
static void strcpy2(char* dest, char* src) {
|
||||
if (!src) *dest = 0;
|
||||
else strcpy(dest, src);
|
||||
}
|
||||
|
||||
void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
||||
PROJECT* prp;
|
||||
PLATFORM* pp;
|
||||
|
@ -248,23 +253,23 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
|||
prp = (PROJECT*)vp;
|
||||
memset(prp, 0, sizeof(PROJECT));
|
||||
prp->id = atoi(r[i++]);
|
||||
strcpy(prp->name, r[i++]);
|
||||
strcpy2(prp->name, r[i++]);
|
||||
break;
|
||||
case TYPE_PLATFORM:
|
||||
pp = (PLATFORM*)vp;
|
||||
memset(pp, 0, sizeof(PLATFORM));
|
||||
pp->id = atoi(r[i++]);
|
||||
pp->create_time = atoi(r[i++]);
|
||||
strcpy(pp->name, r[i++]);
|
||||
strcpy2(pp->name, r[i++]);
|
||||
break;
|
||||
case TYPE_APP:
|
||||
app = (APP*)vp;
|
||||
memset(app, 0, sizeof(APP));
|
||||
app->id = atoi(r[i++]);
|
||||
app->create_time = atoi(r[i++]);
|
||||
strcpy(app->name, r[i++]);
|
||||
strcpy2(app->name, r[i++]);
|
||||
app->min_version = atoi(r[i++]);
|
||||
strcpy(app->result_xml_template, r[i++]);
|
||||
strcpy2(app->result_xml_template, r[i++]);
|
||||
break;
|
||||
case TYPE_APP_VERSION:
|
||||
avp = (APP_VERSION*)vp;
|
||||
|
@ -274,10 +279,10 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
|||
avp->appid = atoi(r[i++]);
|
||||
avp->version_num = atoi(r[i++]);
|
||||
avp->platformid = atoi(r[i++]);
|
||||
strcpy(avp->xml_doc, r[i++]);
|
||||
strcpy2(avp->xml_doc, r[i++]);
|
||||
avp->min_core_version = atoi(r[i++]);
|
||||
avp->max_core_version = atoi(r[i++]);
|
||||
strcpy(avp->message, r[i++]);
|
||||
strcpy2(avp->message, r[i++]);
|
||||
avp->deprecated = atoi(r[i++]);
|
||||
break;
|
||||
case TYPE_USER:
|
||||
|
@ -285,17 +290,17 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
|||
memset(up, 0, sizeof(USER));
|
||||
up->id = atoi(r[i++]);
|
||||
up->create_time = atoi(r[i++]);
|
||||
strcpy(up->email_addr, r[i++]);
|
||||
strcpy(up->name, r[i++]);
|
||||
strcpy(up->web_password, r[i++]);
|
||||
strcpy(up->authenticator, r[i++]);
|
||||
strcpy(up->country, r[i++]);
|
||||
strcpy(up->postal_code, r[i++]);
|
||||
strcpy2(up->email_addr, r[i++]);
|
||||
strcpy2(up->name, r[i++]);
|
||||
strcpy2(up->web_password, r[i++]);
|
||||
strcpy2(up->authenticator, r[i++]);
|
||||
strcpy2(up->country, r[i++]);
|
||||
strcpy2(up->postal_code, r[i++]);
|
||||
up->total_credit = atof(r[i++]);
|
||||
up->expavg_credit = atof(r[i++]);
|
||||
up->expavg_time = atof(r[i++]);
|
||||
strcpy(up->global_prefs, r[i++]);
|
||||
strcpy(up->project_prefs, r[i++]);
|
||||
strcpy2(up->global_prefs, r[i++]);
|
||||
strcpy2(up->project_prefs, r[i++]);
|
||||
up->teamid = atoi(r[i++]);
|
||||
break;
|
||||
case TYPE_TEAM:
|
||||
|
@ -303,11 +308,11 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
|||
memset(tp, 0, sizeof(TEAM));
|
||||
tp->id = atoi(r[i++]);
|
||||
tp->userid = atoi(r[i++]);
|
||||
strcpy(tp->name, r[i++]);
|
||||
strcpy(tp->name_lc, r[i++]);
|
||||
strcpy(tp->url, r[i++]);
|
||||
strcpy(tp->name_html, r[i++]);
|
||||
strcpy(tp->description, r[i++]);
|
||||
strcpy2(tp->name, r[i++]);
|
||||
strcpy2(tp->name_lc, r[i++]);
|
||||
strcpy2(tp->url, r[i++]);
|
||||
strcpy2(tp->name_html, r[i++]);
|
||||
strcpy2(tp->description, r[i++]);
|
||||
tp->nusers = atoi(r[i++]);
|
||||
break;
|
||||
case TYPE_HOST:
|
||||
|
@ -322,21 +327,21 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
|||
hp->expavg_credit = atof(r[i++]);
|
||||
hp->expavg_time = atof(r[i++]);
|
||||
hp->timezone = atoi(r[i++]);
|
||||
strcpy(hp->domain_name, r[i++]);
|
||||
strcpy(hp->serialnum, r[i++]);
|
||||
strcpy(hp->last_ip_addr, r[i++]);
|
||||
strcpy2(hp->domain_name, r[i++]);
|
||||
strcpy2(hp->serialnum, r[i++]);
|
||||
strcpy2(hp->last_ip_addr, r[i++]);
|
||||
hp->nsame_ip_addr = atoi(r[i++]);
|
||||
hp->on_frac = atof(r[i++]);
|
||||
hp->connected_frac = atof(r[i++]);
|
||||
hp->active_frac = atof(r[i++]);
|
||||
hp->p_ncpus = atoi(r[i++]);
|
||||
strcpy(hp->p_vendor, r[i++]);
|
||||
strcpy(hp->p_model, r[i++]);
|
||||
strcpy2(hp->p_vendor, r[i++]);
|
||||
strcpy2(hp->p_model, r[i++]);
|
||||
hp->p_fpops = atof(r[i++]);
|
||||
hp->p_iops = atof(r[i++]);
|
||||
hp->p_membw = atof(r[i++]);
|
||||
strcpy(hp->os_name, r[i++]);
|
||||
strcpy(hp->os_version, r[i++]);
|
||||
strcpy2(hp->os_name, r[i++]);
|
||||
strcpy2(hp->os_version, r[i++]);
|
||||
hp->m_nbytes = atof(r[i++]);
|
||||
hp->m_cache = atof(r[i++]);
|
||||
hp->m_swap = atof(r[i++]);
|
||||
|
@ -354,8 +359,8 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
|||
wup->appid = atoi(r[i++]);
|
||||
wup->previous_wuid = atoi(r[i++]);
|
||||
wup->has_successor = (atoi(r[i++])!=0);
|
||||
strcpy(wup->name, r[i++]);
|
||||
strcpy(wup->xml_doc, r[i++]);
|
||||
strcpy2(wup->name, r[i++]);
|
||||
strcpy2(wup->xml_doc, r[i++]);
|
||||
wup->batch = atoi(r[i++]);
|
||||
wup->rsc_fpops = atof(r[i++]);
|
||||
wup->rsc_iops = atof(r[i++]);
|
||||
|
@ -382,12 +387,12 @@ void row_to_struct(MYSQL_ROW& r, void* vp, int type) {
|
|||
rp->report_deadline = atoi(r[i++]);
|
||||
rp->sent_time = atoi(r[i++]);
|
||||
rp->received_time = atoi(r[i++]);
|
||||
strcpy(rp->name, r[i++]);
|
||||
strcpy2(rp->name, r[i++]);
|
||||
rp->exit_status = atoi(r[i++]);
|
||||
rp->cpu_time = atof(r[i++]);
|
||||
strcpy(rp->xml_doc_in, r[i++]);
|
||||
strcpy(rp->xml_doc_out, r[i++]);
|
||||
strcpy(rp->stderr_out, r[i++]);
|
||||
strcpy2(rp->xml_doc_in, r[i++]);
|
||||
strcpy2(rp->xml_doc_out, r[i++]);
|
||||
strcpy2(rp->stderr_out, r[i++]);
|
||||
rp->batch = atoi(r[i++]);
|
||||
rp->project_state = atoi(r[i++]);
|
||||
rp->validate_state = atoi(r[i++]);
|
||||
|
|
|
@ -54,6 +54,7 @@ int db_close() {
|
|||
void db_print_error(char* p) {
|
||||
if (mp) {
|
||||
printf("<br>%s: Database error: %s\n", p, mysql_error(mp));
|
||||
fprintf(stderr, "%s: Database error: %s\n", p, mysql_error(mp));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,28 +2,20 @@
|
|||
<h2>Setting up a data server</h2>
|
||||
|
||||
<p>
|
||||
The BOINC data server is implemented as an Apache
|
||||
or similar web server.
|
||||
Its upload function runs as a CGI program.
|
||||
It has been tested under Linux and Solaris.
|
||||
The BOINC data server is implemented using Apache
|
||||
or a similar web server.
|
||||
It is used both to upload and to download files.
|
||||
File download is handled by the web server, using GET operations.
|
||||
File upload is done by a CGI program, <b>file_upload_handler</b>.
|
||||
The host need not have access to the BOINC database.
|
||||
<p>
|
||||
You must copy the file upload authentication key
|
||||
to each data server.
|
||||
|
||||
<h3>Compiling the file upload handler</h3>
|
||||
<p>
|
||||
The upload handler, file_upload_handler,
|
||||
is compiled by the makefile in sched/.
|
||||
The following environment variables must be defined first:
|
||||
<pre>
|
||||
setenv BOINC_UPLOAD_DIR /users/barry/upload
|
||||
setenv BOINC_KEY_DIR /users/barry/keys
|
||||
</pre>
|
||||
<p>
|
||||
BOINC_UPLOAD_DIR is that path of the upload directory.
|
||||
BOINC_KEY_DIR is a directory containing the
|
||||
file upload authentication public key.
|
||||
The file upload handler uses a configuration of
|
||||
the same format as used by the
|
||||
<a href=sched_server_setup.html>scheduling server</a>.
|
||||
|
||||
<h3>Web server configuration</h3>
|
||||
<p>
|
||||
|
|
|
@ -4,40 +4,48 @@
|
|||
<p>
|
||||
The BOINC scheduling server runs as a CGI or fast CGI
|
||||
program under Apache or similar web server.
|
||||
It has been tested on Linux and Solaris.
|
||||
The host must have access to the BOINC database.
|
||||
The host must have access to the project's BOINC database.
|
||||
|
||||
<p>
|
||||
The scheduling server uses an auxiliary program
|
||||
called "feeder"; the two programs communicate
|
||||
through a shared-memory segment.
|
||||
The scheduling server uses an auxiliary program called "feeder";
|
||||
the two programs communicate through a shared-memory segment.
|
||||
<p>
|
||||
The scheduling server and feeder programs are compiled
|
||||
by typing "configure" and "make" in the sched/ directory.
|
||||
Prior to doing this, you must define
|
||||
the following environment variables:
|
||||
Both programs read a configuration file <b>config.xml</b>
|
||||
with the following form:
|
||||
<pre>
|
||||
setenv BOINC_DB_NAME boinc_barry
|
||||
setenv BOINC_DB_PASSWD
|
||||
setenv BOINC_SHMEM_KEY 0xdabacafe
|
||||
setenv BOINC_KEY_DIR /users/david/boinc_server/keys
|
||||
<config>
|
||||
<db_name>david_test</db_name>
|
||||
<db_passwd></db_passwd>
|
||||
<shmem_key>0xbeefacafe</shmem_key>
|
||||
<key_dir>/home/david/boinc_keys</key_dir>
|
||||
<upload_dir>/home/david/boinc_projects/test/upload</upload_dir>
|
||||
<user_name>david</user_name>
|
||||
</config>
|
||||
</pre>
|
||||
BOINC_DB_NAME and BOINC_DB_PASSWORD are the
|
||||
name and password of the BOINC database.
|
||||
The elements are as follows:
|
||||
<p>
|
||||
BOINC_SHMEM_KEY is the identifier of the
|
||||
shared-memory segment;
|
||||
<table border=1 cellpadding=10>
|
||||
<tr><td>db_name</td><td>The name of the BOINC database</td></tr>
|
||||
<tr><td>db_password</td><td>The password of the BOINC database</td></tr>
|
||||
<tr><td>shmem_key</td><td>
|
||||
The identifier of the shared-memory segment;
|
||||
it is an arbitrary 32-bit quantity,
|
||||
but must be unique among different BOINC servers
|
||||
sharing a single host.
|
||||
<p>
|
||||
BOINC_KEY_DIR is the directory containing
|
||||
</td></tr>
|
||||
<tr><td>key_dir</td><td>
|
||||
The directory containing
|
||||
the file upload authentication private key.
|
||||
|
||||
<p>
|
||||
If any of these variables changes,
|
||||
you must do a "make clean; make" in the sched directory.
|
||||
|
||||
</td></tr>
|
||||
<tr><td>upload_dir</td><td>
|
||||
The directory where uploaded files are stored
|
||||
(this is used by the <a href=data_server_setup.html>data server</a>).
|
||||
</td></tr>
|
||||
<tr><td>user_name</td><td>
|
||||
This name is prepended to web log error messages
|
||||
to distinguish between multiple servers on a single host.
|
||||
</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
You must modify your Apache config file
|
||||
to allow execution of the scheduling server.
|
||||
|
@ -52,4 +60,4 @@ ScriptAlias /boinc-cgi/ "/users/barry/cgi/"
|
|||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
</pre>
|
||||
</pre>
|
||||
|
|
|
@ -1,6 +1,19 @@
|
|||
<title>Test applications and scripts</title>
|
||||
<body bgcolor=ffffff>
|
||||
<h2>Test applications and scripts</h2>
|
||||
|
||||
<pre>
|
||||
setenv BOINC_PROJECTS_DIR /home/david/boinc_projects
|
||||
setenv BOINC_HOSTS_DIR /home/david/boinc_hosts
|
||||
setenv BOINC_USER_NAME david
|
||||
setenv BOINC_SRC_DIR /home/david/boinc_cvs/boinc
|
||||
setenv BOINC_CGI_DIR /home/david/cgi-bin
|
||||
setenv BOINC_CGI_URL http://localhost/cgi-bin
|
||||
setenv BOINC_HTML_DIR /home/david/html
|
||||
setenv BOINC_HTML_URL http://localhost
|
||||
setenv BOINC_KEY_DIR /home/david/boinc_keys
|
||||
setenv BOINC_PLATFORM i686-pc-linux-gnu
|
||||
</pre>
|
||||
<p>
|
||||
The <b>apps</b> directory contains the following test applications:
|
||||
<ul>
|
||||
|
@ -43,12 +56,3 @@ These scripts use functions defined in the PHP include file
|
|||
You can use these functions to easily write test
|
||||
scripts for your own applications.
|
||||
|
||||
<pre>
|
||||
setenv BOINC_DOWNLOAD_DIR ~/download
|
||||
setenv BOINC_UPLOAD_URL http://maggie.ssl.berkeley.edu/barry/cgi/file_upload_handler
|
||||
setenv BOINC_DOWNLOAD_URL http://maggie.ssl.berkeley.edu/barry/download
|
||||
setenv BOINC_PLATFORM sparc-sun-solaris2.7
|
||||
setenv BOINC_EMAIL barry@ssl.berkeley.edu
|
||||
setenv BOINC_USER barry
|
||||
setenv BOINC_MASTER_URL http:\\\\\/\\\\/maggie.ssl.berkeley.edu\\\\/~barry
|
||||
</pre>
|
|
@ -1,7 +1,9 @@
|
|||
<title>Setting up a web site</title>
|
||||
|
||||
<h2>Setting up a web site</h2>
|
||||
|
||||
<p>
|
||||
|
||||
|
||||
<h3>The master URL</h3>
|
||||
<p>
|
||||
Each project is publicly identified by a <b>master URL</b>.
|
||||
|
|
|
@ -13,6 +13,6 @@ create an account, then download the BOINC client.
|
|||
<li><a href=team.php>Teams</a></li>
|
||||
</ul>
|
||||
<!--
|
||||
<scheduler>http://localhost/davea_boinc_cgi/cgi</scheduler>
|
||||
<scheduler>SCHEDULER_URL</scheduler>
|
||||
-->
|
||||
</body>
|
||||
|
|
|
@ -33,7 +33,7 @@ int md5_file(char* path, char* output, double& nbytes) {
|
|||
nbytes = 0;
|
||||
f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
fprintf(stdout, "md5_file: can't open %s\n", path);
|
||||
fprintf(stderr, "md5_file: can't open %s\n", path);
|
||||
perror("md5_file");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ bool match_tag(char* buf, char* tag) {
|
|||
bool parse_int(char* buf, char* tag, int& x) {
|
||||
char* p = strstr(buf, tag);
|
||||
if (!p) return false;
|
||||
x = atoi(p+strlen(tag));
|
||||
x = strtol(p+strlen(tag), 0, 0); // this parses 0xabcd correctly
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,12 +9,6 @@ CFLAGS = -g -Wall @DEFS@ \
|
|||
-I@top_srcdir@/db \
|
||||
-I@top_srcdir@/lib \
|
||||
-I@top_srcdir@/tools \
|
||||
-DBOINC_DB_NAME=\"$(BOINC_DB_NAME)\" \
|
||||
-DBOINC_DB_PASSWD=\"$(BOINC_DB_PASSWD)\" \
|
||||
-DBOINC_SHMEM_KEY=$(BOINC_SHMEM_KEY) \
|
||||
-DBOINC_KEY_DIR=\"$(BOINC_KEY_DIR)\" \
|
||||
-DBOINC_UPLOAD_DIR=\"$(BOINC_UPLOAD_DIR)\" \
|
||||
-DBOINC_USER=\"$(BOINC_USER)\" \
|
||||
-I/usr/local/mysql/include \
|
||||
-I@top_srcdir@/RSAEuro/source \
|
||||
|
||||
|
@ -22,7 +16,7 @@ CC = g++ $(CFLAGS)
|
|||
|
||||
CLIBS = @LIBS@
|
||||
|
||||
PROGS = cgi feeder show_shmem file_upload_handler fcgi validate_test
|
||||
PROGS = cgi feeder show_shmem file_upload_handler validate_test
|
||||
|
||||
all: $(PROGS)
|
||||
|
||||
|
@ -31,6 +25,7 @@ CGI_OBJS = \
|
|||
main.o \
|
||||
sched_shmem.o \
|
||||
server_types.o \
|
||||
config.o \
|
||||
../db/db_mysql.o \
|
||||
../db/mysql_util.o \
|
||||
../lib/shmem.o \
|
||||
|
@ -39,8 +34,10 @@ CGI_OBJS = \
|
|||
FEEDER_OBJS = \
|
||||
feeder.o \
|
||||
sched_shmem.o \
|
||||
config.o \
|
||||
../db/db_mysql.o \
|
||||
../db/mysql_util.o \
|
||||
../lib/parse.o \
|
||||
../lib/shmem.o
|
||||
|
||||
SHOW_SHMEM_OBJS = \
|
||||
|
@ -52,6 +49,7 @@ SHOW_SHMEM_OBJS = \
|
|||
|
||||
FILE_UPLOAD_OBJS = \
|
||||
file_upload_handler.o \
|
||||
config.o \
|
||||
../lib/crypt.o \
|
||||
../lib/parse.o \
|
||||
../lib/md5.o \
|
||||
|
@ -61,6 +59,7 @@ FILE_UPLOAD_OBJS = \
|
|||
VALIDATE_OBJS = \
|
||||
validate.o \
|
||||
validate_test.o \
|
||||
config.o \
|
||||
../db/db_mysql.o \
|
||||
../db/mysql_util.o \
|
||||
../lib/parse.o
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parse.h"
|
||||
#include "error_numbers.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
int CONFIG::parse(FILE* in) {
|
||||
char buf[256];
|
||||
|
||||
memset(this, 0, sizeof(CONFIG));
|
||||
while (fgets(buf, 256, in)) {
|
||||
if (match_tag(buf, "</config>")) return 0;
|
||||
else if (parse_str(buf, "<db_name>", db_name, sizeof(db_name))) continue;
|
||||
else if (parse_str(buf, "<db_passwd>", db_passwd, sizeof(db_passwd))) continue;
|
||||
else if (parse_int(buf, "<shmem_key>", shmem_key)) continue;
|
||||
else if (parse_str(buf, "<key_dir>", key_dir, sizeof(key_dir))) continue;
|
||||
else if (parse_str(buf, "<upload_dir>", upload_dir, sizeof(upload_dir))) continue;
|
||||
else if (parse_str(buf, "<user_name>", user_name, sizeof(user_name))) continue;
|
||||
}
|
||||
return ERR_XML_PARSE;
|
||||
}
|
||||
|
||||
int CONFIG::parse_file() {
|
||||
FILE* f;
|
||||
|
||||
f = fopen("config.xml", "r");
|
||||
if (!f) return ERR_FOPEN;
|
||||
return parse(f);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
// info needed by server-side software
|
||||
//
|
||||
class CONFIG {
|
||||
public:
|
||||
char db_name[256];
|
||||
char db_passwd[256];
|
||||
int shmem_key;
|
||||
char key_dir[256];
|
||||
char upload_dir[256];
|
||||
char user_name[256];
|
||||
|
||||
int parse(FILE*);
|
||||
int parse_file();
|
||||
};
|
|
@ -51,11 +51,14 @@
|
|||
|
||||
#include "db.h"
|
||||
#include "shmem.h"
|
||||
#include "config.h"
|
||||
#include "sched_shmem.h"
|
||||
|
||||
#define RESULTS_PER_ENUM 100
|
||||
#define TRIGGER_FILENAME "feeder_trigger"
|
||||
|
||||
CONFIG config;
|
||||
|
||||
int check_trigger(SCHED_SHMEM* ssp) {
|
||||
FILE* f;
|
||||
char buf[256];
|
||||
|
@ -66,7 +69,7 @@ int check_trigger(SCHED_SHMEM* ssp) {
|
|||
fclose(f);
|
||||
if (!strcmp(buf, "<quit/>\n")) {
|
||||
detach_shmem((void*)ssp);
|
||||
destroy_shmem(BOINC_SHMEM_KEY);
|
||||
destroy_shmem(config.shmem_key);
|
||||
unlink(TRIGGER_FILENAME);
|
||||
exit(0);
|
||||
} else if (!strcmp(buf, "<reread_db/>\n")) {
|
||||
|
@ -175,25 +178,31 @@ int main(int argc, char** argv) {
|
|||
bool asynch = false;
|
||||
void* p;
|
||||
|
||||
retval = config.parse_file();
|
||||
if (retval) {
|
||||
fprintf(stderr, "feeder: can't parse config file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i=1; i<argc; i++) {
|
||||
if (!strcmp(argv[i], "-asynch")) {
|
||||
asynch = true;
|
||||
}
|
||||
}
|
||||
|
||||
retval = destroy_shmem(BOINC_SHMEM_KEY);
|
||||
retval = destroy_shmem(config.shmem_key);
|
||||
if (retval) {
|
||||
fprintf(stderr, "feeder: can't destroy shmem\n");
|
||||
exit(1);
|
||||
}
|
||||
retval = create_shmem(BOINC_SHMEM_KEY, sizeof(SCHED_SHMEM), &p);
|
||||
retval = create_shmem(config.shmem_key, sizeof(SCHED_SHMEM), &p);
|
||||
if (retval) {
|
||||
fprintf(stderr, "feeder: can't create shmem\n");
|
||||
exit(1);
|
||||
}
|
||||
ssp = (SCHED_SHMEM*)p;
|
||||
ssp->init();
|
||||
retval = db_open(getenv("BOINC_DB_NAME"), getenv("BOINC_DB_PASSWD"));
|
||||
retval = db_open(config.db_name, config.db_passwd);
|
||||
if (retval) {
|
||||
fprintf(stderr, "feeder: db_open: %d\n", retval);
|
||||
exit(1);
|
||||
|
|
|
@ -58,8 +58,11 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include "parse.h"
|
||||
#include "config.h"
|
||||
#include "crypt.h"
|
||||
|
||||
CONFIG config;
|
||||
|
||||
#define MAX_FILES 32
|
||||
|
||||
struct FILE_INFO {
|
||||
|
@ -86,7 +89,7 @@ int FILE_INFO::parse(FILE* in) {
|
|||
strcatdup(signed_xml, buf);
|
||||
if (parse_str(buf, "<name>", name, sizeof(name))) continue;
|
||||
if (parse_double(buf, "<max_nbytes>", max_nbytes)) continue;
|
||||
//fprintf(stderr, "file_upload_handler (%s): FILE_INFO::parse: unrecognized: %s \n", BOINC_USER, buf);
|
||||
//fprintf(stderr, "file_upload_handler (%s): FILE_INFO::parse: unrecognized: %s \n", config.user, buf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -97,7 +100,7 @@ int print_status(int status, char* message) {
|
|||
printf("<error>%s</error>\n", message);
|
||||
fprintf(stderr,
|
||||
"file_upload_handler (%s): status %d: %s>\n",
|
||||
BOINC_USER, status, message
|
||||
config.user_name, status, message
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
|
@ -164,7 +167,7 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) {
|
|||
if (retval) {
|
||||
fprintf(stderr,
|
||||
"file_upload_handler (%s): FILE_INFO.parse\n",
|
||||
BOINC_USER
|
||||
config.user_name
|
||||
);
|
||||
return retval;
|
||||
}
|
||||
|
@ -182,7 +185,7 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) {
|
|||
struct stat sbuf;
|
||||
// TODO: check to ensure path doesn't point somewhere bad
|
||||
//
|
||||
sprintf( path, "%s/%s", BOINC_UPLOAD_DIR, file_name );
|
||||
sprintf(path, "%s/%s", config.upload_dir, file_name );
|
||||
retval = stat( path, &sbuf );
|
||||
if (retval && errno != ENOENT) {
|
||||
print_status( -1, "cannot open file" );
|
||||
|
@ -226,12 +229,12 @@ int handle_request(FILE* in, R_RSA_PUBLIC_KEY& key) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
sprintf(path, "%s/%s", BOINC_UPLOAD_DIR, file_info.name);
|
||||
sprintf(path, "%s/%s", config.upload_dir, file_info.name);
|
||||
retval = copy_socket_to_file(in, path, offset, nbytes);
|
||||
if (retval) {
|
||||
fprintf(stderr,
|
||||
"file_upload_handler (%s): copy_socket_to_file %d %s\n",
|
||||
BOINC_USER, retval, path
|
||||
config.user_name, retval, path
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
@ -244,7 +247,7 @@ int get_key(R_RSA_PUBLIC_KEY& key) {
|
|||
FILE* f;
|
||||
int retval;
|
||||
char buf[256];
|
||||
sprintf(buf, "%s/upload_public", BOINC_KEY_DIR);
|
||||
sprintf(buf, "%s/upload_public", config.key_dir);
|
||||
f = fopen(buf, "r");
|
||||
if (!f) return -1;
|
||||
retval = scan_key_hex(f, (KEY*)&key, sizeof(key));
|
||||
|
@ -257,9 +260,14 @@ int main() {
|
|||
int retval;
|
||||
R_RSA_PUBLIC_KEY key;
|
||||
|
||||
retval = config.parse_file();
|
||||
if (retval) {
|
||||
print_status(-1, "can't read config file");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
retval = get_key(key);
|
||||
if (retval) {
|
||||
fprintf(stderr, "file_upload_handler: can't read key file\n");
|
||||
print_status(-1, "can't read key file");
|
||||
exit(0);
|
||||
}
|
||||
|
|
53
sched/main.C
53
sched/main.C
|
@ -29,6 +29,8 @@ using namespace std;
|
|||
#include "db.h"
|
||||
#include "parse.h"
|
||||
#include "shmem.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "server_types.h"
|
||||
#include "handle_request.h"
|
||||
#include "main.h"
|
||||
|
@ -64,22 +66,29 @@ int main() {
|
|||
unsigned int counter=0;
|
||||
char* code_sign_key;
|
||||
bool found;
|
||||
CONFIG config;
|
||||
|
||||
sprintf(path, "%s/code_sign_public", BOINC_KEY_DIR);
|
||||
retval = config.parse_file();
|
||||
if (retval) {
|
||||
fprintf(stderr, "Can't parse config file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sprintf(path, "%s/code_sign_public", config.key_dir);
|
||||
retval = read_file_malloc(path, code_sign_key);
|
||||
if (retval) {
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't read code sign key file (%s)\n",
|
||||
BOINC_USER, path
|
||||
config.user_name, path
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
retval = attach_shmem(BOINC_SHMEM_KEY, &p);
|
||||
retval = attach_shmem(config.shmem_key, &p);
|
||||
if (retval) {
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't attach shmem\n",
|
||||
BOINC_USER
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -88,7 +97,7 @@ int main() {
|
|||
if (retval) {
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): shmem has wrong struct sizes - recompile\n",
|
||||
BOINC_USER
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -97,23 +106,23 @@ int main() {
|
|||
if (ssp->ready) break;
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): waiting for ready flag\n",
|
||||
BOINC_USER
|
||||
config.user_name
|
||||
);
|
||||
sleep(1);
|
||||
}
|
||||
if (!ssp->ready) {
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): feeder doesn't seem to be running\n",
|
||||
BOINC_USER
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
//fprintf(stderr, "got ready flag\n");
|
||||
retval = db_open(BOINC_DB_NAME, BOINC_DB_PASSWD);
|
||||
retval = db_open(config.db_name, config.db_passwd);
|
||||
if (retval) {
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't open database\n",
|
||||
BOINC_USER
|
||||
config.user_name
|
||||
);
|
||||
return_error("can't open database");
|
||||
exit(1);
|
||||
|
@ -126,7 +135,7 @@ int main() {
|
|||
if (!found) {
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't find project\n",
|
||||
BOINC_USER
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -141,24 +150,40 @@ int main() {
|
|||
fprintf(stdout, "Content-type: text/plain\n\n");
|
||||
fout = fopen(req_path, "w");
|
||||
if (!fout) {
|
||||
exit(return_error("Compiled by BOINC_USER: can't write request file"));
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't write request file",
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
copy_stream(stdin, fout);
|
||||
fclose(fout);
|
||||
fin = fopen(req_path, "r");
|
||||
if (!fin) {
|
||||
exit(return_error("Compiled by BOINC_USER: can't read request file"));
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't read request file",
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
fout = fopen(reply_path, "w");
|
||||
if (!fout) {
|
||||
exit(return_error("Compiled by BOINC_USER: can't write reply file"));
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't write reply file",
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
handle_request(fin, fout, *ssp, code_sign_key);
|
||||
fclose(fin);
|
||||
fclose(fout);
|
||||
fin = fopen(reply_path, "r");
|
||||
if (!fin) {
|
||||
exit(return_error("Compiled by BOINC_USER: can't read reply file"));
|
||||
fprintf(stderr,
|
||||
"BOINC scheduler (%s): can't read reply file",
|
||||
config.user_name
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
copy_stream(fin, stdout);
|
||||
fclose(fin);
|
||||
|
|
|
@ -42,10 +42,13 @@
|
|||
#include <vector>
|
||||
|
||||
#include "db.h"
|
||||
#include "config.h"
|
||||
|
||||
extern int check_set(vector<RESULT>, int& canonical, double& credit);
|
||||
extern int check_pair(RESULT&, RESULT&, bool&);
|
||||
|
||||
CONFIG config;
|
||||
|
||||
#define SECONDS_IN_DAY (3600*24)
|
||||
#define EXP_DECAY_RATE (1./(SECONDS_IN_DAY*7))
|
||||
|
||||
|
@ -179,7 +182,12 @@ int main(int argc, char** argv) {
|
|||
APP app;
|
||||
bool did_something;
|
||||
|
||||
retval = db_open(getenv("BOINC_DB_NAME"), getenv("BOINC_DB_PASSWD"));
|
||||
retval = config.parse_file();
|
||||
if (retval) {
|
||||
fprintf(stderr, "Can't parse config file\n");
|
||||
exit(1);
|
||||
}
|
||||
retval = db_open(config.db_name, config.db_passwd);
|
||||
if (retval) {
|
||||
fprintf(stderr, "validate: db_open: %d\n", retval);
|
||||
exit(1);
|
||||
|
|
|
@ -20,8 +20,11 @@
|
|||
#include <vector>
|
||||
|
||||
#include "db.h"
|
||||
#include "config.h"
|
||||
#include "parse.h"
|
||||
|
||||
extern CONFIG config;
|
||||
|
||||
// get the name of a result's (first) output file
|
||||
//
|
||||
void get_output_file_path(RESULT& result, char* path) {
|
||||
|
@ -31,7 +34,7 @@ void get_output_file_path(RESULT& result, char* path) {
|
|||
strcpy(path, "");
|
||||
retval = parse_str(result.xml_doc_in, "<name>", buf, sizeof(buf));
|
||||
if (retval) return;
|
||||
char* upload_dir = getenv("BOINC_UPLOAD_DIR");
|
||||
char* upload_dir = config.upload_dir;
|
||||
sprintf(path, "%s/%s", upload_dir, buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
|
||||
// test.inc
|
||||
//
|
||||
// A set of classes for testing BOINC.
|
||||
// These classes let you create multiple projects and multiple hosts
|
||||
// (all running on a single machine),
|
||||
// add applications and work units, run the system,
|
||||
// and verify that the results are correct.
|
||||
//
|
||||
// See doc/test.html for details
|
||||
|
||||
// get an enviroment variable, and abort script if missing
|
||||
//
|
||||
function get_env_var($name) {
|
||||
$x = getenv($name);
|
||||
if ($x == null) {
|
||||
echo "Environment variable $name not defined\n";
|
||||
exit();
|
||||
}
|
||||
return $x;
|
||||
}
|
||||
|
||||
function run_db_script($script, $db_name) {
|
||||
$db_dir = get_env_var("BOINC_SRC_DIR")."/db";
|
||||
$x = "sed -e s/BOINC_DB_NAME/$db_name/ $db_dir/$script | mysql";
|
||||
//echo $x;
|
||||
PassThru($x);
|
||||
}
|
||||
|
||||
function db_open($db_name) {
|
||||
$retval = mysql_connect();
|
||||
if (!$retval) {
|
||||
echo "mysql_connect() failed\n";
|
||||
exit();
|
||||
}
|
||||
$retval = mysql_select_db($db_name);
|
||||
if (!$retval) {
|
||||
echo "mysql_select_db() failed\n";
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
function db_query($query) {
|
||||
if (!mysql_query($query)) {
|
||||
echo "mysql_query failed: $query\n";
|
||||
echo mysql_error();
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
function run_tool($cmd) {
|
||||
$tool_dir = get_env_var("BOINC_SRC_DIR")."/tools/";
|
||||
$cmd = $tool_dir.$cmd;
|
||||
PassThru($cmd);
|
||||
}
|
||||
|
||||
class App {
|
||||
var $name;
|
||||
|
||||
function App($name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
|
||||
class App_Version {
|
||||
var $app;
|
||||
var $version;
|
||||
var $exec_name;
|
||||
|
||||
function App_Version($app) {
|
||||
$this->app = $app;
|
||||
$this->version = 1;
|
||||
$this->exec_name = $app->name;
|
||||
}
|
||||
}
|
||||
|
||||
class Project {
|
||||
var $name;
|
||||
var $users;
|
||||
var $apps;
|
||||
var $app_versions;
|
||||
var $project_dir;
|
||||
var $db_name;
|
||||
var $generate_keys;
|
||||
var $shmem_key;
|
||||
var $key_dir;
|
||||
var $download_url;
|
||||
var $scheduler_url;
|
||||
var $upload_url;
|
||||
var $user_name;
|
||||
var $master_url;
|
||||
|
||||
function Project() {
|
||||
$this->name = "test";
|
||||
$this->users = array();
|
||||
$this->apps = array();
|
||||
$this->app_versions = array();
|
||||
$this->generate_keys = false;
|
||||
$this->shmem_key = "0xbeefacafe";
|
||||
}
|
||||
|
||||
function add_user($user) {
|
||||
array_push($this->users, $user);
|
||||
}
|
||||
|
||||
function add_app($app) {
|
||||
array_push($this->apps, $app);
|
||||
}
|
||||
|
||||
function add_app_version($app_version) {
|
||||
array_push($this->app_versions, $app_version);
|
||||
}
|
||||
|
||||
// Set up the database and directory structures for a project
|
||||
//
|
||||
function Install() {
|
||||
$base_dir = get_env_var("BOINC_PROJECTS_DIR");
|
||||
$source_dir = get_env_var("BOINC_SRC_DIR");
|
||||
$this->download_url = get_env_var("BOINC_HTML_URL")."/".$this->name."/download";
|
||||
$this->upload_url = get_env_var("BOINC_CGI_URL")."/".$this->name."/file_upload_handler";
|
||||
$this->scheduler_url = get_env_var("BOINC_CGI_URL")."/".$this->name."/cgi";
|
||||
$this->project_dir = $base_dir."/".$this->name;
|
||||
$this->master_url = get_env_var("BOINC_HTML_URL")."/".$this->name."/html_user/index.html";
|
||||
PassThru("rm -rf $this->project_dir");
|
||||
PassThru("mkdir $this->project_dir");
|
||||
PassThru("mkdir $this->project_dir/cgi");
|
||||
PassThru("mkdir $this->project_dir/upload; chmod uog+w $this->project_dir/upload");
|
||||
PassThru("mkdir $this->project_dir/download");
|
||||
PassThru("mkdir $this->project_dir/keys");
|
||||
PassThru("mkdir $this->project_dir/html_ops");
|
||||
PassThru("mkdir $this->project_dir/html_user");
|
||||
|
||||
if ($this->generate_keys) {
|
||||
} else {
|
||||
$this->key_dir = get_env_var("BOINC_KEY_DIR");
|
||||
PassThru("cp $this->key_dir/* $this->project_dir/keys");
|
||||
}
|
||||
|
||||
// set up the database
|
||||
//
|
||||
$this->user_name = get_env_var("BOINC_USER_NAME");
|
||||
$this->db_name = $this->user_name."_".$this->name;
|
||||
run_db_script("drop.sql", $this->db_name);
|
||||
run_db_script("schema.sql", $this->db_name);
|
||||
run_db_script("constraints.sql", $this->db_name);
|
||||
|
||||
db_open($this->db_name);
|
||||
db_query("insert into project(name) values('$this->name')");
|
||||
|
||||
$platform = get_env_var("BOINC_PLATFORM");
|
||||
db_query("insert into platform(name) values('$platform')");
|
||||
|
||||
for ($i=0; $i<sizeof($this->users); $i++) {
|
||||
$user = $this->users[$i];
|
||||
$now = time(0);
|
||||
db_query("insert into user values (0, $now, '$user->email_addr', '$user->name', 'foobar', '$user->authenticator', 'Peru', '12345', 0, 0, 0, '', '', 0)");
|
||||
}
|
||||
|
||||
echo "adding apps\n";
|
||||
for ($i=0; $i<sizeof($this->apps); $i++) {
|
||||
$app = $this->apps[$i];
|
||||
db_query("insert into app(name, create_time) values ('$app->name', $now)");
|
||||
}
|
||||
|
||||
echo "adding app versions\n";
|
||||
for ($i=0; $i<sizeof($this->app_versions); $i++) {
|
||||
$app_version = $this->app_versions[$i];
|
||||
$app = $app_version->app;
|
||||
run_tool("add app_version -db_name $this->db_name -app_name $app->name -platform_name $platform -version $app_version->version -download_dir $this->project_dir/download -download_url $this->download_url -code_sign_keyfile $this->key_dir/code_sign_private -exec_dir $source_dir/apps -exec_files $app_version->exec_name");
|
||||
}
|
||||
|
||||
// copy the CGI programs and feeder to the project dir,
|
||||
// and make a config file there
|
||||
//
|
||||
PassThru("cp $source_dir/sched/cgi $this->project_dir/cgi/");
|
||||
PassThru("cp $source_dir/sched/file_upload_handler $this->project_dir/cgi/");
|
||||
PassThru("cp $source_dir/sched/feeder $this->project_dir/cgi/");
|
||||
$f = fopen("$this->project_dir/cgi/config.xml", "w");
|
||||
fputs($f, "<config>\n");
|
||||
fputs($f, " <db_name>$this->db_name</db_name>\n");
|
||||
fputs($f, " <db_passwd>$this->db_passwd</db_passwd>\n");
|
||||
fputs($f, " <shmem_key>$this->shmem_key</shmem_key>\n");
|
||||
fputs($f, " <key_dir>$this->key_dir</key_dir>\n");
|
||||
fputs($f, " <upload_dir>$this->project_dir/upload</upload_dir>\n");
|
||||
fputs($f, " <user_name>$this->user_name</user_name>\n");
|
||||
fputs($f, "</config>\n");
|
||||
fclose($f);
|
||||
|
||||
// copy the user and administrative PHP files to the project dir,
|
||||
//
|
||||
PassThru("cp -f $source_dir/html_user/* $this->project_dir/html_user");
|
||||
PassThru("cp -f $source_dir/html_ops/* $this->project_dir/html_ops");
|
||||
|
||||
// put a file with the database name in each directory
|
||||
//
|
||||
$f = fopen("$this->project_dir/html_user/db_name", "w");
|
||||
fputs($f, "$this->db_name\n");
|
||||
fclose($f);
|
||||
$f = fopen("$this->project_dir/html_ops/db_name", "w");
|
||||
fputs($f, "$this->db_name\n");
|
||||
fclose($f);
|
||||
|
||||
// edit "index.html" in the user directory to have
|
||||
// the right scheduler URL
|
||||
//
|
||||
$u = str_replace("/", "\\\/", $this->scheduler_url);
|
||||
$x = "sed -e s/SCHEDULER_URL/$u/ $this->project_dir/html_user/index.html > temp; mv temp $this->project_dir/html_user/index.html";
|
||||
echo "$x\n";
|
||||
PassThru($x);
|
||||
|
||||
// create symbolic links to the CGI and HTML directories
|
||||
//
|
||||
$cgi_dir = get_env_var("BOINC_CGI_DIR");
|
||||
$cgi_url = get_env_var("BOINC_CGI_URL");
|
||||
$html_dir = get_env_var("BOINC_HTML_DIR");
|
||||
$html_url = get_env_var("BOINC_HTML_URL");
|
||||
PassThru("rm -f $cgi_dir/$this->name");
|
||||
PassThru("ln -s $this->project_dir/cgi $cgi_dir/$this->name");
|
||||
PassThru("rm -f $html_dir/$this->name");
|
||||
PassThru("ln -s $this->project_dir $html_dir/$this->name");
|
||||
}
|
||||
|
||||
function start(){
|
||||
PassThru("cd $this->project_dir/cgi; feeder -asynch > feeder_out");
|
||||
}
|
||||
|
||||
function stop() {
|
||||
$f = fopen($this->project_dir."/cgi/feeder_trigger", "w");
|
||||
fputs($f, "<quit/>\n");
|
||||
fclose($f);
|
||||
}
|
||||
|
||||
function check_results_done() {
|
||||
db_open($this->db_name);
|
||||
$result = mysql_query("select * from result where state<>4");
|
||||
while ($x = mysql_fetch_object($result)) {
|
||||
echo "result $x->id is not done\n";
|
||||
}
|
||||
}
|
||||
|
||||
function compare_file($result, $correct) {
|
||||
PassThru("diff $this->project_dir/upload/$result $correct", $retval);
|
||||
if ($retval) {
|
||||
echo "File mismatch: $out $correct\n";
|
||||
} else {
|
||||
echo "Files match: $out $correct\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class User {
|
||||
var $name;
|
||||
var $authenticator;
|
||||
|
||||
function User() {
|
||||
$this->name = "John";
|
||||
$this->email_addr = "john@boinc.org";
|
||||
$this->authenticator = "3f7b90793a0175ad0bda68684e8bd136";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Host {
|
||||
var $name;
|
||||
var $projects;
|
||||
var $user;
|
||||
var $host_dir;
|
||||
|
||||
function Host($user) {
|
||||
$this->user = $user;
|
||||
$this->name = "test";
|
||||
$this->projects = array();
|
||||
}
|
||||
|
||||
function add_project($project) {
|
||||
array_push($this->projects, $project);
|
||||
}
|
||||
|
||||
function install() {
|
||||
$base_dir = get_env_var("BOINC_HOSTS_DIR");
|
||||
$this->host_dir = $base_dir."/".$this->name;
|
||||
$user = $this->user;
|
||||
PassThru("rm -rf $this->host_dir");
|
||||
PassThru("mkdir $this->host_dir");
|
||||
|
||||
// create account files
|
||||
//
|
||||
echo "creating account files\n";
|
||||
for ($i=0; $i<sizeof($this->projects); $i++) {
|
||||
$project = $this->projects[$i];
|
||||
$encoded_name = strtr($project->name, "/", "_");
|
||||
echo "writing $this->host_dir/account_$encoded_name.xml\n";
|
||||
$f = fopen($this->host_dir."/account_$encoded_name.xml", "w");
|
||||
fputs($f, "<account>\n");
|
||||
fputs($f, " <master_url>$project->master_url</master_url>\n");
|
||||
fputs($f, " <authenticator>$user->authenticator</authenticator>\n");
|
||||
fputs($f, " <resource_share>1</resource_share>\n");
|
||||
fputs($f, "</account>\n");
|
||||
fclose($f);
|
||||
}
|
||||
|
||||
// copy log_flags.xml
|
||||
//
|
||||
PassThru("cp log_flags.xml $this->host_dir");
|
||||
}
|
||||
|
||||
function run($args) {
|
||||
echo "Running core client\n";
|
||||
$source_dir = get_env_var("BOINC_SRC_DIR");
|
||||
$platform = get_env_var("BOINC_PLATFORM");
|
||||
PassThru("cd $this->host_dir; $source_dir/client/boinc_1_$platform $args");
|
||||
}
|
||||
}
|
||||
|
||||
class Work {
|
||||
var $project;
|
||||
var $app;
|
||||
var $wu_template;
|
||||
var $result_template;
|
||||
var $nresults;
|
||||
var $input_files;
|
||||
|
||||
function Work($project, $app) {
|
||||
$this->project = $project;
|
||||
$this->app = $app;
|
||||
$this->input_files = array();
|
||||
}
|
||||
|
||||
function install() {
|
||||
$project = $this->project;
|
||||
$app = $this->app;
|
||||
for ($i=0; $i<sizeof($this->input_files); $i++) {
|
||||
$x = $this->input_files[$i];
|
||||
PassThru("cp $x $project->project_dir/download");
|
||||
}
|
||||
$cmd = "create_work -db_name $project->db_name -download_dir $project->project_dir/download -upload_url $project->upload_url -download_url $project->download_url/ -keyfile $project->key_dir/upload_private -appname $app->name -rsc_iops 180000000000.0 -rsc_fpops 0.0 -wu_name $this->wu_template -wu_template $this->wu_template -result_template $this->result_template -nresults $this->nresults ";
|
||||
for ($i=0; $i<sizeof($this->input_files); $i++) {
|
||||
$x = $this->input_files[$i];
|
||||
$cmd = $cmd." ".$x;
|
||||
}
|
||||
run_tool($cmd);
|
||||
}
|
||||
}
|
|
@ -1,33 +1,35 @@
|
|||
#! /usr/local/bin/php
|
||||
<?php
|
||||
// test the uc (upper-case) application
|
||||
//
|
||||
// You must have done "make" in all source directories
|
||||
include_once("test.inc");
|
||||
|
||||
include_once("init.inc");
|
||||
$project = new Project;
|
||||
$user = new User();
|
||||
$host = new Host($user);
|
||||
$app = new App("upper_case");
|
||||
$app_version = new App_Version($app);
|
||||
|
||||
check_env_vars();
|
||||
clear_db();
|
||||
if (true) {
|
||||
clear_server_dirs(false);
|
||||
} else {
|
||||
clear_server_dirs(true);
|
||||
create_keys();
|
||||
}
|
||||
clear_client_dirs();
|
||||
init_client_dirs("prefs1.xml", "account1.xml");
|
||||
copy_to_download_dir("input");
|
||||
add_project("Test Project");
|
||||
add_platform(null);
|
||||
add_user(null);
|
||||
add_app("upper_case", null, null);
|
||||
add_core_client(null);
|
||||
create_work("-appname upper_case -rsc_iops 180000000000.0 -rsc_fpops 0.0 -wu_name uc_wu -wu_template uc_wu -result_template uc_result -nresults 2 input input input input input");
|
||||
start_feeder();
|
||||
//run_client("-exit_after 10");
|
||||
run_client("-exit_when_idle");
|
||||
stop_feeder();
|
||||
check_results_done();
|
||||
compare_file("uc_wu_0_0", "uc_correct_output");
|
||||
compare_file("uc_wu_1_0", "uc_correct_output");
|
||||
$project->add_user($user);
|
||||
$project->add_app($app);
|
||||
$project->add_app_version($app_version);
|
||||
$project->install(); // must install projects before adding to hosts
|
||||
|
||||
$host->add_project($project);
|
||||
$host->install();
|
||||
|
||||
echo "adding work\n";
|
||||
|
||||
$work = new Work($project, $app);
|
||||
$work->wu_template = "uc_wu";
|
||||
$work->result_template = "uc_result";
|
||||
$work->nresults = 2;
|
||||
array_push($work->input_files, "input");
|
||||
$work->install();
|
||||
|
||||
$project->start();
|
||||
$host->run("-exit_when_idle");
|
||||
$project->stop();
|
||||
|
||||
$project->check_results_done();
|
||||
$project->compare_file("uc_wu_0_0", "uc_correct_output");
|
||||
$project->compare_file("uc_wu_1_0", "uc_correct_output");
|
||||
?>
|
||||
|
|
19
tools/add.C
19
tools/add.C
|
@ -57,11 +57,11 @@ int version, retval, nexec_files;
|
|||
double nbytes;
|
||||
bool signed_exec_files;
|
||||
char buf[256], md5_cksum[64];
|
||||
char *app_name=0, *platform_name=0, *project_name=0;
|
||||
char *db_name=0, *db_passwd=0, *app_name=0, *platform_name=0, *project_name=0;
|
||||
char* exec_dir=0, *exec_files[10], *signature_files[10];
|
||||
char *email_addr=0, *user_name=0, *web_password=0, *authenticator=0;
|
||||
char *global_prefs_file=0, *download_dir, *download_url;
|
||||
char* code_sign_keyfile;
|
||||
char* code_sign_keyfile=0;
|
||||
char *message=0, *message_priority=0;
|
||||
|
||||
void add_project() {
|
||||
|
@ -248,12 +248,12 @@ void add_user() {
|
|||
int main(int argc, char** argv) {
|
||||
int i, retval;
|
||||
|
||||
retval = db_open(getenv("BOINC_DB_NAME"), getenv("BOINC_DB_PASSWD"));
|
||||
if (retval) {
|
||||
printf("can't open DB %s\n", getenv("BOINC_DB_NAME"));
|
||||
}
|
||||
for (i=2; i<argc; i++) {
|
||||
if (!strcmp(argv[i], "-project_name")) {
|
||||
if (!strcmp(argv[i], "-db_name")) {
|
||||
db_name = argv[++i];
|
||||
} else if (!strcmp(argv[i], "-db_passwd")) {
|
||||
db_passwd = argv[++i];
|
||||
} else if (!strcmp(argv[i], "-project_name")) {
|
||||
i++;
|
||||
project_name = argv[i];
|
||||
} else if (!strcmp(argv[i], "-app_name")) {
|
||||
|
@ -321,6 +321,11 @@ int main(int argc, char** argv) {
|
|||
code_sign_keyfile = argv[i];
|
||||
}
|
||||
}
|
||||
retval = db_open(db_name, db_passwd);
|
||||
if (retval) {
|
||||
fprintf(stderr, "can't open DB %s\n", db_name);
|
||||
exit(1);
|
||||
}
|
||||
if (!strcmp(argv[1], "project")) {
|
||||
add_project();
|
||||
} else if (!strcmp(argv[1], "app")) {
|
||||
|
|
|
@ -61,12 +61,13 @@ int read_filename(char* path, char* buf) {
|
|||
//
|
||||
static int process_wu_template(
|
||||
char* wu_name, char* tmplate, char* out,
|
||||
char* dirpath, char** infiles, int n
|
||||
char* dirpath, char** infiles, int n,
|
||||
char* upload_url, char* download_url
|
||||
) {
|
||||
char* p;
|
||||
char buf[MAX_BLOB_SIZE], md5[33], path[256];
|
||||
bool found;
|
||||
int i;
|
||||
int i, retval;
|
||||
double nbytes;
|
||||
assert(wu_name!=NULL);
|
||||
assert(tmplate!=NULL);
|
||||
|
@ -82,7 +83,7 @@ static int process_wu_template(
|
|||
found = true;
|
||||
i = atoi(p+strlen(INFILE_MACRO));
|
||||
if (i >= n) {
|
||||
fprintf(stderr, "invalid file number\n");
|
||||
fprintf(stderr, "process_wu_template: invalid file number\n");
|
||||
return 1;
|
||||
}
|
||||
strcpy(buf, p+strlen(INFILE_MACRO)+1+2); // assume <= 10 files
|
||||
|
@ -93,14 +94,14 @@ static int process_wu_template(
|
|||
if (p) {
|
||||
found = true;
|
||||
strcpy(buf, p+strlen(UPLOAD_URL_MACRO));
|
||||
strcpy(p, getenv("BOINC_UPLOAD_URL"));
|
||||
strcpy(p, upload_url);
|
||||
strcat(p, buf);
|
||||
}
|
||||
p = strstr(out, DOWNLOAD_URL_MACRO);
|
||||
if (p) {
|
||||
found = true;
|
||||
strcpy(buf, p+strlen(DOWNLOAD_URL_MACRO));
|
||||
strcpy(p, getenv("BOINC_DOWNLOAD_URL"));
|
||||
strcpy(p, download_url);
|
||||
strcat(p, buf);
|
||||
}
|
||||
p = strstr(out, MD5_MACRO);
|
||||
|
@ -108,11 +109,15 @@ static int process_wu_template(
|
|||
found = true;
|
||||
i = atoi(p+strlen(MD5_MACRO));
|
||||
if (i >= n) {
|
||||
fprintf(stderr, "invalid file number\n");
|
||||
fprintf(stderr, "process_wu_template: invalid file number\n");
|
||||
return 1;
|
||||
}
|
||||
sprintf(path, "%s/%s", dirpath, infiles[i]);
|
||||
md5_file(path, md5, nbytes);
|
||||
retval = md5_file(path, md5, nbytes);
|
||||
if (retval) {
|
||||
fprintf(stderr, "process_wu_template: md5_file %d\n", retval);
|
||||
return 1;
|
||||
}
|
||||
strcpy(buf, p+strlen(MD5_MACRO)+1+2); // assume <= 10 files
|
||||
strcpy(p, md5);
|
||||
strcat(p, buf);
|
||||
|
@ -130,7 +135,8 @@ static int process_wu_template(
|
|||
}
|
||||
|
||||
int create_result(
|
||||
WORKUNIT& wu, char* result_template_filename, int i, R_RSA_PRIVATE_KEY& key
|
||||
WORKUNIT& wu, char* result_template_filename, int i, R_RSA_PRIVATE_KEY& key,
|
||||
char* upload_url, char* download_url
|
||||
) {
|
||||
RESULT r;
|
||||
char base_outfile_name[256];
|
||||
|
@ -155,7 +161,8 @@ int create_result(
|
|||
result_template_file,
|
||||
tempfile,
|
||||
key,
|
||||
base_outfile_name, wu.name, r.name
|
||||
base_outfile_name, wu.name, r.name,
|
||||
upload_url, download_url
|
||||
);
|
||||
rewind(tempfile);
|
||||
read_file(tempfile, r.xml_doc_in);
|
||||
|
@ -176,7 +183,8 @@ int create_work(
|
|||
char* infile_dir,
|
||||
char** infiles,
|
||||
int ninfiles,
|
||||
R_RSA_PRIVATE_KEY& key
|
||||
R_RSA_PRIVATE_KEY& key,
|
||||
char* upload_url, char* download_url
|
||||
) {
|
||||
int i, retval;
|
||||
assert(wu_template!=NULL);
|
||||
|
@ -188,20 +196,30 @@ int create_work(
|
|||
|
||||
wu.create_time = time(0);
|
||||
retval = process_wu_template(
|
||||
wu.name, wu_template, wu.xml_doc, infile_dir, infiles, ninfiles
|
||||
wu.name, wu_template, wu.xml_doc, infile_dir, infiles, ninfiles,
|
||||
upload_url, download_url
|
||||
);
|
||||
if (retval) return retval;
|
||||
if (retval) {
|
||||
fprintf(stderr, "process_wu_template: %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
if (wu.dynamic_results) {
|
||||
wu.max_results = nresults;
|
||||
} else {
|
||||
wu.nresults_unsent = nresults;
|
||||
}
|
||||
retval = db_workunit_new(wu);
|
||||
if (retval) {
|
||||
fprintf(stderr, "create_work: db_workunit_new %d\n", retval);
|
||||
return retval;
|
||||
}
|
||||
wu.id = db_insert_id();
|
||||
|
||||
if (!wu.dynamic_results) {
|
||||
for (i=0; i<nresults; i++) {
|
||||
create_result(wu, result_template_file, i, key);
|
||||
create_result(
|
||||
wu, result_template_file, i, key, upload_url, download_url
|
||||
);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
extern int process_result_template(
|
||||
FILE* in, FILE* out,
|
||||
R_RSA_PRIVATE_KEY& key,
|
||||
char* base_filename, char* wu_name, char* result_name
|
||||
char* base_filename, char* wu_name, char* result_name,
|
||||
char* upload_url, char* download_url
|
||||
);
|
||||
|
||||
extern int read_file(FILE*, char* buf);
|
||||
|
@ -36,7 +37,9 @@ extern int create_work(
|
|||
char* infile_dir,
|
||||
char** infiles,
|
||||
int ninfiles,
|
||||
R_RSA_PRIVATE_KEY&
|
||||
R_RSA_PRIVATE_KEY&,
|
||||
char* upload_url,
|
||||
char* download_url
|
||||
);
|
||||
|
||||
extern int grant_credit(int resultid, double cobblestones);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// create_work
|
||||
// -appname name
|
||||
// -download_dir x
|
||||
// -rsc_fpops n
|
||||
// -rsc_iops n
|
||||
// -rsc_memory n
|
||||
|
@ -58,20 +59,14 @@ int main(int argc, char** argv) {
|
|||
char** infiles;
|
||||
int i, ninfiles, nresults;
|
||||
R_RSA_PRIVATE_KEY key;
|
||||
char* boinc_download_dir = getenv("BOINC_DOWNLOAD_DIR");
|
||||
char download_dir[256], db_name[256], db_passwd[256];
|
||||
char upload_url[256], download_url[256];
|
||||
|
||||
srand(time(NULL));
|
||||
if (!boinc_download_dir) {
|
||||
printf("must define BOINC_DOWNLOAD_DIR");
|
||||
exit(1);
|
||||
}
|
||||
if (db_open(getenv("BOINC_DB_NAME"), getenv("BOINC_DB_PASSWD"))) {
|
||||
printf( "Error opening database.\n" );
|
||||
exit(0);
|
||||
}
|
||||
strcpy(wu_template_file, "");
|
||||
strcpy(result_template_file, "");
|
||||
strcpy(app.name, "");
|
||||
strcpy(db_passwd, "");
|
||||
strcpy(keyfile, "");
|
||||
nresults = 1;
|
||||
i = 1;
|
||||
|
@ -81,6 +76,16 @@ int main(int argc, char** argv) {
|
|||
if (!strcmp(argv[i], "-appname")) {
|
||||
i++;
|
||||
strcpy(app.name, argv[i]);
|
||||
} else if (!strcmp(argv[i], "-db_name")) {
|
||||
strcpy(db_name, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-db_passwd")) {
|
||||
strcpy(db_passwd, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-upload_url")) {
|
||||
strcpy(upload_url, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-download_url")) {
|
||||
strcpy(download_url, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-download_dir")) {
|
||||
strcpy(download_dir, argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-wu_name")) {
|
||||
i++;
|
||||
strcpy(wu.name, argv[i]);
|
||||
|
@ -123,41 +128,44 @@ int main(int argc, char** argv) {
|
|||
if (!strlen(app.name) || !strlen(wu.name) || !strlen(wu_template_file)
|
||||
|| !strlen(result_template_file)
|
||||
) {
|
||||
printf("bad cmdline\n");
|
||||
fprintf(stderr, "create_work: bad cmdline\n");
|
||||
exit(1);
|
||||
}
|
||||
if (db_open(db_name, db_passwd)) {
|
||||
fprintf(stderr, "create_work: error opening database.\n" );
|
||||
exit(0);
|
||||
}
|
||||
retval = db_app_lookup_name(app);
|
||||
if (retval) {
|
||||
printf("app not found\n");
|
||||
fprintf(stderr, "create_work: app not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//fprintf(stderr, "wu_template = %s\n", wu_template);
|
||||
retval = read_filename(wu_template_file, wu_template);
|
||||
if (retval) {
|
||||
fprintf(stderr, "can't open WU template\n");
|
||||
fprintf(stderr, "create_work: can't open WU template\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (wu.dynamic_results) {
|
||||
strcpy(app.result_xml_template, result_template);
|
||||
retval = db_app_update(app);
|
||||
if (retval) printf("db_app_update: %d\n", retval);
|
||||
if (retval) fprintf(stderr, "create_work: db_app_update: %d\n", retval);
|
||||
}
|
||||
|
||||
wu.appid = app.id;
|
||||
|
||||
|
||||
FILE* fkey = fopen(keyfile, "r");
|
||||
rewind(fkey);
|
||||
if (!fkey) {
|
||||
printf("create_work: can't open key file (%s)\n", keyfile);
|
||||
fprintf(stderr, "create_work: can't open key file (%s)\n", keyfile);
|
||||
exit(1);
|
||||
}
|
||||
rewind(fkey);
|
||||
retval = scan_key_hex(fkey, (KEY*)&key, sizeof(key));
|
||||
fclose(fkey);
|
||||
if (retval) {
|
||||
printf("can't parse key\n");
|
||||
fprintf(stderr, "create_work: can't parse key\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -166,10 +174,12 @@ int main(int argc, char** argv) {
|
|||
wu_template,
|
||||
result_template_file,
|
||||
nresults,
|
||||
boinc_download_dir,
|
||||
download_dir,
|
||||
infiles,
|
||||
ninfiles,
|
||||
key
|
||||
key,
|
||||
upload_url,
|
||||
download_url
|
||||
);
|
||||
if (retval) fprintf(stderr, "create_work: %d\n", retval);
|
||||
db_close();
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
int process_result_template(
|
||||
FILE* in, FILE* out,
|
||||
R_RSA_PRIVATE_KEY& key,
|
||||
char* base_filename, char* wu_name, char* result_name
|
||||
char* base_filename, char* wu_name, char* result_name,
|
||||
char* upload_url, char* download_url
|
||||
) {
|
||||
char* p,*q, *signed_xml=strdup("");
|
||||
char buf[256], temp[256];
|
||||
|
@ -102,14 +103,14 @@ int process_result_template(
|
|||
if (p) {
|
||||
found = true;
|
||||
strcpy(temp, p+strlen(UPLOAD_URL_MACRO));
|
||||
strcpy(p, getenv("BOINC_UPLOAD_URL"));
|
||||
strcpy(p, upload_url);
|
||||
strcat(p, temp);
|
||||
}
|
||||
p = strstr(buf, DOWNLOAD_URL_MACRO);
|
||||
if (p) {
|
||||
found = true;
|
||||
strcpy(temp, p+strlen(DOWNLOAD_URL_MACRO));
|
||||
strcpy(p, getenv("BOINC_DOWNLOAD_URL"));
|
||||
strcpy(p, download_url);
|
||||
strcat(p, temp);
|
||||
}
|
||||
p = strstr(buf, WU_NAME_MACRO);
|
||||
|
|
Loading…
Reference in New Issue