-
Notifications
You must be signed in to change notification settings - Fork 224
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support ssh connection to windows targets #813
Comments
Hi @ndelo! We do indeed assume that users using the ssh transport are connecting to unix hosts - https://github.com/puppetlabs/bolt/blob/master/lib/bolt/transport/ssh/connection.rb#L309 is the specific lines that will need to change. I'm not sure what the best approach to this will be though - maybe adding a check for the host os? Or having some kind of 'tag' on the hosts that are windows, and using that instead of the transport to determine commands like mkdir? Most of the team is off this week and early next week, so you might hear more next Wednesday or so! |
We'd like to separate the context of transport from the shell you're operating in on the target, but that'll be a bit of an undertaking. We've started it for powershell. I imagine it would look like Transports: ssh, winrm, local ssh would default to shell, but could have a config to override that and use powershell on the target. |
That would work for our use cases. I think Win OpenSSH defaults to CMD, but we’re testing with changing the default shell to PS.
In your thinking, would ‘shell’ be an available CLI option when executing bolt?
…Sent from my iPhone
On Jan 2, 2019, at 3:57 PM, Michael Smith <notifications@github.com<mailto:notifications@github.com>> wrote:
We'd like to separate the context of transport from the shell you're operating in on the target, but that'll be a bit of an undertaking. We've started it for powershell. I imagine it would look like
Transports: ssh, winrm, local
Shell: powershell, (linux) shell
ssh would default to shell, but could have a config to override that and use powershell on the target.
winrm would default to powershell and could be overridden to shell.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.51.al%2Fpuppetlabs%2Fbolt%2Fissues%2F813%23issuecomment-450982801&data=02%7C01%7Cndelo%40Princeton.EDU%7C744332b2999748a007a908d670f4f785%7C2ff601167431425db5af077d7791bda4%7C0%7C0%7C636820594765057009&sdata=gwcdRGQ%2BeaHt82py%2F%2BwAz0TnjxSXNMI3Xsop0I7qfw0%3D&reserved=0>, or mute the thread<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.51.al%2Fnotifications%2Funsubscribe-auth%2FAZjQ0YWptcu_O1J0m_ktQ9E9m9zjFRYeks5u_R1NgaJpZM4Zj12x&data=02%7C01%7Cndelo%40Princeton.EDU%7C744332b2999748a007a908d670f4f785%7C2ff601167431425db5af077d7791bda4%7C0%7C0%7C636820594765057009&sdata=XVCvt8h6JksVfMMDphCQCiBRHYlDR2uMG3kBDdiZdtI%3D&reserved=0>.
|
It would definitely be a configuration option in inventory. We add it elsewhere (bolt.yaml and CLI) when it seems useful. |
bolt --version
1.17.0 |
+1 |
Relates to #1492 |
…transports Previously, the similarities between the local and SSH transports were represented by the Sudoable base transport class. This made the two transports tightly coupled to bash. It also meant we had two separate implementations of sudo support, one for each of the transports. This commit introduces a conceptual split between the "connection" portion of a transport and the "shell" that it talks to on the other end. In this case, "local" and "SSH" are two implementations of how to connect to a target, but the Bolt::Shell::Bash class contains all the logic of how to actually get something done over the connection. The SSH and local connection classes now are required to implement only two methods: `execute` and `copy_file`. All other operations are built in terms of those two primitives. All logic for how to run commands, scripts, and tasks on a bash target, including how to invoke sudo, is now contained in th Bolt::Shell::Bash class. This represents the first step in eventually supporting running against Powershell targets over SSH.
…transports Previously, the similarities between the local and SSH transports were represented by the Sudoable base transport class. This made the two transports tightly coupled to bash. It also meant we had two separate implementations of sudo support, one for each of the transports. This commit introduces a conceptual split between the "connection" portion of a transport and the "shell" that it talks to on the other end. In this case, "local" and "SSH" are two implementations of how to connect to a target, but the Bolt::Shell::Bash class contains all the logic of how to actually get something done over the connection. The SSH and local connection classes now are required to implement only two methods: `execute` and `copy_file`. All other operations are built in terms of those two primitives. All logic for how to run commands, scripts, and tasks on a bash target, including how to invoke sudo, is now contained in th Bolt::Shell::Bash class. This represents the first step in eventually supporting running against Powershell targets over SSH.
…transports Previously, the similarities between the local and SSH transports were represented by the Sudoable base transport class. This made the two transports tightly coupled to bash. It also meant we had two separate implementations of sudo support, one for each of the transports. This commit introduces a conceptual split between the "connection" portion of a transport and the "shell" that it talks to on the other end. In this case, "local" and "SSH" are two implementations of how to connect to a target, but the Bolt::Shell::Bash class contains all the logic of how to actually get something done over the connection. The SSH and local connection classes now are required to implement only two methods: `execute` and `copy_file`. All other operations are built in terms of those two primitives. All logic for how to run commands, scripts, and tasks on a bash target, including how to invoke sudo, is now contained in th Bolt::Shell::Bash class. This represents the first step in eventually supporting running against Powershell targets over SSH.
Previously, we set environment variables with the `sudo` invocation and relied on `sudo` to pass them through to the command being executed. That doesn't work in every configuration or with every run-as command. It also unnecessarily makes those values available to `sudo`. We now set the environment variables *inside* the `sudo` invocation, ensuring they're passed to the command we're trying to execute. This changes the local transport to no longer rely on Open3's ability to set environment variables directly. That means SSH and local now pass environment variables in exactly the same way.
…transports Previously, the similarities between the local and SSH transports were represented by the Sudoable base transport class. This made the two transports tightly coupled to bash. It also meant we had two separate implementations of sudo support, one for each of the transports. This commit introduces a conceptual split between the "connection" portion of a transport and the "shell" that it talks to on the other end. In this case, "local" and "SSH" are two implementations of how to connect to a target, but the Bolt::Shell::Bash class contains all the logic of how to actually get something done over the connection. The SSH and local connection classes now are required to implement only two methods: `execute` and `copy_file`. All other operations are built in terms of those two primitives. All logic for how to run commands, scripts, and tasks on a bash target, including how to invoke sudo, is now contained in th Bolt::Shell::Bash class. This represents the first step in eventually supporting running against Powershell targets over SSH.
Previously, we set environment variables with the `sudo` invocation and relied on `sudo` to pass them through to the command being executed. That doesn't work in every configuration or with every run-as command. It also unnecessarily makes those values available to `sudo`. We now set the environment variables *inside* the `sudo` invocation, ensuring they're passed to the command we're trying to execute. This changes the local transport to no longer rely on Open3's ability to set environment variables directly. That means SSH and local now pass environment variables in exactly the same way.
…transports Previously, the similarities between the local and SSH transports were represented by the Sudoable base transport class. This made the two transports tightly coupled to bash. It also meant we had two separate implementations of sudo support, one for each of the transports. This commit introduces a conceptual split between the "connection" portion of a transport and the "shell" that it talks to on the other end. In this case, "local" and "SSH" are two implementations of how to connect to a target, but the Bolt::Shell::Bash class contains all the logic of how to actually get something done over the connection. The SSH and local connection classes now are required to implement only two methods: `execute` and `copy_file`. All other operations are built in terms of those two primitives. All logic for how to run commands, scripts, and tasks on a bash target, including how to invoke sudo, is now contained in th Bolt::Shell::Bash class. This represents the first step in eventually supporting running against Powershell targets over SSH.
Previously, we set environment variables with the `sudo` invocation and relied on `sudo` to pass them through to the command being executed. That doesn't work in every configuration or with every run-as command. It also unnecessarily makes those values available to `sudo`. We now set the environment variables *inside* the `sudo` invocation, ensuring they're passed to the command we're trying to execute. This changes the local transport to no longer rely on Open3's ability to set environment variables directly. That means SSH and local now pass environment variables in exactly the same way.
When using run-as, we first `cd` to the user's homedir to ensure we're not running from a directory that the run-as user can't access. However, the run-as user's homedir doesn't necessarily have to exist. Previously, that would cause a failure as the `cd` would fail and we would therefore refuse to run the actual command. Now, we just *try* to `cd` to the homedir if possible and then run the command regardless.
This commit factors out the Powershell code from the WinRM and Windows local transports to match the transport/shell split implemented for SSH and Bash. That is, the transports are now merely responsible for connecting to the target, executing commands and uploading files, while the powershell shell class handles running tasks, etc. We no longer have a dedicated local_windows transport, instead using the standard local transport. The local transport will run any command it's given via powershell. This matches the non-windows behavior where commands are run via shell. Due to bugs in passing stdin from ruby to powershell, we cannot simply send the commands over stdin. Therefore, we write the commands to a file and point powershell at that. This also avoids limitations around command-line length if we were to instead run via `powershell.exe -Command`. Because commands are now run via powershell, we can run into problems with powershell inserting a byte order marker in content that we supply to a task via stdin. For that reason, we now detect whether the [Console] object is configured to use UTF-8 and, if so, we replace its encoding a non-BOM version of UTF-8. This also standardizes the newline behavior between the local and WinRM transports. Previously, the WinRM transport would return \r\n while the local transport would return \n. They now consistently return \r\n. !feature * **Commands run over local transport on Windows use powershell** ([puppetlabs#1708](puppetlabs#1708)) Previously, the local transport on Windows would exec commands directly, meaning powershell constructs couldn't be used. These commands are now always executed through powershell, so powershell commands and script snippets can be run. * **Commands and tasks on Windows now consistently return \r\n** ([puppetlabs#1708](puppetlabs#1708)) The local transport on Windows was returning \n while WinRM returned \r\n. They are now consistent and always use \r\n.
…gin shell This adds a new `login-shell` option to the SSH transport which can be used to tell Bolt which shell to expect. We support a number of bash-compatible shells and powershell, which is experimental. Selecting any of the supported non-powershell options will result in identical behavior. !feature * **Experimental support for interacting with Windows hosts via PowerShell over SSH** ([puppetlabs#813](puppetlabs#813)) The `login-shell: powershell` config setting can be set on a target to connect over SSH while running commands and tasks via PowerShell instead of Bash.
We now disallow tty/run-as when using PowerShell and allow extensions. We don't fail if extension is set when not using PowerShell, though it will be ignored.
…gin shell This adds a new `login-shell` option to the SSH transport which can be used to tell Bolt which shell to expect. We support a number of bash-compatible shells and powershell, which is experimental. Selecting any of the supported non-powershell options will result in identical behavior. !feature * **Experimental support for interacting with Windows hosts via PowerShell over SSH** ([puppetlabs#813](puppetlabs#813)) The `login-shell: powershell` config setting can be set on a target to connect over SSH while running commands and tasks via PowerShell instead of Bash.
We now disallow tty/run-as when using PowerShell and allow extensions. We don't fail if extension is set when not using PowerShell, though it will be ignored.
(GH-813) Abstract Powershell shell implementation
…gin shell This adds a new `login-shell` option to the SSH transport which can be used to tell Bolt which shell to expect. We support a number of bash-compatible shells and powershell, which is experimental. Selecting any of the supported non-powershell options will result in identical behavior. !feature * **Experimental support for interacting with Windows hosts via PowerShell over SSH** ([puppetlabs#813](puppetlabs#813)) The `login-shell: powershell` config setting can be set on a target to connect over SSH while running commands and tasks via PowerShell instead of Bash.
We now disallow tty/run-as when using PowerShell and allow extensions. We don't fail if extension is set when not using PowerShell, though it will be ignored.
Older versions of OpenSSH have a bug that causes quotes and backslashes to be eaten before they can be properly interpreted by powershell. This causes every task invocation to fail. We now detect the SSH version and fail if it's one that is known to be incompatible.
…gin shell This adds a new `login-shell` option to the SSH transport which can be used to tell Bolt which shell to expect. We support a number of bash-compatible shells and powershell, which is experimental. Selecting any of the supported non-powershell options will result in identical behavior. !feature * **Experimental support for interacting with Windows hosts via PowerShell over SSH** ([puppetlabs#813](puppetlabs#813)) The `login-shell: powershell` config setting can be set on a target to connect over SSH while running commands and tasks via PowerShell instead of Bash. This feature requires OpenSSH >= 7.9 on the target.
We now disallow tty/run-as when using PowerShell and allow extensions. We don't fail if extension is set when not using PowerShell, though it will be ignored.
Older versions of OpenSSH have a bug that causes quotes and backslashes to be eaten before they can be properly interpreted by powershell. This causes every task invocation to fail. We now detect the SSH version and fail if it's one that is known to be incompatible.
Older versions of OpenSSH have a bug that causes quotes and backslashes to be eaten before they can be properly interpreted by powershell. This causes every task invocation to fail. We now detect the SSH version and fail if it's one that is known to be incompatible.
We can't execute commands that are 32700+ bytes long over SSH. Therefore, we now wrap such commands in a script and invoke that. This factors out the code that already does such wrapping for the local transport and moves it to the Powershell class where it more rightly belongs. This has the benefit that we no longer generate a script for commands that are smaller than the limit when using the local transport. Except for tasks like apply_catalog which receive large amounts of data on stdin, most things should fit under the limit.
We can't execute commands that are 32700+ bytes long over SSH. Therefore, we now wrap such commands in a script and invoke that. This factors out the code that already does such wrapping for the local transport and moves it to the Powershell class where it more rightly belongs. This has the benefit that we no longer generate a script for commands that are smaller than the limit when using the local transport. Except for tasks like apply_catalog which receive large amounts of data on stdin, most things should fit under the limit.
We can't execute commands that are 32700+ bytes long over SSH. Therefore, we now wrap such commands in a script and invoke that. This factors out the code that already does such wrapping for the local transport and moves it to the Powershell class where it more rightly belongs. This has the benefit that we no longer generate a script for commands that are smaller than the limit when using the local transport. Except for tasks like apply_catalog which receive large amounts of data on stdin, most things should fit under the limit.
…gin shell This adds a new `login-shell` option to the SSH transport which can be used to tell Bolt which shell to expect. We support a number of bash-compatible shells and powershell, which is experimental. Selecting any of the supported non-powershell options will result in identical behavior. !feature * **Experimental support for interacting with Windows hosts via PowerShell over SSH** ([puppetlabs#813](puppetlabs#813)) The `login-shell: powershell` config setting can be set on a target to connect over SSH while running commands and tasks via PowerShell instead of Bash. This feature requires OpenSSH >= 7.9 on the target.
We now disallow tty/run-as when using PowerShell and allow extensions. We don't fail if extension is set when not using PowerShell, though it will be ignored.
Older versions of OpenSSH have a bug that causes quotes and backslashes to be eaten before they can be properly interpreted by powershell. This causes every task invocation to fail. We now detect the SSH version and fail if it's one that is known to be incompatible.
We can't execute commands that are 32700+ bytes long over SSH. Therefore, we now wrap such commands in a script and invoke that. This factors out the code that already does such wrapping for the local transport and moves it to the Powershell class where it more rightly belongs. This has the benefit that we no longer generate a script for commands that are smaller than the limit when using the local transport. Except for tasks like apply_catalog which receive large amounts of data on stdin, most things should fit under the limit.
We need to close this file on Windows before it can be moved.
This needs to be double-quoted (escape_arguments) instead of single-quoted (quote_string).
…wershell-over-ssh (puppetlabsGH-813) Add the ability to select powershell as the SSH login shell
Problem
Bolt transport make assumptions about what shell and commands are available on the the target based on the transport that is being used.
Solution:
Command building logic should be split out of command execution logic in the transports. Each transport should probe what the login shell is on the other side of the connection and cache that information with the "connection" for the duration of a bolt execution. It should then build shell specific commands to run over the transports execute functionality.
We only need to support sh/bash for linux and we should assume the same LCD versions of unix commands are available. The code should be written in such a way that we can add csh support without a further refactor however.
We do not need to implement shell discovery functionality in the winrm transport but should for local, ssh, and docker.
Questions:
The text was updated successfully, but these errors were encountered: