1 | #! /usr/bin/env php |
||
2 | <?php |
||
3 | // This file is part of BOINC. |
||
4 | // http://boinc.berkeley.edu |
||
5 | // Copyright (C) 2008 University of California |
||
6 | // |
||
7 | // BOINC is free software; you can redistribute it and/or modify it |
||
8 | // under the terms of the GNU Lesser General Public License |
||
9 | // as published by the Free Software Foundation, |
||
10 | // either version 3 of the License, or (at your option) any later version. |
||
11 | // |
||
12 | // BOINC is distributed in the hope that it will be useful, |
||
13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
15 | // See the GNU Lesser General Public License for more details. |
||
16 | // |
||
17 | // You should have received a copy of the GNU Lesser General Public License |
||
18 | // along with BOINC. If not, see <http://www.gnu.org/licenses/>. |
||
19 | |||
20 | |||
21 | // configure a BOINC server to run single jobs; |
||
22 | // see https://github.com/BOINC/boinc/wiki/SingleJob |
||
23 | // |
||
24 | // Run this from project home dir. |
||
25 | // usage: html/ops/single_job_setup path-to-boinc_samples |
||
26 | |||
27 | |||
28 | ini_set('error_reporting', E_ALL); |
||
29 | |||
30 | // globals |
||
31 | $platform = `arch|tr -d "\n"`.'-pc-linux-gnu'; |
||
32 | // assume we're on Linux |
||
33 | $boinc_samples_dir = null; |
||
34 | $wrapper_filename = null; |
||
35 | $wrapper_md5 = null; |
||
36 | $app_name = null; |
||
37 | $app_id = 0; |
||
38 | |||
39 | function error($x) { |
||
40 | echo "$x\n"; |
||
41 | exit(1); |
||
42 | } |
||
43 | |||
44 | function check_dirs() { |
||
45 | if (!file_exists('config.xml')) { |
||
46 | error("Run this from project home dir"); |
||
47 | } |
||
48 | } |
||
49 | |||
50 | function usage() { |
||
51 | error("Usage: ./html/ops/single_job_setup path-to-boinc_samples"); |
||
52 | } |
||
53 | |||
54 | function get_includes() { |
||
55 | $c = getcwd(); |
||
56 | chdir('html/ops'); |
||
57 | require_once('../inc/util_ops.inc'); |
||
58 | BoincDb::get(); |
||
59 | chdir($c); |
||
60 | } |
||
61 | |||
62 | |||
63 | // check for existence of wrapper, get its checksum |
||
64 | // |
||
65 | function check_wrapper_exists() { |
||
66 | global $boinc_samples_dir, $wrapper_filename, $wrapper_md5; |
||
67 | |||
68 | $wrapper_filename = "$boinc_samples_dir/wrapper/wrapper"; |
||
69 | if (!file_exists($wrapper_filename)) { |
||
70 | echo "$wrapper_filename doesn't exist.\n"; |
||
71 | error("Make sure you've built boinc_samples."); |
||
72 | } |
||
73 | $wrapper_md5 = md5_file($wrapper_filename); |
||
74 | if (!$wrapper_md5) { |
||
75 | error("Can't read wrapper"); |
||
76 | } |
||
77 | } |
||
78 | |||
79 | // add application record in DB if not there |
||
80 | // |
||
81 | function add_application() { |
||
82 | global $app_name, $app_id, $platform; |
||
83 | |||
84 | $app_name = "single_job_$platform"; |
||
85 | $app = BoincApp::lookup("name='$app_name'"); |
||
86 | if ($app) { |
||
87 | $app_id = $app->id; |
||
88 | } else { |
||
89 | $now = time(); |
||
90 | $app_id = BoincApp::insert("(create_time, name, user_friendly_name) values ($now, '$app_name','Jobs for $platform')"); |
||
91 | if (!$app_id) { |
||
92 | error("Couldn't add application"); |
||
93 | } |
||
94 | } |
||
95 | } |
||
96 | |||
97 | // create apps/appname |
||
98 | // |
||
99 | function add_apps_dir() { |
||
100 | global $app_name; |
||
101 | |||
102 | $app_dir = "apps/$app_name"; |
||
103 | if (!is_dir($app_dir)) { |
||
104 | if (!mkdir($app_dir)) { |
||
105 | error("Couldn't make app dir"); |
||
106 | } |
||
107 | } |
||
108 | } |
||
109 | |||
110 | function app_version_dir($app_name, $i, $platform) { |
||
111 | return "apps/$app_name/1.$i/$platform"; |
||
112 | } |
||
113 | |||
114 | function make_app_version_dir($app_name, $i, $platform) { |
||
115 | @mkdir("apps/$app_name"); |
||
0 ignored issues
–
show
|
|||
116 | @mkdir("apps/$app_name/1.$i"); |
||
117 | @mkdir("apps/$app_name/1.$i/$platform"); |
||
118 | return 0; |
||
119 | } |
||
120 | |||
121 | |||
122 | // check for apps/appname/1.N/platform, |
||
123 | // find the largest such N; see if have new wrapper |
||
124 | // If needed, create new version, copy wrapper |
||
125 | // |
||
126 | function create_app_dir() { |
||
127 | global $app_name, $app_id, $platform, $wrapper_filename; |
||
128 | global $wrapper_md5; |
||
129 | |||
130 | $i = 0; |
||
131 | $latest_i = -1; |
||
132 | $have_latest_wrapper = false; |
||
133 | while (1) { |
||
134 | $app_dir = app_version_dir($app_name, $i, $platform); |
||
135 | if (!file_exists($app_dir)) break; |
||
136 | $latest_i = $i; |
||
137 | $i++; |
||
138 | } |
||
139 | |||
140 | if ($latest_i >= 0) { |
||
141 | $i = $latest_i; |
||
142 | $app_dir = app_version_dir($app_name, $i, $platform); |
||
143 | $file = "$app_dir/".$app_name."_1.".$i; |
||
144 | $latest_md5 = md5_file($file); |
||
145 | if ($latest_md5 == $wrapper_md5) { |
||
146 | $have_latest_wrapper = true; |
||
147 | echo "App version is current.\n"; |
||
148 | } else { |
||
149 | echo "$latest_md5 != $wrapper_md5\n"; |
||
150 | } |
||
151 | } |
||
152 | |||
153 | if ($have_latest_wrapper) { |
||
154 | echo "Current wrapper already installed.\n"; |
||
155 | |||
156 | // make sure they ran update_versions |
||
157 | // |
||
158 | $av = BoincAppVersion::lookup("appid=$app_id and version_num=$i"); |
||
159 | if (!$av) { |
||
160 | echo "- type 'bin/update_versions', and answer 'y' to all questions.\n"; |
||
161 | } |
||
162 | } else { |
||
163 | echo "Installing current wrapper.\n"; |
||
164 | $i = $latest_i + 1; |
||
165 | $app_dir = app_version_dir($app_name, $i, $platform); |
||
166 | if (make_app_version_dir($app_name, $i, $platform)) { |
||
167 | error("Couldn't create dir: $app_dir"); |
||
168 | } |
||
169 | $file = "$app_dir/$app_name"."_1.".$i; |
||
170 | if (!copy($wrapper_filename, $file)) { |
||
171 | error("Couldn't copy $wrapper_filename to $file"); |
||
172 | } |
||
173 | chmod($file, 0750); |
||
174 | echo "- type 'bin/update_versions', and answer 'y' to all questions.\n"; |
||
175 | } |
||
176 | } |
||
177 | |||
178 | // make sure daemons are in the config file |
||
179 | // |
||
180 | function check_config_file() { |
||
181 | global $app_name, $platform; |
||
182 | |||
183 | $config = file_get_contents('config.xml'); |
||
184 | if (!strstr($config, "single_job_assimilator")) { |
||
185 | echo "- Add the following to the <daemons> section of config.xml:\n |
||
186 | <daemon> |
||
187 | <cmd>single_job_assimilator -app $app_name</cmd> |
||
188 | <output>single_job_assimilator_$platform.out</output> |
||
189 | <pid>single_job_assimilator_$platform.pid</pid> |
||
190 | </daemon> |
||
191 | <daemon> |
||
192 | <cmd>sample_trivial_validator -app $app_name</cmd> |
||
193 | <output>sample_trivial_validator_$platform.out</output> |
||
194 | <pid>sample_trivial_validator_$platform.pid</pid> |
||
195 | </daemon> |
||
196 | Then restart your project by typing |
||
197 | bin/stop |
||
198 | bin/start |
||
199 | "; |
||
200 | } |
||
201 | } |
||
202 | |||
203 | if ($argc != 2) usage(); |
||
204 | $boinc_samples_dir = $argv[1]; |
||
205 | check_wrapper_exists(); |
||
206 | get_includes(); |
||
207 | add_application(); |
||
208 | add_apps_dir(); |
||
209 | create_app_dir(); |
||
210 | check_config_file(); |
||
211 | ?> |
||
212 |
If you suppress an error, we recommend checking for the error condition explicitly: