Permalink
Browse files

merging hh feature/windows

  • Loading branch information...
2 parents 4b2728b + 8ce8f06 commit f45954fb0402d2cdfb44fc0d3cec7c34f3e11591 @jedi4ever committed Nov 5, 2012
Showing with 1,555 additions and 73 deletions.
  1. +4 −0 Gemfile
  2. +2 −0 lib/veewee/command/vagrant/basebox.rb
  3. +39 −0 lib/veewee/command/vagrant/winrm.rb
  4. +26 −0 lib/veewee/command/vbox.rb
  5. +6 −1 lib/veewee/definition.rb
  6. +3 −0 lib/veewee/error.rb
  7. +8 −0 lib/veewee/provider/core/box.rb
  8. +30 −14 lib/veewee/provider/core/box/build.rb
  9. +17 −0 lib/veewee/provider/core/box/copy.rb
  10. +31 −12 lib/veewee/provider/core/box/exec.rb
  11. +1 −0 lib/veewee/provider/core/box/floppy.rb
  12. +7 −3 lib/veewee/provider/core/box/halt.rb
  13. +15 −0 lib/veewee/provider/core/box/iwinrm.rb
  14. +7 −1 lib/veewee/provider/core/box/validate_tags.rb
  15. +120 −0 lib/veewee/provider/core/box/wincp.rb
  16. +45 −0 lib/veewee/provider/core/box/winrm.rb
  17. +47 −0 lib/veewee/provider/core/helper/comm.rb
  18. +20 −9 lib/veewee/provider/core/helper/web.rb
  19. +165 −0 lib/veewee/provider/core/helper/winrm.rb
  20. +1 −1 lib/veewee/provider/parallels/box/helper/buildinfo.rb
  21. +1 −0 lib/veewee/provider/virtualbox/box.rb
  22. +16 −8 lib/veewee/provider/virtualbox/box/create.rb
  23. +6 −3 lib/veewee/provider/virtualbox/box/helper/buildinfo.rb
  24. +9 −0 lib/veewee/provider/virtualbox/box/helper/create.rb
  25. +31 −0 lib/veewee/provider/virtualbox/box/helper/winrm_options.rb
  26. +33 −12 lib/veewee/provider/virtualbox/box/up.rb
  27. +13 −0 lib/veewee/provider/virtualbox/box/winrm.rb
  28. +1 −1 lib/veewee/provider/vmfusion/box/helper/buildinfo.rb
  29. +6 −6 templates/windows-2008R1-serverstandard-amd64/Autounattend.xml
  30. +1 −1 templates/windows-2008R1-serverweb-amd64/install-winrm.bat
  31. +224 −0 templates/windows-2008R2-serverstandard-amd64-winrm/Autounattend.xml
  32. +87 −0 templates/windows-2008R2-serverstandard-amd64-winrm/README.md
  33. +33 −0 templates/windows-2008R2-serverstandard-amd64-winrm/definition.rb
  34. +2 −0 templates/windows-2008R2-serverstandard-amd64-winrm/install-chef.bat
  35. +4 −0 templates/windows-2008R2-serverstandard-amd64-winrm/install-vbox.bat
  36. BIN templates/windows-2008R2-serverstandard-amd64-winrm/oracle-cert.cer
  37. +74 −0 templates/windows-2008R2-serverstandard-amd64-winrm/postinstall.sh
  38. +227 −0 templates/windows-7-enterprise-amd64-winrm/Autounattend.xml
  39. +52 −0 templates/windows-7-enterprise-amd64-winrm/README.md
  40. +26 −0 templates/windows-7-enterprise-amd64-winrm/definition.rb
  41. +2 −0 templates/windows-7-enterprise-amd64-winrm/install-chef.bat
  42. +4 −0 templates/windows-7-enterprise-amd64-winrm/install-vbox.bat
  43. BIN templates/windows-7-enterprise-amd64-winrm/oracle-cert.cer
  44. +74 −0 templates/windows-7-enterprise-amd64-winrm/postinstall.bat
  45. +34 −0 validation/veewee-windows.feature
  46. +1 −1 veewee.gemspec
View
@@ -10,5 +10,9 @@ source "http://rubygems.org"
group :test do
gem "rake"
+ gem "ruby-libvirt"
+ gem "em-winrm", :git => 'git://github.com/hh/em-winrm.git', :ref => '31745601d3'
+ gem "chef"
+ gem "knife-windows"
end
gemspec
@@ -8,6 +8,7 @@
require 'veewee/command/vagrant/up'
require 'veewee/command/vagrant/halt'
require 'veewee/command/vagrant/ssh'
+require 'veewee/command/vagrant/winrm'
require 'veewee/command/vagrant/define'
require 'veewee/command/vagrant/undefine'
require 'veewee/command/vagrant/validate'
@@ -33,6 +34,7 @@ def initialize(argv,env)
@subcommands.register(:up) { Veewee::Command::Vagrant::Up }
@subcommands.register(:halt) { Veewee::Command::Vagrant::Halt }
@subcommands.register(:ssh) { Veewee::Command::Vagrant::Ssh }
+ @subcommands.register(:winrm) { Veewee::Command::Vagrant::Winrm }
@subcommands.register(:define) { Veewee::Command::Vagrant::Define }
@subcommands.register(:undefine) { Veewee::Command::Vagrant::Undefine }
@subcommands.register(:export) { Veewee::Command::Vagrant::Export }
@@ -0,0 +1,39 @@
+require 'optparse'
+
+module Veewee
+ module Command
+ module Vagrant
+ class Winrm < ::Vagrant::Command::Base
+ def execute
+ options = {}
+
+ opts = OptionParser.new do |opts|
+ opts.banner = "Winrm into the basebox"
+ opts.separator ""
+ opts.separator "Usage: vagrant basebox winrm <boxname> <command>"
+
+ opts.on("-d", "--debug", "enable debugging") do |d|
+ options['debug'] = d
+ end
+
+ end
+
+ # Parse the options
+ argv = parse_options(opts)
+ return if !argv
+ raise ::Vagrant::Errors::CLIInvalidUsage, :help => opts.help.chomp if argv.length < 2
+
+ begin
+ venv=Veewee::Environment.new(options)
+ venv.ui=@env.ui
+ venv.providers["virtualbox"].get_box(argv[0]).iwinrm(arg[1])
+ rescue Veewee::Error => ex
+ venv.ui.error ex
+ exit -1
+ end
+
+ end
+ end
+ end
+ end
+end
View
@@ -53,6 +53,32 @@ def ssh(box_name,command=nil)
venv.providers["virtualbox"].get_box(box_name).issh(command)
end
+
+ desc "winrm [BOXNAME] [COMMAND]", "Execute command via winrm"
+ method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging"
+ def winrm(box_name,command=nil)
+ venv=Veewee::Environment.new(options)
+ venv.ui=env.ui
+ venv.providers["virtualbox"].get_box(box_name).winrm(command,{:exitcode => "*"})
+ end
+
+ desc "iwinrm [BOXNAME] [COMMAND]", "Interactive winrm login"
+ method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging"
+ def iwinrm(box_name,command=nil)
+ venv=Veewee::Environment.new(options)
+ venv.ui=env.ui
+ venv.providers["virtualbox"].get_box(box_name).iwinrm(command)
+ end
+
+ desc "copy [BOXNAME] [SRC] [DST]", "Copy a file to the VM"
+ method_option :debug,:type => :boolean , :default => false, :aliases => "-d", :desc => "enable debugging"
+ def copy(box_name,src,dst)
+ venv=Veewee::Environment.new(options)
+ venv.ui=env.ui
+ venv.providers["virtualbox"].get_box(box_name).copy_to_box(src,dst)
+ 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"
View
@@ -21,6 +21,8 @@ class Definition
attr_accessor :ssh_login_timeout, :ssh_user , :ssh_password, :ssh_key, :ssh_host_port, :ssh_guest_port
+ attr_accessor :winrm_login_timeout, :winrm_user , :winrm_password, :winrm_host_port, :winrm_guest_port
+
attr_accessor :sudo_cmd
attr_accessor :shutdown_cmd
@@ -84,6 +86,9 @@ def initialize(name,path,env)
# :ssh_host_port => "2222", :ssh_guest_port => "22", :sudo_cmd => "echo '%p'|sudo -S sh '%f'",
# :shutdown_cmd => "shutdown -h now",
# :kickstart_file => nil,
+ @winrm_host_port = "5985"; @winrm_guest_port = "5985"
+ @winrm_login_timeout = "10000"
+ @boot_cmd_sequence = [] # Empty list by default
@virtualbox={:vm_options => {}}
@vmfusion={:vm_options => {}}
@@ -172,7 +177,7 @@ def valid?
# Postinstall files require a valid user and password
unless self.postinstall_files.nil?
- if self.ssh_user.nil? || self.ssh_password.nil?
+ if (self.ssh_user.nil? || self.ssh_password.nil?) && (self.winrm_user.nil? || self.winrm_password.nil?)
return false
end
end
View
@@ -17,6 +17,9 @@ class TemplateError < Error
class SshError < Error
end
+
+ class WinrmError < Error
+ end
end
#Usage (from the exceptional ruby book)
@@ -3,15 +3,21 @@
require 'veewee/provider/core/helper/web'
require 'veewee/provider/core/helper/shell'
require 'veewee/provider/core/helper/iso'
+require 'veewee/provider/core/helper/winrm'
+require 'veewee/provider/core/helper/comm'
require 'veewee/provider/core/box/build'
require 'veewee/provider/core/box/scp'
+require 'veewee/provider/core/box/wincp'
+require 'veewee/provider/core/box/copy'
require 'veewee/provider/core/box/exec'
require 'veewee/provider/core/box/poweroff'
require 'veewee/provider/core/box/halt'
require 'veewee/provider/core/box/sudo'
require 'veewee/provider/core/box/ssh'
require 'veewee/provider/core/box/issh'
+require 'veewee/provider/core/box/winrm'
+require 'veewee/provider/core/box/iwinrm'
require 'veewee/provider/core/box/floppy'
require 'veewee/provider/core/box/validate_tags'
@@ -28,6 +34,8 @@ class Box
include ::Veewee::Provider::Core::Helper::Web
include ::Veewee::Provider::Core::Helper::Shell
include ::Veewee::Provider::Core::Helper::Ssh
+ include ::Veewee::Provider::Core::Helper::Winrm
+ include ::Veewee::Provider::Core::Helper::Comm
include ::Veewee::Provider::Core::Helper::Iso
include ::Veewee::Provider::Core::BoxCommand
@@ -74,16 +74,21 @@ def build(options={})
sleep 2
end
+
self.transfer_buildinfo(options)
# Filtering post install files based upon --postinstall-include and --postinstall--exclude
definition.postinstall_files=filter_postinstall_files(options)
self.handle_postinstall(options)
- ui.success "The box #{name} was built succesfully!"
+ ui.success "The box #{name} was build succesfully!"
ui.info "You can now login to the box with:"
- ui.info ssh_command_string
+ if (definition.winrm_user && definition.winrm_password)
+ env.ui.info winrm_command_string
+ else
+ env.ui.info ssh_command_string
+ end
return self
end
@@ -165,11 +170,11 @@ def handle_kickstart(options)
kickstartfiles=definition.kickstart_file
if kickstartfiles.nil? || kickstartfiles.length == 0
- ui.info "Skipping webserver as no kickstartfile was specified"
+ env.ui.info "Skipping webserver as no kickstartfile was specified"
+ else
+ env.ui.info "Starting a webserver #{definition.kickstart_ip}:#{definition.kickstart_port}\n"
end
- ui.info "Starting a webserver #{definition.kickstart_ip}:#{definition.kickstart_port}\n"
-
# Check if the kickstart is an array or a single string
if kickstartfiles.is_a?(String)
# Let's turn it into an array
@@ -197,17 +202,23 @@ def handle_postinstall(options)
definition.postinstall_files.each do |postinstall_file|
# Filenames of postinstall_files are relative to their definition
filename=File.join(definition.path,postinstall_file)
- self.scp(filename,File.basename(filename))
- self.exec("chmod +x \"#{File.basename(filename)}\"")
+ self.copy_to_box(filename,File.basename(filename))
+ if not (definition.winrm_user && definition.winrm_password)
+ self.exec("chmod +x \"#{File.basename(filename)}\"")
+ end
end
# Prepare a pre_poinstall file if needed (not nil , or not empty)
unless definition.pre_postinstall_file.to_s.empty?
pre_filename=File.join(definition.path, definition.pre_postinstall_file)
- self.scp(pre_filename,File.basename(pre_filename))
- self.exec("chmod +x \"#{File.basename(pre_filename)}\"")
- # Inject the call to the real script by executing the first argument (it will be the postinstall script file name to be executed)
- self.exec("execute=\"\\n# We must execute the script passed as the first argument\\n\\$1\" && printf \"%b\\n\" \"$execute\" >> #{File.basename(pre_filename)}")
+ self.copy_to_box(filename,File.basename(pre_filename))
+ if (definition.winrm_user && definition.winrm_password)
+ # not implemented on windows yet
+ else
+ self.exec("chmod +x \"#{File.basename(pre_filename)}\"")
+ # Inject the call to the real script by executing the first argument (it will be the postinstall script file name to be executed)
+ self.exec("execute=\"\\n# We must execute the script passed as the first argument\\n\\$1\" && printf \"%b\\n\" \"$execute\" >> #{File.basename(pre_filename)}")
+ end
end
# Now iterate over the postinstall files
@@ -218,14 +229,19 @@ def handle_postinstall(options)
unless File.basename(postinstall_file).start_with?("_")
unless definition.pre_postinstall_file.to_s.empty?
+ raise 'not implemented on windows yet' if (definition.winrm_user && definition.winrm_password)
# Filename of pre_postinstall_file are relative to their definition
pre_filename=File.join(definition.path, definition.pre_postinstall_file)
# Upload the pre postinstall script if not already transfered
command = "./" + File.basename(pre_filename)
command = sudo(command) + " ./"+File.basename(filename)
else
- command = "./"+File.basename(filename)
- command = sudo(command)
+ if (definition.winrm_user && definition.winrm_password)
+ # no sudo on windows, batch files only please?
+ self.exec(File.basename(filename))
+ else
+ self.exec(sudo("./"+File.basename(filename)))
+ end
end
self.exec(command)
@@ -249,7 +265,7 @@ def transfer_buildinfo(options)
infofile.puts "#{info[:content]}"
infofile.rewind
infofile.close
- self.scp(infofile.path,info[:filename])
+ self.copy_to_box(infofile.path,info[:filename])
infofile.delete
rescue RuntimeError => ex
ui.error("Error transfering file #{info[:filename]} failed, possible not enough permissions to write? #{ex}",:prefix => false)
@@ -0,0 +1,17 @@
+module Veewee
+ module Provider
+ module Core
+ module BoxCommand
+
+ def copy_to_box(localfile,remotefile,options={})
+ raise Veewee::Error,"Box is not running" unless self.running?
+ if definition.winrm_user && definition.winrm_password # prefer winrm
+ self.wincp(localfile,remotefile,options)
+ else
+ self.scp(localfile,remotefile,options)
+ end
+ end
+ end # Module
+ end # Module
+ end # Module
+end # Module
@@ -8,25 +8,44 @@ def ssh_command_string
"ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p #{ssh_options[:port]} -l #{definition.ssh_user} #{self.ip_address}"
end
+ def winrm_command_string
+ "knife winrm -m #{self.ip_address} -P #{winrm_options[:port]} -x #{definition.winrm_user}" +
+ " -P #{definition.winrm_password} COMMAND"
+ end
+
def exec(command,options={})
raise Veewee::Error,"Box is not running" unless self.running?
- begin
- new_options=ssh_options.merge(options)
- self.when_ssh_login_works(self.ip_address,new_options) do
- begin
- env.logger.info "About to execute remote command #{command} on box #{name} - #{self.ip_address} - #{new_options}"
- result=self.ssh_execute(self.ip_address,command,new_options)
+ if definition.winrm_user && definition.winrm_password
+ begin
+ new_options=winrm_options.merge(options)
+ self.when_winrm_login_works(self.ip_address,winrm_options.merge(options)) do
+ result = self.winrm_execute(self.ip_address,command,new_options)
return result
- rescue RuntimeError => ex
- error= "Error executing command #{command} : #{ex}"
- error+="\n#{ex.backtrace.join("\n")}" unless ex.backtrace.empty?
- raise Veewee::SshError, error
end
+ rescue RuntimeError => ex
+ env.ui.error "Error executing command #{command} : #{ex}"
+ raise Veewee::WinrmError, ex
+ end
+ else # definition.ssh_user && definition.ssh_password
+ begin
+ new_options=ssh_options.merge(options)
+ self.when_ssh_login_works(self.ip_address,new_options) do
+ begin
+ env.logger.info "About to execute remote command #{command} on box #{name} - #{self.ip_address} - #{new_options}"
+ result=self.ssh_execute(self.ip_address,command,new_options)
+ return result
+ rescue RuntimeError => ex
+ env.ui.error "Error executing command #{command} : #{ex}"
+ raise Veewee::SshError, ex
+ end
+ end
+ rescue Net::SSH::AuthenticationFailed => ex # may want to catch winrm auth fails as well
+ env.ui.error "Authentication failure"
+ raise Veewee::SshError, "Authentication failure\n"+ex
end
- rescue Net::SSH::AuthenticationFailed => ex
- raise Veewee::SshError, "Authentication failure\n"+ex
end
+
end
end # Module
end # Module
@@ -5,6 +5,7 @@ module BoxCommand
def create_floppy(floppy_filename)
# Todo Check for java
# Todo check output of commands
+ # Todo allow for .erb templates
# Check for floppy
unless definition.floppy_files.nil?
@@ -9,9 +9,13 @@ def halt(options={})
if options["force"]==true
self.poweroff
else
- self.exec("echo '#{definition.shutdown_cmd}' > /tmp/shutdown.sh")
- self.exec("chmod +x /tmp/shutdown.sh")
- self.exec(sudo("/tmp/shutdown.sh"))
+ if definition.winrm_user && definition.winrm_password # prefer winrm
+ self.exec("#{definition.shutdown_cmd}")
+ else
+ self.exec("echo '#{definition.shutdown_cmd}' > /tmp/shutdown.sh")
+ self.exec("chmod +x /tmp/shutdown.sh")
+ self.exec(sudo("/tmp/shutdown.sh"))
+ end
end
else
raise Veewee::Error,"Box is not running"
@@ -0,0 +1,15 @@
+require 'veewee/provider/core/helper/ssh'
+module Veewee
+ module Provider
+ module Core
+ module BoxCommand
+
+ def iwinrm(command=nil,options={})
+ self.winrm(command,options.merge({:interactive => true}))
+ end
+
+ end # Module
+ end # Module
+ end # Module
+end # Module
+
@@ -31,7 +31,13 @@ def validate_tags(tags,options)
ENV['VEEWEE_BOXNAME']=@name
ENV['VEEWEE_PROVIDER']=@provider.name
- feature_path=File.join(File.dirname(__FILE__),"..","..","..","..","..","validation","veewee.feature")
+ if definition.winrm_user && definition.winrm_password # prefer winrm
+ featurefile="veewee-windows.feature"
+ else
+ featurefile="veewee.feature"
+ end
+
+ feature_path=File.join(File.dirname(__FILE__),"..","..","..","..","..","validation",featurefile)
features=Array.new
features[0]=feature_path
Oops, something went wrong.

0 comments on commit f45954f

Please sign in to comment.