~ubuntu-branches/ubuntu/trusty/gdis/trusty

« back to all changes in this revision

Viewing changes to grid.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Leidert (dale)
  • Date: 2009-04-06 17:12:18 UTC
  • mfrom: (3.1.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090406171218-uizoe126jrq09ytt
Tags: 0.90-1
* New upstream release 0.90.
* Acknowledge NMU (closes: #492994). Thanks to Neil Williams.

* makefile.debian: Upstream doesn't provide a Makefile to edit - so created
  our own.
* debian/compat: Added and set to be 5.
* debian/control: Added Homepage, Vcs* and DM-Upload-Allowed fields.
  (Maintainer): Set to the debichem team with approval by Noèl.
  (Uploaders): Added myself.
  (Build-Depends): Increased debhelper version to 5. Removed glutg3-dev.
  Added dpatch.
  (Standards-Version): Bumped to 3.8.1.
  (Description): Removed homepage. Fixed a typo.
* debian/copyright: Updated, completed and adjusted.
* debian/dirs: Dropped useless file.
* debian/docs: Renamed to debian/gdis.docs.
* debian/menu: Renamed to debian/gdis.menu.
  (section): Fixed accordingly to policy.
* debian/gdis.1: Just some formatting changes.
* debian/gdis.desktop: Added file (with small fixes) provided by Phill Bull
  (LP: #111353).
* debian/gdis.install: Added.
* debian/rules: Cleaned. Installation is now done by dh_install. Make sure,
  the CVS directory is not copied. Added dh_desktop call.
* debian/source.lintian-overrides: makefile.debian is created for Debian but
  lives outside debian/.
* debian/watch: Added.
* debian/README.build: Dropped.
* debian/README.source: Added to be compliant to the policy v3.8.
* debian/patches/Debian_make.dpatch: Added.
  - gdis.h (ELEM_FILE): Moved fix for gdis.elemts path (#399132) to this
    patch.
* debian/patches/00list: Added.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) 2003 by Sean David Fleming
 
3
 
 
4
sean@ivec.org
 
5
 
 
6
This program is free software; you can redistribute it and/or
 
7
modify it under the terms of the GNU General Public License
 
8
as published by the Free Software Foundation; either version 2
 
9
of the License, or (at your option) any later version.
 
10
 
 
11
This program is distributed in the hope that it will be useful,
 
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
GNU General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU General Public License
 
17
along with this program; if not, write to the Free Software
 
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
19
 
 
20
The GNU GPL can also be found at http://www.gnu.org
 
21
*/
 
22
 
 
23
#include <stdio.h>
 
24
#include <string.h>
 
25
#include <stdlib.h>
 
26
#include <unistd.h>
 
27
#include <sys/types.h>
 
28
 
 
29
#ifndef __WIN32
 
30
#include <sys/wait.h>
 
31
#endif
 
32
 
 
33
#include "gdis.h"
 
34
#include "file.h"
 
35
#include "grid.h"
 
36
#include "job.h"
 
37
#include "task.h"
 
38
#include "parse.h"
 
39
#include "model.h"
 
40
#include "grisu_client.h"
 
41
#include "interface.h"
 
42
 
 
43
extern struct sysenv_pak sysenv;
 
44
 
 
45
/* CURRENT - register apps for a GRID destination */
 
46
/* NULL -> not on grid */
 
47
/* TODO - consider storing structs containing more info */
 
48
/*        ie site, app details etc - for faster job building */
 
49
 
 
50
GHashTable *grid_table=NULL;
 
51
/* CURRENT - assume credential already uploaded for the time being */
 
52
gint grid_authenticated=FALSE;
 
53
gchar *myproxy_init=NULL;
 
54
 
 
55
void grid_application_set(const gchar *name, const gchar *value)
 
56
{
 
57
#ifdef WITH_GRISU
 
58
if (grid_table)
 
59
  g_hash_table_replace(grid_table, g_strdup(name), g_strdup(value));
 
60
#else
 
61
return(NULL);
 
62
#endif
 
63
}
 
64
 
 
65
gchar *grid_application_get(const gchar *name)
 
66
{
 
67
#ifdef WITH_GRISU
 
68
if (grid_table)
 
69
  return(g_hash_table_lookup(grid_table, name));
 
70
else
 
71
  return(NULL);
 
72
#else
 
73
return(NULL);
 
74
#endif
 
75
}
 
76
 
 
77
void grid_application_remove(const gchar *name)
 
78
{
 
79
#ifdef WITH_GRISU
 
80
if (grid_table)
 
81
  g_hash_table_remove(grid_table, name);
 
82
#else
 
83
return(NULL);
 
84
#endif
 
85
}
 
86
 
 
87
GList *grid_application_all(void)
 
88
{
 
89
#ifdef WITH_GRISU
 
90
return(g_hash_table_get_keys(grid_table));
 
91
#else
 
92
return(NULL);
 
93
#endif
 
94
}
 
95
 
 
96
GSList *grid_search_by_name(const gchar *name)
 
97
{
 
98
#ifdef WITH_GRISU
 
99
return(grisu_submit_find(name));
 
100
#else
 
101
return(NULL);
 
102
#endif
 
103
}
 
104
 
 
105
/*********************************************/
 
106
/* allocate and initialize a grid job object */
 
107
/*********************************************/
 
108
gpointer grid_new(void)
 
109
{
 
110
struct grid_pak *grid;
 
111
 
 
112
grid = g_malloc(sizeof(struct grid_pak));
 
113
 
 
114
grid->user_vo = NULL;
 
115
grid->jobname = NULL;
 
116
grid->exename = NULL;
 
117
grid->exe_version = NULL;
 
118
grid->jobcode = JOB_UNKNOWN;
 
119
 
 
120
grid->remote_q = NULL;
 
121
grid->remote_root = NULL;
 
122
grid->remote_exe = NULL;
 
123
grid->remote_exe_module = NULL;
 
124
grid->remote_site = NULL;
 
125
 
 
126
grid->remote_exe_type=-1;
 
127
grid->remote_exe_np=1;
 
128
 
 
129
grid->local_cwd = NULL;
 
130
grid->local_input = NULL;
 
131
grid->local_output = NULL;
 
132
 
 
133
return(grid);
 
134
}
 
135
 
 
136
/**************************/
 
137
/* free a grid job object */
 
138
/**************************/
 
139
void grid_free(gpointer data)
 
140
{
 
141
struct grid_pak *grid=data;
 
142
 
 
143
g_assert(grid != NULL);
 
144
 
 
145
g_free(grid->user_vo);
 
146
g_free(grid->jobname);
 
147
g_free(grid->exename);
 
148
g_free(grid->exe_version);
 
149
 
 
150
g_free(grid->remote_q);
 
151
g_free(grid->remote_root);
 
152
g_free(grid->remote_exe);
 
153
g_free(grid->remote_exe_module);
 
154
g_free(grid->remote_site);
 
155
 
 
156
g_free(grid->local_cwd);
 
157
g_free(grid->local_input);
 
158
g_free(grid->local_output);
 
159
 
 
160
g_free(grid);
 
161
}
 
162
 
 
163
/***************************************/
 
164
/* get the DN from an x509 certificate */
 
165
/***************************************/
 
166
// openssl x509 -noout -in usercert.pem -subject
 
167
gchar *grid_get_DN(gchar *certificate_fullpath)
 
168
{
 
169
gint i, j, status;
 
170
gchar *cmd, *out, *err, *subject=NULL;
 
171
GError *error=NULL;
 
172
 
 
173
cmd = g_strdup_printf("openssl x509 -noout -in %s -subject", certificate_fullpath);
 
174
 
 
175
/* TODO - get the output */
 
176
if (g_spawn_command_line_sync(cmd, &out, &err, &status, &error))
 
177
  {
 
178
  for (i=0 ; i<8000 ; i++)
 
179
    {
 
180
    if (out[i] == '/')
 
181
      {
 
182
/* not sure why but plain g_strdup adds a crappy char (null?) */
 
183
/* to the string, so scan for the end and use strndup instead */
 
184
      for (j=i ; j<9000 ; j++)
 
185
        {
 
186
        if (out[j] == '\0')
 
187
          break;
 
188
        }
 
189
      subject = g_strndup(&out[i], j-i-1);
 
190
      break;
 
191
      }
 
192
    }
 
193
  }
 
194
g_free(cmd);
 
195
 
 
196
return(subject);
 
197
}
 
198
 
 
199
gboolean grid_credential_get()
 
200
{
 
201
return(FALSE);
 
202
}
 
203
 
 
204
/*******************************************************/
 
205
/* set valid auth in case of external means (eg) grisu */
 
206
/*******************************************************/
 
207
/* TODO - could chuck into sysenv eventually */
 
208
void grid_auth_set(gint value)
 
209
{
 
210
grid_authenticated=value;
 
211
}
 
212
 
 
213
/*********************************************/
 
214
/* verify current authentication information */
 
215
/*********************************************/
 
216
gint grid_auth_check(void)
 
217
{
 
218
#ifdef WITH_GRISU
 
219
GSList *list;
 
220
 
 
221
/* perform a grisu operation that requires authentication */
 
222
/* NB: use anything fast (as long as auth info is in the header) */
 
223
//list = grisu_fqans_get();
 
224
list = grisu_site_list();
 
225
if (list)
 
226
  {
 
227
  g_slist_free(list);
 
228
  grid_authenticated = TRUE;
 
229
  return(TRUE);
 
230
  }
 
231
#endif
 
232
 
 
233
grid_authenticated = FALSE;
 
234
 
 
235
return(FALSE);
 
236
}
 
237
 
 
238
/****************************************************/
 
239
/* upload a temporary credential to a remote server */
 
240
/****************************************************/
 
241
/* TODO - if grid_passwd is NULL -> use stdin */
 
242
#define DEBUG_GRID_CREDENTIAL_INIT 0
 
243
void grid_credential_init(const gchar *grid_password)
 
244
{
 
245
#ifdef WITH_GRISU
 
246
gint inp, out, err;
 
247
gchar **argv, **envp;
 
248
const gchar *username, *password, *server, *port;
 
249
GError *error=NULL;
 
250
GPid pid;
 
251
FILE *fpi, *fpo, *fpe;
 
252
 
 
253
/* TODO - informative user error messages */
 
254
if (!grid_password)
 
255
  return;
 
256
if (grid_authenticated)
 
257
  return;
 
258
if (!myproxy_init)
 
259
  return;
 
260
 
 
261
username = grisu_username_get();
 
262
password = grisu_password_get();
 
263
server = grisu_myproxy_get();
 
264
port = grisu_myproxyport_get();
 
265
 
 
266
#if DEBUG_GRID_CREDENTIAL_INIT
 
267
printf("Credential for: "); 
 
268
printf("%s : %s -> %s : %s\n", username, password, server, port);
 
269
#endif
 
270
 
 
271
/* FIXME - authentication issues with myproxy/myproxy2 */
 
272
/* solution is to point at myproxy2 and set */
 
273
/* MYPROXY_SERVER_DN /C=AU/O=APACGrid/OU=VPAC/CN=myproxy2.arcs.org.au */
 
274
 
 
275
/* FIXME - need to ensure enviroment has GT_PROXY_MODE set to "old" */
 
276
/* unless markus fixes grisu's credential retrieval */
 
277
/* build argument vector */
 
278
 
 
279
/* FIXME - implement this */
 
280
envp = g_malloc(3 * sizeof(gchar *));
 
281
*(envp) = g_strdup("GT_PROXYMODE=old");
 
282
*(envp+1) = g_strdup("MYPROXY_SERVER_DN=/C=AU/O=APACGrid/OU=VPAC/CN=myproxy2.arcs.org.au");
 
283
*(envp+2) = NULL;
 
284
 
 
285
 
 
286
argv = g_malloc(10 * sizeof(gchar *));
 
287
/* NB: need full path to executable */
 
288
*(argv) = g_strdup(myproxy_init);
 
289
 
 
290
*(argv+1) = g_strdup("-l");
 
291
*(argv+2) = g_strdup(username);
 
292
 
 
293
/* small lifetime while we debug */
 
294
*(argv+3) = g_strdup("-c");
 
295
*(argv+4) = g_strdup("1");
 
296
 
 
297
*(argv+5) = g_strdup("-a");
 
298
 
 
299
*(argv+6) = g_strdup("-S");
 
300
 
 
301
*(argv+7) = g_strdup("-s");
 
302
*(argv+8) = g_strdup(server);
 
303
*(argv+9) = NULL;
 
304
 
 
305
 
 
306
/* spawn process */
 
307
if (g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
 
308
                             NULL, NULL, &pid, &inp, &out, &err, &error))
 
309
  {
 
310
 
 
311
  if (pid)
 
312
    {
 
313
/* parent - wait until child is done */
 
314
//printf("parent: waiting for child...\n");
 
315
 
 
316
fpi = fdopen(inp, "a");
 
317
fpo = fdopen(out, "r");
 
318
fpe = fdopen(err, "r");
 
319
 
 
320
/* NB: -S will make myproxy prompt for grid passphrase */
 
321
/* and then the credential password once only */
 
322
/* CURRENT - not sure why this isnt working - it seems */
 
323
/* to work if run manually from the command line */
 
324
 
 
325
fprintf(fpi, "%s\n", grid_password);
 
326
fflush(fpi);
 
327
 
 
328
/* CURRENT - this seems to fix the problem! */
 
329
/* obviously a delay is needed while myproxy-init processes the */
 
330
/* grid_password to generate a local proxy */
 
331
/* the problem is - how to we poll stdout to know when to send the */
 
332
/* passphrase ... which is probably better than an arbitrary sleep */
 
333
 
 
334
#ifndef WIN32
 
335
sleep(5);
 
336
#endif
 
337
 
 
338
/* test if process has terminated */
 
339
/* note that if it has - child is reaped and we cant call waitpid() again */
 
340
 
 
341
#ifndef __WIN32
 
342
if (waitpid(pid, NULL, WNOHANG) > 0)
 
343
  {
 
344
printf("Bad password.\n");
 
345
 
 
346
    g_spawn_close_pid(pid);
 
347
    grid_authenticated = FALSE;
 
348
 
 
349
  return;
 
350
  }
 
351
#endif
 
352
 
 
353
//printf("waitpid 4: %d\n", waitpid(pid, NULL, WEXITED | WNOHANG));
 
354
 
 
355
 
 
356
fprintf(fpi, "%s\n", password);
 
357
fflush(fpi);
 
358
fclose(fpi);
 
359
 
 
360
#if DEBUG_GRID_CREDENTIAL_INIT
 
361
gchar *line;
 
362
do
 
363
  {
 
364
  line = file_read_line(fpo);
 
365
  printf("FORK, stdout: %s\n", line);
 
366
  g_free(line);
 
367
  }
 
368
while(line != NULL);
 
369
do
 
370
  {
 
371
  line = file_read_line(fpe);
 
372
  printf("FORK, stderr : %s\n", line);
 
373
  g_free(line);
 
374
  }
 
375
while(line != NULL);
 
376
#endif
 
377
 
 
378
/* cleanup */
 
379
fclose(fpo);
 
380
fclose(fpe);
 
381
 
 
382
close(inp);
 
383
close(out);
 
384
close(err);
 
385
 
 
386
#ifndef __WIN32
 
387
    waitpid(pid, NULL, WEXITED);
 
388
#endif
 
389
 
 
390
    g_spawn_close_pid(pid);
 
391
 
 
392
    grid_authenticated = TRUE;
 
393
 
 
394
 
 
395
/* sleep - give the uploaded proxy some time to "stick" to the server */
 
396
/* FIXME - better to poll (myproxy-logon?) for the credential */
 
397
printf("Uploading Credential, please wait ...\n");
 
398
 
 
399
#ifndef WIN32
 
400
sleep(5);
 
401
#endif
 
402
 
 
403
printf("Done.\n");
 
404
 
 
405
    }
 
406
  }
 
407
else
 
408
  {
 
409
  printf("Failed to upload credential, myproxy-init not found or bad connectivity?\n");
 
410
  }
 
411
 
 
412
g_strfreev(argv);
 
413
g_strfreev(envp);
 
414
#endif
 
415
 
 
416
return;
 
417
}
 
418
 
 
419
/****************************************************/
 
420
/* get short text message describing current status */
 
421
/****************************************************/
 
422
const gchar *grid_get_status()
 
423
{
 
424
if (grid_authenticated)
 
425
  return("Authenticated");
 
426
else
 
427
  return("Not authenticated");
 
428
}
 
429
 
 
430
/***********************************************************/
 
431
/* generate a random alphabetical string of specified size */
 
432
/***********************************************************/
 
433
gchar *grid_random_alpha(gint length)
 
434
{
 
435
gint i;
 
436
GRand *r;
 
437
GString *text;
 
438
 
 
439
r = g_rand_new();
 
440
text = g_string_new(NULL);
 
441
 
 
442
for (i=length ; i-- ; )
 
443
  {
 
444
  g_string_sprintfa(text, "%c", g_rand_int_range(r, 'a', 'z'));
 
445
  }
 
446
 
 
447
g_rand_free(r);
 
448
 
 
449
return(g_string_free(text, FALSE));
 
450
}
 
451
 
 
452
/************************************************************/
 
453
/* generate a random alpha-numeric string of specified size */
 
454
/************************************************************/
 
455
gchar *grid_random_alphanum(gint length)
 
456
{
 
457
gint i, decide;
 
458
GRand *r;
 
459
GString *text;
 
460
 
 
461
r = g_rand_new();
 
462
text = g_string_new(NULL);
 
463
 
 
464
/* NB: some systems require an alphabetical character first */
 
465
g_string_sprintfa(text, "%c", g_rand_int_range(r, 'a', 'z'));
 
466
i=1;
 
467
while (i<length)
 
468
  {
 
469
  decide = g_rand_int_range(r, 0, 99);
 
470
  if (decide < 50)
 
471
    g_string_sprintfa(text, "%c", g_rand_int_range(r, 'a', 'z'));
 
472
  else
 
473
    g_string_sprintfa(text, "%c", g_rand_int_range(r, '0', '9'));
 
474
  i++;
 
475
  }
 
476
 
 
477
g_rand_free(r);
 
478
 
 
479
return(g_string_free(text, FALSE));
 
480
}
 
481
 
 
482
/**********************************/
 
483
/* attempt to upload a credential */
 
484
/**********************************/
 
485
gint grid_connect(gint method)
 
486
{
 
487
#ifdef WITH_GRISU
 
488
switch (method)
 
489
  {
 
490
  case GRID_MYPROXY:
 
491
    grid_auth_check();
 
492
    break;
 
493
 
 
494
  case GRID_LOCALPROXY:
 
495
/* if successful, send info to grisu client for soap header */
 
496
/* CURRENT - myproxy-init fed with grid_passwd */
 
497
    grid_credential_init(grisu_password_get());
 
498
    break;
 
499
  }
 
500
 
 
501
grisu_auth_set(TRUE);
 
502
 
 
503
return(TRUE);
 
504
 
 
505
#else
 
506
return(FALSE);
 
507
#endif
 
508
}
 
509
 
 
510
/**************/
 
511
/* initialize */
 
512
/**************/
 
513
void grid_setup(void)
 
514
{
 
515
if (!grid_table)
 
516
  {
 
517
#ifdef WITH_GRISU
 
518
  grisu_init();
 
519
 
 
520
  if (!myproxy_init)
 
521
    myproxy_init = g_find_program_in_path("myproxy-init");
 
522
  if (!myproxy_init)
 
523
    printf("grid_setup() Warning. Failed to locate: myproxy-init\n");
 
524
 
 
525
#endif
 
526
 
 
527
  grid_table = g_hash_table_new(g_str_hash, g_str_equal);
 
528
  }
 
529
}
 
530
 
 
531
/***********/
 
532
/* cleanup */
 
533
/***********/
 
534
void grid_cleanup(void)
 
535
{
 
536
g_hash_table_destroy(grid_table);
 
537
}
 
538
 
 
539
/*****************************************/
 
540
/* process completed jobs after download */
 
541
/*****************************************/
 
542
/* this could be generic, since we assume output is on local filestore */
 
543
void grid_process_job(const gchar *job_name, GSList *file_list)
 
544
{
 
545
#ifdef WITH_GRISU
 
546
gint type;
 
547
gchar *ext, *name;
 
548
gchar *input=NULL, *output=NULL;
 
549
GSList *item;
 
550
struct model_pak *model;
 
551
 
 
552
type = grisu_job_type(job_name);
 
553
 
 
554
switch (type)
 
555
  {
 
556
  case JOB_GULP:
 
557
    printf("processing GULP job ... \n");
 
558
 
 
559
    for (item=file_list ; item ; item=g_slist_next(item))
 
560
      {
 
561
      name = item->data;
 
562
 
 
563
/* skip if no extension */
 
564
      ext = file_extension_get(name);
 
565
      if (!ext)
 
566
        continue;
 
567
 
 
568
/* load results file as preference for coords */
 
569
      if (g_strncasecmp(ext, "res", 3) == 0)
 
570
        input = name;
 
571
/* only load original input file if no results file found */
 
572
      if (g_strncasecmp(ext, "gin", 3) == 0)
 
573
        {
 
574
        if (!input)
 
575
          input = name;
 
576
        }
 
577
/* output file containing energies etc */
 
578
      if (g_strncasecmp(ext, "go", 2) == 0)
 
579
        output = name;
 
580
      }
 
581
 
 
582
if (!output)
 
583
  {
 
584
  printf("No GULP output file found. Failed job?\n");
 
585
  break;
 
586
  }
 
587
if (!input)
 
588
  {
 
589
  printf("No GULP input file found. Failed authentication?\n");
 
590
  break;
 
591
  }
 
592
 
 
593
/* create new model for the results */
 
594
    model = model_new();
 
595
/* read main data from the res file (correct charges etc.) */
 
596
    read_gulp(input, model);
 
597
/* graft to the model tree, so subsequent GULP read doesn't replace coords */
 
598
 
 
599
/* CURRENT - give the loaded model the same name as the job ... better method? */
 
600
    if (model->basename)
 
601
      {
 
602
      g_free(model->basename);
 
603
//      model->basename = g_strdup(job_name);
 
604
//      model->basename = g_strdup(input);
 
605
 
 
606
      model->basename = parse_strip(input);
 
607
      }
 
608
 
 
609
sysenv.active_model = model;
 
610
 
 
611
    tree_model_add(model);
 
612
/* get the output energy/phonons etc. */
 
613
    read_gulp_output(output, model);
 
614
 
 
615
/* FIXME - if the GULP job fails - model_prep() isnt called, and the */
 
616
/* model camera isnt initialized => error trap when gdis tries to visualize */
 
617
    if (!model->camera)
 
618
      {
 
619
printf("WARNING: GULP calculation has possibly failed.\n");
 
620
      model_prep(model);
 
621
      }
 
622
/* TODO - return model - so gui part decides whether to force a select/display or not */
 
623
//gui_model_select(model);
 
624
 
 
625
    break;
 
626
 
 
627
  case JOB_GAMESS:
 
628
    printf("processsing GAMESS job ... \n");
 
629
 
 
630
    for (item=file_list ; item ; item=g_slist_next(item))
 
631
      {
 
632
      name = item->data;
 
633
      ext = file_extension_get(name);
 
634
/* skip if no extension */
 
635
      if (!ext)
 
636
        continue;
 
637
 
 
638
      if (g_strncasecmp(ext, "gmot", 4) == 0)
 
639
        output = name;
 
640
      }
 
641
 
 
642
    if (output)
 
643
      {
 
644
/* create new model for the results */
 
645
      model = model_new();
 
646
/* read main data from the res file (correct charges etc.) */
 
647
      read_gms_out(output, model);
 
648
 
 
649
      if (model->basename)
 
650
        {
 
651
        g_free(model->basename);
 
652
        model->basename = g_strdup(job_name);
 
653
        }
 
654
 
 
655
sysenv.active_model = model;
 
656
 
 
657
      tree_model_add(model);
 
658
 
 
659
/* FIXME - if the job fails - model_prep() isnt called, and the */
 
660
/* model camera isnt initialized => error trap when gdis tries to visualize */
 
661
    if (!model->camera)
 
662
      {
 
663
printf("WARNING: GAMESS calculation has possibly failed.\n");
 
664
      model_prep(model);
 
665
      }
 
666
 
 
667
/* TODO - return model - so gui part decides whether to force a select/display or not */
 
668
//gui_model_select(model);
 
669
//sysenv.active_model = model;
 
670
 
 
671
      }
 
672
    else
 
673
      {
 
674
printf("No GAMESS output file found. Failed job?\n");
 
675
      }
 
676
 
 
677
    break;
 
678
 
 
679
  default:
 
680
    printf("Error, unknown job\n");
 
681
    return;
 
682
  }
 
683
#endif
 
684
}
 
685
 
 
686
/***************************/
 
687
/* download completed jobs */
 
688
/***************************/
 
689
GSList *grid_download_job(const gchar *name)
 
690
{
 
691
#ifdef WITH_GRISU
 
692
gchar *remote_cwd, *local, *remote;
 
693
GSList *item, *list, *results=NULL;
 
694
 
 
695
printf("Getting result files for: %s\n", name);
 
696
 
 
697
remote_cwd = grisu_job_cwd(name);
 
698
 
 
699
/* TODO - get job type (GULP etc) from name (eg grisu_job_type()) and filter */
 
700
//printf("Working directory = %s\n", cwd);
 
701
 
 
702
if (remote_cwd)
 
703
  {
 
704
  list = grisu_file_list(remote_cwd);
 
705
 
 
706
  for (item=list ; item ; item=g_slist_next(item))
 
707
    {
 
708
    gchar *file = item->data;
 
709
    printf("[%s]\n", file);
 
710
// TODO - strictly - should be the job's local_output destination here */
 
711
    local =  g_build_filename(sysenv.cwd, file, NULL);
 
712
    remote =  g_build_filename(remote_cwd, file, NULL);
 
713
 
 
714
//printf("Transferring [%s] -> [%s]\n", remote, local);
 
715
 
 
716
/* if download is successful add to results list for post-processing */
 
717
    if (grisu_file_download(remote, local))
 
718
      results = g_slist_prepend(results, local);
 
719
 
 
720
    g_free(remote);
 
721
    }
 
722
  g_free(remote_cwd);
 
723
  }
 
724
 
 
725
return(results);
 
726
#else
 
727
return(NULL);
 
728
#endif
 
729
}
 
730
 
 
731
/**********************************/
 
732
/* background task job submission */
 
733
/**********************************/
 
734
void grid_job_start(gpointer data)
 
735
{
 
736
#ifdef WITH_GRISU
 
737
gint alen, rlen;
 
738
gchar *jobxml, *value, *tmp;
 
739
gchar *fs_absolute, *fs_relative;
 
740
gchar *local, *remote;
 
741
GHashTable *details;
 
742
GSList *list;
 
743
struct grid_pak *grid=data;
 
744
 
 
745
g_assert(grid != NULL);
 
746
g_assert(grid->exename != NULL);
 
747
g_assert(grid->remote_q != NULL);
 
748
 
 
749
grid->jobcode = grisu_job_type(grid->exename);
 
750
grid->user_vo = g_strdup(grisu_vo_get());
 
751
 
 
752
grid->remote_site = grisu_site_name(grid->remote_q);
 
753
if (!grid->remote_site)
 
754
  {
 
755
  printf("Could not determine submission site.\n");
 
756
  return;
 
757
  }
 
758
 
 
759
list = grisu_application_versions(grid->exename, grid->remote_site);
 
760
if (list)
 
761
  {
 
762
/* CURRENT - just use the first entry */
 
763
  if (grid->exe_version)
 
764
    g_free(grid->exe_version);
 
765
  grid->exe_version = g_strdup(list->data); 
 
766
  }
 
767
else
 
768
  {
 
769
/* strictly, not all programs would require a version */
 
770
/* eg gamess does, but gulp doesnt */
 
771
  printf("Warning: could not determine executable version of [%s] at [%s]\n", grid->exename, grid->remote_site);
 
772
  }
 
773
 
 
774
details = grisu_application_details(grid->exename, grid->remote_site);
 
775
if (details)
 
776
  {
 
777
  tmp = g_hash_table_lookup(details, "Executables");
 
778
  if (!tmp)
 
779
    {
 
780
    printf("Failed to locate executable on remote site.\n");
 
781
    return;
 
782
    }
 
783
  grid->remote_exe = g_strdup(tmp);
 
784
 
 
785
  tmp = g_hash_table_lookup(details, "Module");
 
786
  if (tmp)
 
787
    grid->remote_exe_module = g_strdup(tmp);
 
788
 
 
789
//printf("Requiring module [%s]\n", grid->remote_exe_module);
 
790
 
 
791
/* CURRENT - prefer serial over parallel */
 
792
  value = g_hash_table_lookup(details, "ParallelAvail");
 
793
  if (g_strncasecmp(value, "true", 4) == 0)
 
794
    {
 
795
    grid->remote_exe_type = GRID_MPI;
 
796
/* CURRENT - hack to force // ie mpi */
 
797
    grid->remote_exe_np = 2;
 
798
    }
 
799
 
 
800
/* CURRENT - prefer serial over parallel */
 
801
  value = g_hash_table_lookup(details, "SerialAvail");
 
802
  if (g_strncasecmp(value, "true", 4) == 0)
 
803
    {
 
804
    grid->remote_exe_type = GRID_SERIAL;
 
805
    grid->remote_exe_np = 1;
 
806
    }
 
807
 
 
808
  if (grid->remote_exe_type == -1)
 
809
    {
 
810
    printf("Failed to determine serial/parallel invocation method on remote site.\n");
 
811
    return;
 
812
    }
 
813
  }
 
814
else
 
815
  {
 
816
  printf("Failed to get application details from MDS.\n");
 
817
  return;
 
818
  }
 
819
 
 
820
// -----------------
 
821
 
 
822
grid->jobname = grisu_jobname_request(grid->jobcode);
 
823
if (!grid->jobname)
 
824
  {
 
825
  printf("Failed to create job, not authenticated?\n");
 
826
  return;
 
827
  }
 
828
 
 
829
/* calculate mount point */
 
830
fs_absolute = grisu_absolute_job_dir(grid->jobname, grid->remote_q, grid->user_vo);
 
831
if (!fs_absolute)
 
832
  {
 
833
  printf("Failed to locate a valid remote filesystem for VO [%s] at [%s]\n", grid->user_vo, grid->remote_site);
 
834
  return;
 
835
  }
 
836
 
 
837
fs_relative = grisu_relative_job_dir(grid->jobname);
 
838
g_assert(fs_relative != NULL);
 
839
 
 
840
alen = strlen(fs_absolute);
 
841
rlen = strlen(fs_relative);
 
842
if (alen > rlen)
 
843
  grid->remote_root = g_strndup(fs_absolute, alen-rlen);
 
844
else
 
845
  {
 
846
  printf("Bad filesystem returned by grisu.\n");
 
847
// cope as best we can
 
848
  grid->remote_root = g_strdup(fs_absolute);
 
849
  }
 
850
 
 
851
//printf("Remote root: %s\n", grid->remote_root);
 
852
 
 
853
/* upload stage */
 
854
 
 
855
/* TODO - stat the file to ensure it was written */
 
856
if (!grid->local_input || !grid->local_cwd)
 
857
  {
 
858
  printf("Error, job input file not correctly written.\n");
 
859
  return;
 
860
  }
 
861
 
 
862
/* TODO - could do this earlier as well ... */
 
863
switch (grid->jobcode)
 
864
  {
 
865
  case JOB_GAMESS:
 
866
    grid->local_output = parse_extension_set(grid->local_input, "gmot");
 
867
    break;
 
868
  case JOB_GULP:
 
869
    grid->local_output = parse_extension_set(grid->local_input, "got");
 
870
    break;
 
871
  }
 
872
 
 
873
local = g_build_filename(grid->local_cwd, grid->local_input, NULL);
 
874
remote = g_build_filename(fs_absolute, grid->local_input, NULL);
 
875
 
 
876
//printf("upload [%s] -> [%s]\n", local, remote);
 
877
 
 
878
grisu_file_upload(local, remote);
 
879
 
 
880
g_free(local);
 
881
g_free(remote);
 
882
 
 
883
 
 
884
jobxml = grisu_xml_create(grid);
 
885
 
 
886
//printf(" *** XML:\n%s\n", jobxml);
 
887
 
 
888
grisu_job_configure(grid->jobname, jobxml);
 
889
grisu_job_submit(grid->jobname, grid->user_vo);
 
890
 
 
891
g_free(fs_absolute);
 
892
g_free(fs_relative);
 
893
g_free(jobxml);
 
894
 
 
895
#endif
 
896
}
 
897
 
 
898
/*******************/
 
899
/* completion task */
 
900
/*******************/
 
901
void grid_job_stop(gpointer data)
 
902
{
 
903
struct grid_pak *grid=data;
 
904
 
 
905
/* TODO - free the grid structre */
 
906
grid_free(grid);
 
907
 
 
908
#ifdef WITH_GUI
 
909
grid_task_stop();
 
910
#endif
 
911
 
 
912
/* refresh all jobs */
 
913
/* FIXME - too expensive to keep doing all the time */
 
914
/* FIXME - do this at start (eg when connecting ... and only add/del subsequently) */
 
915
//gui_job_refresh_all();
 
916
}
 
917
 
 
918
/*******************************************************/
 
919
/* submit a grid job (potentially from setup a dialog) */
 
920
/*******************************************************/
 
921
/* name = application name (eg "gulp") */
 
922
gint grid_job_submit(const gchar *name, gpointer data)
 
923
{
 
924
#ifdef WITH_GRISU
 
925
gchar *remote_q;
 
926
struct grid_pak *grid=data;
 
927
 
 
928
/* checks */
 
929
g_assert(grid != NULL);
 
930
 
 
931
/* test we have a valid grid destination */
 
932
remote_q = grid_application_get(name);
 
933
if (!remote_q)
 
934
  {
 
935
  printf("No valid destination queue registered for: %s\n", name);
 
936
  return(FALSE);
 
937
  }
 
938
 
 
939
#ifdef WITH_GUI
 
940
if (!grid_task_start())
 
941
  return(FALSE);
 
942
#endif
 
943
 
 
944
grid->exename = g_strdup(name);
 
945
grid->remote_q = g_strdup(remote_q);
 
946
 
 
947
/* submit and lock model */
 
948
task_new("grid", grid_job_start, grid, grid_job_stop, grid, NULL);
 
949
 
 
950
return(TRUE);
 
951
#else
 
952
printf("No grid support installed.\n");
 
953
 
 
954
return(FALSE);
 
955
#endif
 
956
}
 
957