Cimpress-MCP / vagrant-winrm-syncedfolders

Use WinRM synced folders for Windows guests using the built in WinRM communcator
Other
22 stars 10 forks source link

Sync folder uploaded wrong after vagrant halt && vagrant up #11

Open kamlim1k opened 7 years ago

kamlim1k commented 7 years ago

Have configuration like this :

config.vm.synced_folder './dsc', '/tmp/dsc', type: 'winrm'

After initial vagrant up folder on guest created like this:

/tmp/dsc/...

After vagrant halt && vagrant up synced folder become like this :

/tmp/dsc/dsc/...
chrisbaldauf commented 7 years ago

Hi @kamlim1k, it would be helpful if you could provide some more background information. I found this in the Vagrant project's issue creation template and it would be helpful if you could fill in the details.

Vagrant version

Run vagrant -v to show the version. If you are not running the latest version of Vagrant, please upgrade before submitting an issue.

Host operating system

This is the operating system that you run locally.

Guest operating system

This is the operating system you run in the virtual machine.

Vagrantfile

# Copy-paste your Vagrantfile here

Please note, if you are using Homestead or a different Vagrantfile format, we may be unable to assist with your issue. Try to reproduce the issue using a vanilla Vagrantfile first.

Debug output

Provide a link to a GitHub Gist containing the complete debug output: https://www.vagrantup.com/docs/other/debugging.html. The debug output should be very long. Do NOT paste the debug output in the issue, just paste the link to the Gist.

kamlim1k commented 7 years ago

Vagrant 1.9.1 Mac OS Sierra 10.12.2 Windows Server 2016

Vagrant.configure('2') do |config|
  config.vm.box = 'dummy'
  config.vm.synced_folder './dsc', '/tmp/dsc', type: 'winrm'
....
end
chrisbaldauf commented 7 years ago

Unfortunately, I don't currently have access to a Windows Server 2016 environment in order to test this so I think I'll need some more information.

1) Could you please also paste the output of running vagrant plugin list? 2) Could you paste the full output of running vagrant up && vagrant halt && vagrant up? 3) Does this behavior change if you use another synced_folder provider, such as rsync?

kamlim1k commented 7 years ago

vagrant-aws (0.7.2) vagrant-aws-winrm (0.0.7) vagrant-dsc (2.0.0) vagrant-share (1.1.6, system) vagrant-winrm-syncedfolders (1.0.1)

I will try to setup simple vagrant configuration tomorrow and add logs and output.

I haven't try rsync, maybe try tomorrow as well

kamlim1k commented 7 years ago

Finally had time to do some test image.

Installed Plugins:

vagrant-aws (0.7.2)
vagrant-aws-winrm (0.0.7)
vagrant-dsc (2.0.0)
vagrant-share (1.1.6, system)
vagrant-winrm-syncedfolders (1.0.1)

Vagrant File :

require 'yaml'

vars = YAML.load_file ENV['CONFIG_FILE'] || 'vars.yml'

Vagrant.configure('2') do |config|
  config.vm.box = 'dummy'

  config.ssh.pty = true

  config.vm.provider :aws do |aws, override|
    aws.aws_profile = vars['aws']['profile']
    aws.region = vars['aws']['region']
    aws.ami = vars['aws']['ami']
    aws.instance_type = vars['aws']['instance_type']
    aws.keypair_name = vars['aws']['keypair_name']
    aws.subnet_id = vars['aws']['subnet_id']
    aws.security_groups = vars['aws']['security_groups']
    aws.associate_public_ip = vars['aws']['associate_public_ip']
    aws.block_device_mapping = vars['aws']['block_device_mapping']
    aws.elastic_ip = vars['aws']['elastic_ip']
    aws.tags = vars['aws']['tags']

    override.vm.communicator = :winrm

    override.winrm.username = 'Administrator'
    override.winrm.password = :aws
    override.winrm.guest_port = 5986
    override.winrm.transport = :ssl
    override.winrm.ssl_peer_verification = false

    override.ssh.private_key_path = vars['ssh']['private_key_path']
  end

  config.vm.synced_folder '.', '/vagrant', disabled: true
  config.vm.synced_folder 'manifests', '/tmp/manifests', type: 'winrm'
end

vagrant up :

...
INFO synced_folders: Invoking synced folder enable: winrm
 INFO interface: info: Uploading with WinRM: /Users/nikolai/Development/Sources/vagrant-test/manifests => /tmp/manifests
 INFO interface: info: ==> default: Uploading with WinRM: /Users/nikolai/Development/Sources/vagrant-test/manifests => /tmp/manifests
DEBUG winrm: Attempting WinRM upload attempt number 1
INFO winrm: Uploading: /Users/nikolai/Development/Sources/vagrant-test/manifests to /tmp/manifests
DEBUG winrmshell: [WinRM] opening remote shell on https://ec2-34-196-59-249.compute-1.amazonaws.com:5986/wsman
DEBUG winrmshell: [WinRM] remote shell 93EE8FCD-F74D-47D7-98BB-8CB582852861 is open on https://ec2-34-196-59-249.compute-1.amazonaws.com:5986/wsman
DEBUG winrmshell: creating hash for directory /tmp/manifests
DEBUG winrmshell: Populating files
DEBUG winrmshell: +++ Adding test.yml
DEBUG winrmshell: === All files added.
DEBUG winrmshell: Running check_files.ps1
DEBUG winrmshell: @{
DEBUG winrmshell:   "$env:TEMP\winrm-upload\tmpzip-8b2fa5376c53094a502d02f35eef6a20.zip" = "8b2fa5376c53094a502d02f35eef6a20"
DEBUG winrmshell: }
DEBUG winrmshell: Uploading /var/folders/3y/cdjvsntn7n9cx696m6sfnys80000gn/T/tmpzip-20170107-61764-xiruoa.zip to encoded tmpfile $env:TEMP\b64-8b2fa5376c53094a502d02f35eef6a20.txt
DEBUG winrmshell: Finished uploading /var/folders/3y/cdjvsntn7n9cx696m6sfnys80000gn/T/tmpzip-20170107-61764-xiruoa.zip to encoded tmpfile $env:TEMP\b64-8b2fa5376c53094a502d02f35eef6a20.txt (0.152 KB over 1 chunks) in (0m0.22s)
DEBUG winrmshell: Running decode_files.ps1
DEBUG winrmshell: @{
DEBUG winrmshell:   "$env:TEMP\b64-8b2fa5376c53094a502d02f35eef6a20.txt" = @{
DEBUG winrmshell:     "dst" = "/tmp/manifests\manifests";
DEBUG winrmshell:     "tmpzip" = "$env:TEMP\winrm-upload\tmpzip-8b2fa5376c53094a502d02f35eef6a20.zip"
DEBUG winrmshell:   }
DEBUG winrmshell: }
DEBUG winrmshell: Cleaned up src_zip /var/folders/3y/cdjvsntn7n9cx696m6sfnys80000gn/T/tmpzip-20170107-61764-xiruoa.zip
DEBUG winrmshell: Uploaded 1 items dirty_check: (0m2.38s) stream_files: (0m0.22s) decode: (0m3.52s)
DEBUG winrmshell: [WinRM] closing remote shell 93EE8FCD-F74D-47D7-98BB-8CB582852861 on https://ec2-34-196-59-249.compute-1.amazonaws.com:5986/wsman
DEBUG winrmshell: [WinRM] remote shell 93EE8FCD-F74D-47D7-98BB-8CB582852861 closed
...

Sync folders correctly :

screen shot 2017-01-07 at 5 13 49 pm

vagrant reload :

...
 INFO synced_folders: Invoking synced folder enable: winrm
 INFO interface: info: Uploading with WinRM: /Users/nikolai/Development/Sources/vagrant-test/manifests => /tmp/manifests
 INFO interface: info: ==> default: Uploading with WinRM: /Users/nikolai/Development/Sources/vagrant-test/manifests => /tmp/manifests
DEBUG winrm: Attempting WinRM upload attempt number 1
 INFO winrm: Uploading: /Users/nikolai/Development/Sources/vagrant-test/manifests to /tmp/manifests
DEBUG winrmshell: [WinRM] opening remote shell on https://ec2-34-196-59-249.compute-1.amazonaws.com:5986/wsman
DEBUG winrmshell: [WinRM] remote shell 19D87D51-74F1-492F-9569-7789BAC1535A is open on https://ec2-34-196-59-249.compute-1.amazonaws.com:5986/wsman
DEBUG winrmshell: creating hash for directory /tmp/manifests
DEBUG winrmshell: Populating files
DEBUG winrmshell: +++ Adding test.yml
DEBUG winrmshell: === All files added.
DEBUG winrmshell: Running check_files.ps1
DEBUG winrmshell: @{
DEBUG winrmshell:   "$env:TEMP\winrm-upload\tmpzip-8b2fa5376c53094a502d02f35eef6a20.zip" = "8b2fa5376c53094a502d02f35eef6a20"
DEBUG winrmshell: }
DEBUG winrmshell: File /tmp/manifests\manifests is up to date, skipping
DEBUG winrmshell: Running decode_files.ps1
DEBUG winrmshell: @{
DEBUG winrmshell:   "clean1" = @{
DEBUG winrmshell:     "dst" = "/tmp/manifests\manifests";
DEBUG winrmshell:     "tmpzip" = "$env:TEMP\winrm-upload\tmpzip-8b2fa5376c53094a502d02f35eef6a20.zip"
DEBUG winrmshell:   }
DEBUG winrmshell: }
DEBUG winrmshell: Cleaned up src_zip /var/folders/3y/cdjvsntn7n9cx696m6sfnys80000gn/T/tmpzip-20170107-63368-rmmpsh.zip
DEBUG winrmshell: Uploaded 2 items dirty_check: (0m4.09s) stream_files: (0m0.00s) decode: (0m5.00s)
DEBUG winrmshell: [WinRM] closing remote shell 19D87D51-74F1-492F-9569-7789BAC1535A on https://ec2-34-196-59-249.compute-1.amazonaws.com:5986/wsman
DEBUG winrmshell: [WinRM] remote shell 19D87D51-74F1-492F-9569-7789BAC1535A closed

Synced folders incorrect (creates nested folder):

screen shot 2017-01-07 at 5 18 01 pm screen shot 2017-01-07 at 5 25 39 pm
kamlim1k commented 7 years ago

Interesting... I was trying to setup/use rsync and looking into rsync code in vagrant found this in def self.rsync_single(machine, ssh_info, opts)

        # Make sure the host path ends with a "/" to avoid creating
        # a nested directory...
        if !hostpath.end_with?("/")
          hostpath += "/"
        end

Maybe that what should be added ?

chrisbaldauf commented 7 years ago

That looks promising, I'll take a look into it tomorrow. If you have time to try a local patch and let me know if it works, that would be appreciated.

kamlim1k commented 7 years ago

Sure, if anything need to be tested I will find time. I also look through winrm-fs repo and find this today : https://github.com/WinRb/winrm-fs/pull/52 It looks like slash will not be handled correctly if added unless that pull request will be merged on winrm-fs.

devbeard commented 5 years ago

I am guessing this never got fixed? I encountered this issue today and found this discussion. I have a folder "Tests" with a subfolder Scenarios that I want to copy to the VM. This results in the directory structure /tmp/vagrant-dsc-116/Tests/Scenarios/Scenarios/filename.ps1 (116 is one of many). Attempted a local fix in synced_folder.rb to get around this, copied from @kamlim1k's post from above, but with no luck yet.

takesson commented 5 years ago

Looks like this/similar issue has generalized itself in recent versions of Vagrant (currently 2.2.5). The additional folder depth is created during the first boot which makes chef_zero provisioning fail because the cookbooks are one level deeper than expected.

Seems like very few people are using this plugin now. What is the mainstream solution for Windows guests on AWS? I want to use the standard AWS AMIs where there is no SSHD. Preferably with minimal installations in bootstrap script. Host OS is Linux which means SMB is not an option.

Any ideas welcome.

takesson commented 5 years ago

Maybe a good idea to move to Windows 2019 and use the OpenSSH shipped by Microsoft. Perhaps simple to combine with cygwin rsync.

Chocolatey has a small rsync package.

deargle commented 4 years ago

egads I have it... or at least, part of it, for chef-solo provisioning.

The two key codeblocks are these:

https://github.com/hashicorp/vagrant/blob/b03f8f5aac3267a5e183e644a411ac244098e96a/plugins/communicators/winrm/shell.rb#L109-L128 is what gets called by this plugin first.

https://github.com/WinRb/winrm-fs/blob/035ad88490ec09eef5e93a1bb00f36c71ec9efe9/lib/winrm-fs/core/file_transporter.rb#L178-L191 , which determines to where the final directory will be unzipped, expects the "to" destination to not include the folder basename -- it appends it.

The first codeblock wants the "from" path to end in /., but chef-solo only retains the folder name. So, I change:

https://github.com/Cimpress-MCP/vagrant-winrm-syncedfolders/blob/0d0c4531a15539869242c206230e9229aab5c38b/lib/vagrant-winrm-syncedfolders/synced_folder.rb#L42

to

comm.upload(hostpath + "/.", guestpath)

But it's still getting nested-duplicated on subsequent vagrant reloads.

takesson commented 4 years ago

In my experience it has been challenging to keep a vagrant setup with multiple plugins stable over time/years. I decided to remove plugins whenever possible and Microsoft shipping with OpenSSH gave an opportunity to drop this plugin.

I now have a setup where Windows 2019 is bootstrapped (from the base AWS image) to enable the Microsoft-shipped OpenSSH, deploy an SSH key, install rsync with choco. The synced folders can then run rsync over SSH while core Vagrant communications is still winrm.

I am now using a single Vagrant plugin (AWS). I need to do some clean-up of the bootstrap script but I can post tidbits if anyone is interested.

deargle commented 4 years ago

@takesson that is sounding like the best approach. I'm on GCP and launching a windows server image within a nested debian instance, trying to be able to integrate with metasploitable3 https://github.com/rapid7/metasploitable3 . So I only need to provision the images once. Metasploitable's current approach is a bunch of gnarly one-off scripts, but there is a PR for switching the windows provisioning to chef. I'll probably do your openssh - choco - rsync thing too. I noticed that the prepared IE virtual machines that microsoft provides all have openssh installed -- even the old Windows 7 ones. These ones: https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/

deargle commented 4 years ago

Although, I should note that the nested dir bug I think belongs to WinRM ruby library -- not to this plugin. Regardless, I'm abandoning WinRM.

deargle commented 4 years ago

Noteworthy @takesson, relevant to you asking about modern trends for provisioning windows vms with only winrm: the venerable https://github.com/ruzickap/packer-templates/blob/e1066391c8c0a8529eac221ec49bc19d42072662/windows.json#L130-L132 uses ansible over winrm to great success. Combined with podunk shell scripts.

For my project (https://github.com/deargle/vuln-windows-2019/blob/master/Vagrantfile), I ended up just doing provisioning with powershell scripts, building off of a pre-packered win2019 instance. Enabling builtin openssh wasn't hard, https://github.com/deargle/vuln-windows-2019/blob/master/scripts/openssh-builtin.ps1. I didn't get as far as testing synced folders because I haven't tried adding chef yet, but again, I'll probably just do ansible if it comes to something that powershell can't handle.

takesson commented 4 years ago

@deargle I agree it was not hard to enable builtin openssh and login with password. It was a bit trickier to get the public key configured to enable rsync. Figured it out and it seems stable now.

I prefer to avoid maintaining any images/boxes so I can always use the latest available AMI on AWS.

deargle commented 4 years ago

Cool, can you share your rsync public key solution?

On Mon, Dec 2, 2019, 2:58 PM Thomas Åkesson notifications@github.com wrote:

@deargle https://github.com/deargle I agree it was not hard to enable builtin openssh and login with password. It was a bit trickier to get the public key configured to enable rsync. Figured it out and it seems stable now.

I prefer to avoid maintaining any images/boxes so I can always use the latest available AMI on AWS.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Cimpress-MCP/vagrant-winrm-syncedfolders/issues/11?email_source=notifications&email_token=AAI6Y7O3ZV2H6B33TWKGVTDQWWAG3A5CNFSM4C3M5UXKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFVWH6Y#issuecomment-560686075, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI6Y7OB242CBECGMZ4NSMLQWWAG3ANCNFSM4C3M5UXA .

takesson commented 4 years ago

Setting up SSH public key for the administrators group. Microsoft has configured OpenSSH such that individual keys for Administrator cannot be added without modifying config files.

Note: I am doing rsync over SSH but the Vagrant communicator is still over WinRM. I tried the winssh communicator but it seemed broken. Anyone having success with the winssh communicator?

# Configure authorized_keys for administrators group instead.
# Individual authorized_keys requires changes to c:\ProgramData\ssh\sshd_config.
# Getting key via curl works via ssh but not in userdata script.
# AWS: Get the public key via instance meta-data.
Invoke-WebRequest -Uri "http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key" -Outfile "C:\\ProgramData\\ssh\\administrators_authorized_keys"
# Alternatively: public key in the script:
#Set-Content -Path 'c:\ProgramData\ssh\administrators_authorized_keys' -Value 'ssh-rsa AAAAB3N... primary-keypair'
icacls C:\ProgramData\ssh\administrators_authorized_keys /remove "NT AUTHORITY\Authenticated Users"
icacls C:\ProgramData\ssh\administrators_authorized_keys /inheritance:r
icacls C:\ProgramData\ssh\administrators_authorized_keys /setowner "NT AUTHORITY\SYSTEM"

Install rsync via Chocolatey:

# Install chocolatey in order to install rsync (shared folders)
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
choco install --force -y rsync

I have very basic Powershell skills so there might be things to clean up.