-
Notifications
You must be signed in to change notification settings - Fork 779
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
Vsphere support #504
base: master
Are you sure you want to change the base?
Vsphere support #504
Changes from 2 commits
be62d86
31cd689
2d37c53
af30be1
5995241
ad26ace
da330c6
2b32e61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ end | |
|
||
group :test do | ||
gem "rake" | ||
gem "em-winrm", :git => 'git://github.com/hh/em-winrm.git', :ref => '31745601d3' | ||
gem "em-winrm", :git => 'http://github.com/hh/em-winrm.git', :ref => '31745601d3' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changes to em-winrm probably should not go into this pull request There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't disagree, though I do have to maintain this as a local change because git:// does not work within my corporate network. The change above wasn't actually meant to be included in the commits, just haven't had a change to get it changed back. |
||
#gem "chef" | ||
#gem "knife-windows" | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
The veewee vSphere provider adds the capability to create base boxes/VMs on VMware ESXi/vSphere and vCenter servers. Because this capability leverages a centralized hypervisor (rather than a local hypervisor on the machien running the veewee command), there are some considerations when building a machine that are unique to this provider. | ||
|
||
## Credentials | ||
|
||
vSphere/vCenter require a users to authenticate actions the remote server in order to perform management actions. User credentials can be specified in 3 ways, in order of precedence: | ||
|
||
1. Use the -h (i.e., host), -u (i.e., user), and -p (i.e., password) options with each `veewee vsphere` command | ||
2. Set the `VEEWEE_VSPHERE_AUTHFILE` environment variable to the path of a YAML files with the server hostname and credentials | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be better if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One of my original thoughts was to have the stored credentials in a predefined location within the users home directory, however it wasn't clear to me how this would work with use cases where veewee would be called by an automated process (e.g., Jenkins running a CI job) that may not be provided a traditional home directory (i.e., I think it would be reasonable to check for |
||
3. The host and user can be provided by either method above, and veewee vsphere provider will prompt the user for the password. | ||
|
||
Note, a `VEEWEE_VSPHERE_AUTHFILE` YAML file contains credentials to login to a given vSphere/vCenter server. It is the responsibility of the user to ensure this file has appropriate access controls applied to ensure proper security compliance. | ||
|
||
### YAML configuration format | ||
|
||
```yaml | ||
--- | ||
host: vcenter.example.com | ||
user: vsphere-user | ||
password: vsphere-password | ||
``` | ||
|
||
## Networking support | ||
|
||
vSphere does not have built in support concepts like a NAT network configuration within the hypervisor itself. This means that when creating a virtual machine, a veewee vSphere user needs to have the appropriate networking capability in place prior to issuing vSphere build commands. In addition, there are special steps that must be completed within definition.rb and kickstart or preseed.cfg files to ensure network support works as expected. | ||
|
||
### Virtual Network | ||
|
||
Each vSphere/vCenter enviornment has a series of virtual networks that can be added to an individual virtual machine. Veewee must specify the virtual network when building a vSphere VM to make sure the remaining commands can be executed as expected. The virtual network can be set in 3 ways, listed below in the order of precedence: | ||
|
||
1. `--net` option provided with the `veewee vsphere build` command | ||
2. Contents of the definition.rb vsphere properties `:vsphere => { :vm_options => { :network => "VM Network" } }` | ||
3. Default Virtual Network | ||
|
||
Along with the above virtual network definition, the following assumptions are made about the state of the network: | ||
|
||
* The network includes a DHCP server that can provide a new VM with an IP address to communicate on the network | ||
* The host issuing the veewee command has a route to the VM after its created on the virtual network | ||
|
||
### Veewee Host IP | ||
|
||
Because we cannot assume anything about the network topology between the veewee host and the virtual network attached to a VMware VM build using the vSphere provider, the IP address used to serve the kickstart or preseed.cfg file must be specified as part of the definition.rb file. This can be configured using the following: | ||
|
||
:vsphere => { :kickstart_ip => "192.168.0.1" } | ||
|
||
veewee will raise an error if this configuration is not complete. | ||
|
||
## Data Location | ||
|
||
vSphere defines storage for VMs and files as a series of datastores within a given server or cluster. The vSphere provider must specify a datastore to build a given VM in. The datastore can be set in 3 ways, listed below in the order of precedence: | ||
|
||
1. `--ds` option provided with the `veewee vsphere build` command | ||
2. Contents of the definition.rb vsphere properties `:vsphere => { :vm_options => { :datastore => "datastore" } }` | ||
3. Default datastore (i.e., first datastore in the servers list) | ||
|
||
Note, the datastore location chosen is used for both creating the VM and its associated files, and also for uploading ISO files used to build the VM. | ||
|
||
## VMware Tools | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be a good idea to put the VMware tools setup in a vsphere.sh postinstall file which will be automatically included in the list of postinstall files only if the vsphere provider is used. This would require some changes on handling the postinstall files, but I would very much vote for such a change. See also issue #505 for more details. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per my notes, the VMware tools need to be installed during the OS installation process to allow the guest IP to be retrieve so postinstall processing to work. If there are straightforward ways to retrieve the IP address without the tools installed (and from some other links I've seen today there might be) the approach you suggest could work. But, barring an alternate method to get an IP address it needs to be part of the preseed or kickstart process. |
||
|
||
In order to complete postinstall.sh scripts, veewee has to be able to determine the created VMs IP address after OS installation is complete. vSphere/vCenter do not have a method to retrieve this information withou the VMware Tools--the VMware equivalent of VirtualBox Guest Additions--installed on the guest OS. Therefore, the kickstart or preseed.cfg files used to automated the OS installation must be modified in order to install VMware Tools prior to the OS installation completing. This will allow post installation actions to execute as expected. | ||
|
||
### RHEL/CentOS Instructions | ||
|
||
Follow the instructions from VMware for installing VMware tools on a RHEL platform as seen at the following link: http://www.vmware.com/download/packages.html. | ||
|
||
### Ubuntu Instructions | ||
|
||
On Ubuntu distributions, VMware tools can be added by installing the open-vm-tools from the multiverse repository inside the preseed.cfg file. For example: | ||
|
||
d-i pkgsel/include string openssh-server open-vm-tools | ||
|
||
There can be only one instance of this within a preseed.cfg file, so ensure that if you add open-vm-tools to the existing command as provided. | ||
|
||
## External tool pre-requisites | ||
|
||
The following tools are needed to support the execution of the vSphere provider: | ||
|
||
* curl - used to upload files to a vSphere datastore (specifically to support ISO uploads). This will hopefully be corrected in later revisions to replace curl with a native ruby solution | ||
* ovftool - used for the `veewee vsphere export` command to export a VM from the vSphere/vCenter server to an ova file | ||
|
||
The veewee vSphere provider assumes both of these tools are in the user's path. | ||
|
||
## Command Timing | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This actually is quite a big issue. Several templates (e.g. Ubuntu 12.04) seem to have very short boot delays. If possible the boot delays should be increased to safe values for all templates. Again something we might want to handle in issue #505 and follow ups to it. |
||
|
||
Working with a remote server increases the likelihood that veewee processes that depend on waits or delays to execute a given command will fail leaving veewee and the guest VM being built in an unstable state. Users should consider increasing timeouts if issues appear where steps are out of sequence. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
module Veewee | ||
module Command | ||
class Vsphere< Veewee::Command::GroupBase | ||
|
||
register "vsphere", "Subcommand for Vmware vsphere" | ||
desc "build [BOX_NAME]", "Build box" | ||
method_option :vsphere_host,:type => :string , :default => nil, :aliases => "-h", :desc => "VSphere Host" | ||
method_option :vsphere_user,:type => :string , :default => nil, :aliases => "-u", :desc => "VSphere User" | ||
method_option :vsphere_password,:type => :string , :default => nil, :aliases => "-p", :desc => "VSphere Password" | ||
method_option :datastore,:type => :string , :default => nil, :aliases => "--ds", :desc => "VSphere Datastore" | ||
method_option :network,:type => :string , :default => nil, :aliases => "--net", :desc => "VSphere Virtual Network" | ||
method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "force the build" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
method_option :nogui,:type => :boolean , :default => false, :aliases => "-n", :desc => "no gui" | ||
method_option :auto,:type => :boolean , :default => false, :aliases => "-a", :desc => "auto answers" | ||
method_option :postinstall_include, :type => :array, :default => [], :aliases => "-i", :desc => "ruby regexp of postinstall filenames to additionally include" | ||
method_option :postinstall_exclude, :type => :array, :default => [], :aliases => "-e", :desc => "ruby regexp of postinstall filenames to exclude" | ||
def build(box_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).build(options) | ||
end | ||
|
||
method_option :vsphere_host,:type => :string , :default => nil, :aliases => "-h", :desc => "VSphere Host" | ||
method_option :vsphere_user,:type => :string , :default => nil, :aliases => "-u", :desc => "VSphere User" | ||
method_option :vsphere_password,:type => :string , :default => nil, :aliases => "-p", :desc => "VSphere Password" | ||
method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "force the destroy" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
method_option :nogui,:type => :boolean , :default => false, :aliases => "-n", :desc => "no gui" | ||
desc "destroy [BOXNAME]", "Destroys the virtualmachine that was built" | ||
def destroy(box_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).destroy(options) | ||
end | ||
|
||
method_option :vsphere_host,:type => :string , :default => nil, :aliases => "-h", :desc => "VSphere Host" | ||
method_option :vsphere_user,:type => :string , :default => nil, :aliases => "-u", :desc => "VSphere User" | ||
method_option :vsphere_password,:type => :string , :default => nil, :aliases => "-p", :desc => "VSphere Password" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "force the shutdown" | ||
desc "halt [BOXNAME]", "Activates a shutdown the virtualmachine" | ||
def halt(box_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).halt(options) | ||
end | ||
|
||
method_option :vsphere_host,:type => :string , :default => nil, :aliases => "-h", :desc => "VSphere Host" | ||
method_option :vsphere_user,:type => :string , :default => nil, :aliases => "-u", :desc => "VSphere User" | ||
method_option :vsphere_password,:type => :string , :default => nil, :aliases => "-p", :desc => "VSphere Password" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
method_option :nogui,:type => :boolean , :default => false, :aliases => "-n", :desc => "no gui" | ||
desc "up [BOXNAME]", "Starts a Box" | ||
def up(box_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).up(options) | ||
end | ||
|
||
desc "scp [BOXNAME] [LOCAL FILE] [REMOTE FILE]", "SCP to box" | ||
method_option :vsphere_host,:type => :string , :default => nil, :aliases => "-h", :desc => "VSphere Host" | ||
method_option :vsphere_user,:type => :string , :default => nil, :aliases => "-u", :desc => "VSphere User" | ||
method_option :vsphere_password,:type => :string , :default => nil, :aliases => "-p", :desc => "VSphere Password" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
def scp(box_name,local_file,remote_file) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).scp(local_file,remote_file) | ||
end | ||
|
||
desc "ssh [BOXNAME] [COMMAND]", "SSH to box" | ||
method_option :vsphere_host,:type => :string , :default => nil, :aliases => "-h", :desc => "VSphere Host" | ||
method_option :vsphere_user,:type => :string , :default => nil, :aliases => "-u", :desc => "VSphere User" | ||
method_option :vsphere_password,:type => :string , :default => nil, :aliases => "-p", :desc => "VSphere Password" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
def ssh(box_name,command=nil) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).issh(command) | ||
end | ||
|
||
desc "define [BOXNAME] [TEMPLATE]", "Define a new basebox starting from a template" | ||
method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "overwrite the definition" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
def define(definition_name, template_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.definitions.define(definition_name,template_name,options) | ||
env.ui.info "The basebox '#{definition_name}' has been succesfully created from the template '#{template_name}'" | ||
env.ui.info "You can now edit the definition files stored in definitions/#{definition_name} or build the box with:" | ||
env.ui.info "veewee vsphere build '#{definition_name}'" | ||
end | ||
|
||
desc "undefine [BOXNAME]", "Removes the definition of a basebox " | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
def undefine(definition_name) | ||
env.ui.info "Removing definition #{definition_name}" , :prefix => false | ||
begin | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.definitions.undefine(definition_name,options) | ||
env.ui.info "Definition #{definition_name} succesfully removed",:prefix => false | ||
rescue Error => ex | ||
env.ui.error "#{ex}" , :prefix => false | ||
exit -1 | ||
end | ||
end | ||
|
||
desc "validate [NAME]", "Validates a box against vsphere compliancy rules" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
method_option :tags, :type => :array , :default => %w{vsphere puppet chef}, :aliases => "-t", :desc => "tags to validate" | ||
def validate(box_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).validate_vsphere(options) | ||
end | ||
|
||
desc "ostypes", "List the available Operating System types" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
def ostypes | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.ostypes.each do |name| | ||
env.ui.info "- #{name}" | ||
end | ||
end | ||
|
||
desc "path [NAME]", "Prints the vms path" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "overwrite existing file" | ||
def path(box_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
env.ui.info venv.providers["vsphere"].get_box(box_name).path | ||
end | ||
|
||
desc "export [NAME]", "Exports the basebox to the ova format" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "overwrite existing file" | ||
def export(box_name) | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.providers["vsphere"].get_box(box_name).export_ova(options) | ||
end | ||
|
||
desc "templates", "List the currently available templates" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
def templates | ||
env.ui.info "The following templates are available:",:prefix => false | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.templates.each do |name,template| | ||
env.ui.info "veewee vsphere define '<box_name>' '#{name}'",:prefix => false | ||
end | ||
end | ||
|
||
desc "list", "Lists all defined boxes" | ||
method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging" | ||
def list | ||
env.ui.info "The following local definitions are available:",:prefix => false | ||
venv=Veewee::Environment.new(options) | ||
venv.ui=env.ui | ||
venv.definitions.each do |name,definition| | ||
env.ui.info "- #{name}" | ||
end | ||
end | ||
|
||
end | ||
|
||
end | ||
end |
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.
It may be a good idea to create a group for vsphere (similar to the one for kvm) which holds the rbvmomi gem.