From e4375397719678133541c762e7dce1e38c28a8b5 Mon Sep 17 00:00:00 2001 From: lguichard Date: Wed, 1 Jan 2025 01:04:49 +0100 Subject: [PATCH 1/2] Feat - Add support of Process concurrently and pool --- README.md | 28 +++++++ src/PendingProcess.php | 20 ++++- src/ProcessSsh.php | 19 ----- tests/ProcessSshTest.php | 154 +++++++++++++++++++++------------------ 4 files changed, 132 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 93784d1..114c231 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,34 @@ $result = Process::ssh([ ->run('ls -al'); ``` +### Use the favorites method provided by Laravel's Process class. + +For more information, refer to the official documentation : https://laravel.com/docs/11.x/processes + +```php +[$result1, $result2] = Process::ssh([ + 'host' => '192.168.1.10', + 'user' => 'username', + 'password' => 'your_password', + ]) + ->concurrently(function (Pool $pool) { + $pool->command('ls -al'); + $pool->command('whoami'); + }); +``` + +```php +$result = Process::ssh([ + 'host' => '192.168.1.10', + 'user' => 'username', + 'password' => 'your_password', + ]) + ->pool(function (Pool $pool) { + $pool->command('ls -al'); + $pool->command('whoami'); + }); +``` + ## Testing To run the package's tests: diff --git a/src/PendingProcess.php b/src/PendingProcess.php index f36f8da..2f0982f 100644 --- a/src/PendingProcess.php +++ b/src/PendingProcess.php @@ -21,6 +21,18 @@ class PendingProcess extends BasePendingProcess private bool $handleSsh = false; + /** + * Override the command string to handle SSH commands. + */ + public function command(array|string $command) + { + $command = $this->buildCommand($command); + + $this->command = $command; + + return $this; + } + /** * Set configuration for the SSH connection. */ @@ -60,6 +72,10 @@ public function setConfig(array $config, bool $handleSsh) */ public function buildCommand(array|string|null $command): array|string|null { + if (! $command) { + return $command; + } + if (! $this->handleSsh) { return $command; } @@ -161,6 +177,8 @@ protected function toSymfonyProcess(array|string|null $command) { $command = $this->buildCommand($command); - return parent::toSymfonyProcess($command); + $process = parent::toSymfonyProcess($command); + + return $process; } } diff --git a/src/ProcessSsh.php b/src/ProcessSsh.php index 73477f8..62d920e 100644 --- a/src/ProcessSsh.php +++ b/src/ProcessSsh.php @@ -50,15 +50,6 @@ public function addExtraOption(string $option): self return $this; } - public function pool(callable $callback) - { - if ($this->handleSsh) { - throw new \InvalidArgumentException('Cannot pool processes with SSH enabled.'); - } - - return parent::pool($callback); - } - public function pipe(callable|array $callback, ?callable $output = null) { if ($this->handleSsh) { @@ -68,16 +59,6 @@ public function pipe(callable|array $callback, ?callable $output = null) return parent::pipe($callback, $output); } - public function concurrently(callable $callback, ?callable $output = null) - { - - if ($this->handleSsh) { - throw new \InvalidArgumentException('Cannot concurrently processes with SSH enabled.'); - } - - return parent::concurrently($callback, $output); - } - /** * Create a new pending process instance. */ diff --git a/tests/ProcessSshTest.php b/tests/ProcessSshTest.php index b8e5dae..63154db 100644 --- a/tests/ProcessSshTest.php +++ b/tests/ProcessSshTest.php @@ -3,16 +3,23 @@ use Bagel\ProcessSsh\PendingProcess; use Bagel\ProcessSsh\Providers\ProcessSshServiceProvider; use Illuminate\Process\FakeProcessResult; +use Illuminate\Process\Pool; use Illuminate\Support\Facades\Process; use Orchestra\Testbench\TestCase; uses(TestCase::class)->beforeEach(function () { $this->app->register(ProcessSshServiceProvider::class); + + $this->basicSshConfig = [ + 'host' => '192.178.0.1', + 'user' => 'ubuntu', + 'port' => 22, + ]; }); it('process config set', function () { $process = Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', 'user' => 'ubuntu', 'port' => 22, 'extraOptions' => [ @@ -22,7 +29,7 @@ 'private_key' => '/path/to/key', ]); - expect($process->sshConfig()['host'])->toBe('example.com'); + expect($process->sshConfig()['host'])->toBe('192.178.0.1'); expect($process->sshConfig()['user'])->toBe('ubuntu'); expect($process->sshConfig()['port'])->toBe(22); expect($process->sshConfig()['extraOptions'])->toBe([ @@ -34,7 +41,7 @@ it('process add extra options', function () { $process = Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', 'user' => 'ubuntu', 'port' => 22, ])->addExtraOption('-o StrictHostKeyChecking=no'); @@ -46,7 +53,7 @@ it('process disableStrictHostKeyChecking', function () { $process = Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', 'user' => 'ubuntu', 'port' => 22, ])->disableStrictHostKeyChecking(); @@ -64,12 +71,12 @@ Process::fake(); $process = Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', ]) ->disableStrictHostKeyChecking() ->run('ls -al'); - expect($process->command())->toBe("ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null example.com 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); + expect($process->command())->toBe("ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null 192.178.0.1 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); Process::assertRan('ls -al'); }); @@ -78,7 +85,7 @@ Process::fake(); $process = Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', 'user' => 'ubuntu', 'password' => 'password', 'port' => 22, @@ -90,7 +97,7 @@ ->disableStrictHostKeyChecking() ->run('ls -al'); - expect($process->command())->toBe("sshpass -p 'password' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@example.com 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); + expect($process->command())->toBe("sshpass -p 'password' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@192.178.0.1 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); Process::assertRan('ls -al'); }); @@ -99,7 +106,7 @@ Process::fake(); $process = Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', 'user' => 'ubuntu', 'port' => 22, 'private_key' => '/path/to/key', @@ -107,29 +114,11 @@ ->disableStrictHostKeyChecking() ->run('ls -al'); - expect($process->command())->toBe("ssh -i /path/to/key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@example.com 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); + expect($process->command())->toBe("ssh -i /path/to/key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ubuntu@192.178.0.1 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); Process::assertRan('ls -al'); }); -it('exception thrown process run with array', function () { - Process::fake(); - - Process::ssh([ - 'host' => '127.0.0.1', - ])->run(['ls', '-al']); - -})->throws(InvalidArgumentException::class, 'Array commands are not supported for SSH connections'); - -it('exception thrown process start with array', function () { - Process::fake(); - - Process::ssh([ - 'host' => '127.0.0.1', - ])->start(['ls', '-al']); - -})->throws(InvalidArgumentException::class, 'Array commands are not supported for SSH connections'); - it('Process can run normaly', function () { Process::fake(); @@ -160,7 +149,7 @@ Process::fake(); Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', 'user' => 'ubuntu', 'password' => 'password', 'port' => 22, @@ -179,7 +168,7 @@ Process::fake(); Process::ssh([ - 'host' => 'example.com', + 'host' => '192.178.0.1', 'user' => 'ubuntu', 'password' => 'password', 'port' => 22, @@ -194,60 +183,87 @@ }); }); -it('can\'t pool processes with SSH enabled', function () { +it('invoke process::concurrently', function () { Process::fake(); - Process::ssh([ - 'host' => 'example.com', - 'user' => 'ubuntu', - 'password' => 'password', - 'port' => 22, - ])->pool(function () { - // + $process = Process::concurrently(function (Pool $pool) { + $pool->command('ls -al'); + $pool->command('whoami'); }); -})->throws(InvalidArgumentException::class, 'Cannot pool processes with SSH enabled.'); + expect($process[0]->command())->toBe('ls -al'); + expect($process[1]->command())->toBe('whoami'); + + Process::assertRan('ls -al'); + Process::assertRan('whoami'); +}); -it('can\'t pipe processes with SSH enabled', function () { +it('invoke process::concurrently ssh', function () { Process::fake(); - Process::ssh([ - 'host' => 'example.com', - 'user' => 'ubuntu', - 'password' => 'password', - 'port' => 22, - ])->pipe(function () { - // + $process = Process::ssh($this->basicSshConfig)->concurrently(function (Pool $pool) { + $pool->command('ls -al'); + $pool->command('whoami'); }); -})->throws(InvalidArgumentException::class, 'Cannot pipe processes with SSH enabled.'); + expect($process[0]->command())->toBe("ssh ubuntu@192.178.0.1 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); + expect($process[1]->command())->toBe("ssh ubuntu@192.178.0.1 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'whoami'.PHP_EOL.'EOF-PROCESS-SSH'); + +}); -it('can\'t concurrently processes with SSH enabled', function () { +it('invoke process::pool', function () { Process::fake(); - Process::ssh([ - 'host' => 'example.com', - 'user' => 'ubuntu', - 'password' => 'password', - 'port' => 22, - ])->concurrently(function () { - // + $process = Process::pool(function (Pool $pool) { + $pool->command('ls -al'); + $pool->command('whoami'); + }); + + $results = $process->wait(); + expect($results[0]->command())->toBe('ls -al'); + expect($results[1]->command())->toBe('whoami'); + + Process::assertRan('ls -al'); + Process::assertRan('whoami'); +}); + +it('invoke process::pool ssh', function () { + Process::fake(); + + $process = Process::ssh($this->basicSshConfig)->pool(function (Pool $pool) { + $pool->command('ls -al'); + $pool->command('whoami'); }); -})->throws(InvalidArgumentException::class, 'Cannot concurrently processes with SSH enabled.'); + $results = $process->wait(); + expect($results[0]->command())->toBe("ssh ubuntu@192.178.0.1 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'ls -al'.PHP_EOL.'EOF-PROCESS-SSH'); + expect($results[1]->command())->toBe("ssh ubuntu@192.178.0.1 'bash -se' << \EOF-PROCESS-SSH".PHP_EOL.'whoami'.PHP_EOL.'EOF-PROCESS-SSH'); + +}); + +it('exception thrown process run with array', function () { + Process::fake(); + + Process::ssh([ + 'host' => '127.0.0.1', + ])->run(['ls', '-al']); + +})->throws(InvalidArgumentException::class, 'Array commands are not supported for SSH connections.'); + +it('exception thrown process start with array', function () { + Process::fake(); -// it('timeout process', function () { -// //Process::fake(); + Process::ssh([ + 'host' => '127.0.0.1', + ])->start(['ls', '-al']); -// $process = Process::ssh([ -// 'host' => '192.168.8.5', -// 'user' => 'ubuntu', -// //'password' => 'password', -// 'port' => 22, -// ]) -// ->run('ls'); +})->throws(InvalidArgumentException::class, 'Array commands are not supported for SSH connections.'); -// dump($process->errorOutput()); -// dump($process->output()); +it('invoke process::pipe', function () { + Process::fake(); -// })->only(); + $process = Process::ssh($this->basicSshConfig)->pipe([ + 'ls -al', + 'whoami', + ]); +})->throws(InvalidArgumentException::class, 'Cannot pipe processes with SSH enabled.'); From 14d094c9347eb88d4838de3f4f096c15dcdb30aa Mon Sep 17 00:00:00 2001 From: lguichard Date: Wed, 1 Jan 2025 01:11:09 +0100 Subject: [PATCH 2/2] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 114c231..b7a11f8 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,18 @@ $result = Process::ssh([ For more information, refer to the official documentation : https://laravel.com/docs/11.x/processes +```php +$process = Process::ssh([ + 'host' => '192.168.1.10', + 'user' => 'username', + 'password' => 'your_password', + ]) + ->start('bash import.sh'); + +$result = $process->wait(); + +``` + ```php [$result1, $result2] = Process::ssh([ 'host' => '192.168.1.10',