Skip to content

Commit

Permalink
Merge branch 'release/v0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
frapposelli committed Sep 5, 2014
2 parents efeb268 + 0fd41e8 commit 829a53d
Show file tree
Hide file tree
Showing 12 changed files with 243 additions and 127 deletions.
101 changes: 67 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
[Vagrant](http://www.vagrantup.com) provider for VMware vCenter®
=============

[Version 0.2.1](../../releases/tag/v0.2.1) has been released!
[Version 0.3.0](../../releases/tag/v0.3.0) has been released!
-------------

Please note that this software is still Alpha/Beta quality and is not recommended for production usage.

We have a wide array of boxes available at [Vagrant Cloud](https://vagrantcloud.com/gosddc) you can use them directly or you can roll your own as you please, make sure to install VMware tools in it.

Changes in [version 0.2.1](../../releases/tag/v0.2.1) include:
This plugin supports the universal [```vmware_ovf``` box format](https://github.com/gosddc/packer-post-processor-vagrant-vmware-ovf/wiki/vmware_ovf-Box-Format), that is 100% portable between [vagrant-vcloud](https://github.com/frapposelli/vagrant-vcloud), [vagrant-vcenter](https://github.com/gosddc/vagrant-vcenter) and [vagrant-vcloudair](https://github.com/gosddc/vagrant-vcloudair), no more double boxes!.

Fixes
Changes in [version 0.3.0](../../releases/tag/v0.3.0) include:

- Hostname using linux prep needs to be hostname and domain not fqdn on both.
- Checking the power state at that spot can cause ruby exceptions to be thrown.
Fixes

Thanks to [Karl Pietri](https://github.com/BarnacleBob) for this PR.
- ```vmware_ovf``` support!
- You can now specify network using the ```public_network``` notation of Vagrant.
- Plugin is now operating in parallel, MOAR SPEED!
- Create the VM folder if it doesn't exist.
- Several bug fixes.

Install
-------------
Expand All @@ -40,44 +43,74 @@ Configuration
Here's a sample Multi-VM Vagrantfile:

```ruby
nodes = [
{ hostname: 'web-vm', box: 'gosddc/precise32' },
{ hostname: 'ssh-vm', box: 'gosddc/precise32' },
{ hostname: 'sql-vm', box: 'gosddc/precise32' },
{ hostname: 'lb-vm', box: 'gosddc/precise32' }
]
ENV['VAGRANT_DEFAULT_PROVIDER'] = 'vcenter'

Vagrant.configure('2') do |config|
nodes = []

config.vm.provider :vcenter do |vcenter|
vcenter.hostname = 'my.vcenter.hostname'
vcenter.username = 'myUsername'
vcenter.password = 'myPassword'
vcenter.folder_name = 'myFolderName'
vcenter.datacenter_name = 'MyDatacenterName'
vcenter.computer_name = 'MyHostOrCluster'
vcenter.datastore_name = 'MyDatastore'
vcenter.template_folder_name = 'My/Template/Folder/Path'
vcenter.network_name = 'myNetworkName'
# If you want to use linked clones, set this to true
vcenter.linked_clones = true
end
[*1..5].each do |n|
nodes << { hostname: "centos#{n}",
box: 'gosddc/centos65-x64',
ip: "10.250.21.#{n}",
mem: 1024 * n,
cpu: n }
end

[*1..5].each do |n|
nodes << { hostname: "precise#{n}",
box: 'gosddc/precise32',
ip: "10.250.22.#{n}",
mem: 1024 * n,
cpu: n }
end

# Go through nodes and configure each of them.j
Vagrant.configure('2') do |config|

# Go through nodes and configure each of them.
nodes.each do |node|

config.vm.provider :vcenter do |vcenter|
vcenter.hostname = 'my.vcenter.hostname'
vcenter.username = 'myUsername'
vcenter.password = 'myPassword'
vcenter.folder_name = 'myFolderName'
vcenter.datacenter_name = 'MyDatacenterName'
vcenter.computer_name = 'MyHostOrCluster'
vcenter.datastore_name = 'MyDatastore'
vcenter.network_name = 'myNetworkName'
vcenter.linked_clones = true
end

config.vm.define node[:hostname] do |node_config|
node_config.vm.box = node[:box]
node_config.vm.hostname = node[:hostname]
node_config.vm.box_url = node[:box_url]
# node_config.vm.provision :puppet do |puppet|
# puppet.manifests_path = 'puppet/manifests'
# puppet.manifest_file = 'site.pp'
# puppet.module_path = 'puppet/modules'
# puppet.options = "--verbose --debug"
# end

# Let's configure the network for the VM, only the ip changes and is
# coming from the nodes array
node_config.vm.network :public_network,
ip: node[:ip],
netmask: '255.255.0.0',
gateway: '10.250.254.254',
dns_server_list: ['8.8.4.4', '8.8.8.8'],
dns_suffix_list: ['ad.lab.gosddc.com']

# Let's override some provider settings for specific VMs
node_config.vm.provider :vcenter do |override|
# Override number of cpu and memory based on what's in the nodes array
override.num_cpu = node[:cpu]
override.memory = node[:mem]
case node[:hostname]
# Override the folder name based on the hostname of the VM
when /centos/
override.folder_name = 'Vagrant/centos'
when /precise/
override.folder_name = 'Vagrant/ubuntu/precise'
end
end
node_config.nfs.functional = false
end
end
end

```

Contribute
Expand Down
20 changes: 15 additions & 5 deletions lib/vagrant-vcenter/action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Action
def self.action_boot
Vagrant::Action::Builder.new.tap do |b|
b.use PowerOn
b.use PrepareNFSSettings
b.use Provision
b.use SyncedFolders
end
Expand Down Expand Up @@ -93,10 +94,16 @@ def self.action_destroy
if env[:result]
b2.use ConfigValidate
b2.use ConnectvCenter
b2.use Call, IsRunning do |env2, b3|
# If the VM is running, must power off
b3.use action_halt if env2[:result]
b3.use Destroy
b2.use Call, IsCreated do |env2, b3|
unless env2[:result]
b3.use MessageNotCreated
next
end
b3.use Call, IsRunning do |env3, b4|
# If the VM is running, must power off
b4.use action_halt if env3[:result]
b4.use Destroy
end
end
else
b2.use MessageWillNotDestroy
Expand All @@ -113,6 +120,7 @@ def self.action_provision
b2.use MessageNotCreated
next
end
b2.use PrepareNFSSettings
b2.use Provision
b2.use SyncedFolders
end
Expand Down Expand Up @@ -170,10 +178,10 @@ def self.action_ssh_run
def self.action_up
Vagrant::Action::Builder.new.tap do |b|
b.use ConfigValidate
b.use ConnectvCenter
b.use Call, IsCreated do |env, b2|
b2.use HandleBox unless env[:result]
end
b.use ConnectvCenter
b.use InventoryCheck
b.use Call, IsCreated do |env, b2|
b2.use BuildVM unless env[:result]
Expand Down Expand Up @@ -216,6 +224,8 @@ def self.action_up
action_root.join('power_off')
autoload :PowerOn,
action_root.join('power_on')
autoload :PrepareNFSSettings,
action_root.join('prepare_nfs_settings')
autoload :ReadSSHInfo,
action_root.join('read_ssh_info')
autoload :ReadState,
Expand Down
74 changes: 56 additions & 18 deletions lib/vagrant-vcenter/action/build_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,42 +116,69 @@ def call(env)
dev_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(:device => card, :operation => "edit")
config_spec.deviceChange = [dev_spec]
end

spec.config = config_spec
end

if config.enable_vm_customization or config.enable_vm_customization == 'true'
gIPSettings = RbVmomi::VIM.CustomizationGlobalIPSettings(
:dnsServerList => config.dns_server_list,
:dnsSuffixList => config.dns_suffix_list)
public_networks = env[:machine].config.vm.networks.select {
|n| n[0].eql? :public_network
}

network_spec = public_networks.first[1]

@logger.debug("This is our network #{public_networks.inspect}")

if network_spec

# Check for sanity and validation of network parameters.

# Specify ip but no netmask
if network_spec[:ip] && !network_spec[:netmask]
fail Errors::WrongNetworkSpec
end

# specify netmask but no ip
if !network_spec[:ip] && network_spec[:netmask]
fail Errors::WrongNetworkSpec
end

global_ip_settings = RbVmomi::VIM.CustomizationGlobalIPSettings(
:dnsServerList => network_spec[:dns_server_list],
:dnsSuffixList => network_spec[:dns_suffix_list])

prep = RbVmomi::VIM.CustomizationLinuxPrep(
:domain => env[:machine].name.to_s.sub(/^[^.]+\./,''),
:domain => env[:machine].name.to_s.sub(/^[^.]+\./, ''),
:hostName => RbVmomi::VIM.CustomizationFixedName(
:name => env[:machine].name.to_s.split('.')[0]))

adapter = RbVmomi::VIM.CustomizationIPSettings(
:gateway => [config.gateway],
:ip => RbVmomi::VIM.CustomizationFixedIp(
:ipAddress => config.ipaddress),
:subnetMask => config.netmask)


# if no ip and no netmask, let's default to dhcp
if !network_spec[:ip] && !network_spec[:netmask]
adapter = RbVmomi::VIM.CustomizationIPSettings(
:ip => RbVmomi::VIM.CustomizationDhcpIpGenerator())
else
adapter = RbVmomi::VIM.CustomizationIPSettings(
:gateway => [network_spec[:gateway]],
:ip => RbVmomi::VIM.CustomizationFixedIp(
:ipAddress => network_spec[:ip]),
:subnetMask => network_spec[:netmask])
end

nic_map = [RbVmomi::VIM.CustomizationAdapterMapping(
:adapter => adapter)]

cust_spec = RbVmomi::VIM.CustomizationSpec(
:globalIPSettings => gIPSettings,
:globalIPSettings => global_ip_settings,
:identity => prep,
:nicSettingMap => nic_map)

spec.customization = cust_spec
end

@logger.debug("Spec: #{spec.pretty_inspect}")

@logger.debug("disable_auto_vm_name: #{config.disable_auto_vm_name}")

if config.disable_auto_vm_name or config.disable_auto_vm_name == 'true'
if config.disable_auto_vm_name || config.disable_auto_vm_name == 'true'
vm_target = vm_name.to_s
else
vm_target = "Vagrant-#{Etc.getlogin}-" +
Expand All @@ -167,8 +194,19 @@ def call(env)
root_vm_folder = dc.vmFolder
vm_folder = root_vm_folder
unless config.folder_name.nil?
vm_folder = root_vm_folder.traverse(config.folder_name,
RbVmomi::VIM::Folder)
begin
# Better ask for forgiveness than permission ;-)
@logger.debug("Creating folder #{config.folder_name}.")
vm_folder = root_vm_folder.traverse(config.folder_name,
RbVmomi::VIM::Folder,
create = true)
# FIXME: we should trap the correct exception
rescue RbVmomi::Fault
# if somebody else created the folder already...
@logger.debug("Folder #{config.folder_name} already exists.")
vm_folder = root_vm_folder.traverse(config.folder_name,
RbVmomi::VIM::Folder)
end
end
@logger.debug("folder for VM: #{vm_folder}")

Expand Down
25 changes: 25 additions & 0 deletions lib/vagrant-vcenter/action/is_created.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,34 @@ def initialize(app, env)
def call(env)
vm_id = env[:machine].id
if vm_id

# VM is in the vagrant registry, now we need to check if it's
# actually in vcenter

# FIXME: this part needs some cleanup
config = env[:machine].provider_config

# FIXME: Raise a correct exception
dc = config.vcenter_cnx.serviceInstance.find_datacenter(
config.datacenter_name) or abort 'datacenter not found'

root_vm_folder = dc.vmFolder

vm = root_vm_folder.findByUuid(env[:machine].id)

unless vm
@logger.info('VM is in the vagrant registry but not in vcenter')
# Clear the ID
env[:machine].id = nil
env[:result] = false
end

# VM is in the registry AND in vcenter
@logger.info("VM has been created and ID is: [#{vm_id}]")
env[:result] = true

else
# VM is not in the registry
@logger.warn('VM has not been created')
env[:result] = false
end
Expand Down
25 changes: 25 additions & 0 deletions lib/vagrant-vcenter/action/prepare_nfs_settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'socket'

module VagrantPlugins
module VCenter
module Action
class PrepareNFSSettings
include Vagrant::Util::Retryable

def initialize(app, env)
@app = app
@logger = Log4r::Logger.new('vagrant_vcenter::action::nfs')
end

def call(env)
host_ip = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address

@logger.debug("Setting host_ip to #{host_ip}")

env[:nfs_host_ip] = host_ip
@app.call env
end
end
end
end
end
3 changes: 3 additions & 0 deletions lib/vagrant-vcenter/action/read_ssh_info.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def read_ssh_info(env)
return nil
end

@logger.debug("Setting nfs_machine_ip to #{address}")
env[:nfs_machine_ip] = address

{ :host => address, :port => 22 }
end
end
Expand Down
12 changes: 6 additions & 6 deletions lib/vagrant-vcenter/action/read_state.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ def call(env)
end

def read_state(env)
if env[:machine].id.nil?
@logger.info('VM is not created yet')
return :not_created
end

# FIXME: this part needs some cleanup
config = env[:machine].provider_config

Expand All @@ -27,14 +32,9 @@ def read_state(env)

vm = root_vm_folder.findByUuid(env[:machine].id)

#@logger.debug("Current power state: #{vm.runtime.powerState}")
# @logger.debug("Current power state: #{vm.runtime.powerState}")
vm_name = env[:machine].name

if env[:machine].id.nil?
@logger.info("VM [#{vm_name}] is not created yet")
return :not_created
end

if vm.runtime.powerState == 'poweredOff'
@logger.info("VM [#{vm_name}] is stopped")
return :stopped
Expand Down
Loading

0 comments on commit 829a53d

Please sign in to comment.