Skip to content
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

The box is not able to report an address for WinRM to connect to yet. #144

Closed
cignul9 opened this issue Aug 3, 2015 · 6 comments
Closed

Comments

@cignul9
Copy link

cignul9 commented Aug 3, 2015

Versions:
Vagrant (1.7.4)
vagrant-vsphere (1.4.0)

I am attempting to create one instance of a Windows Server 2012 R2 box from a template. I run 'vagrant up' and watch the process build a VM and enter the stage where it is waiting for 'ssh' (which in this case is of course really WinRM). If you've seen the customization spec in action a Windows server will reboot several times before it's done. During one or more of those reboots it acquires an IP address that is not what you set in the customization spec. These IP addresses may be from DHCP, or the IP address of the original template, or IPv6. When the IP address of the clone is IPv6 it dies with error "Invalid argument - connect(2)". When it is any other IPv4 address besides the one it expects from the config, Vagrant stops polling vSphere for machine updates (I measured this with tcpdump). It doesn't log an error or stop, instead it just hangs as if it should be polling but isn't. This seems to be a bug with the vSphere provider. If the template or customization spec isn't configured properly the provider should die and furnish and error that would give me a hint at what I'm supposed to correct ("Invalid argument, blah blah" doesn't cut it).

Is there something I can do that would help me figure out why it stops polling?

config.yml

---
providers:
  vsphere:
    user:                     <redacted>
    password:                 <redacted>
    host:                     <redacted>
    insecure:                 true
    box:                      vsphere
    box_url:                  vsphere.box

templates:
  - name:                   TEMPLATES/Windows Server 2012 R2 Vagrant Template
    username:                 Administrator
    password:                 <redacted>

servers:
  - name:                   <redacted>
    ip:                       <redacted>
    ram:                      6048
    cpus:                     2
    vsphere:
      template_index:         0
      customization_spec:     sql-test
      vlan:                   <redacted>
      datacenter:             <redacted>
      compute_resource:       <redacted>
      vm_base_path:           /
    ansible_extra_vars:
      ansible_ssh_user:       Administrator
      ansible_ssh_pass:       <redacted>
      ansible_ssh_port:       5986
      ansible_connection:     winrm

ansible:
  playbook:                 <redacted>/sql-test.yml
  vault_password_file:      /root/vault-pass.txt

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'yaml'

VAGRANTFILE_API_VERSION = '2'
VAGRANT_DEFAULT_PROVIDER = 'vsphere'
VAGRANT_PROVIDER = VAGRANT_DEFAULT_PROVIDER if ENV['VAGRANT_PROVIDER'].nil?

config_file = YAML.load_file('config.yml')
servers = config_file['servers']
vsphere_config = config_file['providers']['vsphere']

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  case VAGRANT_PROVIDER
    when 'vsphere'
      config.vm.provider :vsphere do |vsphere|
        vsphere.user = vsphere_config['user']
        vsphere.password = vsphere_config['password']
        vsphere.host = vsphere_config['host']
        vsphere.insecure = vsphere_config['insecure']
      end
  end
  servers.each do |server|
    template = config_file['templates'][server['vsphere']['template_index']]
    config.vm.define server['name'] do |os|
      os.vm.provider :vsphere do |vsphere, override|
        override.vm.box = vsphere_config['box']
        override.vm.box_url = vsphere_config['box_url']
        override.vm.synced_folder '.', '/vagrant', disabled: true
        #override.vm.network 'private_network', ip: server['ip'] 
        vsphere.template_name = template['name']
        vsphere.customization_spec_name = server['vsphere']['customization_spec']
        vsphere.vlan = server['vsphere']['vlan']
        vsphere.data_center_name = server['vsphere']['datacenter']
        vsphere.compute_resource_name = server['vsphere']['compute_resource']
        vsphere.vm_base_path = server['vsphere']['vm_base_path']
        vsphere.name = server['name']
        vsphere.memory_mb = server['ram']
        vsphere.cpu_count = server['cpus']
      end
      os.ssh.insert_key = false
      os.ssh.private_key_path = template['private_key_file']
      os.ssh.password = template['password']
      config.vm.provision 'ansible' do |os|
        os.extra_vars = server['ansible_extra_vars']
        os.vault_password_file = config_file['ansible']['vault_password_file']
        os.playbook = config_file['ansible']['playbook']
        os.host_key_checking = false
        os.verbose = 'vv'
      end
    end
  end
end
@cignul9
Copy link
Author

cignul9 commented Aug 3, 2015

Updating my facts:

  • I'm a colossal doofus for overlooking that I didn't specify in the Vagrantfile that I'm working with a windows box. So vagrant was attempting to connect via ssh the whole time. I failed to capture it with tcpdump because I was filtering ssh. Here's the updated configs:

config.yml

---
providers:
  vsphere:
    user:                     <redacted>
    password:                 <redacted>
    host:                     <redacted>
    insecure:                 true
    box:                      vsphere
    box_url:                  vsphere.box

templates:
  - name:                   TEMPLATES/Windows Server 2012 R2 Vagrant Template
    os:                       windows
    username:                 Administrator
    password:                 <redacted>

servers:
  - name:                   <redacted>
    ip:                       <redacted>
    ram:                      6048
    cpus:                     2
    vsphere:
      template_index:         0
      customization_spec:     sql-test
      vlan:                   <redacted>
      datacenter:             <redacted>
      compute_resource:       <redacted>
      vm_base_path:           /
    ansible_extra_vars:
      ansible_ssh_user:       Administrator
      ansible_ssh_pass:       <redacted>
      ansible_ssh_port:       5986
      ansible_connection:     winrm

ansible:
  playbook:                 <redacted>/sql-test.yml
  vault_password_file:      /root/vault-pass.txt

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'yaml'

VAGRANTFILE_API_VERSION = '2'
VAGRANT_DEFAULT_PROVIDER = 'vsphere'
VAGRANT_PROVIDER = VAGRANT_DEFAULT_PROVIDER if ENV['VAGRANT_PROVIDER'].nil?

config_file = YAML.load_file('config.yml')
servers = config_file['servers']
vsphere_config = config_file['providers']['vsphere']

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  case VAGRANT_PROVIDER
    when 'vsphere'
      config.vm.provider :vsphere do |vsphere|
        vsphere.user = vsphere_config['user']
        vsphere.password = vsphere_config['password']
        vsphere.host = vsphere_config['host']
        vsphere.insecure = vsphere_config['insecure']
      end
  end
  servers.each do |server|
    template = config_file['templates'][server['vsphere']['template_index']]
    config.vm.define server['name'] do |os|
      os.vm.provider :vsphere do |vsphere, override|
        override.vm.box = vsphere_config['box']
        override.vm.box_url = vsphere_config['box_url']
        override.vm.synced_folder '.', '/vagrant', disabled: true
        override.vm.network 'private_network', ip: server['ip'] 
        vsphere.template_name = template['name']
        vsphere.customization_spec_name = server['vsphere']['customization_spec']
        vsphere.vlan = server['vsphere']['vlan']
        vsphere.data_center_name = server['vsphere']['datacenter']
        vsphere.compute_resource_name = server['vsphere']['compute_resource']
        vsphere.vm_base_path = server['vsphere']['vm_base_path']
        vsphere.name = server['name']
        vsphere.memory_mb = server['ram']
        vsphere.cpu_count = server['cpus']
      end
      if template['os'] == 'linux'
        os.vm.communicator = :ssh
        os.vm.guest = :linux
        os.ssh.insert_key = false
        os.ssh.private_key_path = template['private_key_file']
        os.ssh.password = template['password']
      end
      if template['os'] == 'windows'
        os.vm.communicator = :winrm
        os.vm.guest = :windows
        os.winrm.username = template['username']
        os.winrm.password = template['password']
      end
      config.vm.provision 'ansible' do |os|
        os.extra_vars = server['ansible_extra_vars']
        os.vault_password_file = config_file['ansible']['vault_password_file']
        os.playbook = config_file['ansible']['playbook']
        os.host_key_checking = false
        os.verbose = 'vv'
      end
    end
  end
end
  • The new problem is that I get a helpful error after the cloned VM boots but before it has any available IP address. Vagrant gives up with this message:

The box is not able to report an address for WinRM to connect to yet.
WinRM cannot access this Vagrant environment. Please wait for the
Vagrant environment to be running and try again.

But I want vagrant to continue with provisioning with Ansible.

Any ideas on how to get vagrant to keep trying until it reaches the IP address I configured, like it does for ssh?

@cignul9 cignul9 changed the title vagrant up hangs after cloning from template The box is not able to report an address for WinRM to connect to yet. Aug 4, 2015
@cignul9
Copy link
Author

cignul9 commented Aug 4, 2015

New update:

I'm not a Ruby wiz, but it appears that the vagrant-vsphere plugin is missing the winrm_info capability, which vagrant needs in order to loop while it waits for the machine to finish the customization spec deets. I will attempt to copy the ssh_info capability to add winrm_info, test, and issue a pull request.

@y4roslav
Copy link

Any updates related to that?

@lilirui
Copy link

lilirui commented Aug 27, 2015

vagrant (1.7.4)
vagrant-vsphere (1.4.0)

I got the exactly same error:
==> windows: Waiting for WinRM to become available...
The box is not able to report an address for WinRM to connect to yet.
WinRM cannot access this Vagrant environment. Please wait for the
Vagrant environment to be running and try again.

@zdman135
Copy link

This appears to be a bug. I am also experiencing the same problem.
@cignul9 appears to be correct:
The vagrant-vsphere plugin is not obtaining the IP address or hostname information from the winrm_info because it doesn't have that capability built in. It keeps wanting to use ssh... even though in my Vagrantfile I have specified: config.vm.communicator = "winrm" .

I went ahead and hardcoded the IP address into my Vagrantfile, and re-ran vagrant up.
I am able to get past that problem, but now I am getting a new error:
action/close_vsphere.rb

So it appears theres some dependencies when trying to close vsphere that isn't getting passed to that ruby file.

This is my Vagrantfile if you are curious:

-- mode: ruby --

vi: set ft=ruby :

Vagrant.configure("2") do |config|

config.vm.box = 'vsphere'
config.vm.box_url = '/Users/rich/automation/vsphere/dummy/dummy.box'
config.vm.communicator = "winrm"

You should be using the vagrant-windows Vagrant Plugin!

Admin user name and password

config.winrm.username = "vagrant"
config.winrm.password = "vagrant"
config.winrm.host = "10.50.13.106"
config.winrm.port = 5985

config.windows.halt_timeout = 30
config.winrm.max_tries = 30

config.vm.guest = :windows
config.vm.network "private_network", ip: "10.50.13.106"
config.vm.network :forwarded_port, guest: 3389, host: 3389
config.vm.network :forwarded_port, guest: 5985, host: 5985, id: "winrm", auto_correct: true

Ensure that all networks are set to private

config.windows.set_work_network = true

config.vm.provider :vsphere do |vsphere|
# The host we're going to connect to
vsphere.host = '10.50.13.111'

The host for the new VM

vsphere.compute_resource_name = '10.50.13.110'            
# The resource pool for the new VM
vsphere.resource_pool_name = 'testPool'                    

# The template we're going to clone        
vsphere.template_name = 'WindowsTest'    

# The name of the new machine
vsphere.name = 'bingo'

# vSphere login
vsphere.user = 'root'                                    

# vSphere password
vsphere.password = 'vmware'                            

# If you don't have SSL configured correctly, set this to 'true'
vsphere.insecure = true                                    

end
end

@chris-orchard
Copy link

I am experiencing this issue again. From this hashicorp/vagrant#6181 it appears to be due to a change in vagrant.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants