From 6eabd34068d6ee9eed3d156e28d0a3730ff702c1 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Fri, 24 Oct 2014 14:22:07 -0700 Subject: [PATCH] server: extend script_validator and script_assimilator to pass extra args You can arrange to pass result IDs, runtime, etc. to your validation and assimilation scripts. See http://boinc.berkeley.edu/trac/wiki/ValidationSimple#Usingscriptinglanguages http://boinc.berkeley.edu/trac/wiki/AssimilateIntro#Usingscriptinglanguages --- lib/str_util.cpp | 13 ++++ lib/str_util.h | 2 + sched/script_assimilator.cpp | 65 ++++++++++++++------ sched/script_validator.cpp | 116 +++++++++++++++++++++++++---------- 4 files changed, 146 insertions(+), 50 deletions(-) diff --git a/lib/str_util.cpp b/lib/str_util.cpp index 1d9bfee816..58f3a617e9 100644 --- a/lib/str_util.cpp +++ b/lib/str_util.cpp @@ -26,6 +26,7 @@ #ifndef _WIN32 #include "config.h" +#include #include #include #include @@ -45,6 +46,8 @@ #include "str_util.h" using std::string; +using std::stringstream; +using std::vector; // Use this instead of strncpy(). // Result will always be null-terminated, and it's faster. @@ -740,3 +743,13 @@ void parse_serialnum(char* in, char* boinc, char* vbox, char* coprocs) { in = p; } } + +vector split(string s, char delim) { + vector result; + stringstream ss(s); + string item; + while (getline(ss, item, delim)) { + result.push_back(item); + } + return result; +} diff --git a/lib/str_util.h b/lib/str_util.h index 263c604268..ea2eec7f29 100644 --- a/lib/str_util.h +++ b/lib/str_util.h @@ -19,6 +19,7 @@ #define STR_UTIL_H #include +#include #include extern void strcpy_overlap(char*, const char*); @@ -99,4 +100,5 @@ extern const char* batch_state_string(int state); extern void strip_translation(char* p); +extern std::vector split(std::string, char delim); #endif diff --git a/sched/script_assimilator.cpp b/sched/script_assimilator.cpp index 0c8e3225dd..035f4ddefa 100644 --- a/sched/script_assimilator.cpp +++ b/sched/script_assimilator.cpp @@ -15,14 +15,28 @@ // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . -// An assimilator that runs a script of your choosing to handle completed jobs. -// This script is invoked as +// An assimilator that runs a script to handle completed jobs, +// so that you can do assimilation in Python, PHP, Perl, bash, etc. // -// scriptname --wu_name X f1 ... fn -// where X is the workunit name -// and f1 ... fn are the output files of the canonical result -// or -// scriptname --wu_name X --error N +// cmdline args to this program: +// --script "scriptname arg1 ... argn" +// +// The script assimilates a completed job. +// +// arg1 ... argn represent cmdline args to be passed to the script. +// the options are: +// +// files list of output files of the job's canonical result +// wu_id workunit ID +// result_id ID of the canonical result +// runtime runtime of the canonical result +// +// if no args are specified, the script is invoked as +// scriptname wu_id files +// +// If the workunit has no canonical result (i.e. it failed) +// the script is invoked as +// scriptname --error N wu_id // where N is an integer encoding the reasons for the job's failure // (see WU_ERROR_* in html/inc/common_defs.inc) @@ -41,16 +55,19 @@ using std::vector; using std::string; bool first = true; -char script[MAXPATHLEN]; +vector script; void parse_cmdline() { - strcpy(script, ""); for (int i=1; i& /*results*/, RESULT& canonical_result ) { int retval; - char cmd[4096]; + char cmd[4096], buf[256]; + unsigned int i, j; if (first) { parse_cmdline(); @@ -70,17 +88,28 @@ int assimilate_handler( } if (wu.canonical_resultid) { - sprintf(cmd, "%s --wu_name %s", script, wu.name); + sprintf(cmd, "../bin/%s", script[0].c_str()); vector paths; retval = get_output_file_paths(canonical_result, paths); if (retval) return retval; - for (unsigned int i=0; i. // A validator that runs scripts to check and compare results, -// so that you can do your validation on Python, Perl, bash, etc. +// so that you can do your validation in Python, PHP, Perl, bash, etc. // -// cmdline args: -// --init_script scriptname -// --compare_script scriptname +// cmdline args to this program: +// --init_script "scriptname arg1 ... argn" +// --compare_script "scriptname arg1 ... argn" // -// the init script is called as -// scriptname f1 ... fn -// where f1 ... fn are the output files of a job (there may be just one) +// The init script checks the validity of a result, +// e.g. that the output files have the proper format. // It returns zero if the files are valid // -// the compare script is called as -// scriptname f1 ... fn g1 ... gn -// where f1 ... fn are the output files of one job, -// and g1 ... gn are the output files are another job. -// It returns zero if the files are equivalent. +// The compare script compares two results. +// If returns zero if the output files are equivalent. +// +// arg1 ... argn represent cmdline args to be passed to the scripts. +// The options for init_script are: +// +// files list of paths of output files of the result +// result_id result ID +// runtime task runtime +// +// Additional options for compare_script, for the second result: +// files2 list of paths of output files +// result_id2 result ID +// runtime2 task runtime +// +// "arg1 ... argn" can be omitted, +// in which case only the output file paths are passed to the scripts. #include @@ -46,19 +57,25 @@ using std::string; using std::vector; bool first = true; -char init_script[MAXPATHLEN], compare_script[MAXPATHLEN]; +vector init_script, compare_script; + // first element is script path, other elements are args void parse_cmdline() { - strcpy(init_script, ""); - strcpy(compare_script, ""); for (int i=1; i paths; int retval; retval = get_output_file_paths(result, paths); @@ -80,10 +100,21 @@ int init_result(RESULT& result, void*&) { return retval; } char cmd[4096]; - strcpy(cmd, init_script); - for (unsigned int i=0; i