Lock paths in the scm cache

This is necessary now that hydra-evaluator runs multiple evaluations
in parallel, to prevent corruption of Git/Mercurial clones.
This commit is contained in:
Eelco Dolstra 2017-02-21 18:11:53 +01:00
parent 52753e49c2
commit 9f6afb3375
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
2 changed files with 22 additions and 22 deletions

View file

@ -7,6 +7,7 @@ use File::Path;
use Hydra::Helper::Nix; use Hydra::Helper::Nix;
use Nix::Store; use Nix::Store;
use Encode; use Encode;
use Fcntl qw(:flock);
sub supportedInputTypes { sub supportedInputTypes {
my ($self, $inputTypes) = @_; my ($self, $inputTypes) = @_;
@ -18,14 +19,28 @@ sub _isHash {
return length($rev) == 40 && $rev =~ /^[0-9a-f]+$/; return length($rev) == 40 && $rev =~ /^[0-9a-f]+$/;
} }
# Clone or update a branch of a repository into our SCM cache. sub _parseValue {
sub _cloneRepo { my ($value) = @_;
my ($self, $uri, $branch, $deepClone) = @_; (my $uri, my $branch, my $deepClone) = split ' ', $value;
$branch = defined $branch ? $branch : "master";
return ($uri, $branch, $deepClone);
}
sub fetchInput {
my ($self, $type, $name, $value) = @_;
return undef if $type ne "git";
my ($uri, $branch, $deepClone) = _parseValue($value);
# Clone or update a branch of the repository into our SCM cache.
my $cacheDir = getSCMCacheDir . "/git"; my $cacheDir = getSCMCacheDir . "/git";
mkpath($cacheDir); mkpath($cacheDir);
my $clonePath = $cacheDir . "/" . sha256_hex($uri); my $clonePath = $cacheDir . "/" . sha256_hex($uri);
open(my $lock, ">", "$clonePath.lock") or die;
flock($lock, LOCK_EX) or die;
my $res; my $res;
if (! -d $clonePath) { if (! -d $clonePath) {
# Clone everything and fetch the branch. # Clone everything and fetch the branch.
@ -61,25 +76,6 @@ sub _cloneRepo {
} }
} }
return $clonePath;
}
sub _parseValue {
my ($value) = @_;
(my $uri, my $branch, my $deepClone) = split ' ', $value;
$branch = defined $branch ? $branch : "master";
return ($uri, $branch, $deepClone);
}
sub fetchInput {
my ($self, $type, $name, $value) = @_;
return undef if $type ne "git";
my ($uri, $branch, $deepClone) = _parseValue($value);
my $clonePath = $self->_cloneRepo($uri, $branch, $deepClone);
my $timestamp = time; my $timestamp = time;
my $sha256; my $sha256;
my $storePath; my $storePath;

View file

@ -6,6 +6,7 @@ use Digest::SHA qw(sha256_hex);
use File::Path; use File::Path;
use Hydra::Helper::Nix; use Hydra::Helper::Nix;
use Nix::Store; use Nix::Store;
use Fcntl qw(:flock);
sub supportedInputTypes { sub supportedInputTypes {
my ($self, $inputTypes) = @_; my ($self, $inputTypes) = @_;
@ -40,6 +41,9 @@ sub fetchInput {
my $clonePath = _clonePath($uri); my $clonePath = _clonePath($uri);
open(my $lock, ">", "$clonePath.lock") or die;
flock($lock, LOCK_EX) or die;
if (! -d $clonePath) { if (! -d $clonePath) {
(my $res, $stdout, $stderr) = captureStdoutStderr(600, (my $res, $stdout, $stderr) = captureStdoutStderr(600,
"hg", "clone", $uri, $clonePath); "hg", "clone", $uri, $clonePath);