client/lib: add GUI RPCs for reading and writing app_config.xml files.

These will allow GUIs (e.g. BoincTasks) to provide dialogs for editing app config info.
This commit is contained in:
David Anderson 2017-05-11 20:16:35 -07:00
parent 4a9cc3e725
commit 5b6f648570
6 changed files with 187 additions and 9 deletions

View File

@ -62,6 +62,7 @@ Commands:\n\
--create_account URL email passwd name\n\
--file_transfer URL filename op file transfer operation\n\
op = retry | abort\n\
--get_app_config URL show app config for given project\n\
--get_cc_status\n\
--get_daily_xfer_history show network traffic history\n\
--get_disk_usage show disk usage\n\
@ -585,6 +586,24 @@ int main(int argc, char** argv) {
printf("retval %d\n", retval);
} else if (!strcmp(cmd, "--network_available")) {
retval = rpc.network_available();
} else if (!strcmp(cmd, "--set_app_config")) {
// for testing purposes only
//
APP_CONFIGS ac;
APP_CONFIG a;
ac.clear();
strcpy(a.name, "uppercase");
a.max_concurrent = 2;
ac.app_configs.push_back(a);
retval = rpc.set_app_config(argv[2], ac);
} else if (!strcmp(cmd, "--get_app_config")) {
APP_CONFIGS ac;
retval = rpc.get_app_config(argv[2], ac);
if (!retval) {
MIOFILE mf;
mf.init_file(stdout);
ac.write(mf);
}
} else if (!strcmp(cmd, "--get_cc_status")) {
CC_STATUS cs;
retval = rpc.get_cc_status(cs);

View File

@ -1087,6 +1087,27 @@ static void handle_get_cc_config(GUI_RPC_CONN& grc) {
}
}
static void handle_get_app_config(GUI_RPC_CONN& grc) {
string url;
string s;
char path[MAXPATHLEN];
while (!grc.xp.get_tag()) {
if (grc.xp.parse_string("url", url)) continue;
}
PROJECT* p = gstate.lookup_project(url.c_str());
if (!p) {
grc.mfout.printf("<error>no such project</error>");
return;
}
sprintf(path, "%s/%s", p->project_dir(), APP_CONFIG_FILE_NAME);
printf("path: %s\n", path);
int retval = read_file_string(path, s);
if (!retval) {
strip_whitespace(s);
grc.mfout.printf("%s\n", s.c_str());
}
}
static void handle_set_cc_config(GUI_RPC_CONN& grc) {
int retval;
char buf[65536];
@ -1114,6 +1135,47 @@ static void handle_set_cc_config(GUI_RPC_CONN& grc) {
}
}
static void handle_set_app_config(GUI_RPC_CONN& grc) {
APP_CONFIGS ac;
string url;
MSG_VEC mv;
LOG_FLAGS lf;
int parse_retval = -1;
while (!grc.xp.get_tag()) {
if (grc.xp.match_tag("app_config")) {
lf.init();
parse_retval = ac.parse(grc.xp, mv, lf);
} else if (grc.xp.parse_string("url", url)) {
continue;
}
}
if (parse_retval) {
grc.mfout.printf("<error>XML parse failed<error/>\n");
return;
}
PROJECT* p = gstate.lookup_project(url.c_str());
if (!p) {
grc.mfout.printf("<error>no such project<error/>\n");
return;
}
char path[MAXPATHLEN];
sprintf(path, "%s/app_config.xml", p->project_dir());
FILE* f = fopen(path, "w");
if (!f) {
msg_printf(p, MSG_INTERNAL_ERROR,
"Can't open app config file %s", path
);
grc.mfout.printf("<error>can't open app_config.xml file<error/>\n");
return;
}
MIOFILE mf;
mf.init_file(f);
ac.write(mf);
grc.mfout.printf("<success/>\n");
}
static void handle_get_notices(GUI_RPC_CONN& grc) {
int seqno = 0;
while (!grc.xp.get_tag()) {
@ -1331,6 +1393,7 @@ GUI_RPC gui_rpcs[] = {
GUI_RPC("abort_file_transfer", handle_abort_file_transfer, true, false, false),
GUI_RPC("abort_result", handle_abort_result, true, false, false),
GUI_RPC("acct_mgr_info", handle_acct_mgr_info, true, false, true),
GUI_RPC("get_app_config", handle_get_app_config, true, false, false),
GUI_RPC("get_cc_config", handle_get_cc_config, true, false, false),
GUI_RPC("get_global_prefs_file", handle_get_global_prefs_file, true, false, false),
GUI_RPC("get_global_prefs_override", handle_get_global_prefs_override,
@ -1358,6 +1421,7 @@ GUI_RPC gui_rpcs[] = {
GUI_RPC("report_device_status", handle_report_device_status, true, false, false),
GUI_RPC("resume_result", handle_resume_result, true, false, false),
GUI_RPC("run_benchmarks", handle_run_benchmarks, true, false, false),
GUI_RPC("set_app_config", handle_set_app_config, true, false, false),
GUI_RPC("set_cc_config", handle_set_cc_config, true, false, false),
GUI_RPC("set_global_prefs_override", handle_set_global_prefs_override,
true, false, false),

View File

@ -495,7 +495,6 @@ int CC_CONFIG::write(MIOFILE& out, LOG_FLAGS& log_flags) {
int j;
unsigned int i;
out.printf("<set_cc_config>\n");
out.printf("<cc_config>\n");
log_flags.write(out);
@ -694,7 +693,6 @@ int CC_CONFIG::write(MIOFILE& out, LOG_FLAGS& log_flags) {
);
out.printf(" </options>\n</cc_config>\n");
out.printf("</set_cc_config>\n");
return 0;
}
@ -801,10 +799,6 @@ int APP_CONFIGS::parse(XML_PARSER& xp, MSG_VEC& mv, LOG_FLAGS& log_flags) {
char buf[1024];
int n;
clear();
if (!xp.parse_start("app_config")) {
mv.push_back(string("Missing <app_config> in app_config.xml"));
return ERR_XML_PARSE;
}
while (!xp.get_tag()) {
if (!xp.is_tag) {
sprintf(buf, "unexpected text '%s' in app_config.xml", xp.parsed_tag);
@ -849,6 +843,58 @@ int APP_CONFIGS::parse_file(FILE* f, MSG_VEC& mv, LOG_FLAGS& log_flags) {
MIOFILE mf;
XML_PARSER xp(&mf);
mf.init_file(f);
if (!xp.parse_start("app_config")) {
mv.push_back(string("Missing <app_config> in app_config.xml"));
return ERR_XML_PARSE;
}
return parse(xp, mv, log_flags);
}
void APP_CONFIGS::write(MIOFILE& out) {
out.printf(
" <app_config>\n"
);
for (unsigned int i=0; i<app_configs.size(); i++) {
APP_CONFIG& ac = app_configs[i];
out.printf(
" <app>\n"
" <name>%s</name>\n"
" <max_concurrent>%d</max_concurrent>\n"
" <gpu_gpu_usage>%f</gpu_gpu_usage>\n"
" <gpu_cpu_usage>%f</gpu_cpu_usage>\n"
" <fraction_done_exact>%d</fraction_done_exact>\n"
" <report_results_immediately>%d</report_results_immediately>\n"
" </app>\n",
ac.name,
ac.max_concurrent,
ac.gpu_gpu_usage,
ac.gpu_cpu_usage,
ac.fraction_done_exact?1:0,
ac.report_results_immediately?1:0
);
}
for (unsigned int i=0; i<app_version_configs.size(); i++) {
APP_VERSION_CONFIG& avc = app_version_configs[i];
out.printf(
" <app_version>\n"
" <app_name>%s</app_name>\n"
" <plan_class>%s</plan_class>\n"
" <cmdline>%s</cmdline>\n"
" <avg_ncpus>%f</avg_ncpus>\n"
" <ngpus>%f</ngpus>\n"
" </app_version>\n",
avc.app_name,
avc.plan_class,
avc.cmdline,
avc.avg_ncpus,
avc.ngpus
);
}
out.printf(
" <project_max_concurrent>%d</project_max_concurrent>\n"
" <report_results_immediately>%d</report_results_immediately>\n"
" </app_config>\n",
project_max_concurrent,
report_results_immediately?1:0
);
}

View File

@ -248,6 +248,7 @@ struct APP_CONFIGS {
int parse(XML_PARSER&, MSG_VEC&, LOG_FLAGS&);
int parse_file(FILE*, MSG_VEC&, LOG_FLAGS&);
int config_app_versions(PROJECT*, bool show_warnings);
void write(MIOFILE&);
void clear() {
app_configs.clear();
app_version_configs.clear();

View File

@ -752,8 +752,8 @@ struct RPC_CLIENT {
int set_global_prefs_override_struct(GLOBAL_PREFS&, GLOBAL_PREFS_MASK&);
int get_cc_config(CC_CONFIG& config, LOG_FLAGS& log_flags);
int set_cc_config(CC_CONFIG& config, LOG_FLAGS& log_flags);
//int get_app_config(const char* url, APP_CONFIGS& conf);
//int set_app_config(const char* url, APP_CONFIGS& conf);
int get_app_config(const char* url, APP_CONFIGS& conf);
int set_app_config(const char* url, APP_CONFIGS& conf);
int get_daily_xfer_history(DAILY_XFER_HISTORY&);
int set_language(const char*);
};

View File

@ -2606,11 +2606,59 @@ int RPC_CLIENT::set_cc_config(CC_CONFIG& config, LOG_FLAGS& log_flags) {
mf.init_buf_write(buf, sizeof(buf));
config.write(mf, log_flags);
retval = rpc.do_rpc(buf);
string x = string("<set_cc_config>\n")+buf+string("</set_cc_config>\n");
retval = rpc.do_rpc(x.c_str());
if (retval) return retval;
return rpc.parse_reply();
}
int RPC_CLIENT::get_app_config(const char* url, APP_CONFIGS& config) {
int retval;
static LOG_FLAGS log_flags;
SET_LOCALE sl;
RPC rpc(this);
MSG_VEC mv;
char buf[1024];
sprintf(buf,
"<get_app_config>\n"
" <url>%s</url>\n"
"</get_app_config>\n",
url
);
retval = rpc.do_rpc(buf);
if (retval) return retval;
while (!rpc.xp.get_tag()) {
if (rpc.xp.match_tag("app_config")) {
return config.parse(rpc.xp, mv, log_flags);
} else if (rpc.xp.match_tag("error")) {
rpc.xp.element_contents("</error>", buf, sizeof(buf));
printf("get_app_config error: %s\n", buf);
return -1;
}
}
return ERR_XML_PARSE;
}
int RPC_CLIENT::set_app_config(const char* url, APP_CONFIGS& config) {
SET_LOCALE sl;
char buf[64000];
MIOFILE mf;
int retval;
RPC rpc(this);
mf.init_buf_write(buf, sizeof(buf));
mf.printf("<url>%s</url>\n", url);
config.write(mf);
string x = string("<set_app_config>\n")+buf+string("</set_app_config>\n");
retval = rpc.do_rpc(x.c_str());
if (retval) return retval;
return rpc.parse_reply();
}
static int parse_notices(XML_PARSER& xp, NOTICES& notices) {
int retval;