Skip to content

Commit

Permalink
Prevent git from hanging a process
Browse files Browse the repository at this point in the history
* Use of a timeout when IPC::Run invokes
* Enhance error message and notify user for likely solution

I tried to catch the prompt but I assume that the process is not
running in a tty and IPC::Run could not get the output.

Signed-off-by: Ioannis Bonatakis <[email protected]>
  • Loading branch information
b10n1k committed Jan 28, 2025
1 parent 2ff2afc commit 878d06e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 17 deletions.
13 changes: 8 additions & 5 deletions lib/OpenQA/Git.pm
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ sub _validate_attributes ($self) {

sub _run_cmd ($self, $args, $options = {}) {
my $include_git_path = $options->{include_git_path} // 1;
my $ssh_batchmode = $options->{ssh_batchmode} // 0;
#warn(">>>> $options");
my $batchmode = $options->{batchmode} // 0;
my @cmd;
push @cmd, 'env', 'GIT_SSH_COMMAND=ssh -oBatchMode=yes' if $ssh_batchmode;
push @cmd, 'env', 'GIT_SSH_COMMAND=ssh -oBatchMode=yes' if $batchmode;
#push @cmd, 'env', $options->{nopass} if $options->{nopass};
push @cmd, $self->_prepare_git_command($include_git_path), @$args;

my $result = run_cmd_with_log_return_error(\@cmd);
Expand Down Expand Up @@ -97,6 +99,7 @@ sub commit ($self, $args = undef) {

# push changes
if (($self->config->{do_push} || '') eq 'yes') {
#my $options->{nopass} = "GIT_TERMINAL_PROMPT=false";
$res = $self->_run_cmd(['push']);
return $self->_format_git_error($res, 'Unable to push Git commit') unless $res->{status};
}
Expand All @@ -123,14 +126,14 @@ sub check_sha ($self, $sha) {
}

sub get_remote_default_branch ($self, $url) {
my $r = $self->_run_cmd(['ls-remote', '--symref', $url, 'HEAD'], {include_git_path => 0, ssh_batchmode => 1});
my $r = $self->_run_cmd(['ls-remote', '--symref', $url, 'HEAD'], {include_git_path => 0, batchmode => 1});
die qq/Error detecting remote default branch name for "$url": $r->{stdout} $r->{stderr}/
unless $r->{status} && $r->{stdout} =~ m{refs/heads/(\S+)\s+HEAD};
return $1;
}

sub clone_url ($self, $url) {
my $r = $self->_run_cmd(['clone', $url, $self->dir], {include_git_path => 0, ssh_batchmode => 1});
my $r = $self->_run_cmd(['clone', $url, $self->dir], {include_git_path => 0, batchmode => 1});
die $self->_format_git_error($r, qq/Failed to clone "$url"/) unless $r->{status};
}

Expand All @@ -141,7 +144,7 @@ sub get_origin_url ($self) {
}

sub fetch ($self, $branch_arg) {
my $r = $self->_run_cmd(['fetch', 'origin', $branch_arg], {ssh_batchmode => 1});
my $r = $self->_run_cmd(['fetch', 'origin', $branch_arg], {batchmode => 1});
die $self->_format_git_error($r, "Failed to fetch from '$branch_arg'") unless $r->{status};
}

Expand Down
1 change: 0 additions & 1 deletion lib/OpenQA/Task/Needle/Delete.pm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ sub register {

sub _delete_needles {
my ($app, $minion_job, $args) = @_;

my $schema = $app->schema;
my $needles = $schema->resultset('Needles');
my $user = $schema->resultset('Users')->find($args->{user_id});
Expand Down
36 changes: 25 additions & 11 deletions lib/OpenQA/Utils.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use Mojo::Base -strict, -signatures;
use Carp;
use Cwd 'abs_path';
use Filesys::Df qw(df);
use IPC::Run();
use IPC::Run qw(run timeout);
use Mojo::URL;
use Regexp::Common 'URI';
use Time::Seconds;
Expand Down Expand Up @@ -333,13 +333,17 @@ sub run_cmd_with_log {
sub run_cmd_with_log_return_error ($cmd, %args) {
my $stdout_level = $args{stdout} // 'debug';
my $stderr_level = $args{stderr} // 'debug';
my $timeout_duration = 30;
log_info('Running cmd: ' . join(' ', @$cmd));
my ($stdin, $stdout_err, $stdout, $stderr) = ('') x 4;
try {
my ($stdin, $stdout_err, $stdout, $stderr) = ('') x 4;
my $ipc_run_succeeded = IPC::Run::run($cmd, \$stdin, \$stdout, \$stderr);
my $ipc_run = run($cmd, \$stdin, \$stdout, \$stderr, timeout($timeout_duration));
my $return_code = $?;
chomp $stderr;
if ($ipc_run_succeeded) {
#my $return_code = $?;
# use Data::Dumper;
#print "***";print Dumper($@);
if ($ipc_run) {
OpenQA::Log->can("log_$stdout_level")->($stdout);
OpenQA::Log->can("log_$stderr_level")->($stderr);
log_info("cmd returned $return_code");
Expand All @@ -349,20 +353,30 @@ sub run_cmd_with_log_return_error ($cmd, %args) {
log_error("cmd returned $return_code");
}
return {
status => $ipc_run_succeeded,
status => $ipc_run,
return_code => $return_code,
stdout => $stdout,
stderr => $stderr,
};
}
catch {
return {
status => 0,
return_code => undef,
stderr => 'an internal error occurred',
stdout => '',
my $additional_info = "If you use http for CASEDIR or NEEDLES_DIR is adviced to

Check warning on line 363 in lib/OpenQA/Utils.pm

View workflow job for this annotation

GitHub Actions / Perlcritic

Useless interpolation of literal string - severity 3

[ValuesAndExpressions::ProhibitInterpolationOfLiterals] See page 51 of PBP
configure git with the insteadof option in the .gitconfig file.
Run the following command to:
git config [--global] url.\"git://github.com\".insteadOf https://github.com";
my $stderr_msg = ($_ =~ /timeout/)
? join(' ', @$cmd) . " timed out after $timeout_duration seconds \nNote:\n$additional_info"
: 'an internal error occurred';
#$stderr_msg .= "prompt detected" if $stdout =~ /Username.*:/;
log_error($stderr_msg);
return {
status => 0,
return_code => undef,
stderr => $stderr_msg,
stdout => '',
};
};
};

}

sub asset_type_from_setting {
Expand Down

0 comments on commit 878d06e

Please sign in to comment.