diff --git a/client/app_test.cpp b/client/app_test.cpp index a273b4e176..490d4c267e 100644 --- a/client/app_test.cpp +++ b/client/app_test.cpp @@ -238,7 +238,7 @@ void CLIENT_STATE::app_test_init() { ); #endif #ifdef APP_DOCKER_WRAPPER - wu->command_line = "--verbose"; + wu->command_line = "--verbose --nsecs 20"; wu->input_files.push_back( *make_file(proj, "infile", "in", INPUT_FILE, false) ); diff --git a/client/cs_apps.cpp b/client/cs_apps.cpp index 7ff235d629..4d90cb88c0 100644 --- a/client/cs_apps.cpp +++ b/client/cs_apps.cpp @@ -422,7 +422,7 @@ void cleanup_docker(DOCKER_JOB_INFO &info, DOCKER_CONN &dc) { if (!docker_is_boinc_name(name.c_str())) continue; if (info.container_present(name)) continue; sprintf(cmd, "rm %s", name.c_str()); - retval = dc.command(cmd, out); + retval = dc.command(cmd, out2); if (retval) { fprintf(stderr, "Docker command failed: %s\n", cmd); continue; diff --git a/html/user/buda_submit.php b/html/user/buda_submit.php index 901b7b419a..52a01d0b90 100644 --- a/html/user/buda_submit.php +++ b/html/user/buda_submit.php @@ -114,7 +114,7 @@ function parse_batch_dir($batch_dir, $variant_desc) { foreach(scandir("$batch_dir/$fname") as $f2) { if ($f2[0] == '.') continue; if ($f2 == 'cmdline') { - $cmdline = file_get_contents("$batch_dir/$f2"); + $cmdline = trim(file_get_contents("$batch_dir/$f2")); } if (!in_array($f2, $unshared_files)) { error_page("$fname/$f2 is not an input file name"); @@ -182,6 +182,9 @@ function stage_input_files($batch_dir, $batch_desc, $batch_id) { } } +// run bin/create_work to create the jobs. +// Use --stdin, where each job is described by a line +// function create_jobs( $variant_desc, $batch_desc, $batch_id, $batch_dir_name, $wrapper_verbose ) { @@ -222,13 +225,12 @@ function create_jobs( fwrite($h, $job_cmds); $ret = pclose($h); if ($ret) { - echo $cmd; - echo "\n\n"; - echo $job_cmds; - echo "\n\n"; + echo "
create_work failed.\n";
+        echo "command: $cmd\n\n";
+        echo "job lines:\n$job_cmds\n\n";
+        echo "error file:\n";
         readfile("../../buda_batches/errfile");
         exit;
-        error_page("create_work failed: $x");
     }
 }
 
diff --git a/samples/docker_wrapper/docker_wrapper.cpp b/samples/docker_wrapper/docker_wrapper.cpp
index 1e970249b0..2d304d28c8 100644
--- a/samples/docker_wrapper/docker_wrapper.cpp
+++ b/samples/docker_wrapper/docker_wrapper.cpp
@@ -1,10 +1,37 @@
-// docker_wrapper: runs a BOINC job in a Docker container
+// This file is part of BOINC.
+// https://boinc.berkeley.edu
+// Copyright (C) 2024 University of California
 //
-// runs in a directory (i.e. slot dir) containing
+// BOINC is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Lesser General Public License
+// as published by the Free Software Foundation,
+// either version 3 of the License, or (at your option) any later version.
+//
+// BOINC is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with BOINC.  If not, see .
+
+// docker_wrapper: run a BOINC job in a Docker container,
+//      and interface between the BOINC client and the container
+//
+// docker_wrapper [options] arg1 arg2 ...
+// options:
+// --verbose            write Docker commands and outputs to stderr
+// --config   config filename, default job.toml
+// --dockerfile         Dockerfile name, default Dockerfile
+// --sporadic           app is sporadic
+//
+// args are passed as cmdline args to main prog in container
+//
+// docker_wrapper runs in a directory (usually slot dir) containing
 //
 // Dockerfile
 // job.toml
-//      optional job config file
+//      optional config file
 // input files (link or physical)
 // executable files (link or physical)
 //
@@ -118,6 +145,7 @@ bool verbose = false;
 const char* config_file = "job.toml";
 const char* dockerfile = "Dockerfile";
 DOCKER_CONN docker_conn;
+vector app_args;
 
 // parse job config file
 //
@@ -263,11 +291,18 @@ int create_container() {
             );
         }
     }
-    sprintf(cmd, "create --name %s %s %s %s",
+    sprintf(cmd, "create --name %s %s %s",
         container_name,
-        slot_cmd, project_cmd,
-        image_name
+        slot_cmd, project_cmd
     );
+    // add command-line args
+    strcat(cmd, " -e ARGS=\"");
+    for (string arg: app_args) {
+        strcat(cmd, " ");
+        strcat(cmd, arg.c_str());
+    }
+    strcat(cmd, "\" ");
+    strcat(cmd, image_name);
     retval = docker_conn.command(cmd, out);
     if (retval) return retval;
     if (error_output(out)) return -1;
@@ -437,6 +472,8 @@ int main(int argc, char** argv) {
             config_file = argv[++j];
         } else if (!strcmp(argv[j], "--dockerfile")) {
             dockerfile = argv[++j];
+        } else {
+            app_args.push_back(argv[j]);
         }
     }
 
diff --git a/samples/docker_wrapper/test/main.sh b/samples/docker_wrapper/test/main.sh
index 542cc5ba86..f4b47e1185 100755
--- a/samples/docker_wrapper/test/main.sh
+++ b/samples/docker_wrapper/test/main.sh
@@ -4,4 +4,4 @@ resolve () {
     sed 's/..\/..\/projects\/[^\/]*\//\/project\//; s/<\/soft_link>//' $1 | tr -d '\r\n'
 }
 
-./worker --nsecs 1 $(resolve in) out
+./worker $@ $(resolve in) out