diff --git a/features/aliases.feature b/features/aliases.feature index 9c06b003ea..4284c3a1a5 100644 --- a/features/aliases.feature +++ b/features/aliases.feature @@ -230,7 +230,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo --debug --version` Then STDERR should contain: """ - Running SSH command: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -T -vvv '' 'wp --debug --version' + Running SSH command: ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -T WP_CLI_SSH_RUN=1 -vvv '' 'wp --debug --version' """ @skip-windows @skip-macos @@ -306,7 +306,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo plugin list --debug` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; wp plugin list --debug' + Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; WP_CLI_SSH_RUN=1 wp plugin list --debug' """ @skip-windows @skip-macos @@ -321,7 +321,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo post create --post_title=My Title --debug` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; wp post create --post_title=My Title + Running SSH command: ssh -T -vvv 'user@host' 'cd '\''/path/to/wordpress'\''; WP_CLI_SSH_RUN=1 wp post create --post_title=My Title """ @skip-windows @skip-macos @@ -337,7 +337,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo --debug --version` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'env WP_CLI_RUNTIME_ALIAS= + Running SSH command: ssh -T -vvv 'user@host' 'WP_CLI_SSH_RUN=1 env WP_CLI_RUNTIME_ALIAS= """ And STDERR should contain: """ @@ -390,7 +390,7 @@ Feature: Create shortcuts to specific WordPress installs When I try `wp @foo --debug --version` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'user@host' 'env WP_CLI_RUNTIME_ALIAS= + Running SSH command: ssh -T -vvv 'user@host' 'WP_CLI_SSH_RUN=1 env WP_CLI_RUNTIME_ALIAS= """ And STDERR should contain: """ diff --git a/features/flags.feature b/features/flags.feature index 371619a8e7..0fe0f641f7 100644 --- a/features/flags.feature +++ b/features/flags.feature @@ -396,7 +396,7 @@ Feature: Global flags When I try `WP_CLI_STRICT_ARGS_MODE=1 wp --debug --ssh=/ --ssh-args="-o BatchMode=yes" --version` Then STDERR should contain: """ - Running SSH command: ssh '-o BatchMode=yes' -T -vvv '' 'WP_CLI_STRICT_ARGS_MODE=1 wp + Running SSH command: ssh '-o BatchMode=yes' -T -vvv '' 'WP_CLI_STRICT_ARGS_MODE=1 WP_CLI_SSH_RUN=1 wp """ @skip-windows @skip-macos @@ -404,7 +404,7 @@ Feature: Global flags When I try `wp --debug --ssh=wordpress:/my/path --version` Then STDERR should contain: """ - Running SSH command: ssh -T -vvv 'wordpress' 'cd '\''/my/path'\''; wp + Running SSH command: ssh -T -vvv 'wordpress' 'cd '\''/my/path'\''; WP_CLI_SSH_RUN=1 wp """ @skip-windows @skip-macos @@ -415,12 +415,38 @@ Feature: Global flags Running SSH command: docker exec --user 'user' 'wordpress' sh -c """ + Scenario: Root-level ssh config should support Docker scheme + Given an empty directory + And a wp-cli.yml file: + """ + ssh: docker:user@wordpress + """ + When I try `WP_CLI_DOCKER_NO_INTERACTIVE=1 wp --debug --version` + Then STDERR should contain: + """ + Running SSH command: docker exec --user 'user' 'wordpress' sh -c + """ + + Scenario: Root-level ssh config should support Docker scheme with an alias + Given an empty directory + And a wp-cli.yml file: + """ + ssh: docker:user@wordpress + @local: + path: /var/www/html + """ + When I try `WP_CLI_DOCKER_NO_INTERACTIVE=1 wp @local --debug --version` + Then STDERR should contain: + """ + Running SSH command: docker exec --user 'user' 'wordpress' sh -c + """ + @skip-windows @skip-macos 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 + Running SSH command: ssh '-o ConnectTimeout=5' -T -vvv 'wordpress' 'WP_CLI_SSH_RUN=1 wp """ @skip-windows @skip-macos @@ -428,7 +454,7 @@ Feature: Global flags 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 + Running SSH command: ssh '-o ConnectTimeout=5' '-o ServerAliveInterval=10' -T -vvv 'wordpress' 'WP_CLI_SSH_RUN=1 wp """ @skip-windows @skip-macos diff --git a/php/WP_CLI/Configurator.php b/php/WP_CLI/Configurator.php index 1c4e9fce7e..58226e38b0 100644 --- a/php/WP_CLI/Configurator.php +++ b/php/WP_CLI/Configurator.php @@ -435,7 +435,7 @@ public function merge_yml( $path, $current_alias = null ) { self::arrayify( $value ); $this->config[ $key ] = array_merge( $this->config[ $key ], $value ); } else { - if ( $current_alias && in_array( $key, self::$alias_spec, true ) ) { + if ( $current_alias && in_array( $key, self::$alias_spec, true ) && ! in_array( $key, array( 'ssh', 'ssh-args', 'proxyjump', 'key' ), true ) ) { continue; } $this->config[ $key ] = $value; diff --git a/php/WP_CLI/Runner.php b/php/WP_CLI/Runner.php index abca85368e..87b3060940 100644 --- a/php/WP_CLI/Runner.php +++ b/php/WP_CLI/Runner.php @@ -687,6 +687,7 @@ private function run_ssh_command( string $connection_string ): void { if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) { $env_vars .= 'WP_CLI_STRICT_ARGS_MODE=1 '; } + $env_vars .= 'WP_CLI_SSH_RUN=1 '; $wp_binary = Utils\get_env_or_config( 'WP_CLI_SSH_BINARY' ) ?: 'wp'; $wp_args = array_slice( (array) $GLOBALS['argv'], 1 ); @@ -832,7 +833,12 @@ private function generate_ssh_command( $bits, $wp_command ) { } if ( 'docker-compose-run' === $bits['scheme'] ) { - $command = '%s run %s%s%s%s%s%s %s'; + $command = '%s run %s%s%s%s%s%s%s %s'; + + $env_flags = '-e WP_CLI_SSH_RUN=1 '; + if ( getenv( 'WP_CLI_STRICT_ARGS_MODE' ) ) { + $env_flags .= '-e WP_CLI_STRICT_ARGS_MODE=1 '; + } $escaped_command = sprintf( $command, @@ -842,6 +848,7 @@ private function generate_ssh_command( $bits, $wp_command ) { $bits['path'] ? '--workdir ' . escapeshellarg( $bits['path'] ) . ' ' : '', $is_stdout_tty || Utils\get_env_or_config( 'WP_CLI_DOCKER_NO_TTY' ) ? '' : '-T ', $is_stdin_tty || Utils\get_env_or_config( 'WP_CLI_DOCKER_NO_INTERACTIVE' ) ? '' : '-i ', + $env_flags, escapeshellarg( $bits['host'] ), $wp_command ); @@ -1560,9 +1567,15 @@ function ( $alias ) { } if ( $this->config['ssh'] ) { - // @phpstan-ignore cast.string - $this->run_ssh_command( (string) $this->config['ssh'] ); - return; + // Don't recurse if SSH came from config file and we're already in an SSH/container session. + // Still allow SSH if it was explicitly passed via --ssh= on the CLI (present in runtime_config). + $ssh_from_cli = isset( $this->runtime_config['ssh'] ) && '' !== $this->runtime_config['ssh']; + if ( getenv( 'WP_CLI_SSH_RUN' ) && ! $ssh_from_cli ) { + WP_CLI::debug( 'Skipping SSH from config file: already running inside an SSH/container session. Use the `--ssh` flag to override.', 'bootstrap' ); + } else { + // @phpstan-ignore cast.string + $this->run_ssh_command( (string) $this->config['ssh'] ); + } } // Log WP-CLI HTTP requests