forked from lix-project/hydra
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:
parent
52753e49c2
commit
9f6afb3375
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue