4287 |
09 Jan 17 |
nicklas |
1 |
package net.sf.basedb.reggie.grid; |
4281 |
20 Dec 16 |
nicklas |
2 |
|
6656 |
29 Mar 22 |
nicklas |
3 |
import java.io.InputStream; |
4599 |
28 Sep 17 |
nicklas |
4 |
import java.util.ArrayList; |
5619 |
20 Sep 19 |
nicklas |
5 |
import java.util.HashMap; |
4599 |
28 Sep 17 |
nicklas |
6 |
import java.util.List; |
5619 |
20 Sep 19 |
nicklas |
7 |
import java.util.Map; |
4599 |
28 Sep 17 |
nicklas |
8 |
|
4599 |
28 Sep 17 |
nicklas |
9 |
import net.sf.basedb.core.BooleanParameterType; |
4281 |
20 Dec 16 |
nicklas |
10 |
import net.sf.basedb.core.DbControl; |
6635 |
09 Mar 22 |
nicklas |
11 |
import net.sf.basedb.core.Include; |
4599 |
28 Sep 17 |
nicklas |
12 |
import net.sf.basedb.core.IntegerParameterType; |
4287 |
09 Jan 17 |
nicklas |
13 |
import net.sf.basedb.core.InvalidDataException; |
6656 |
29 Mar 22 |
nicklas |
14 |
import net.sf.basedb.core.ItemNotFoundException; |
4599 |
28 Sep 17 |
nicklas |
15 |
import net.sf.basedb.core.Job; |
4281 |
20 Dec 16 |
nicklas |
16 |
import net.sf.basedb.core.Sample; |
4599 |
28 Sep 17 |
nicklas |
17 |
import net.sf.basedb.core.StringParameterType; |
4599 |
28 Sep 17 |
nicklas |
18 |
import net.sf.basedb.opengrid.CmdResult; |
4599 |
28 Sep 17 |
nicklas |
19 |
import net.sf.basedb.opengrid.JobDefinition; |
4599 |
28 Sep 17 |
nicklas |
20 |
import net.sf.basedb.opengrid.JobStatus; |
4599 |
28 Sep 17 |
nicklas |
21 |
import net.sf.basedb.opengrid.OpenGrid; |
4599 |
28 Sep 17 |
nicklas |
22 |
import net.sf.basedb.opengrid.OpenGridCluster; |
4599 |
28 Sep 17 |
nicklas |
23 |
import net.sf.basedb.opengrid.OpenGridSession; |
4281 |
20 Dec 16 |
nicklas |
24 |
import net.sf.basedb.opengrid.ScriptBuilder; |
7372 |
06 Oct 23 |
nicklas |
25 |
import net.sf.basedb.opengrid.config.ClusterType; |
7372 |
06 Oct 23 |
nicklas |
26 |
import net.sf.basedb.opengrid.config.JobConfig; |
6628 |
07 Mar 22 |
nicklas |
27 |
import net.sf.basedb.opengrid.filetransfer.InputStreamUploadSource; |
6628 |
07 Mar 22 |
nicklas |
28 |
import net.sf.basedb.opengrid.filetransfer.UploadSource; |
6635 |
09 Mar 22 |
nicklas |
29 |
import net.sf.basedb.opengrid.service.OpenGridService; |
6628 |
07 Mar 22 |
nicklas |
30 |
import net.sf.basedb.reggie.Reggie; |
6635 |
09 Mar 22 |
nicklas |
31 |
import net.sf.basedb.reggie.XmlConfig; |
4281 |
20 Dec 16 |
nicklas |
32 |
import net.sf.basedb.reggie.dao.Annotationtype; |
4281 |
20 Dec 16 |
nicklas |
33 |
import net.sf.basedb.reggie.dao.ReggieItem; |
4281 |
20 Dec 16 |
nicklas |
34 |
import net.sf.basedb.reggie.dao.Subtype; |
4281 |
20 Dec 16 |
nicklas |
35 |
import net.sf.basedb.reggie.projectarchive.FilePermission; |
4281 |
20 Dec 16 |
nicklas |
36 |
|
4281 |
20 Dec 16 |
nicklas |
37 |
/** |
4281 |
20 Dec 16 |
nicklas |
Utility methods for script generation. |
4281 |
20 Dec 16 |
nicklas |
39 |
|
4281 |
20 Dec 16 |
nicklas |
@author nicklas |
4281 |
20 Dec 16 |
nicklas |
@since 4.xx |
4281 |
20 Dec 16 |
nicklas |
42 |
*/ |
4281 |
20 Dec 16 |
nicklas |
43 |
public final class ScriptUtil |
4281 |
20 Dec 16 |
nicklas |
44 |
{ |
4281 |
20 Dec 16 |
nicklas |
45 |
|
4281 |
20 Dec 16 |
nicklas |
// No instances |
4281 |
20 Dec 16 |
nicklas |
47 |
private ScriptUtil() |
4281 |
20 Dec 16 |
nicklas |
48 |
{} |
4281 |
20 Dec 16 |
nicklas |
49 |
|
4281 |
20 Dec 16 |
nicklas |
50 |
/** |
4281 |
20 Dec 16 |
nicklas |
Utility method for setting the 'umask' depending on the |
4281 |
20 Dec 16 |
nicklas |
consent on the case. The method will search for a |
4281 |
20 Dec 16 |
nicklas |
parent "Case" item and check if the "Consent" annotation |
4281 |
20 Dec 16 |
nicklas |
is set to yes. The "umask" is then set: |
4281 |
20 Dec 16 |
nicklas |
55 |
|
4281 |
20 Dec 16 |
nicklas |
* Yes: umask -S u=rwx,g=rx,o= |
4281 |
20 Dec 16 |
nicklas |
* No: umask -S u=rwx,g=,o= |
4281 |
20 Dec 16 |
nicklas |
58 |
|
5595 |
11 Sep 19 |
nicklas |
If an external group is given, the consent is not checked, but it is assumed that the permission |
5595 |
11 Sep 19 |
nicklas |
should be set to {@link FilePermission#EXTERNAL_GROUP_READABLE}. |
5595 |
11 Sep 19 |
nicklas |
61 |
|
4281 |
20 Dec 16 |
nicklas |
@return TRUE if there is a consent, FALSE if not |
4281 |
20 Dec 16 |
nicklas |
63 |
*/ |
5595 |
11 Sep 19 |
nicklas |
64 |
public static FilePermission setUmaskForItem(DbControl dc, ReggieItem<?> item, String externalGroup, ScriptBuilder script) |
4281 |
20 Dec 16 |
nicklas |
65 |
{ |
5595 |
11 Sep 19 |
nicklas |
66 |
FilePermission permission = FilePermission.NO_CONSENT; |
5595 |
11 Sep 19 |
nicklas |
67 |
if (externalGroup != null) |
5595 |
11 Sep 19 |
nicklas |
68 |
{ |
5595 |
11 Sep 19 |
nicklas |
69 |
permission = FilePermission.EXTERNAL_GROUP_READABLE; |
5595 |
11 Sep 19 |
nicklas |
70 |
} |
5595 |
11 Sep 19 |
nicklas |
71 |
else |
5595 |
11 Sep 19 |
nicklas |
72 |
{ |
5595 |
11 Sep 19 |
nicklas |
73 |
Sample theCase = (Sample)item.findSingleParent(dc, Subtype.CASE); |
5595 |
11 Sep 19 |
nicklas |
74 |
if ("Yes".equals(Annotationtype.CONSENT.getAnnotationValue(dc, theCase))) |
5595 |
11 Sep 19 |
nicklas |
75 |
{ |
5595 |
11 Sep 19 |
nicklas |
76 |
permission = FilePermission.CONSENT; |
5595 |
11 Sep 19 |
nicklas |
77 |
} |
5595 |
11 Sep 19 |
nicklas |
78 |
} |
5595 |
11 Sep 19 |
nicklas |
79 |
script.cmd("umask -S "+permission.getUmask()); |
5595 |
11 Sep 19 |
nicklas |
80 |
return permission; |
4281 |
20 Dec 16 |
nicklas |
81 |
} |
4281 |
20 Dec 16 |
nicklas |
82 |
|
4287 |
09 Jan 17 |
nicklas |
83 |
/** |
5930 |
06 May 20 |
nicklas |
Add a 'chgrp' command to set the group of the given 'folder' and all files and subdirectories in it. |
5930 |
06 May 20 |
nicklas |
If a 'parentFolder' is given and is a parent folder of the 'folder' a 'chgrp' command is added |
5930 |
06 May 20 |
nicklas |
to parent folder up to (but not including) the parent folder. Errors are logged to ${WD}/chgrp.out. |
5930 |
06 May 20 |
nicklas |
'itemName' is used for logging errors only |
5930 |
06 May 20 |
nicklas |
@since 4.27 |
5930 |
06 May 20 |
nicklas |
89 |
*/ |
5930 |
06 May 20 |
nicklas |
90 |
public static void addChgrp(String groupName, String folder, String itemName, String parentFolder, ScriptBuilder script) |
5930 |
06 May 20 |
nicklas |
91 |
{ |
5930 |
06 May 20 |
nicklas |
// Make sure parent folder ends with '/' and folder doesn't so that the while loop breaks correctly |
5930 |
06 May 20 |
nicklas |
93 |
if (folder.endsWith("/")) folder = folder.substring(0, folder.length()-1); |
5930 |
06 May 20 |
nicklas |
94 |
if (parentFolder != null && !parentFolder.endsWith("/")) parentFolder += "/"; |
5930 |
06 May 20 |
nicklas |
95 |
|
5930 |
06 May 20 |
nicklas |
96 |
script.cmd("chgrp -R " + groupName + " " + folder + " 2>> ${WD}/chgrp.out || echo [" + itemName +"] >> ${WD}/chgrp.out"); |
5930 |
06 May 20 |
nicklas |
97 |
|
5930 |
06 May 20 |
nicklas |
98 |
while (parentFolder != null) |
5930 |
06 May 20 |
nicklas |
99 |
{ |
5930 |
06 May 20 |
nicklas |
100 |
int last = folder.lastIndexOf('/'); |
5930 |
06 May 20 |
nicklas |
101 |
if (last == -1) break; |
5930 |
06 May 20 |
nicklas |
102 |
folder = folder.substring(0, last); // Move up one directory: /foo/bar/x --> /foo/bar |
5930 |
06 May 20 |
nicklas |
// Check if we have reached the parent folder |
5930 |
06 May 20 |
nicklas |
104 |
if (folder.indexOf(parentFolder) == -1) break; |
5930 |
06 May 20 |
nicklas |
105 |
|
5930 |
06 May 20 |
nicklas |
106 |
script.cmd("chgrp " + groupName + " " + folder + " 2>> ${WD}/chgrp.out || echo [" + itemName +"] >> ${WD}/chgrp.out"); |
5930 |
06 May 20 |
nicklas |
107 |
} |
5930 |
06 May 20 |
nicklas |
108 |
} |
5930 |
06 May 20 |
nicklas |
109 |
|
5930 |
06 May 20 |
nicklas |
110 |
/** |
4287 |
09 Jan 17 |
nicklas |
We only allow letters, numbers, dot, underscore and forward slash in path names. |
4287 |
09 Jan 17 |
nicklas |
The path must be at least two levels and not contain a double dot (..). |
4287 |
09 Jan 17 |
nicklas |
@since 4.2 |
4287 |
09 Jan 17 |
nicklas |
114 |
*/ |
4287 |
09 Jan 17 |
nicklas |
115 |
public static String checkValidPath(String path, boolean isDirectory, boolean twoLevels) |
4287 |
09 Jan 17 |
nicklas |
116 |
{ |
4287 |
09 Jan 17 |
nicklas |
117 |
if (path == null) |
4287 |
09 Jan 17 |
nicklas |
118 |
{ |
4287 |
09 Jan 17 |
nicklas |
119 |
throw new NullPointerException("path"); |
4287 |
09 Jan 17 |
nicklas |
120 |
} |
4287 |
09 Jan 17 |
nicklas |
// Get rid of trailing '/' |
4287 |
09 Jan 17 |
nicklas |
122 |
if (path.endsWith("/")) path = path.substring(0, path.length()-1); |
4287 |
09 Jan 17 |
nicklas |
// Check valid characters |
4287 |
09 Jan 17 |
nicklas |
124 |
if (!path.matches("[a-zA-Z0-9._\\-/]+")) |
4287 |
09 Jan 17 |
nicklas |
125 |
{ |
4287 |
09 Jan 17 |
nicklas |
126 |
throw new InvalidDataException("Path may only contain [a-zA-Z0-9._-/]: " + path); |
4287 |
09 Jan 17 |
nicklas |
127 |
} |
4287 |
09 Jan 17 |
nicklas |
128 |
if (twoLevels) |
4287 |
09 Jan 17 |
nicklas |
129 |
{ |
4287 |
09 Jan 17 |
nicklas |
// Path must be at least two levels |
4287 |
09 Jan 17 |
nicklas |
131 |
if (!path.matches("/[a-zA-Z0-9._\\-]+/[a-zA-Z0-9._\\-].*")) |
4287 |
09 Jan 17 |
nicklas |
132 |
{ |
4287 |
09 Jan 17 |
nicklas |
133 |
throw new InvalidDataException("Path must be at least two levels deep: " + path); |
4287 |
09 Jan 17 |
nicklas |
134 |
} |
4287 |
09 Jan 17 |
nicklas |
135 |
} |
4287 |
09 Jan 17 |
nicklas |
136 |
else |
4287 |
09 Jan 17 |
nicklas |
137 |
{ |
4287 |
09 Jan 17 |
nicklas |
// Path must start with '/' |
4287 |
09 Jan 17 |
nicklas |
139 |
if (!path.startsWith("/")) |
4287 |
09 Jan 17 |
nicklas |
140 |
{ |
4287 |
09 Jan 17 |
nicklas |
141 |
throw new InvalidDataException("Path must start with '/': " + path); |
4287 |
09 Jan 17 |
nicklas |
142 |
} |
4287 |
09 Jan 17 |
nicklas |
143 |
} |
4287 |
09 Jan 17 |
nicklas |
// Not allowed to move up to parent directory |
4287 |
09 Jan 17 |
nicklas |
145 |
if (path.contains("..")) |
4287 |
09 Jan 17 |
nicklas |
146 |
{ |
4287 |
09 Jan 17 |
nicklas |
147 |
throw new InvalidDataException("Path may not contain '..': " + path); |
4287 |
09 Jan 17 |
nicklas |
148 |
} |
4287 |
09 Jan 17 |
nicklas |
149 |
return path; |
4287 |
09 Jan 17 |
nicklas |
150 |
} |
4287 |
09 Jan 17 |
nicklas |
151 |
|
4287 |
09 Jan 17 |
nicklas |
152 |
/** |
4287 |
09 Jan 17 |
nicklas |
Checks that a value is allowed as a file/directory name. |
4287 |
09 Jan 17 |
nicklas |
We only allow letters, numbers, dot and underscore names. |
4287 |
09 Jan 17 |
nicklas |
It may not contain a double dot (..). |
4287 |
09 Jan 17 |
nicklas |
@since 4.2 |
4287 |
09 Jan 17 |
nicklas |
157 |
*/ |
4287 |
09 Jan 17 |
nicklas |
158 |
public static String checkValidFilename(String filename) |
4287 |
09 Jan 17 |
nicklas |
159 |
{ |
4287 |
09 Jan 17 |
nicklas |
160 |
if (filename == null) |
4287 |
09 Jan 17 |
nicklas |
161 |
{ |
4287 |
09 Jan 17 |
nicklas |
162 |
throw new NullPointerException("filename"); |
4287 |
09 Jan 17 |
nicklas |
163 |
} |
4287 |
09 Jan 17 |
nicklas |
164 |
if (!filename.matches("[a-zA-Z0-9._\\-]+")) |
4287 |
09 Jan 17 |
nicklas |
165 |
{ |
4287 |
09 Jan 17 |
nicklas |
166 |
throw new InvalidDataException("File name may only contain [a-zA-Z0-9._-]: " + filename); |
4287 |
09 Jan 17 |
nicklas |
167 |
} |
4287 |
09 Jan 17 |
nicklas |
// Not allowed to move up to parent directory |
4287 |
09 Jan 17 |
nicklas |
169 |
if (filename.contains("..")) |
4287 |
09 Jan 17 |
nicklas |
170 |
{ |
4287 |
09 Jan 17 |
nicklas |
171 |
throw new InvalidDataException("File name may not contain '..': " + filename); |
4287 |
09 Jan 17 |
nicklas |
172 |
} |
4287 |
09 Jan 17 |
nicklas |
173 |
return filename; |
4287 |
09 Jan 17 |
nicklas |
174 |
} |
4287 |
09 Jan 17 |
nicklas |
175 |
|
4287 |
09 Jan 17 |
nicklas |
176 |
/** |
4287 |
09 Jan 17 |
nicklas |
Script parameters may only contain letters, numbers, dot, underscore and hyphen. |
4287 |
09 Jan 17 |
nicklas |
@since 4.2 |
4287 |
09 Jan 17 |
nicklas |
179 |
*/ |
4287 |
09 Jan 17 |
nicklas |
180 |
public static String checkValidScriptParameter(String param) |
4287 |
09 Jan 17 |
nicklas |
181 |
{ |
4287 |
09 Jan 17 |
nicklas |
182 |
if (param != null && !param.matches("[a-zA-Z0-9._\\-]+")) |
4287 |
09 Jan 17 |
nicklas |
183 |
{ |
4287 |
09 Jan 17 |
nicklas |
184 |
throw new InvalidDataException("Parameter may only contain [a-zA-Z0-9._-]: " + param); |
4287 |
09 Jan 17 |
nicklas |
185 |
} |
4287 |
09 Jan 17 |
nicklas |
186 |
return param; |
4287 |
09 Jan 17 |
nicklas |
187 |
} |
4599 |
28 Sep 17 |
nicklas |
188 |
|
4599 |
28 Sep 17 |
nicklas |
189 |
/** |
7372 |
06 Oct 23 |
nicklas |
Parse the submitOptions string and add as options to the job configuration. |
7372 |
06 Oct 23 |
nicklas |
The submitOptions must be a string with one option per line that contains a key |
7372 |
06 Oct 23 |
nicklas |
and value or only a key in the format: key=value | key |
7372 |
06 Oct 23 |
nicklas |
Lines starting with '#' are ignored. |
7372 |
06 Oct 23 |
nicklas |
194 |
|
7372 |
06 Oct 23 |
nicklas |
@since 4.49.3 |
7372 |
06 Oct 23 |
nicklas |
196 |
*/ |
7372 |
06 Oct 23 |
nicklas |
197 |
public static void addSubmitOptions(JobConfig job, String submitOptions, ClusterType clusterType) |
7372 |
06 Oct 23 |
nicklas |
198 |
{ |
7372 |
06 Oct 23 |
nicklas |
199 |
if (submitOptions == null || submitOptions.length() == 0) return; |
7372 |
06 Oct 23 |
nicklas |
200 |
for (String keyVal : submitOptions.split("\\n")) |
7372 |
06 Oct 23 |
nicklas |
201 |
{ |
7372 |
06 Oct 23 |
nicklas |
202 |
String[] kv = keyVal.strip().split("\\=", 2); |
7372 |
06 Oct 23 |
nicklas |
203 |
String key = kv[0]; |
7372 |
06 Oct 23 |
nicklas |
// ignore empty lines and lines starting with # |
7372 |
06 Oct 23 |
nicklas |
205 |
if (key.length() == 0 || key.startsWith("#")) continue; |
7372 |
06 Oct 23 |
nicklas |
206 |
|
7372 |
06 Oct 23 |
nicklas |
207 |
String val = kv.length == 2 ? kv[1] : ""; |
7372 |
06 Oct 23 |
nicklas |
208 |
if (clusterType == ClusterType.SLURM) |
7372 |
06 Oct 23 |
nicklas |
209 |
{ |
7372 |
06 Oct 23 |
nicklas |
210 |
job.setSbatchOption(key, val); |
7372 |
06 Oct 23 |
nicklas |
211 |
} |
7372 |
06 Oct 23 |
nicklas |
212 |
else if (clusterType == ClusterType.OPENGRID) |
7372 |
06 Oct 23 |
nicklas |
213 |
{ |
7372 |
06 Oct 23 |
nicklas |
214 |
job.setQsubOption(key, val); |
7372 |
06 Oct 23 |
nicklas |
215 |
} |
7372 |
06 Oct 23 |
nicklas |
216 |
} |
7372 |
06 Oct 23 |
nicklas |
217 |
} |
7372 |
06 Oct 23 |
nicklas |
218 |
|
7372 |
06 Oct 23 |
nicklas |
219 |
/** |
4599 |
28 Sep 17 |
nicklas |
Submit the list of job definitions to the specified cluster. |
4599 |
28 Sep 17 |
nicklas |
@since 4.12 |
4599 |
28 Sep 17 |
nicklas |
222 |
*/ |
4599 |
28 Sep 17 |
nicklas |
223 |
public static List<Job> submitJobs(DbControl dc, OpenGridCluster cluster, List<JobDefinition> jobDefs) |
4599 |
28 Sep 17 |
nicklas |
224 |
{ |
4599 |
28 Sep 17 |
nicklas |
225 |
OpenGridSession ogSession = null; |
4599 |
28 Sep 17 |
nicklas |
226 |
List<Job> jobs = new ArrayList<>(jobDefs.size()); |
4664 |
30 Jan 18 |
nicklas |
227 |
if (jobDefs.size() > 0) |
4599 |
28 Sep 17 |
nicklas |
228 |
{ |
4661 |
29 Jan 18 |
nicklas |
229 |
try |
4599 |
28 Sep 17 |
nicklas |
230 |
{ |
4661 |
29 Jan 18 |
nicklas |
231 |
ogSession = cluster.connect(5); |
4661 |
29 Jan 18 |
nicklas |
// Submit jobs to cluster |
4661 |
29 Jan 18 |
nicklas |
233 |
CmdResult<List<JobStatus>> qsub = ogSession.qsub(dc, jobDefs); |
4661 |
29 Jan 18 |
nicklas |
234 |
qsub.throwExceptionIfNonZeroExitStatus(); |
4599 |
28 Sep 17 |
nicklas |
235 |
|
4661 |
29 Jan 18 |
nicklas |
236 |
StringParameterType sType = new StringParameterType(); |
4661 |
29 Jan 18 |
nicklas |
237 |
BooleanParameterType bType = new BooleanParameterType(); |
4661 |
29 Jan 18 |
nicklas |
238 |
IntegerParameterType iType = new IntegerParameterType(); |
4661 |
29 Jan 18 |
nicklas |
239 |
for (int jobNo = 0; jobNo < jobDefs.size(); jobNo++) |
4599 |
28 Sep 17 |
nicklas |
240 |
{ |
4661 |
29 Jan 18 |
nicklas |
241 |
JobStatus status = qsub.getResult().get(jobNo); |
4661 |
29 Jan 18 |
nicklas |
242 |
JobDefinition jobDef = jobDefs.get(jobNo); |
4661 |
29 Jan 18 |
nicklas |
243 |
Job job = jobDef.getBaseJob(); |
4661 |
29 Jan 18 |
nicklas |
244 |
jobs.add(job); |
4661 |
29 Jan 18 |
nicklas |
245 |
|
4661 |
29 Jan 18 |
nicklas |
246 |
job.setParameterValue("jobName", sType, status.getName()); |
4661 |
29 Jan 18 |
nicklas |
247 |
if (jobDef.getDebug()) |
4661 |
29 Jan 18 |
nicklas |
248 |
{ |
4661 |
29 Jan 18 |
nicklas |
249 |
job.setParameterValue("debug", bType, jobDef.getDebug()); |
4661 |
29 Jan 18 |
nicklas |
250 |
} |
4661 |
29 Jan 18 |
nicklas |
251 |
if (jobDef.getConfig().getPriority() != null) |
4661 |
29 Jan 18 |
nicklas |
252 |
{ |
4661 |
29 Jan 18 |
nicklas |
253 |
job.setParameterValue("priority", iType, jobDef.getConfig().getPriority().intValue()); |
4661 |
29 Jan 18 |
nicklas |
254 |
} |
4661 |
29 Jan 18 |
nicklas |
255 |
|
4661 |
29 Jan 18 |
nicklas |
256 |
String jobId = status.getJobIdentifier().getClusterJobId(); |
4661 |
29 Jan 18 |
nicklas |
257 |
if (jobId == null || jobId.equals("")) |
4661 |
29 Jan 18 |
nicklas |
258 |
{ |
4661 |
29 Jan 18 |
nicklas |
259 |
job.doneError("Cluster returned no job-id for this job"); |
4661 |
29 Jan 18 |
nicklas |
260 |
continue; |
4661 |
29 Jan 18 |
nicklas |
261 |
} |
4599 |
28 Sep 17 |
nicklas |
262 |
} |
4599 |
28 Sep 17 |
nicklas |
263 |
} |
4661 |
29 Jan 18 |
nicklas |
264 |
finally |
4661 |
29 Jan 18 |
nicklas |
265 |
{ |
4661 |
29 Jan 18 |
nicklas |
266 |
OpenGrid.close(ogSession); |
4661 |
29 Jan 18 |
nicklas |
267 |
} |
4599 |
28 Sep 17 |
nicklas |
268 |
} |
4599 |
28 Sep 17 |
nicklas |
269 |
return jobs; |
4599 |
28 Sep 17 |
nicklas |
270 |
} |
4287 |
09 Jan 17 |
nicklas |
271 |
|
5619 |
20 Sep 19 |
nicklas |
272 |
/** |
5619 |
20 Sep 19 |
nicklas |
Parse errors from 'chgrp' command that is used to share files for external samples. |
5619 |
20 Sep 19 |
nicklas |
274 |
|
5619 |
20 Sep 19 |
nicklas |
The file is expected to contain output to stderr from 'chgrp' followed by the |
5619 |
20 Sep 19 |
nicklas |
name of the item (inside brackets) the errors are related to: |
5619 |
20 Sep 19 |
nicklas |
277 |
|
5619 |
20 Sep 19 |
nicklas |
chgrp: changing group of `/...foobar/lib.g': Operation not permitted |
5619 |
20 Sep 19 |
nicklas |
[foobar.lib.g] |
5619 |
20 Sep 19 |
nicklas |
280 |
|
5619 |
20 Sep 19 |
nicklas |
This parser will pick up item names and use for keys in a map with the |
5619 |
20 Sep 19 |
nicklas |
preceeding line as value: |
5619 |
20 Sep 19 |
nicklas |
283 |
|
5619 |
20 Sep 19 |
nicklas |
foobar.lib.g --> chgrp: changing group of `/...foobar/lib.g': Operation not permitted |
5619 |
20 Sep 19 |
nicklas |
285 |
|
5619 |
20 Sep 19 |
nicklas |
@since 4.24 |
5619 |
20 Sep 19 |
nicklas |
287 |
*/ |
5619 |
20 Sep 19 |
nicklas |
288 |
public static Map<String, String> parseChgrpErrors(String chgrp) |
5619 |
20 Sep 19 |
nicklas |
289 |
{ |
5619 |
20 Sep 19 |
nicklas |
290 |
Map<String, String> errors = new HashMap<>(); |
5619 |
20 Sep 19 |
nicklas |
291 |
if (chgrp != null) |
5619 |
20 Sep 19 |
nicklas |
292 |
{ |
5619 |
20 Sep 19 |
nicklas |
293 |
String[] lines = chgrp.split("\n"); |
5619 |
20 Sep 19 |
nicklas |
294 |
for (int lineNo = 1; lineNo < lines.length; lineNo++) |
5619 |
20 Sep 19 |
nicklas |
295 |
{ |
5619 |
20 Sep 19 |
nicklas |
296 |
String line = lines[lineNo]; |
5619 |
20 Sep 19 |
nicklas |
297 |
if (line.length() > 3 && line.startsWith("[") && line.endsWith("]")) |
5619 |
20 Sep 19 |
nicklas |
298 |
{ |
5619 |
20 Sep 19 |
nicklas |
299 |
String name = line.substring(1, line.length()-1); |
5619 |
20 Sep 19 |
nicklas |
300 |
String msg = lines[lineNo-1]; |
5619 |
20 Sep 19 |
nicklas |
301 |
errors.put(name, msg); |
5619 |
20 Sep 19 |
nicklas |
302 |
} |
5619 |
20 Sep 19 |
nicklas |
303 |
} |
5619 |
20 Sep 19 |
nicklas |
304 |
} |
5619 |
20 Sep 19 |
nicklas |
305 |
return errors; |
5619 |
20 Sep 19 |
nicklas |
306 |
} |
4287 |
09 Jan 17 |
nicklas |
307 |
|
6628 |
07 Mar 22 |
nicklas |
308 |
/** |
6635 |
09 Mar 22 |
nicklas |
Check if the current cluster has been configured with the specified configuration option. |
6635 |
09 Mar 22 |
nicklas |
If not, search among all configured clusters and return the first one that is connected |
6635 |
09 Mar 22 |
nicklas |
and configured. If no such cluster is found, the current one is returned in any case. |
6635 |
09 Mar 22 |
nicklas |
312 |
|
6635 |
09 Mar 22 |
nicklas |
This method is intended to be used by auto-confirm handlers to check if the current cluster |
6635 |
09 Mar 22 |
nicklas |
can continue with the next step or if the pipeline need to move to another cluster. Typically |
6635 |
09 Mar 22 |
nicklas |
a top-level configuration section is checked, for example, 'demux' or 'align-hisat'. |
6635 |
09 Mar 22 |
nicklas |
316 |
|
6635 |
09 Mar 22 |
nicklas |
@since 4.38 |
6635 |
09 Mar 22 |
nicklas |
318 |
*/ |
6635 |
09 Mar 22 |
nicklas |
319 |
public static OpenGridCluster autoSelectClusterWithConfig(DbControl dc, String xpath, OpenGridCluster current) |
6635 |
09 Mar 22 |
nicklas |
320 |
{ |
6635 |
09 Mar 22 |
nicklas |
321 |
List<OpenGridCluster> clusters = new ArrayList<>(); |
7228 |
01 Jun 23 |
nicklas |
322 |
if (current != null) clusters.add(current); |
6635 |
09 Mar 22 |
nicklas |
323 |
clusters.addAll(OpenGridService.getInstance().getClusters(dc, Include.ALL)); |
6635 |
09 Mar 22 |
nicklas |
324 |
for (OpenGridCluster cluster : clusters) |
6635 |
09 Mar 22 |
nicklas |
325 |
{ |
6635 |
09 Mar 22 |
nicklas |
326 |
if (!cluster.getClusterInfo().isConnected()) continue; |
6635 |
09 Mar 22 |
nicklas |
327 |
XmlConfig cfg = Reggie.getConfig(cluster.getId()); |
6635 |
09 Mar 22 |
nicklas |
328 |
if (cfg != null && cfg.getElement(xpath) != null) |
6635 |
09 Mar 22 |
nicklas |
329 |
{ |
6635 |
09 Mar 22 |
nicklas |
// This cluster is connected and configured |
6635 |
09 Mar 22 |
nicklas |
331 |
return cluster; |
6635 |
09 Mar 22 |
nicklas |
332 |
} |
6635 |
09 Mar 22 |
nicklas |
333 |
} |
6635 |
09 Mar 22 |
nicklas |
334 |
return current; |
6635 |
09 Mar 22 |
nicklas |
335 |
} |
6635 |
09 Mar 22 |
nicklas |
336 |
|
6635 |
09 Mar 22 |
nicklas |
337 |
/** |
6628 |
07 Mar 22 |
nicklas |
Create an upload source instance for uploading a static script |
6628 |
07 Mar 22 |
nicklas |
inside the reggie.jar file. The path is either a full reference |
6628 |
07 Mar 22 |
nicklas |
to file or a the name of a file in the net.sf.basedb.reggie.grid.scripts |
6628 |
07 Mar 22 |
nicklas |
package. |
6628 |
07 Mar 22 |
nicklas |
@since 4.38 |
6628 |
07 Mar 22 |
nicklas |
343 |
*/ |
6628 |
07 Mar 22 |
nicklas |
344 |
public static UploadSource upload(String path) |
6628 |
07 Mar 22 |
nicklas |
345 |
{ |
6628 |
07 Mar 22 |
nicklas |
346 |
int last = path.lastIndexOf('/'); |
6628 |
07 Mar 22 |
nicklas |
347 |
String name = path; |
6628 |
07 Mar 22 |
nicklas |
348 |
if (last > 0) |
6628 |
07 Mar 22 |
nicklas |
349 |
{ |
6628 |
07 Mar 22 |
nicklas |
350 |
name = path.substring(last+1); |
6628 |
07 Mar 22 |
nicklas |
351 |
} |
6628 |
07 Mar 22 |
nicklas |
352 |
else |
6628 |
07 Mar 22 |
nicklas |
353 |
{ |
6628 |
07 Mar 22 |
nicklas |
354 |
path = "/net/sf/basedb/reggie/grid/scripts/"+name; |
6628 |
07 Mar 22 |
nicklas |
355 |
} |
6656 |
29 Mar 22 |
nicklas |
356 |
InputStream in = Reggie.class.getResourceAsStream(path); |
6656 |
29 Mar 22 |
nicklas |
357 |
if (in == null) throw new ItemNotFoundException(path); |
6656 |
29 Mar 22 |
nicklas |
358 |
return new InputStreamUploadSource(name, in); |
6628 |
07 Mar 22 |
nicklas |
359 |
} |
6628 |
07 Mar 22 |
nicklas |
360 |
|
6653 |
23 Mar 22 |
nicklas |
361 |
/** |
6662 |
01 Apr 22 |
nicklas |
Get a script file as a string. The path is either a full reference |
6662 |
01 Apr 22 |
nicklas |
to file or a the name of a file in the net.sf.basedb.reggie.grid.scripts |
6662 |
01 Apr 22 |
nicklas |
package. |
6662 |
01 Apr 22 |
nicklas |
@since 4.38 |
6662 |
01 Apr 22 |
nicklas |
366 |
*/ |
6662 |
01 Apr 22 |
nicklas |
367 |
public static String getAsString(String path) |
6662 |
01 Apr 22 |
nicklas |
368 |
{ |
6662 |
01 Apr 22 |
nicklas |
369 |
int last = path.lastIndexOf('/'); |
6662 |
01 Apr 22 |
nicklas |
370 |
String name = path; |
6662 |
01 Apr 22 |
nicklas |
371 |
if (last > 0) |
6662 |
01 Apr 22 |
nicklas |
372 |
{ |
6662 |
01 Apr 22 |
nicklas |
373 |
name = path.substring(last+1); |
6662 |
01 Apr 22 |
nicklas |
374 |
} |
6662 |
01 Apr 22 |
nicklas |
375 |
else |
6662 |
01 Apr 22 |
nicklas |
376 |
{ |
6662 |
01 Apr 22 |
nicklas |
377 |
path = "/net/sf/basedb/reggie/grid/scripts/"+name; |
6662 |
01 Apr 22 |
nicklas |
378 |
} |
6662 |
01 Apr 22 |
nicklas |
379 |
return Reggie.getTemplateFile(path); |
6662 |
01 Apr 22 |
nicklas |
380 |
} |
6662 |
01 Apr 22 |
nicklas |
381 |
|
6662 |
01 Apr 22 |
nicklas |
382 |
/** |
6653 |
23 Mar 22 |
nicklas |
If the string is a multi-line string, remove white-space from the beginning of |
6653 |
23 Mar 22 |
nicklas |
each line so that they |
6653 |
23 Mar 22 |
nicklas |
@since 4.38 |
6653 |
23 Mar 22 |
nicklas |
386 |
*/ |
6653 |
23 Mar 22 |
nicklas |
387 |
public static String multilineIndent(String in) |
6653 |
23 Mar 22 |
nicklas |
388 |
{ |
6657 |
30 Mar 22 |
nicklas |
389 |
if (in == null) return null; |
6653 |
23 Mar 22 |
nicklas |
390 |
StringBuilder out = new StringBuilder(); |
6653 |
23 Mar 22 |
nicklas |
391 |
for (String l : in.split("\n")) |
6653 |
23 Mar 22 |
nicklas |
392 |
{ |
6653 |
23 Mar 22 |
nicklas |
393 |
out.append(l.stripLeading()+"\n"); |
6653 |
23 Mar 22 |
nicklas |
394 |
} |
6653 |
23 Mar 22 |
nicklas |
395 |
return out.toString(); |
6653 |
23 Mar 22 |
nicklas |
396 |
} |
4281 |
20 Dec 16 |
nicklas |
397 |
} |