8000 Add global --ssh-args argument for SSH/Docker/Vagrant execution by Copilot · Pull Request #6206 · wp-cli/wp-cli · GitHub
[go: up one dir, main page]

Skip to content
Merged
2 changes: 1 addition & 1 deletion features/cli.feature
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Feature: `wp cli` tasks
When I run `wp cli param-dump --with-values | grep -o '"current":' | uniq -c | tr -d ' '`
Then STDOUT should be:
"""
19"current":
20"current":
"""
And STDERR should be empty
And the return code should be 0
Expand Down
21 changes: 21 additions & 0 deletions features/flags.feature
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,27 @@ Feature: Global flags
Running SSH command: docker exec --user 'user' 'wordpress' sh -c
"""

Scenario: SSH args should be passed to SSH command
When I try `wp --debug --ssh=wordpress --ssh-args="-o ConnectTimeout=5" --version`
Then STDERR should contain:
"""
Running SSH command: ssh '-o ConnectTimeout=5' -T -vvv 'wordpress' 'wp
"""

Scenario: Multiple SSH args should be passed to SSH command
When I try `wp --debug --ssh=wordpress --ssh-args="-o ConnectTimeout=5" --ssh-args="-o ServerAliveInterval=10" --version`
Then STDERR should contain:
"""
Running SSH command: ssh '-o ConnectTimeout=5' '-o ServerAliveInterval=10' -T -vvv 'wordpress' 'wp
"""

Scenario: SSH args should be passed to Docker command
When I try `WP_CLI_DOCKER_NO_INTERACTIVE=1 wp --debug --ssh=docker:wordpress --ssh-args="--env MY_VAR=value" --version`
Then STDERR should contain:
"""
Running SSH command: docker exec '--env MY_VAR=value' 'wordpress' sh -c
"""

Scenario: Customize config-spec with WP_CLI_CONFIG_SPEC_FILTER_CALLBACK
Given a WP installation
And a wp-cli-early-require.php file:
Expand Down
1 change: 1 addition & 0 deletions php/WP_CLI/Configurator.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Configurator {
'url',
'path',
'ssh',
'ssh-args',
'http',
'proxyjump',
'key',
Expand Down
22 changes: 16 additions & 6 deletions php/WP_CLI/Runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ private function run_ssh_command( string $connection_string ): void {
}

foreach ( $wp_args as $k => $v ) {
if ( preg_match( '#--ssh=#', (string) $v ) ) {
if ( preg_match( '#^--ssh(?:-args)?(?:=|$)#', (string) $v ) ) {
unset( $wp_args[ $k ] );
}
}
Expand Down Expand Up @@ -745,6 +745,12 @@ static function ( $arg ): string {
private function generate_ssh_command( $bits, $wp_command ) {
$escaped_command = '';

// Get additional SSH arguments if provided.
$ssh_args_config = WP_CLI::get_config( 'ssh-args' );
$ssh_args = is_array( $ssh_args_config ) && ! empty( $ssh_args_config )
? implode( ' ', array_map( 'escapeshellarg', $ssh_args_config ) )
: '';

// Set default values.
foreach ( [ 'scheme', 'user', 'host', 'port', 'path', 'key', 'proxyjump' ] as $bit ) {
if ( ! isset( $bits[ $bit ] ) ) {
Expand Down Expand Up @@ -772,10 +778,11 @@ private function generate_ssh_command( $bits, $wp_command ) {
: 'docker-compose';

if ( 'docker' === $bits['scheme'] ) {
$command = 'docker exec %s%s%s%s%s sh -c %s';
$command = 'docker exec %s%s%s%s%s%s sh -c %s';

$escaped_command = sprintf(
$command,
$ssh_args ? $ssh_args . ' ' : '',
$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
$is_stdout_tty && ! getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '-t ' : '',
Expand All @@ -786,11 +793,12 @@ private function generate_ssh_command( $bits, $wp_command ) {
}

if ( 'docker-compose' === $bits['scheme'] ) {
$command = '%s exec %s%s%s%s sh -c %s';
$command = '%s exec %s%s%s%s%s sh -c %s';

$escaped_command = sprintf(
$command,
$docker_compose_cmd,
$ssh_args ? $ssh_args . ' ' : '',
$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
$is_stdout_tty || getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ',
Expand All @@ -800,11 +808,12 @@ private function generate_ssh_command( $bits, $wp_command ) {
}

if ( 'docker-compose-run' === $bits['scheme'] ) {
$command = '%s run %s%s%s%s%s %s';
$command = '%s run %s%s%s%s%s%s %s';

$escaped_command = sprintf(
$command,
$docker_compose_cmd,
$ssh_args ? $ssh_args . ' ' : '',
$bits['user'] ? '--user ' . escapeshellarg( $bits['user'] ) . ' ' : '',
$bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '',
$is_stdout_tty || getenv( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ',
Expand Down Expand Up @@ -848,7 +857,7 @@ private function generate_ssh_command( $bits, $wp_command ) {

// If we could not resolve the bits still, fallback to just `vagrant ssh`
if ( 'vagrant' === $bits['scheme'] ) {
$command = 'vagrant ssh -c %s %s';
$command = 'vagrant ssh' . ( $ssh_args ? ' ' . $ssh_args : '' ) . ' -c %s %s';

$escaped_command = sprintf(
$command,
Expand All @@ -860,7 +869,7 @@ private function generate_ssh_command( $bits, $wp_command ) {

// Default scheme is SSH.
if ( 'ssh' === $bits['scheme'] || null === $bits['scheme'] ) {
$command = 'ssh %s %s %s';
$command = 'ssh %s%s %s %s';

if ( $bits['user'] ) {
$bits['host'] = $bits['user'] . '@' . $bits['host'];
Expand All @@ -887,6 +896,7 @@ private function generate_ssh_command( $bits, $wp_command ) {

$escaped_command = sprintf(
$command,
$ssh_args ? $ssh_args . ' ' : '',
implode( ' ', array_filter( $command_args ) ),
escapeshellarg( $bits['host'] ),
escapeshellarg( $wp_command )
Expand Down
2 changes: 1 addition & 1 deletion php/class-wp-cli.php
B94A
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/**
* Various utilities for WP-CLI commands.
*
* @phpstan-type GlobalConfig array{path: string|null, ssh: string|null, http: string|null, url: string|null, user: string|null, 'skip-plugins': true|string[], 'skip-themes': true|string[], 'skip-packages': bool, require: string[], exec: string[], context: string, debug: string|true, prompt: false|string, quiet: bool, apache_modules: string[]}
* @phpstan-type GlobalConfig array{path: string|null, ssh: string|null, 'ssh-args': string[], http: string|null, url: string|null, user: string|null, 'skip-plugins': true|string[], 'skip-themes': true|string[], 'skip-packages': bool, require: string[], exec: string[], context: string, debug: string|true, prompt: false|string, quiet: bool, apache_modules: string[]}
*
* @phpstan-type FlagParameter array{type: 'flag', name: string, description?: string, optional?: bool, repeating?: bool, aliases?: string[]}
* @phpstan-type AssocParameter array{type: 'assoc', name: string, description?: string, options?: string[], default?: string, optional?: bool, value: array{optional: bool, name?: string}, repeating?: bool, aliases?: string[]}
Expand Down
8 changes: 8 additions & 0 deletions php/config-spec.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
'desc' => 'Perform operation against a remote server over SSH (or a container using scheme of "docker", "docker-compose", "docker-compose-run", "vagrant").',
],

'ssh-args' => [
'runtime' => '=<args>',
'file' => '<args>',
'desc' => 'Pass additional arguments to SSH (or other tools specified by --ssh scheme).',
'multiple' => true,
'default' => [],
],

'http' => [
'runtime' => '=<http>',
'file' => '<http>',
Expand Down
0