-
Notifications
You must be signed in to change notification settings - Fork 70
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
First whack at windows (target) support for taste-tester #144
Conversation
Oh one thing this does not yet do is handle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems overall reasonable, but I'd like someone with powershell/windows experience to review it as well. cc @svmastersamurai @HeyItsGilbert
bin/taste-tester
Outdated
rescue StandardError | ||
logger.error("Invalid date: #{time}") | ||
exit 1 | ||
# can make this an implicit rescue after we dtop 2.4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/dtop/drop/ ?
lib/taste_tester/host.rb
Outdated
"$ttconfig = \"#{ttconfig}\"", | ||
"$realconfig = \"#{realconfig}\"", | ||
|
||
# TODO use real tmpfiles |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, you should be able to use New-TemporaryFile
here: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/new-temporaryfile
lib/taste_tester/ssh_util.rb
Outdated
# *and* powershell, so in order to preserve the quotes, it gets | ||
# pretty ugly. | ||
# | ||
# The tldr here is that in shell you can't escapte quotes you're |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/escapte/escape/
lib/taste_tester/ssh_util.rb
Outdated
# | ||
# We're doing the same thing here. What we want on the other side of | ||
# the ssh is: | ||
# Text.Encoding]::Utf8.GetString([Convert]::FromBase64String('...')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you dropped a leading [
and meant [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String('...'))
here?
lib/taste_tester/ssh_util.rb
Outdated
# single quotes too. For simplicity lets call those two functions | ||
# above GetString() and Base64(). So we'll start with: | ||
# ssh host 'GetString(Base64(' | ||
# We've closed that strong, now we add the single quote we want there, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/strong/string/
lib/taste_tester/ssh_util.rb
Outdated
# string 1 string2 string3 | ||
cmd += 'powershell.exe -c -; exit $LASTEXITCODE\'' | ||
# ----------------------------------------^ | ||
# continued strong3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/strong3/string3/
5a51af7
to
e795255
Compare
I can't imagine we have any desire to have TT itself run on Windows, however, one has to manage their windows system sometime, and that means being able to test on those systems. This adds support for the remote system by generating the right powershell to send over ssh. That means there are two requirements to using this: 1. You have ssh enabled on your Windows PC 2. You set the default shell to powershell instead of cmd Both are easily accomplished with this tiny bit of Chef: ```ruby powershell_package 'ComputerManagementDsc' do action :install end dsc_resource 'install ssh-client' do resource :windowscapability module_name 'ComputerManagementDsc' property :name, 'OpenSSH.Client~~~~0.0.1.0' property :ensure, 'Present' end dsc_resource 'install ssh-server' do resource :windowscapability module_name 'ComputerManagementDsc' property :name, 'OpenSSH.Server~~~~0.0.1.0' property :ensure, 'Present' end dsc_resource 'start sshd' do resource :service property :name, 'sshd' property :startuptype, 'Automatic' property :state, 'Running' property :ensure, 'Present' end ``` This also requires you to be on a version modern enough that symlinks actually work - sorry, we're not re-inventing how taste-tester works for old broken OSes. Getting Windws support here is ugly enough as it is. You may be wondering "but Windows has bash support now!"... and you'd be sorta-right. You can enable WSL and Bash in modern Windows, but you end up in a embedded linux environment. You can access the Windows filesystem, but it's not a thing most people are going to want to do on their windows systems. So, powershell it is. This fully supports tunnels and non-tunnels. As far as I can tell, everything works except "bundle mode" and "local transport", but I don't think those are necessary here. In order to not repeat the *crazy* trans-shell logic, I factored out some code that was repeated (but badly, with bugs - now we *always* specify `-o StrictHostKeyChecking=no` and friends, not just sometimes) between ssh.rb and tunnel.rb into ssh_util.rb. I took this approach because it was the least change, and since that's not directly related to this PR, I wanted to minimize that. However, the long-term solution here is to just roll tunnel.rb into ssh.rb. It already has a `tunnel` option it ignores in the initializer. Signed-off-by: Phil Dibowitz <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just nits. Welcome to Powershell! 😂
# Sources must be 'registered' with the Eventlog, so check if we have | ||
# registered and register if necessary | ||
def create_eventlog_if_needed_cmd | ||
get_src = 'Get-EventLog -LogName Application -source taste-tester 2>$null' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably fine. The PowerShell way would be to Pipe this to Out-Null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just follows the docs on MS's site, they did this. But sure, I'm find with whatever. :)
|
||
# Remove our tmp file before we write to it or certutil crashes... | ||
'if (Test-Path $tmp) { rm $tmp }', | ||
'certutil -decode $tmp64 $tmp', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shelling out to certutil feels wrong. .Net methods are available in PowerShell by default. Maybe something like: [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String($tmp))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So like [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String($b64)) | Out-File Encoding ASCII $tmp -Force
maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops. Missed you were writing ASCII. That works, one minor tweak (assuming the $b64 text is ASCII): [Text.Encoding]::ASCII.GetString([Convert]::FromBase64String($b64)) | Out-File Encoding ASCII $tmp -Force
'$b64 | Out-File -Encoding ASCII $tmp64 -Force', | ||
|
||
# Remove our tmp file before we write to it or certutil crashes... | ||
'if (Test-Path $tmp) { rm $tmp }', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rm
is an alias for Remove-Item
which you might want to add a -Force
to. Not sure if we should worry about file locks or if we want it to fail on purpose. If the command failed, would everything stop or would it keep going?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-Force
STILL crashes if the file isn't there... hence the test.
|
||
def build_ssh_cmd(ssh, command_list) | ||
if TasteTester::Config.windows_target | ||
# Powershell has no `&&`. So originally we looked into joining the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PowerShell commands have the notion of ErrorAction
. You could set this globally with $ErrorActionPreference = Stop
or individually by adding $ErrorAction = Stop
to individual cmdlets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I played with that a bit but we also want to catch the "testing by someone else" differently, and I found that I was losing that... I'm sure it can be made ti work...
|
||
while (1 -eq 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while ($true)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason that didn't work for me.
# For the record, if you want to play with this, you do so with: | ||
# (gwmi win32_process | ? processid -eq $PID).parentprocessid | ||
# | ||
# Also note that backtick is a line-continuation marker in powershell. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is almost always a no-no since it makes it super hard to read. I'll recommend a splat below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha I searched for SO LONG on how to break lines in powershell and the only answer I got was "don't"... and then I FINALLY found backtick.
while (1 -eq 1) { | ||
if (-Not (Test-Path $ts)) { | ||
# if we are here, we know we've created our source | ||
Write-EventLog -LogName "Application" -Source "taste-tester" ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$splat = @{
LogName = "Application"
Source = "taste-tester"
EventID = 5
EntryType = "Information"
Message = "Ending tunnel: timestamp file disappeared"
}
Write-EventLog @splat
I can't imagine we have any desire to have TT itself run on Windows,
however, one has to manage their windows system sometime, and that means
being able to test on those systems.
This adds support for the remote system by generating the right
powershell to send over ssh.
That means there are two requirements to using this:
Both are easily accomplished with this tiny bit of Chef:
This also requires you to be on a version modern enough that symlinks
actually work - sorry, we're not re-inventing how taste-tester works
for old broken OSes. Getting Windws support here is ugly enough as it
is.
You may be wondering "but Windows has bash support now!"... and you'd be
sorta-right. You can enable WSL and Bash in modern Windows, but you end
up in a embedded linux environment. You can access the Windows
filesystem, but it's not a thing most people are going to want to do on
their windows systems. So, powershell it is.
This fully supports tunnels and non-tunnels. As far as I can tell,
everything works except "bundle mode" and "local transport", but I don't
think those are necessary here.
In order to not repeat the crazy trans-shell logic, I factored out
some code that was repeated (but badly, with bugs - now we always
specify
-o StrictHostKeyChecking=no
and friends, not just sometimes)between ssh.rb and tunnel.rb into ssh_util.rb. I took this approach
because it was the least change, and since that's not directly related
to this PR, I wanted to minimize that. However, the long-term solution
here is to just roll tunnel.rb into ssh.rb. It already has a
tunnel
option it ignores in the initializer.