[ARVADOS] updated: 5c1f03ef1ae45d3ac222542d33b3125ce8678d65

git at public.curoverse.com git at public.curoverse.com
Fri Oct 3 10:48:03 EDT 2014


Summary of changes:
 apps/workbench/Gemfile                             |   1 +
 apps/workbench/Gemfile.lock                        |   4 +
 .../workbench/app/assets/javascripts/log_viewer.js |   2 +-
 .../app/controllers/application_controller.rb      |  16 +-
 .../app/controllers/collections_controller.rb      |  28 +-
 .../controllers/pipeline_instances_controller.rb   |  18 +-
 apps/workbench/app/helpers/application_helper.rb   |   2 +-
 apps/workbench/app/models/arvados_base.rb          |   2 +-
 apps/workbench/app/models/collection.rb            |   2 +-
 apps/workbench/app/models/node.rb                  |   2 +-
 apps/workbench/app/models/pipeline_instance.rb     |   8 +-
 apps/workbench/app/models/user.rb                  |   2 +-
 apps/workbench/app/models/virtual_machine.rb       |   2 +-
 apps/workbench/app/views/jobs/_show_log.html.erb   |  48 ++-
 .../app/views/projects/_show_dashboard.html.erb    |  49 ++-
 apps/workbench/config/application.default.yml      |   3 +
 .../test/functional/collections_controller_test.rb |  37 +-
 .../pipeline_instances_controller_test.rb          |  68 ++++
 apps/workbench/test/integration/jobs_test.rb       |  56 +++
 .../test/integration/pipeline_instances_test.rb    |  41 +++
 apps/workbench/test/integration/projects_test.rb   |  11 +
 apps/workbench/test/test_helper.rb                 |   1 +
 sdk/cli/bin/crunch-job                             | 377 ++++++++++++---------
 .../app/controllers/arvados/v1/jobs_controller.rb  |   9 +-
 services/api/app/models/arvados_model.rb           |   6 +
 services/api/app/models/job.rb                     |  44 ++-
 services/api/config/application.default.yml        |  26 +-
 services/api/config/routes.rb                      |   1 +
 services/api/script/crunch-dispatch.rb             | 204 +++++++----
 services/api/test/fixtures/collections.yml         |  14 +
 services/api/test/fixtures/jobs.yml                |  37 ++
 services/api/test/fixtures/links.yml               |  14 +
 services/api/test/fixtures/pipeline_instances.yml  |  16 +
 services/api/test/fixtures/pipeline_templates.yml  |  27 ++
 .../functional/arvados/v1/jobs_controller_test.rb  |  17 +-
 services/api/test/integration/jobs_api_test.rb     |   2 +-
 services/api/test/unit/job_test.rb                 |  62 +++-
 services/fuse/tests/test_mount.py                  |   3 +-
 38 files changed, 951 insertions(+), 311 deletions(-)

       via  5c1f03ef1ae45d3ac222542d33b3125ce8678d65 (commit)
       via  e5c3609b5ef99cde98e277881fc5b1c53d33df45 (commit)
       via  a8bc91af9fa285665c1e2304bff956bf12a56ec2 (commit)
       via  e8376cfb9deac7a50651061e2be99a4bc0c46338 (commit)
       via  c1a82be63ffc3b8aa853025672d486758ffc86e6 (commit)
       via  256ceb11e3b67dbe68b955ed09ac0df9f6cda2ba (commit)
       via  2198f66d230634ab4e7e511e176bfbc4af632f0a (commit)
       via  60998a3875f79482533976e6e0ee0f99a9589c46 (commit)
       via  89e7c751bc5eb9ac467f607c9e172e44c1690f4c (commit)
       via  7d9cfb6e0716239f996bae054bc9345a663e0b7e (commit)
       via  2fcc6fabb45befcc2ee4fe237744d6e3df5c4e39 (commit)
       via  62790d76daf181a457d8f47741721967cd9cb7d9 (commit)
       via  2935de4fbccf43b7daedb9412f2ada1bf65c52ab (commit)
       via  23acabd1c9685b0a30027a643ebc10b25d3985d3 (commit)
       via  a8bd120b4b5056e7a688e6ce4a60c1251fe7cb0f (commit)
       via  165a36741ced8d09ec15aa30873e51dab2b3e215 (commit)
       via  5d006b95fdcbb48afffef8272b4d2071acb5221b (commit)
       via  754495b451fb7dc65fe2d2c43fa4876638b0be66 (commit)
       via  9378424698db0e02856d09586333cac9142331b2 (commit)
       via  bd99df2e6c5f7bb0b75c7fa2f1a9c1c2defeca8a (commit)
       via  4ff61dd25a70e6467bbafeaaf794cc381f684384 (commit)
       via  196b4b55725db26af4000162329421c73ca893af (commit)
       via  edc5e4b6645b9b983a85a892bf3d3ad1432a657d (commit)
       via  359d96e3442f93094703a6966aecca9b0a90f55b (commit)
       via  d9d74825806615a539da950686ae801bbbf60e24 (commit)
       via  e910d13fc5fc63a86f20be3b758c08db3d429bc6 (commit)
       via  4769d3156e5d486837f7eb524ab5ca798ed090dc (commit)
       via  3ee8ac519f0c3f3fd211372d2a4699586d5c2aa8 (commit)
       via  d9df153743ada521cb42852ce2b4879b1981bbd9 (commit)
       via  3ff644b461b69c38418384e532e3741a07333daf (commit)
       via  dd0f2323bd5fbcef6a3921c45d6e3025a77d2e35 (commit)
       via  9b16ff9eb231584fcfda5eed029b1c1b08a0b819 (commit)
       via  34e461fe9d33283d8e2135802ee9accb30a5e34f (commit)
       via  70b1ac0b5a02879bb5b60f651bf0810e8362f074 (commit)
       via  8f1554cf9cfc279e0127d7ea2c7a79a98e323f13 (commit)
       via  407f1cf196f60f4af21c89cbdccb2c98e05518fb (commit)
       via  54a951255316417a42a3bd8c77aaa0b58d180440 (commit)
       via  3412c35d3da73b94c133099dceab9770fb465165 (commit)
       via  74cdb4454d4adc6b403c207169313f37332d8aac (commit)
       via  a5c4a1d17c5ea0916ae5049c19841d820f850a84 (commit)
       via  1afcc0c00dc9f901acce6d5b166ee51c497f8555 (commit)
       via  3dfc071494cbb0386ecd7269c72a435fc7f9cc24 (commit)
       via  5233f1d185706095d2f045b8431781c9a421ee16 (commit)
       via  6b17ef224b600b3ce889546d648df43d8aea81f4 (commit)
       via  92d5df330b86fb4c279a6e030258b860bed37358 (commit)
       via  3cdc055b90fd859cbd0e101becb4abd78f4d467f (commit)
       via  a4679fb93b4b835509cc77f9bf2fdce02d40520e (commit)
       via  5a341ad3a358bfadb96c83fb95acb7ce3f50cd83 (commit)
       via  4f41341675c108e9ffa4e5ba15b8bca521152a67 (commit)
       via  521df5cd1e19a671a4f940128c5c61930df9c8bb (commit)
       via  74bcc470f33cd47ca4106a7565871c07c40f9c00 (commit)
       via  641a04fc2dd876440ed983a4cdf0e03f188040c1 (commit)
       via  070ca0d5fdd81ed1d3a32fbfc4d1329bb911bdf1 (commit)
       via  2873926cdbfc8012b276db11d24cea3ad6a4bdd4 (commit)
       via  936ea7131a5c0e254ef213e5e2fe390e4e52e872 (commit)
       via  8bc77d6ee612217cfb50bca997ce3b94c19637e9 (commit)
       via  caa5dd776dfad5e50592a5cc2824c70ac3474b46 (commit)
       via  469f117ead24509639fb5b6ba6c9bd1b6067460c (commit)
       via  4671db01d21dad219582444592e99a74d1fa35d8 (commit)
       via  362be0f8b6b1d559e041c8cda7d9f154fb93ee97 (commit)
      from  75be7487c2bbd83aa5116aa5f8ade5ddf31501da (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 5c1f03ef1ae45d3ac222542d33b3125ce8678d65
Merge: e5c3609 60998a3
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Oct 3 10:47:13 2014 -0400

    3775: Merge branch 'master' into 3775-fetch-git-repo


commit e5c3609b5ef99cde98e277881fc5b1c53d33df45
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Oct 3 10:42:23 2014 -0400

    3775: Remove redundant log message.

diff --git a/sdk/cli/bin/crunch-job b/sdk/cli/bin/crunch-job
index 8a80f9c..eff48a2 100755
--- a/sdk/cli/bin/crunch-job
+++ b/sdk/cli/bin/crunch-job
@@ -424,7 +424,6 @@ else {
       $repo = "$repo/.git";
     }
     $repo_location = 'local';
-    Log(undef, "Using local repository '$repo'");
   } else {
     # $repo is none of the above. It must be the name of a hosted
     # repository.

commit a8bc91af9fa285665c1e2304bff956bf12a56ec2
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Oct 3 10:41:32 2014 -0400

    3775: Clean up reporting of exit codes: say "0 with signal 2", not "512".

diff --git a/sdk/cli/bin/crunch-job b/sdk/cli/bin/crunch-job
index 04ff82f..8a80f9c 100755
--- a/sdk/cli/bin/crunch-job
+++ b/sdk/cli/bin/crunch-job
@@ -376,7 +376,7 @@ if (!defined $no_clear_tmp) {
     freeze_if_want_freeze ($cleanpid);
     select (undef, undef, undef, 0.1);
   }
-  Log (undef, "Cleanup command exited $?");
+  Log (undef, "Cleanup command exited ".exit_status_s($?));
 }
 
 
@@ -465,7 +465,7 @@ else {
     # if $local_repo is already initialized:
     `$gitcmd init --bare`;
     if ($?) {
-      croak("Error: $gitcmd init --bare exited $?");
+      croak("Error: $gitcmd init --bare exited ".exit_status_s($?));
     }
 
     # If $treeish looks like a hash (or abbrev hash) we look it up in
@@ -473,10 +473,11 @@ else {
     # do that with tags/branches though -- those change over time, so
     # they should always be resolved by the remote repo.)
     if ($treeish =~ /^[0-9a-f]{3,40}$/s) {
-      my $sha1 = `$gitcmd rev-list -n1 ''\Q$treeish\E`;
+      # Hide stderr because it's normal for this to fail:
+      my $sha1 = `$gitcmd rev-list -n1 ''\Q$treeish\E 2>/dev/null`;
       if ($? == 0 &&
           $sha1 =~ /^$treeish/ && # Don't use commit 123 @ branch abc!
-          $sha1 =~ /^([0-9a-f]{40})$/) {
+          $sha1 =~ /^([0-9a-f]{40})$/s) {
         $commit = $1;
         Log(undef, "Commit $commit already present in $local_repo");
       }
@@ -495,7 +496,7 @@ else {
       Log(undef, "Fetching objects from $repo to $local_repo");
       `$gitcmd fetch --no-progress --tags ''\Q$repo\E \Q+refs/heads/*:refs/heads/*\E`;
       if ($?) {
-        croak("Error: `$gitcmd fetch` exited $?");
+        croak("Error: `$gitcmd fetch` exited ".exit_status_s($?));
       }
     }
 
@@ -507,7 +508,9 @@ else {
   my $gitcmd = "git --git-dir=\Q$repo\E";
   my $sha1 = `$gitcmd rev-list -n1 ''\Q$treeish\E`;
   unless ($? == 0 && $sha1 =~ /^([0-9a-f]{40})$/) {
-    croak("`$gitcmd rev-list` exited $?, '$treeish' not found. Giving up.");
+    croak("`$gitcmd rev-list` exited "
+          .exit_status_s($?)
+          .", '$treeish' not found. Giving up.");
   }
   $commit = $1;
   Log(undef, "Version $treeish is commit $commit");
@@ -524,7 +527,7 @@ else {
   $ENV{"CRUNCH_SRC_COMMIT"} = $commit;
   $git_archive = `$gitcmd archive ''\Q$commit\E`;
   if ($?) {
-    croak("Error: $gitcmd archive exited $?");
+    croak("Error: $gitcmd archive exited ".exit_status_s($?));
   }
 }
 
@@ -557,7 +560,7 @@ else {
     freeze_if_want_freeze ($installpid);
     select (undef, undef, undef, 0.1);
   }
-  Log (undef, "Install script exited $?");
+  Log (undef, "Install script exited ".exit_status_s($?));
 }
 
 if (!$have_slurm)
@@ -596,7 +599,8 @@ fi
   }
   if ($? != 0)
   {
-    croak("Installing Docker image from $docker_locator returned exit code $?");
+    croak("Installing Docker image from $docker_locator exited "
+          .exit_status_s($?));
   }
 }
 
@@ -974,10 +978,7 @@ sub reapchildren
 
   my $childstatus = $?;
   my $exitvalue = $childstatus >> 8;
-  my $exitinfo = sprintf("exit %d signal %d%s",
-                         $exitvalue,
-                         $childstatus & 127,
-                         ($childstatus & 128 ? ' core dump' : ''));
+  my $exitinfo = "exit ".exit_status_s($childstatus);
   $Jobstep->{'arvados_task'}->reload;
   my $task_success = $Jobstep->{'arvados_task'}->{success};
 
@@ -1411,7 +1412,7 @@ sub save_meta
   my $cmd = "arv-put --portable-data-hash --retries $retry_count " .
       "--filename ''\Q$keep_logfile\E " . quotemeta($local_logfile->filename);
   my $loglocator = `$cmd`;
-  die "system $cmd failed: $?" if $?;
+  die "system $cmd exited ".exit_status_s($?) if $?;
   chomp($loglocator);
 
   $local_logfile = undef;   # the temp file is automatically deleted
@@ -1569,6 +1570,20 @@ sub put_retry_count {
   return ($retries > 3) ? $retries : 3;
 }
 
+sub exit_status_s {
+  # Given a $?, return a human-readable exit code string like "0" or
+  # "1" or "0 with signal 1" or "1 with signal 11".
+  my $exitcode = shift;
+  my $s = $exitcode >> 8;
+  if ($exitcode & 0x7f) {
+    $s .= " with signal " . ($exitcode & 0x7f);
+  }
+  if ($exitcode & 0x80) {
+    $s .= " with core dump";
+  }
+  return $s;
+}
+
 __DATA__
 #!/usr/bin/perl
 

commit e8376cfb9deac7a50651061e2be99a4bc0c46338
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Oct 3 10:17:07 2014 -0400

    3775: Add TODO comments in suspicious-looking collate_output corners.

diff --git a/sdk/cli/bin/crunch-job b/sdk/cli/bin/crunch-job
index 24aca33..04ff82f 100755
--- a/sdk/cli/bin/crunch-job
+++ b/sdk/cli/bin/crunch-job
@@ -1298,10 +1298,13 @@ sub collate_output
     if ($s->can_read(120)) {
       sysread($child_out, $joboutput, 64 * 1024 * 1024);
       chomp($joboutput);
+      # TODO: Ensure exit status == 0.
     } else {
       Log (undef, "timed out reading from 'arv-put'");
     }
   }
+  # TODO: kill $pid instead of waiting, now that we've decided to
+  # ignore further output.
   waitpid($pid, 0);
 
   return $joboutput;

commit c1a82be63ffc3b8aa853025672d486758ffc86e6
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Oct 3 10:16:16 2014 -0400

    3775: Run local/dev jobs on code from arbitrary remote git repositories.
    
    * repository is a local path X -> use local repository X or X/.git.
    
    * repository is a git url (git://, https://, git at host:repo.git, etc)
      fetch branches, tags, and objects from the remote and use the result
      to resolve script_version to a commit sha1 and run the job.
    
    * else -> look up the named repository in Arvados and use its
      fetch_url as a remote git url as above.
    
    * --git-dir is given on the command line -> use that instead of
      $Job->{repository} in the above logic. (This isn't new. It ensures
      we don't go off fetching arbitrary remotes when crunch-dispatch.rb
      has already pulled the code into its own internal git repo.)
    
    Incidental changes:
    
    * Lose support for looking up subversion revision numbers using
      git-svn tags.
    
    * Lose support for CRUNCH_DEFAULT_GIT_DIR environment variable. Pass
      --git-dir instead.
    
    * Improve log messages during checkout/install phase.

diff --git a/sdk/cli/bin/crunch-job b/sdk/cli/bin/crunch-job
index 3467ec3..24aca33 100755
--- a/sdk/cli/bin/crunch-job
+++ b/sdk/cli/bin/crunch-job
@@ -83,7 +83,7 @@ use IPC::Open2;
 use IO::Select;
 use File::Temp;
 use Fcntl ':flock';
-use File::Path qw( make_path );
+use File::Path qw( make_path remove_tree );
 
 use constant EX_TEMPFAIL => 75;
 
@@ -353,137 +353,195 @@ if (!$have_slurm)
 
 
 my $build_script;
+do {
+  local $/ = undef;
+  $build_script = <DATA>;
+};
+my $nodelist = join(",", @node);
 
+if (!defined $no_clear_tmp) {
+  # Clean out crunch_tmp/work, crunch_tmp/opt, crunch_tmp/src*
+  Log (undef, "Clean work dirs");
 
-$ENV{"CRUNCH_SRC_COMMIT"} = $Job->{script_version};
-
-my $skip_install = ($local_job && $Job->{script_version} =~ m{^/});
-if ($skip_install)
-{
-  if (!defined $no_clear_tmp) {
-    my $clear_tmp_cmd = 'rm -rf $JOB_WORK $CRUNCH_TMP/opt $CRUNCH_TMP/src*';
-    system($clear_tmp_cmd) == 0
-	or croak ("`$clear_tmp_cmd` failed: ".($?>>8));
+  my $cleanpid = fork();
+  if ($cleanpid == 0)
+  {
+    srun (["srun", "--nodelist=$nodelist", "-D", $ENV{'TMPDIR'}],
+          ['bash', '-c', 'if mount | grep -q $JOB_WORK/; then for i in $JOB_WORK/*keep; do /bin/fusermount -z -u $i; done; fi; sleep 1; rm -rf $JOB_WORK $CRUNCH_TMP/opt $CRUNCH_TMP/src*']);
+    exit (1);
   }
-  $ENV{"CRUNCH_SRC"} = $Job->{script_version};
-  for my $src_path ("$ENV{CRUNCH_SRC}/arvados/sdk/python") {
-    if (-d $src_path) {
-      system("virtualenv", "$ENV{CRUNCH_TMP}/opt") == 0
-          or croak ("virtualenv $ENV{CRUNCH_TMP}/opt failed: exit ".($?>>8));
-      system ("cd $src_path && ./build.sh && \$CRUNCH_TMP/opt/bin/python setup.py install")
-          == 0
-          or croak ("setup.py in $src_path failed: exit ".($?>>8));
-    }
+  while (1)
+  {
+    last if $cleanpid == waitpid (-1, WNOHANG);
+    freeze_if_want_freeze ($cleanpid);
+    select (undef, undef, undef, 0.1);
   }
+  Log (undef, "Cleanup command exited $?");
 }
-else
-{
-  do {
-    local $/ = undef;
-    $build_script = <DATA>;
-  };
-  Log (undef, "Install revision ".$Job->{script_version});
-  my $nodelist = join(",", @node);
 
-  if (!defined $no_clear_tmp) {
-    # Clean out crunch_tmp/work, crunch_tmp/opt, crunch_tmp/src*
 
-    my $cleanpid = fork();
-    if ($cleanpid == 0)
-    {
-      srun (["srun", "--nodelist=$nodelist", "-D", $ENV{'TMPDIR'}],
-	    ['bash', '-c', 'if mount | grep -q $JOB_WORK/; then for i in $JOB_WORK/*keep; do /bin/fusermount -z -u $i; done; fi; sleep 1; rm -rf $JOB_WORK $CRUNCH_TMP/opt $CRUNCH_TMP/src*']);
-      exit (1);
-    }
-    while (1)
-    {
-      last if $cleanpid == waitpid (-1, WNOHANG);
-      freeze_if_want_freeze ($cleanpid);
-      select (undef, undef, undef, 0.1);
-    }
-    Log (undef, "Clean-work-dir exited $?");
-  }
+my $git_archive;
+if (!defined $git_dir && $Job->{'script_version'} =~ m{^/}) {
+  # If we're in user-land (i.e., not called from crunch-dispatch)
+  # script_version can be an absolute directory path, signifying we
+  # should work straight out of that directory instead of using a git
+  # commit.
+  $ENV{"CRUNCH_SRC_COMMIT"} = $Job->{'script_version'};
+  $ENV{"CRUNCH_SRC"} = $Job->{'script_version'};
+}
+else {
+  $ENV{"CRUNCH_SRC"} = "$ENV{CRUNCH_TMP}/src";
 
   # Install requested code version
-
-  my @execargs;
-  my @srunargs = ("srun",
-		  "--nodelist=$nodelist",
-		  "-D", $ENV{'TMPDIR'}, "--job-name=$job_id");
+  Log (undef, "Looking for version ".$Job->{script_version}." from repository ".$Job->{repository});
 
   $ENV{"CRUNCH_SRC_COMMIT"} = $Job->{script_version};
-  $ENV{"CRUNCH_SRC"} = "$ENV{CRUNCH_TMP}/src";
 
-  my $commit;
-  my $git_archive;
-  my $treeish = $Job->{'script_version'};
-
-  # If we're running under crunch-dispatch, it will have pulled the
-  # appropriate source tree into its own repository, and given us that
-  # repo's path as $git_dir. If we're running a "local" job, and a
-  # script_version was specified, it's up to the user to provide the
-  # full path to a local repository in Job->{repository}.
+  # If we're running under crunch-dispatch, it will have already
+  # pulled the appropriate source tree into its own repository, and
+  # given us that repo's path as $git_dir.
   #
-  # TODO: Accept URLs too, not just local paths. Use git-ls-remote and
-  # git-archive --remote where appropriate.
+  # If we're running a "local" job, we might have to fetch content
+  # from a remote repository.
   #
-  # TODO: Accept a locally-hosted Arvados repository by name or
-  # UUID. Use arvados.v1.repositories.list or .get to figure out the
-  # appropriate fetch-url.
-  my $repo = $git_dir || $ENV{'CRUNCH_DEFAULT_GIT_DIR'} || $Job->{'repository'};
-
+  # (Currently crunch-dispatch gives a local path with --git-dir, but
+  # we might as well accept URLs there too in case it changes its
+  # mind.)
+  my $repo = $git_dir || $Job->{'repository'};
+
+  # Repository can be remote or local. If remote, we'll need to fetch it
+  # to a local dir before doing `git log` et al.
+  my $repo_location;
+
+  if ($repo =~ m{://|\@.*:}) {
+    # $repo is a git url we can clone, like git:// or https:// or
+    # file:/// or git at host:repo.git
+    $repo_location = 'remote';
+  } elsif ($repo =~ m{^\.*/}) {
+    # $repo is a local path to a git index. We'll also resolve ../foo
+    # to ../foo/.git if the latter is a directory.
+    if (-d "$repo/.git") {
+      $repo = "$repo/.git";
+    }
+    $repo_location = 'local';
+    Log(undef, "Using local repository '$repo'");
+  } else {
+    # $repo is none of the above. It must be the name of a hosted
+    # repository.
+    my $arv_repo_list = $arv->{'repositories'}->{'list'}->execute(
+      'filters' => [['name','=',$repo]]
+        )->{'items'};
+    my $n_found = scalar @{$arv_repo_list};
+    if ($n_found > 0) {
+      Log(undef, "Repository '$repo' -> "
+          . join(", ", map { $_->{'uuid'} } @{$arv_repo_list}));
+    }
+    if ($n_found != 1) {
+      croak("Error: Found $n_found repositories with name '$repo'.");
+    }
+    $repo = $arv_repo_list->[0]->{'fetch_url'};
+    $repo_location = 'remote';
+  }
+  Log(undef, "Using $repo_location repository '$repo'");
   $ENV{"CRUNCH_SRC_URL"} = $repo;
 
-  if (-d "$repo/.git") {
-    # We were given a working directory, but we are only interested in
-    # the index.
-    $repo = "$repo/.git";
-  }
+  # Resolve given script_version (we'll call that $treeish here) to a
+  # commit sha1 ($commit).
+  my $treeish = $Job->{'script_version'};
+  my $commit;
+  if ($repo_location eq 'remote') {
+    # We minimize excess object-fetching by re-using the same bare
+    # repository in CRUNCH_TMP/.git for multiple crunch-jobs -- we
+    # just keep adding remotes to it as needed.
+    my $local_repo = $ENV{'CRUNCH_TMP'}."/.git";
+    my $gitcmd = "git --git-dir=\Q$local_repo\E";
+
+    # Set up our local repo for caching remote objects, making
+    # archives, etc.
+    if (!-d $local_repo) {
+      make_path($local_repo) or croak("Error: could not create $local_repo");
+    }
+    # This works (exits 0 and doesn't delete fetched objects) even
+    # if $local_repo is already initialized:
+    `$gitcmd init --bare`;
+    if ($?) {
+      croak("Error: $gitcmd init --bare exited $?");
+    }
+
+    # If $treeish looks like a hash (or abbrev hash) we look it up in
+    # our local cache first, since that's cheaper. (We don't want to
+    # do that with tags/branches though -- those change over time, so
+    # they should always be resolved by the remote repo.)
+    if ($treeish =~ /^[0-9a-f]{3,40}$/s) {
+      my $sha1 = `$gitcmd rev-list -n1 ''\Q$treeish\E`;
+      if ($? == 0 &&
+          $sha1 =~ /^$treeish/ && # Don't use commit 123 @ branch abc!
+          $sha1 =~ /^([0-9a-f]{40})$/) {
+        $commit = $1;
+        Log(undef, "Commit $commit already present in $local_repo");
+      }
+    }
 
-  # If this looks like a subversion r#, look for it in git-svn commit messages
+    if (!defined $commit) {
+      # If $treeish isn't just a hash or abbrev hash, or isn't here
+      # yet, we need to fetch the remote to resolve it correctly.
 
-  if ($treeish =~ m{^\d{1,4}$}) {
-    my $gitlog = `git --git-dir=\Q$repo\E log --pretty="format:%H" --grep="git-svn-id:.*\@"\Q$treeish\E" " master`;
-    chomp $gitlog;
-    Log(undef, "git Subversion search exited $?");
-    if (($? == 0) && ($gitlog =~ /^[a-f0-9]{40}$/)) {
-      $commit = $gitlog;
-      Log(undef, "Using commit $commit for Subversion revision $treeish");
+      # First, remove all local heads. This prevents a name that does
+      # not exist on the remote from resolving to (or colliding with)
+      # a previously fetched branch or tag (possibly from a different
+      # remote).
+      remove_tree("$local_repo/refs/heads", {keep_root => 1});
+
+      Log(undef, "Fetching objects from $repo to $local_repo");
+      `$gitcmd fetch --no-progress --tags ''\Q$repo\E \Q+refs/heads/*:refs/heads/*\E`;
+      if ($?) {
+        croak("Error: `$gitcmd fetch` exited $?");
+      }
     }
+
+    # Now that the data is all here, we will use our local repo for
+    # the rest of our git activities.
+    $repo = $local_repo;
   }
 
-  # If that didn't work, try asking git to look it up as a tree-ish.
-
-  if (!defined $commit) {
-    my $found = `git --git-dir=\Q$repo\E rev-list -1 ''\Q$treeish\E`;
-    chomp $found;
-    Log(undef, "git rev-list exited $? with result '$found'");
-    if (($? == 0) && ($found =~ /^[0-9a-f]{40}$/s)) {
-      $commit = $found;
-      Log(undef, "Using commit $commit for tree-ish $treeish");
-      if ($commit ne $treeish) {
-	# Make sure we record the real commit id in the database,
-	# frozentokey, logs, etc. -- instead of an abbreviation or a
-	# branch name which can become ambiguous or point to a
-	# different commit in the future.
-        $Job->{'script_version'} = $commit;
-        !$job_has_uuid or
-            $Job->update_attributes('script_version' => $commit) or
-            croak("Error while updating job");
-      }
+  my $gitcmd = "git --git-dir=\Q$repo\E";
+  my $sha1 = `$gitcmd rev-list -n1 ''\Q$treeish\E`;
+  unless ($? == 0 && $sha1 =~ /^([0-9a-f]{40})$/) {
+    croak("`$gitcmd rev-list` exited $?, '$treeish' not found. Giving up.");
+  }
+  $commit = $1;
+  Log(undef, "Version $treeish is commit $commit");
+
+  if ($commit ne $Job->{'script_version'}) {
+    # Record the real commit id in the database, frozentokey, logs,
+    # etc. -- instead of an abbreviation or a branch name which can
+    # become ambiguous or point to a different commit in the future.
+    if (!$Job->update_attributes('script_version' => $commit)) {
+      croak("Error: failed to update job's script_version attribute");
     }
   }
 
-  if (defined $commit) {
-    $ENV{"CRUNCH_SRC_COMMIT"} = $commit;
-    @execargs = ("sh", "-c",
-		 "mkdir -p $ENV{CRUNCH_INSTALL} && cd $ENV{CRUNCH_TMP} && perl -");
-    $git_archive = `git --git-dir=\Q$repo\E archive ''\Q$commit\E`;
-    croak("git archive failed: exit " . ($? >> 8)) if ($? != 0);
+  $ENV{"CRUNCH_SRC_COMMIT"} = $commit;
+  $git_archive = `$gitcmd archive ''\Q$commit\E`;
+  if ($?) {
+    croak("Error: $gitcmd archive exited $?");
   }
-  else {
-    croak ("could not figure out commit id for $treeish");
+}
+
+if (!defined $git_archive) {
+  Log(undef, "Skip install phase (no git archive)");
+  if ($have_slurm) {
+    Log(undef, "Warning: This probably means workers have no source tree!");
   }
+}
+else {
+  Log(undef, "Run install script on all workers");
+
+  my @srunargs = ("srun",
+                  "--nodelist=$nodelist",
+                  "-D", $ENV{'TMPDIR'}, "--job-name=$job_id");
+  my @execargs = ("sh", "-c",
+                  "mkdir -p $ENV{CRUNCH_INSTALL} && cd $ENV{CRUNCH_TMP} && perl -");
 
   # Note: this section is almost certainly unnecessary if we're
   # running tasks in docker containers.
@@ -499,7 +557,7 @@ else
     freeze_if_want_freeze ($installpid);
     select (undef, undef, undef, 0.1);
   }
-  Log (undef, "Install exited $?");
+  Log (undef, "Install script exited $?");
 }
 
 if (!$have_slurm)

commit 256ceb11e3b67dbe68b955ed09ac0df9f6cda2ba
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Oct 3 09:42:33 2014 -0400

    3775: Remove stagnant $job_has_uuid flag. Every job has a uuid. The
    only time to skip updating the job record on the server side is when
    croak() happens before $Job is created/fetched.

diff --git a/sdk/cli/bin/crunch-job b/sdk/cli/bin/crunch-job
index 1f7c191..3467ec3 100755
--- a/sdk/cli/bin/crunch-job
+++ b/sdk/cli/bin/crunch-job
@@ -125,8 +125,7 @@ if (defined $job_api_token) {
 }
 
 my $have_slurm = exists $ENV{SLURM_JOBID} && exists $ENV{SLURM_NODELIST};
-my $job_has_uuid = $jobspec =~ /^[-a-z\d]+$/;
-my $local_job = !$job_has_uuid;
+my $local_job = 0;
 
 
 $SIG{'USR1'} = sub
@@ -145,12 +144,13 @@ my $local_logfile;
 
 my $User = $arv->{'users'}->{'current'}->execute;
 
-my $Job = {};
+my $Job;
 my $job_id;
 my $dbh;
 my $sth;
-if ($job_has_uuid)
+if ($jobspec =~ /^[-a-z\d]+$/)
 {
+  # $jobspec is an Arvados UUID, not a JSON job specification
   $Job = $arv->{'jobs'}->{'get'}->execute('uuid' => $jobspec);
   if (!$force_unlock) {
     # If some other crunch-job process has grabbed this job (or we see
@@ -193,8 +193,6 @@ else
   $Job->{'started_at'} = gmtime;
 
   $Job = $arv->{'jobs'}->{'create'}->execute('job' => $Job);
-
-  $job_has_uuid = 1;
 }
 $job_id = $Job->{'uuid'};
 
@@ -283,20 +281,17 @@ foreach (@sinfo)
 
 
 my $jobmanager_id;
-if ($job_has_uuid)
-{
-  # Claim this job, and make sure nobody else does
-  unless ($Job->update_attributes('is_locked_by_uuid' => $User->{'uuid'}) &&
-          $Job->{'is_locked_by_uuid'} == $User->{'uuid'}) {
-    Log(undef, "Error while updating / locking job, exiting ".EX_TEMPFAIL);
-    exit EX_TEMPFAIL;
-  }
-  $Job->update_attributes('state' => 'Running',
-                          'tasks_summary' => { 'failed' => 0,
-                                               'todo' => 1,
-                                               'running' => 0,
-                                               'done' => 0 });
+# Claim this job, and make sure nobody else does
+unless ($Job->update_attributes('is_locked_by_uuid' => $User->{'uuid'}) &&
+        $Job->{'is_locked_by_uuid'} == $User->{'uuid'}) {
+  Log(undef, "Error while updating / locking job, exiting ".EX_TEMPFAIL);
+  exit EX_TEMPFAIL;
 }
+$Job->update_attributes('state' => 'Running',
+                        'tasks_summary' => { 'failed' => 0,
+                                             'todo' => 1,
+                                             'running' => 0,
+                                             'done' => 0 });
 
 
 Log (undef, "start");
@@ -866,7 +861,7 @@ else {
     });
     Log(undef, "output uuid " . $output->{uuid});
     Log(undef, "output hash " . $output->{portable_data_hash});
-    $Job->update_attributes('output' => $output->{portable_data_hash}) if $job_has_uuid;
+    $Job->update_attributes('output' => $output->{portable_data_hash});
   };
   if ($@) {
     Log (undef, "Failed to register output manifest: $@");
@@ -900,9 +895,7 @@ sub update_progress_stats
   $Job->{'tasks_summary'}->{'todo'} = $todo;
   $Job->{'tasks_summary'}->{'done'} = $done;
   $Job->{'tasks_summary'}->{'running'} = $running;
-  if ($job_has_uuid) {
-    $Job->update_attributes('tasks_summary' => $Job->{'tasks_summary'});
-  }
+  $Job->update_attributes('tasks_summary' => $Job->{'tasks_summary'});
   Log (undef, "status: $done done, $running running, $todo todo");
   $progress_is_dirty = 0;
 }
@@ -1031,23 +1024,21 @@ sub check_refresh_wanted
   my @stat = stat $ENV{"CRUNCH_REFRESH_TRIGGER"};
   if (@stat && $stat[9] > $latest_refresh) {
     $latest_refresh = scalar time;
-    if ($job_has_uuid) {
-      my $Job2 = $arv->{'jobs'}->{'get'}->execute('uuid' => $jobspec);
-      for my $attr ('cancelled_at',
-                    'cancelled_by_user_uuid',
-                    'cancelled_by_client_uuid',
-                    'state') {
-        $Job->{$attr} = $Job2->{$attr};
-      }
-      if ($Job->{'state'} ne "Running") {
-        if ($Job->{'state'} eq "Cancelled") {
-          Log (undef, "Job cancelled at " . $Job->{'cancelled_at'} . " by user " . $Job->{'cancelled_by_user_uuid'});
-        } else {
-          Log (undef, "Job state unexpectedly changed to " . $Job->{'state'});
-        }
-        $main::success = 0;
-        $main::please_freeze = 1;
+    my $Job2 = $arv->{'jobs'}->{'get'}->execute('uuid' => $jobspec);
+    for my $attr ('cancelled_at',
+                  'cancelled_by_user_uuid',
+                  'cancelled_by_client_uuid',
+                  'state') {
+      $Job->{$attr} = $Job2->{$attr};
+    }
+    if ($Job->{'state'} ne "Running") {
+      if ($Job->{'state'} eq "Cancelled") {
+        Log (undef, "Job cancelled at " . $Job->{'cancelled_at'} . " by user " . $Job->{'cancelled_by_user_uuid'});
+      } else {
+        Log (undef, "Job state unexpectedly changed to " . $Job->{'state'});
       }
+      $main::success = 0;
+      $main::please_freeze = 1;
     }
   }
 }
@@ -1333,7 +1324,7 @@ sub croak
   Log (undef, $message);
   freeze() if @jobstep_todo;
   collate_output() if @jobstep_todo;
-  cleanup();
+  cleanup() if $Job;
   save_meta() if $local_logfile;
   die;
 }
@@ -1341,7 +1332,6 @@ sub croak
 
 sub cleanup
 {
-  return if !$job_has_uuid;
   if ($Job->{'state'} eq 'Cancelled') {
     $Job->update_attributes('finished_at' => scalar gmtime);
   } else {
@@ -1366,7 +1356,7 @@ sub save_meta
   $local_logfile = undef;   # the temp file is automatically deleted
   Log (undef, "log manifest is $loglocator");
   $Job->{'log'} = $loglocator;
-  $Job->update_attributes('log', $loglocator) if $job_has_uuid;
+  $Job->update_attributes('log', $loglocator);
 }
 
 

commit 2198f66d230634ab4e7e511e176bfbc4af632f0a
Author: Tom Clegg <tom at curoverse.com>
Date:   Fri Oct 3 09:33:46 2014 -0400

    3775: Fix syntax error 2 commits ago.

diff --git a/sdk/cli/bin/crunch-job b/sdk/cli/bin/crunch-job
index 9c32d8e..1f7c191 100755
--- a/sdk/cli/bin/crunch-job
+++ b/sdk/cli/bin/crunch-job
@@ -883,7 +883,7 @@ if ($collated_output && $main::success) {
 } else {
   $final_state = 'Failed';
 }
-$Job->update_attributes('state' => $final_state)
+$Job->update_attributes('state' => $final_state);
 
 exit (($final_state eq 'Complete') ? 0 : 1);
 

commit 7d9cfb6e0716239f996bae054bc9345a663e0b7e
Merge: 75be748 62790d7
Author: Tom Clegg <tom at curoverse.com>
Date:   Thu Oct 2 11:13:19 2014 -0400

    3775: Merge branch 'master' into 3775-fetch-git-repo


-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list