fix: allocate PTY for agent install to work with sudo requiretty

The remote server has 'Defaults requiretty' in sudoers, which prevents
sudo from running without a TTY. Modified SSHService::exec() to accept
an optional  parameter that allocates a pseudo-terminal, and
extracts the exit status from output when PTY is used (since phpseclib
doesn't return exit status in PTY mode).
This commit is contained in:
2026-06-11 18:52:40 -04:00
parent f4c534c020
commit 63bf125420
2 changed files with 16 additions and 4 deletions

View File

@@ -63,7 +63,7 @@ class AgentService
return ['success' => false, 'error' => 'SSH connection failed'];
}
$result = $ssh->exec($remoteCommand, 120);
$result = $ssh->exec($remoteCommand, 120, true);
$ssh->disconnect();
$output = trim($result['output']);
@@ -127,7 +127,7 @@ class AgentService
return ['success' => false, 'error' => 'SSH connection failed'];
}
$result = $ssh->exec($remoteCommand, 60);
$result = $ssh->exec($remoteCommand, 60, true);
$ssh->disconnect();
$output = trim($result['output']);

View File

@@ -73,7 +73,7 @@ class SSHService
}
}
public function exec(string $command, int $timeout = 0): array
public function exec(string $command, int $timeout = 0, bool $pty = false): array
{
if ($this->connection === null || !$this->connection->isConnected()) {
throw new \RuntimeException('No active SSH connection');
@@ -83,10 +83,22 @@ class SSHService
$this->connection->setTimeout($timeout);
$output = $this->connection->exec($command);
if ($pty) {
$command .= '; echo "___EXIT___:$?"';
}
$output = $this->connection->exec($command, null, $pty);
$exitStatus = $this->connection->getExitStatus();
$stderr = $this->connection->getStdError() ?? '';
if ($pty && ($exitStatus === false || $exitStatus === null)) {
if (preg_match('/___EXIT___:(\d+)/', $output, $m)) {
$exitStatus = (int) $m[1];
$output = str_replace($m[0] . "\n", '', $output);
$output = str_replace($m[0], '', $output);
}
}
$this->logger->info("SSH command executed", [
'command' => $command,
'exit_status' => $exitStatus,