Skip to content
Browse files

temporary backup

  • Loading branch information...
1 parent bde5cc0 commit 7db5231ace64cdcc4e4a60ab152fd39110b183c9 @jedi4ever committed Sep 17, 2011
Showing with 1,920 additions and 771 deletions.
  1. +3 −2 Gemfile.lock
  2. +22 −0 bin/veewee-kvm
  3. +34 −0 bin/veewee-kvm-old
  4. +21 −24 bin/{veewee → veewee-vagrant}
  5. +34 −0 bin/veewee-vmfusion
  6. +19 −2 lib/veewee.rb
  7. +6 −6 lib/veewee/builder/core/box.rb
  8. +53 −11 lib/veewee/builder/core/builder.rb
  9. +56 −0 lib/veewee/builder/core/definition.rb
  10. +52 −52 lib/veewee/builder/core/helper/iso.rb
  11. +1 −3 lib/veewee/builder/core/helper/transaction.rb
  12. +118 −0 lib/veewee/builder/core/helper/vnc.rb
  13. +3 −3 lib/veewee/builder/kvm/assemble.rb
  14. +13 −11 lib/veewee/builder/kvm/box.rb
  15. +52 −47 lib/veewee/builder/kvm/build.rb
  16. +12 −0 lib/veewee/builder/kvm/definition.rb
  17. +6 −6 lib/veewee/builder/kvm/destroy.rb
  18. +3 −1 lib/veewee/builder/kvm/helper/buildinfo.rb
  19. +6 −8 lib/veewee/builder/kvm/helper/console_type.rb
  20. +2 −2 lib/veewee/builder/kvm/helper/disk.rb
  21. +12 −6 lib/veewee/builder/kvm/helper/network.rb
  22. +41 −31 lib/veewee/builder/kvm/helper/tunnel.rb
  23. +19 −13 lib/veewee/builder/kvm/helper/vm.rb
  24. +2 −1 lib/veewee/builder/virtualbox/box.rb
  25. +56 −34 lib/veewee/builder/virtualbox/build.rb
  26. +3 −3 lib/veewee/builder/virtualbox/builder.rb
  27. +9 −9 lib/veewee/builder/virtualbox/helper/disk.rb
  28. +7 −2 lib/veewee/builder/virtualbox/helper/network.rb
  29. +1 −1 lib/veewee/builder/virtualbox/helper/path.rb
  30. +12 −12 lib/veewee/builder/virtualbox/helper/vm.rb
  31. +3 −3 lib/veewee/builder/vmfusion/assemble.rb
  32. +5 −5 lib/veewee/builder/vmfusion/box.rb
  33. +3 −3 lib/veewee/builder/vmfusion/build.rb
  34. +12 −0 lib/veewee/builder/vmfusion/definition.rb
  35. +8 −116 lib/veewee/builder/vmfusion/helper/console_type.rb
  36. +10 −7 lib/veewee/builder/vmfusion/helper/vm.rb
  37. +55 −0 lib/veewee/cli.rb
  38. +11 −0 lib/veewee/command.rb
  39. +106 −0 lib/veewee/command/base.rb
  40. +107 −0 lib/veewee/command/group_base.rb
  41. +13 −0 lib/veewee/command/helpers.rb
  42. +17 −0 lib/veewee/command/init.rb
  43. +14 −0 lib/veewee/command/named_base.rb
  44. +14 −0 lib/veewee/command/version.rb
  45. +140 −0 lib/veewee/config.rb
  46. +53 −0 lib/veewee/config/builder.rb
  47. +82 −0 lib/veewee/config/collection.rb
  48. +19 −0 lib/veewee/config/component.rb
  49. +66 −0 lib/veewee/config/definition.rb
  50. +40 −0 lib/veewee/config/veewee.rb
  51. +0 −82 lib/veewee/definition.rb
  52. +234 −0 lib/veewee/environment-ol.rb
  53. +112 −195 lib/veewee/environment.rb
  54. +0 −36 lib/veewee/logger.rb
  55. +0 −12 lib/veewee/logsnippet.txt
  56. +0 −16 lib/veewee/session.rb
  57. +30 −0 lib/veewee/templates/locales/en.yml
  58. +81 −0 lib/veewee/ui.rb
  59. +1 −1 lib/veewee/version.rb
  60. +5 −5 test/environment_test.rb
  61. +1 −0 veewee.gemspec
View
5 Gemfile.lock
@@ -1,20 +1,21 @@
PATH
remote: .
specs:
- veewee (0.2.0)
+ veewee (0.3.0)
ansi (~> 1.3.0)
cucumber (~> 1.0.2)
highline (~> 1.6.1)
net-ssh (~> 2.1.0)
popen4 (~> 0.1.2)
progressbar
rspec (~> 2.5.0)
+ ruby-vnc (~> 1.0.0)
thor (~> 0.14.6)
PATH
remote: /Users/patrick/imac/fog
specs:
- fog (0.10.0)
+ fog (0.11.0)
builder
excon (~> 0.6.5)
formatador (~> 0.2.0)
View
22 bin/veewee-kvm
@@ -0,0 +1,22 @@
+#!/usr/bin/env ruby
+require 'veewee'
+
+env = Veewee::Environment.new
+
+begin
+ # Begin logging
+ # env.logger.info("veewee")
+
+ # Disable color if the proper argument was passed
+ shell = ARGV.include?("--no-color") ? Thor::Shell::Basic.new : Thor::Base.shell.new
+
+ # Attach the UI
+ env.ui = ::Veewee::UI::Shell.new(env, shell)
+ env.load!
+
+ # Start the CLI
+ ::Veewee::CLI.start(ARGV,:env => env)
+
+rescue Veewee::Error => e
+ puts "#{e}"
+end
View
34 bin/veewee-kvm-old
@@ -0,0 +1,34 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+require 'thor'
+require 'libvirt'
+require 'fog'
+
+require 'veewee'
+
+class VeeweeCLI < Thor
+
+ desc "build [NAME]", "build the box defined"
+ method_options :force => :boolean
+ def build(box_name)
+
+
+ logger=ANSI::Logger.new(STDOUT)
+ logger.level=Object.const_get('ANSI').const_get('Logger').const_get('DEBUG')
+ logger.formatter do |severity, timestamp, progname, msg|
+ # "#{progname}@#{timestamp} - #{severity}::#{msg}"
+ "#{msg}\n"
+ end
+ logger.ansicolor=false
+
+
+ puts "Building box #{box_name}"
+ box=Veewee::Environment.new(options,logger).get_builder(:kvm,options).get_box(box_name,box_name,options)
+ box.build(options)
+
+ end
+
+end
+
+VeeweeCLI.start
View
45 bin/veewee → bin/veewee-vagrant
@@ -7,52 +7,49 @@ require 'virtualbox'
require 'veewee'
-
-class VeeweeCLI < Thor
-
- desc "define [NAME] [TEMPLATE]", "initializes a box from a template"
+class VeeweeCLI < Thor
+
+ desc "define [NAME] [TEMPLATE]", "initializes a box from a template"
method_options :force => :boolean
def define(box_name=nil, template=nil)
-
- if (box_name.nil?)
+
+ if (box_name.nil?)
puts "please provide a box_name"
exit
end
-
+
puts "Init a new box #{box_name}, starting from template #{template}"
- Veewee::Environment.define(box_name,template)
-
+ Veewee::Environment.define(box_name,template)
+
end
- desc "templates", "list the template available"
- def templates
+ desc "templates", "list the template available"
+ def templates
Veewee::Environment.list_templates
end
-
- desc "build [NAME]", "build the box defined"
+
+ desc "build [NAME]", "build the box defined"
method_options :force => :boolean
def build(box_name)
puts "Building box #{box_name}"
vs=Veewee::Environment.new(options)
vd=vs.get_definition(box_name)
- vs.build(box_name,vd)
+ vs.build(box_name,vd)
end
- desc "export [NAME]", "export the box"
- method_options :force => :boolean
+ desc "export [NAME]", "export the box"
+ method_options :force => :boolean
def export(box_name)
- if (!box_name.nil?)
- Veewee::Environment.export_box(box_name)
- end
+ if (!box_name.nil?)
+ Veewee::Environment.export_box(box_name)
+ end
end
-
-end
-
+end
version=VirtualBox.version
if (version.match(/^4./))
- VeeweeCLI.start
+ VeeweeCLI.start
else
- puts "veewee only supports VirtualBox 4.x"
+ puts "veewee only supports VirtualBox 4.x"
end
View
34 bin/veewee-vmfusion
@@ -0,0 +1,34 @@
+#!/usr/bin/env ruby
+
+require 'rubygems'
+require 'thor'
+require 'fog'
+require 'fission'
+
+require 'veewee'
+
+class VeeweeCLI < Thor
+
+ desc "build [NAME]", "build the box defined"
+ method_options :force => :boolean
+ def build(box_name)
+
+
+ logger=ANSI::Logger.new(STDOUT)
+ logger.level=Object.const_get('ANSI').const_get('Logger').const_get('DEBUG')
+ logger.formatter do |severity, timestamp, progname, msg|
+ # "#{progname}@#{timestamp} - #{severity}::#{msg}"
+ "#{msg}\n"
+ end
+ logger.ansicolor=false
+
+
+ puts "Building box #{box_name}"
+ box=Veewee::Environment.new(options,logger).get_builder(:vmfusion,options).get_box(box_name,box_name,options)
+ box.build(options)
+
+ end
+
+end
+
+VeeweeCLI.start
View
21 lib/veewee.rb
@@ -1,4 +1,21 @@
+require 'json'
+require 'i18n'
+
+module Veewee
+ # The source root is the path to the root directory of
+ # the Mccloud gem.
+ def self.source_root
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
+ end
+end
+
+# # Default I18n to load the en locale
+I18n.load_path << File.expand_path("templates/locales/en.yml", Veewee.source_root)
+
+# Load the things which must be loaded before anything else
+require 'veewee/cli'
+require 'veewee/ui'
+require 'veewee/command'
require 'veewee/error'
-require 'veewee/logger'
require 'veewee/environment'
-require 'veewee/session'
+require 'veewee/version'
View
12 lib/veewee/builder/core/box.rb
@@ -26,7 +26,7 @@ def handle_postinstall
@definition.postinstall_files.each do |postinstall_file|
# Filenames of postinstall_files are relative to their definition
- filename=File.join(@environment.definition_dir,@box_name,postinstall_file)
+ filename=File.join(@environment.definition_dir,@box_name,postinstall_file)
Veewee::Util::Ssh.when_ssh_login_works(ip_address,ssh_options) do
begin
@@ -40,7 +40,7 @@ def handle_postinstall
newcommand.gsub!(/%u/,"#{@definition.ssh_user}")
newcommand.gsub!(/%f/,"#{postinstall_file}")
Veewee::Util::Ssh.execute(ip_address,"#{newcommand}",ssh_options)
- end
+ end
end
end
@@ -52,7 +52,7 @@ def handle_kickstart
if kickstartfiles.nil? || kickstartfiles.length == 0
puts "Skipping webserver as no kickstartfile was specified"
end
-
+
puts "Starting a webserver on port #{@definition.kickstart_port}"
#:kickstart_port => "7122", :kickstart_ip => self.local_ip, :kickstart_timeout => 1000,:kickstart_file => "preseed.cfg",
if kickstartfiles.is_a?(String)
@@ -63,14 +63,14 @@ def handle_kickstart
kickstartfiles.each do |kickfile|
Veewee::Util::Web.wait_for_request(kickfile,{
:port => @definition.kickstart_port,
- :host => @definition.kickstart_ip,
+ :host => @definition.kickstart_ip,
:timeout => @definition.kickstart_timeout,
:web_dir => File.join(@environment.definition_dir,@box_name)
- })
+ })
end
end
end #End Class
end # End Module
end # End Module
-end # End Module
+end # End Module
View
64 lib/veewee/builder/core/builder.rb
@@ -7,22 +7,45 @@ module Builder
module Core
class Builder
- attr_accessor :environment
+ attr_accessor :env
attr_accessor :options
+
attr_accessor :type
+ attr_accessor :name
+
+ attr_accessor :boxes
+
+ def initialize(name,options,env)
+
+ @name=name
+ @options=options
+ @env=env
- # This is a generic class that will be implemeted by each boxbuilder
- # It passes the options builder_options and links the environment to its
- def initialize(builder_options,environment)
- @environment=environment
- @options=builder_options
- type=self.class.to_s
- # Strip out the module path Veewee::Builder::Virtualbox::Builder
- type['Veewee::Builder::']=''
- type['::Builder']=''
- @type=type
+ @type=self.class.to_s.split("::")[-2]
+
+ @boxes=Hash.new
+
end
+ def get_component(type,env)
+ real_component=nil
+ begin
+ # Now that we know the actual provider, we can check if the provider has this type of component
+ require_path='mccloud/provider/'+@type.to_s.downcase+"/"+type
+ require require_path
+ # Now we can create the real component
+
+ env.logger.debug("provide #{@type} about to create component of type #{type}")
+
+ real_component=Object.const_get("Veewee").const_get("Builder").const_get(@type.to_s.capitalize).const_get(type.to_s.capitalize).new(env)
+
+ rescue Error => e
+ puts "Error getting component - #{e}"
+ end
+ return real_component
+ end
+
+
# This function asks a builder to initialize a box,with a name and definition
def get_box(box_name,definition_name=nil,box_options={})
if definition_name.nil?
@@ -32,6 +55,25 @@ def get_box(box_name,definition_name=nil,box_options={})
box=box_class.new(@environment,box_name,definition_name,box_options)
return box
end
+
+ def check_gem_availability(gems)
+
+ gems.each do |gemname|
+ availability_gem=false
+ begin
+ availability_gem=true unless Gem::Specification::find_by_name("#{gemname}").nil?
+ rescue Gem::LoadError
+ availability_gem=false
+ rescue
+ availability_gem=Gem.available?("#{gemname}")
+ end
+ unless availability_gem
+ abort "The #{gemname} gem is not installed and is required by the #{@name.to_sym} provider"
+ exit
+ end
+ end
+ end
+
end #End Class
View
56 lib/veewee/builder/core/definition.rb
@@ -0,0 +1,56 @@
+module Veewee::Builder
+ module Core
+ class Definition
+
+ attr_accessor :name
+ attr_accessor :env
+
+ def initialize(name,env)
+
+ @name=name
+ @env=env
+
+ # Default is 1 CPU + 256 Mem of memory
+ @cpu_count='1' ; @memory_size='256';
+
+ # Default there is no ISO file mounted
+ @iso_file = nil, @iso_src = nil ; @iso_md5 = nil ; @iso_download_timeout=1000 ; @iso_download_instructions = nil
+
+ # Default is no floppy mounted
+ @floppy_files = nil
+
+ # Default there are no post install files
+ @postinstall_files=[]; @postinstall_timeout = 10000;
+
+# :disk_size => '10240', :disk_format => 'VDI',
+
+# :hostiocache => 'off' ,
+# :os_type_id => 'Ubuntu',
+
+
+# :boot_wait => "10", :boot_cmd_sequence => [ "boot"],
+# :kickstart_port => "7122", :kickstart_ip => "127.0.0.1", :kickstart_timeout => 10000,#
+
+# :ssh_login_timeout => "10000", :ssh_user => "vagrant", :ssh_password => "vagrant",:ssh_key => "",
+# :ssh_host_port => "2222", :ssh_guest_port => "22", :sudo_cmd => "echo '%p'|sudo -S sh '%f'",
+
+# :shutdown_cmd => "shutdown -h now",
+
+
+# :kickstart_file => nil,
+
+# }
+
+# options=defaults.merge(options)
+
+
+ end
+
+ def method_missing(m, *args, &block)
+ env.logger.info "There's no attribute #{m} defined for builder #{@name}-- ignoring it"
+ end
+
+
+ end #End Class
+end #End Module
+end #End Module
View
104 lib/veewee/builder/core/helper/iso.rb
@@ -10,71 +10,71 @@ module Core
def download_progress(url,localfile)
pbar = nil
URI.parse(url).open(
- :content_length_proc => lambda {|t|
+ :content_length_proc => lambda {|t|
if t && 0 < t
pbar = ProgressBar.new("Fetching file", t)
pbar.file_transfer_mode
end
- },
+ },
:progress_proc => lambda {|s|
- pbar.set s if pbar
- }) { |src|
- open("#{localfile}","wb") { |dst|
- dst.write(src.read)
- }
- }
+ pbar.set s if pbar
+ }) { |src|
+ open("#{localfile}","wb") { |dst|
+ dst.write(src.read)
+ }
+ }
- end
-
- def verify_iso(filename,autodownload = false)
- if File.exists?(File.join(@environment.iso_dir,filename))
- puts
- puts "Verifying the isofile #{filename} is ok."
- else
-
- full_path=File.join(@environment.iso_dir,filename)
- path1=Pathname.new(full_path)
- path2=Pathname.new(Dir.pwd)
- rel_path=path1.relative_path_from(path2).to_s
+ end
- puts
- puts "We did not find an isofile in <currentdir>/iso. \n\nThe definition provided the following download information:"
- unless "#{@definition.iso_src}"==""
- puts "- Download url: #{@definition.iso_src}"
- end
- puts "- Md5 Checksum: #{@definition.iso_md5}"
- puts "#{@definition.iso_download_instructions}"
- puts
+ def verify_iso(filename,autodownload = false)
+ if File.exists?(File.join(@environment.iso_dir,filename))
+ puts
+ puts "Verifying the isofile #{filename} is ok."
+ else
- if @definition.iso_src == ""
- puts "Please follow the instructions above:"
- puts "- to get the ISO"
- puts" - put it in <currentdir>/iso"
- puts "- then re-run the command"
- puts
- exit
- else
+ full_path=File.join(@environment.iso_dir,filename)
+ path1=Pathname.new(full_path)
+ path2=Pathname.new(Dir.pwd)
+ rel_path=path1.relative_path_from(path2).to_s
- question=ask("Download? (Yes/No)") {|q| q.default="No"}
- if question.downcase == "yes"
- if !File.exists?(@environment.iso_dir)
- puts "Creating an iso directory"
- FileUtils.mkdir(@environment.iso_dir)
- end
+ puts
+ puts "We did not find an isofile in <currentdir>/iso. \n\nThe definition provided the following download information:"
+ unless "#{@definition.iso_src}"==""
+ puts "- Download url: #{@definition.iso_src}"
+ end
+ puts "- Md5 Checksum: #{@definition.iso_md5}"
+ puts "#{@definition.iso_download_instructions}"
+ puts
- download_progress(@definition.iso_src,full_path)
- else
- puts "You have choosen for manual download: "
- puts "curl -C - -L '#{@definition.iso_src}' -o '#{rel_path}'"
- puts "md5 '#{rel_path}' "
- puts
- exit
- end
+ if @definition.iso_src == ""
+ puts "Please follow the instructions above:"
+ puts "- to get the ISO"
+ puts" - put it in <currentdir>/iso"
+ puts "- then re-run the command"
+ puts
+ exit
+ else
+ question=ask("Download? (Yes/No)") {|q| q.default="No"}
+ if question.downcase == "yes"
+ if !File.exists?(@environment.iso_dir)
+ puts "Creating an iso directory"
+ FileUtils.mkdir(@environment.iso_dir)
end
+
+ download_progress(@definition.iso_src,full_path)
+ else
+ puts "You have choosen for manual download: "
+ puts "curl -C - -L '#{@definition.iso_src}' -o '#{rel_path}'"
+ puts "md5 '#{rel_path}' "
+ puts
+ exit
end
end
- end #Module
- end #Module
+ end
+
+ end
end #Module
+ end #Module
+end #Module
View
4 lib/veewee/builder/core/helper/transaction.rb
@@ -5,7 +5,7 @@ class Transaction
def transaction(name,params, &block)
end
-
+
def transaction2(name,options= { :checksum => "nochecksum"}, &block)
if snapshot_exists(@vmname,name+"-"+options[:checksum])
load_snapshot_vmachine(@vmname,name+"-"+options[:checksum])
@@ -23,5 +23,3 @@ def transaction2(name,options= { :checksum => "nochecksum"}, &block)
end
end
-
-
View
118 lib/veewee/builder/core/helper/vnc.rb
@@ -0,0 +1,118 @@
+require 'net/vnc'
+
+module Veewee
+ module Builder
+ module Core
+
+ def vnc_type(sequence,host,display=20)
+ puts
+ counter=0
+ vnc=Net::VNC.open("#{host}:#{display}",{:wait => 0.01})
+ sequence.each { |s|
+ counter=counter+1
+
+
+ puts "Typing:[#{counter}]: "+s
+
+ keycodes=string_to_vnccode(s)
+
+ keycodes.each do |keycode|
+ if keycode==:wait
+ sleep 1
+ else
+ send_vnc_keycode(vnc,keycode)
+ end
+ end
+ }
+ vnc.close
+ puts "Done typing."
+ puts
+
+ end
+
+ def send_vnc_keycode(vnc,keycode)
+
+ if keycode.is_a?(Symbol)
+ vnc.key_press keycode
+ sleep 0.3
+ else
+ vnc.type_string keycode,{:wait => 0.01}
+ end
+
+ end
+
+
+ def string_to_vnccode(thestring)
+
+ # http://code.google.com/p/ruby-vnc/source/browse/trunk/data/keys.yaml
+
+ special=Hash.new
+ # Specific veewee
+ special['<Wait>'] = :wait
+
+ # VNC Codes
+ special['<Enter>'] = :return
+ special['<Return>'] = :return
+ special['<Esc>'] = :escape
+
+ # These still need some work!
+ special['<Backspace>'] = :backspace
+ special['<Spacebar>'] = ' '
+ special['<Tab>'] = :tab
+ # Hmm, what would the equivalent be here
+ special['<KillX>'] = '1d 38 0e';
+
+ special['<Up>'] = :up
+ special['<Down>'] = :down
+ special['<PageUp>'] = :page_up
+ special['<PageDown>'] = :page_down
+ special['<End>'] = :end
+ special['<Insert>'] = :insert
+ special['<Delete>'] = :delete
+ special['<Left>'] = :left
+ special['<Right>'] = :right
+ special['<Home>'] = :home
+
+ special['<F1>'] = :f1
+ special['<F2>'] = :f2
+ special['<F3>'] = :f3
+ special['<F4>'] = :f4
+ special['<F5>'] = :f5
+ special['<F6>'] = :f6
+ special['<F7>'] = :f7
+ special['<F8>'] = :f8
+ special['<F9>'] = :f9
+ special['<F10>'] = :f10
+
+ keycodes=Array.new
+ thestring.gsub!(/ /,"<Spacebar>")
+
+ until thestring.length == 0
+ nospecial=true;
+ special.keys.each { |key|
+ if thestring.start_with?(key)
+ #take thestring
+ #check if it starts with a special key + pop special string
+ keycodes<<special[key];
+ thestring=thestring.slice(key.length,thestring.length-key.length)
+ nospecial=false;
+ break;
+ end
+ }
+ if nospecial
+ code = thestring.slice(0,1)
+ keycodes << code
+ #pop one
+ thestring=thestring.slice(1,thestring.length-1)
+ end
+ end
+
+ return keycodes
+ end
+
+
+
+ end #Module
+ end #Module
+end #Module
+
View
6 lib/veewee/builder/kvm/assemble.rb
@@ -3,13 +3,13 @@
module Veewee
module Builder
module Kvm
-
+
# This function 'assembles' the box based on the definition
def assemble
# This will also create the disk, and mount the isofile
create_vm
end
-
+
end
end
-end
+end
View
24 lib/veewee/builder/kvm/box.rb
@@ -15,6 +15,7 @@
require 'veewee/builder/kvm/helper/network'
require 'veewee/builder/kvm/helper/console_type'
require 'veewee/builder/kvm/helper/buildinfo'
+require 'veewee/builder/kvm/helper/tunnel'
require 'shellwords'
@@ -27,42 +28,43 @@ class Box < Veewee::Builder::Core::Box
include Veewee::Builder::Kvm
attr_accessor :connection
-
+
def initialize(environment,box_name,definition_name,box_options={})
require 'libvirt'
require 'fog'
-
- @connection=::Fog::Compute.new(:provider => "Libvirt", :libvirt_uri => "qemu+ssh://patrick.debois@juno/system")
-
+
+ # We only do the internal build for now
+ @connection=::Fog::Compute.new(:provider => "Libvirt", :libvirt_uri => "qemu:///system")
+
super(environment,box_name,definition_name,box_options)
- end
+ end
# Translate the definition ssh options to ssh options that can be passed to Net::Ssh calls
# We expect plain ssh for a connection
def ssh_options
- ssh_options={
- :user => @definition.ssh_user,
+ ssh_options={
+ :user => @definition.ssh_user,
:port => 22,
:password => @definition.ssh_password,
:timeout => @definition.ssh_login_timeout.to_i
}
return ssh_options
end
-
+
def running?
if exists?
@connection.servers.all(:name => @box_name).first.ready?
else
false
end
end
-
+
def exists?
!@connection.servers.all(:name => @box_name).nil?
end
-
+
end # End Class
end # End Module
end # End Module
-end # End Module
+end # End Module
View
99 lib/veewee/builder/kvm/build.rb
@@ -1,53 +1,58 @@
-
module Veewee
module Builder
module Kvm
- def build(build_options={})
-
- defaults= { "force" => false, "nogui" => false }
- options=defaults.merge(build_options)
-
- if exists? || vol_exists?
- if options["force"]==true
- if running?
- destroy_vm
- end
- destroy
- else
- puts "Machine and/or volume already exists, use the force flag"
- end
-
- end
- assemble
-
- #Starting machine
- start_vm
-
- #waiting for it to boot
- puts "Waiting for the machine to boot"
- sleep @definition.boot_wait.to_i
-
-
- vnc_port=@connection.servers.all(:name => "#{@box_name}").first.vnc_port
- puts "#{vnc_port}"
-
- puts "ssh enabled? #{@connection.uri.ssh_enabled?}"
-
- # Sending keystrokes
- @web_ip_address=web_ip_address
- send_sequence(@definition.boot_cmd_sequence)
- sleep 120 #Sleep 2 minutes to make arpwatch flush to wait for the ssh, otherwise we will have no ip
-
- # handle_kickstart
-
- transfer_buildinfo_file
-
- handle_postinstall
-
- # Wait for web request
- # Do ssh stuff
-
+ def build(build_options={})
+
+ defaults= { "force" => false, "nogui" => false }
+ options=defaults.merge(build_options)
+
+ if @definition.nil?
+ abort("This definition could not be loaded")
+ end
+
+ if exists? || vol_exists?
+ if options["force"]==true
+ if running?
+ destroy_vm
end
+ destroy
+ else
+ puts "Machine and/or volume already exists, use the force flag"
+ end
+
+ end
+ assemble
+
+ #Starting machine
+ start_vm
+
+ #waiting for it to boot
+ puts "Waiting for the machine to boot"
+ sleep @definition.boot_wait.to_i
+
+ vnc_port=@connection.servers.all(:name => "#{@box_name}").first.vnc_port
+
+ unless @connection.uri.ssh_enabled?
+ ssh_tunnel_start([{:local_port => 5908, :remote_port => vnc_port.to_i , :ip => "127.0.0.1"}])
+ end
+
+ # Sending keystrokes
+ @web_ip_address=web_ip_address
+ send_sequence(@definition.boot_cmd_sequence)
+
+ sleep 120 #Sleep 2 minutes to make arpwatch flush to wait for the ssh, otherwise we will have no ip
+
+ # handle_kickstart
+
+ transfer_buildinfo_file
+
+ handle_postinstall
+
+ ssh_tunnel_stop
+ # Wait for web request
+ # Do ssh stuff
+
+ end
end
end
-end
+end
View
12 lib/veewee/builder/kvm/definition.rb
@@ -0,0 +1,12 @@
+require 'veewee/builder/core/definition'
+
+module Veewee::Builder
+ module Kvm
+
+ class Definition < ::Veewee::Builder::Core::Definition
+ def initialize(name,env)
+ super(name,env)
+ end
+ end
+ end
+end
View
12 lib/veewee/builder/kvm/destroy.rb
@@ -1,27 +1,27 @@
module Veewee
module Builder
module Kvm
-
+
def vol_exists?
!@connection.volumes.all(:name => "#{@box_name}.img").nil?
end
-
+
def destroy(destroy_options={})
if running?
raise RuntimeError,"VM is running" unless !destroy_options["force"].nil?
halt_vm
end
-
+
if exists?
destroy_vm(destroy_options)
end
-
+
if vol_exists?
- destroy_disk(destroy_options)
+ destroy_disk(destroy_options)
end
end
-
+
end
end
end
View
4 lib/veewee/builder/kvm/helper/buildinfo.rb
@@ -4,7 +4,7 @@ module Kvm
def transfer_buildinfo_file
Veewee::Util::Ssh.when_ssh_login_works(ip_address,ssh_options) do
- #Transfer version of Fusion to $HOME/.vmfusion_version
+ #Transfer version of Fusion to $HOME/.vmfusion_version
versionfile=Tempfile.open("libvirt_version")
# Todo get the version of fusion
versionfile.puts "dont know yet"
@@ -14,6 +14,8 @@ def transfer_buildinfo_file
rescue RuntimeError => ex
puts "error transfering file, possible not enough permissions to write? #{ex}"
exit
+ rescue Net::SSH::AuthenticationFailed
+ abort "Authentication failed, #{ex}"
ensure
versionfile.close
versionfile.delete
View
14 lib/veewee/builder/kvm/helper/console_type.rb
@@ -17,12 +17,10 @@ def send_sequence(sequence)
counter=counter+1
s.gsub!(/%IP%/,@web_ip_address);
-
- s.gsub!(/%PORT%/,"80");
+
+ s.gsub!(/%PORT%/,@definition.kickstart_port);
+
s.gsub!(/%NAME%/, @box_name);
-# s.gsub!(/%IP%/,Veewee::Util::Tcp.local_ip);
-# s.gsub!(/%PORT%/,@definition.kickstart_port);
-# s.gsub!(/%NAME%/, @box_name);
puts "Typing:[#{counter}]: "+s
@@ -33,7 +31,7 @@ def send_sequence(sequence)
if keycode==:wait
sleep 1
else
- send_keycode(vnc,keycode)
+ send_keycode(vnc,keycode)
end
end
end
@@ -64,9 +62,9 @@ def send_keycode(vnc,keycode)
def string_to_vnccode(thestring)
-
+
# http://code.google.com/p/ruby-vnc/source/browse/trunk/data/keys.yaml
-
+
special=Hash.new
# Specific veewee
special['<Wait>'] = :wait
View
4 lib/veewee/builder/kvm/helper/disk.rb
@@ -1,7 +1,7 @@
module Veewee
module Builder
module Kvm
-
+
def create_disk
# Creating the disk is part of the server creation
end
@@ -10,7 +10,7 @@ def destroy_disk(destroy_options={})
vol=@connection.volumes.all(:name => "#{@box_name}.img").first
vol.destroy
end
-
+
end
end
end
View
18 lib/veewee/builder/kvm/helper/network.rb
@@ -1,17 +1,23 @@
module Veewee
module Builder
module Kvm
-
- def ip_address
+
+ def ip_address
ip=@connection.servers.all(:name => "#{@box_name}").first.addresses[:public]
return ip.first unless ip.nil?
return ip
end
-
+
def web_ip_address
- #ip -4 -o addr show br0
- ip=Veewee::Util::Ssh.execute("juno","ip -4 -o addr show br0",options ={ :user => "#{connection.uri.user}"}).stdout.split("inet ")[1].split("/").first
- return ip
+ unless @connection.uri.ssh_enabled?
+ ip=Veewee::Util::Tcp.local_ip
+ else
+ # Not supported yet but these are some ideas
+ # Try to figure out the remote IP address
+ # ip -4 -o addr show br0
+ ip=Veewee::Util::Ssh.execute(@connection.uri.host,"ip -4 -o addr show br0",options ={ :user => "#{connection.uri.user}"}).stdout.split("inet ")[1].split("/").first
+ return ip
+ end
end
end
View
72 lib/veewee/builder/kvm/helper/tunnel.rb
@@ -1,34 +1,44 @@
- require 'net/ssh/multi'
-
- module Veewee
- module Builder
- module Kvm
+#require 'net/ssh/multi'
+
+module Veewee
+ module Builder
+ module Kvm
+
+ def ssh_tunnel_start(forwardings)
+ #ssh_options={ :keys => [ vm.private_key ], :paranoid => false, :keys_only => true}
+
+ ssh_options={ :paranoid => false}
+ host=@connection.uri.host
+ user=@connection.uri.user
+
+ puts "Enabling tunneling"
+ @forward_threads=Array.new
+ @forward_threads<< Thread.new {
+ Net::SSH.start(host, user, ssh_options) do |ssh_session|
+ forwardings.each do |forwarding|
+ begin
+ puts "Forwarding remote port #{forwarding[:remote_port]} from #{box_name} to local port #{forwarding[:local_port]}"
+ puts host
+ puts user
+ puts
+ ssh_session.forward.local(forwarding[:local_port], "127.0.0.1",forwarding[:remote_port])
+ rescue Errno::EACCES
+ puts " Error - Access denied to forward remote port #{forwarding[:remote_port]} from #{box_name} to local port #{forwarding[:local_port]}"
+ end
+ end
+ ssh_session.loop {true}
+ end
+ }
+ puts @forward_threads.first.status
+ @forward_threads.first.run
+ puts @forward_threads.first.status
- def ssh_tunnel_start
- #ssh_options={ :keys => [ vm.private_key ], :paranoid => false, :keys_only => true}
-
- ssh_options={ :paranoid => false}
- host=@connection.uri.host
- user=@connection.uri.user
-
- @ssh_tunnel=Net::SSH.start(host, user, ssh_options)
- forwardings=[ { }]
- forwardings.each do |forwarding|
- begin
- puts "Forwarding remote port #{forwarding.remote} from #{vm.name} to local port #{forwarding.local}"
- ssh.forward.local(forwarding.local, private_ip_address,forwarding.remote)
- rescue Errno::EACCES
- puts " Error - Access denied to forward remote port #{forwarding.remote} from #{vm.name} to local port #{forwarding.local}"
- end
- end
-
-
- end
-
- def ssh_tunnel_stop
- @ssh_tunnel.close
- end
-
end
+
+ def ssh_tunnel_stop
+ Thread.kill(@forward_threads.first)
+ end
+
end
- end
+ end
+end
View
32 lib/veewee/builder/kvm/helper/vm.rb
@@ -1,35 +1,41 @@
-
module Veewee
module Builder
module Kvm
def destroy_vm(destroy_options={})
- @connection.servers.all(:name => @box_name).first.destroy
+ matched_servers=@connection.servers.all(:name => @box_name)
+ matched_servers.first.destroy unless matched_servers.nil?
end
def start_vm
- @connection.servers.all(:name => @box_name).first.start
+ matched_servers=@connection.servers.all(:name => @box_name)
+ matched_servers.first.start unless matched_servers.nil?
end
def halt_vm
- @connection.servers.all(:name => @box_name).first.halt
+ matched_servers=@connection.servers.all(:name => @box_name)
+ matched_servers.first.halt unless matched_servers.nil?
end
-
+
def stop_vm
- @connection.servers.all(:name => @box_name).first.stop
+ matched_servers=@connection.servers.all(:name => @box_name)
+ matched_servers.first.stop unless matched_servers.nil?
end
-
+
def create_vm
# Assemble the Virtualmachine and set all the memory and other stuff
-
- s=@connection.servers.create(:template_options => {
+
+ # If local it's just currentdir+iso or the one specified
+ iso_dir="iso"
+
+ # If remote, request homedir + iso?
+
+ s=@connection.servers.create(
:name => @box_name,
- :interface_type => "bridge",
+ :network_interface_type => "bridge",
:iso_file => @definition.iso_file ,
:iso_dir => "/home/patrick.debois/iso",
- :type => "raw"
- })
-
+ :type => "raw")
end
end
View
3 lib/veewee/builder/virtualbox/box.rb
@@ -18,6 +18,7 @@
require 'veewee/builder/virtualbox/helper/dvd'
require 'veewee/builder/virtualbox/helper/network'
require 'veewee/builder/virtualbox/helper/shared_folder'
+require 'veewee/builder/virtualbox/helper/path'
require 'veewee/builder/virtualbox/helper/console_type'
require 'veewee/builder/virtualbox/helper/buildinfo'
@@ -55,4 +56,4 @@ def ssh_options
end # End Class
end # End Module
end # End Module
-end # End Module
+end # End Module
View
90 lib/veewee/builder/virtualbox/build.rb
@@ -3,74 +3,96 @@ module Builder
module Virtualbox
def build(build_options={})
+
+ # Handle the options passed and set some sensible defaults
defaults={ "force" => false, "format" => "vagrant", "nogui" => false }
options = defaults.merge(build_options)
#Suppress those annoying virtualbox messages
- suppress_messages
+ suppress_messages
- #Check iso file
+ # Check the iso file we need to build the box
verify_iso(@definition.iso_file)
+ # Check if the box already exists
vm=VirtualBox::VM.find(@box_name)
-
- # Discarding save state
- if (!vm.nil? && (vm.saved?))
- puts "Removing save state"
- vm.discard_state
- vm.reload
- end
-
- # If the box is running shut it down
- if (!vm.nil? && !(vm.powered_off?))
- puts "Shutting down vm #{@box_name}"
- #We force it here, maybe vm.shutdown is cleaner
- begin
-
- vm.stop
- rescue VirtualBox::Exceptions::InvalidVMStateException
- puts "There was problem sending the stop command because the machine is in an Invalid state"
- puts "Please verify leftovers from a previous build in your vm folder"
+ box_exists=!vm.nil?
+
+ # If the box exists, check if the force flag was passed before continuing
+ if box_exists
+
+ # If no force flag was passed
+ if (options["force"]==false)
+ puts "The box is already there, we can't destroy it"
+ exit
+ else
+
+ # If it has a save state,remove that first
+ if vm.saved?
+ puts "Removing save state"
+ vm.discard_state
+ vm.reload
+ end
+
+ # If the vm is not powered off, perform a shutdown
+ if (!vm.nil? && !(vm.powered_off?))
+ puts "Shutting down vm #{@box_name}"
+ #We force it here, maybe vm.shutdown is cleaner
+ begin
+ vm.stop
+ sleep 3
+ rescue VirtualBox::Exceptions::InvalidVMStateException
+ puts "There was problem sending the stop command because the machine is in an Invalid state"
+ puts "Please verify leftovers from a previous build in your vm folder"
+ end
+ end
+
+ puts "Forcing build by destroying #{@box_name} machine"
+ destroy
end
- sleep 3
end
-
- if (options["force"]==false)
- puts "The box is already there, we can't destroy it"
- exit
- else
- puts "Forcing build by destroying #{@box_name} machine"
- destroy
- end
+ # By now the machine if it existed, should have been shutdown
+ # The last thing to check is if the power we are supposed to ssh to, is still open
if Veewee::Util::Tcp.is_port_open?("localhost", @definition.ssh_host_port)
puts "Hmm, the port #{@definition.ssh_host_port} is open. And we shut down?"
exit
end
-
- #Create the Virtualmachine and set all the memory and other stuff
+ # Everything indicates we can new build a new vm,
+ # time to create the Virtualmachine and set all the memory and other stuff
assemble
- #Starting machine
+ # Once assembled we start the machine
if (options["nogui"]==true)
start_vm("vrdp")
else
start_vm("gui")
end
- #waiting for it to boot
+ # Now we wait the number of seconds specified after the boot
puts "Waiting for the machine to boot"
sleep @definition.boot_wait.to_i
+ # We've waited long enough, time to send the boot_cmd sequence to the console
send_sequence(@definition.boot_cmd_sequence)
+ # Bootsequence has been send (if there was one)
+ # And now we start up the webserver for handling the kickstart and
+ # wait for the file to be fetched
handle_kickstart
+
+ # After the kickstart, we wait for ssh to become available and
+ # once we can login , we transfer some info to the vm about our environment
transfer_buildinfo_file
+ # Now we can run all the post installs scripts
handle_postinstall
+ # w00t, we have succesfully reach this point
+ # so we let user know , the vm is ready to be exported
+
puts "#{@box_name} was build succesfully. "
puts ""
puts "Now you can: "
@@ -82,4 +104,4 @@ def build(build_options={})
end #Module
end #Module
-end #Module
+end #Module
View
6 lib/veewee/builder/virtualbox/builder.rb
@@ -8,12 +8,12 @@ module Veewee
module Builder
module Virtualbox
class Builder < Veewee::Builder::Core::Builder
-
+
def list_ostypes(list_options={})
return VirtualBox::Global.global.lib.virtualbox.guest_os_types
end
-
+
end #End Class
end # End Module
end # End Module
-end # End Module
+end # End Module
View
18 lib/veewee/builder/virtualbox/helper/disk.rb
@@ -3,25 +3,25 @@ module Builder
module Virtualbox
def create_disk
- #Now check the disks
- #Maybe one day we can use the name, now we have to check location
- #disk=VirtualBox::HardDrive.find(box_name)
+ # Now check the disks
+ # Maybe one day we can use the name, now we have to check location
+ # disk=VirtualBox::HardDrive.find(box_name)
location=@box_name+"."+@definition.disk_format.downcase
- found=false
+ found=false
VirtualBox::HardDrive.all.each do |d|
if !d.location.match(/#{location}/).nil?
found=true
break
end
- end
+ end
- #Sometimes the above doesn't find a registered harddisk, but the vdi files is still there
+ # Sometimes the above doesn't find a registered harddisk, but the vdi files is still there
if File.exists?(location)
puts "#{location} file still exists but isn't registered"
puts "Let me clean up that mess for you."
FileUtils.rm(location)
end
-
+
if !found
puts "Creating new harddrive of size #{@definition.disk_size.to_i} "
@@ -42,7 +42,7 @@ def create_disk
end
def attach_disk
-
+
place=get_vm_location
location=@box_name+"."+@definition.disk_format.downcase
@@ -54,7 +54,7 @@ def attach_disk
Veewee::Util::Shell.execute("#{command}")
end
-
+
end
end
end
View
9 lib/veewee/builder/virtualbox/helper/network.rb
@@ -11,9 +11,14 @@ def add_ssh_nat_mapping
port.hostport = @definition.ssh_host_port.to_i
vm.network_adapters[0].nat_driver.forwarded_ports << port
port.save
- vm.save
+ vm.save
+ end
+
+ # The IP-address required to connect is localhost
+ # as ssh login is provider to an NAT forwarding
+ def ip_address
+ return "127.0.0.1"
end
end
end
end
-
View
2 lib/veewee/builder/virtualbox/helper/path.rb
@@ -8,7 +8,7 @@ def get_vm_location
place=shell_results.stdout.split(/\n/).grep(/Default machine/)[0].split(":")[1].strip
return place
end
-
+
end
end
end
View
24 lib/veewee/builder/virtualbox/helper/vm.rb
@@ -1,9 +1,9 @@
module Veewee
module Builder
module Virtualbox
-
+
def verify_ostype
-
+
#Verifying the os.id with the :os_type_id specified
matchfound=false
VirtualBox::Global.global.lib.virtualbox.guest_os_types.collect { |os|
@@ -15,9 +15,9 @@ def verify_ostype
puts "The ostype: #{@definition.os_type_id} is not available in your Virtualbox version"
exit
end
-
+
end
-
+
# This function creates a basic vm
def create_vm
verify_ostype
@@ -28,9 +28,9 @@ def create_vm
puts "shutting down box"
#We force it here, maybe vm.shutdown is cleaner
vm.stop
- end
+ end
- if !vm.nil?
+ if !vm.nil?
puts "Box already exists"
#vm.stop
#vm.destroy
@@ -49,7 +49,7 @@ def create_vm
vm_flags.each do |vm_flag|
if @definition.instance_variable_defined?("@#{vm_flag}")
#vm_flag_value=@definition.instance_variable_get(vm_flag.to_sym)
-
+
vm_flag_value=@definition.instance_variable_get("@#{vm_flag}")
puts "Setting VM Flag #{vm_flag} to #{vm_flag_value}"
command="#{@vboxcmd} modifyvm #{@box_name} --#{vm_flag.to_s} #{vm_flag_value}"
@@ -67,14 +67,14 @@ def create_vm
exit
end
- #Set all params we know
+ #Set all params we know
vm.memory_size=@definition.memory_size.to_i
vm.os_type_id=@definition.os_type_id
vm.cpu_count=@definition.cpu_count.to_i
vm.name=@box_name
puts "Creating vm #{vm.name} : #{vm.memory_size}M - #{vm.cpu_count} CPU - #{vm.os_type_id}"
- #setting bootorder
+ #setting bootorder
vm.boot_order[0]=:hard_disk
vm.boot_order[1]=:dvd
vm.boot_order[2]=:null
@@ -84,8 +84,8 @@ def create_vm
end
-
-
+
+
def start_vm(mode)
vm=VirtualBox::VM.find(@box_name)
vm.start(mode)
@@ -95,4 +95,4 @@ def start_vm(mode)
end
end
-
+
View
6 lib/veewee/builder/vmfusion/assemble.rb
@@ -3,13 +3,13 @@
module Veewee
module Builder
module Vmfusion
-
+
# This function 'assembles' the box based on the definition
def assemble
create_vm
create_disk
end
-
+
end
end
-end
+end
View
10 lib/veewee/builder/vmfusion/box.rb
@@ -33,21 +33,21 @@ class Box < Veewee::Builder::Core::Box
def initialize(environment,box_name,definition_name,box_options={})
super(environment,box_name,definition_name,box_options)
@vmrun_cmd=determine_vmrun_cmd
- end
+ end
# Translate the definition ssh options to ssh options that can be passed to Net::Ssh calls
def ssh_options
- ssh_options={
- :user => @definition.ssh_user,
+ ssh_options={
+ :user => @definition.ssh_user,
:port => 22,
:password => @definition.ssh_password,
:timeout => @definition.ssh_login_timeout.to_i
}
return ssh_options
end
-
+
def is_running?
shellresult=Veewee::Util::Shell.execute("#{fusion_path.shellescape}/vmrun -T ws list")
return shellresult.stdout.include?("#{vmx_file_path}")
@@ -57,4 +57,4 @@ def is_running?
end # End Class
end # End Module
end # End Module
-end # End Module
+end # End Module
View
6 lib/veewee/builder/vmfusion/build.rb
@@ -6,15 +6,15 @@ module Vmfusion
def build(build_options={})
defaults= { "force" => false, "nogui" => false }
options=defaults.merge(build_options)
-
+
if is_running?
if options["force"]==true
stop_vm
destroy
else
puts "Machine is running, we can't build it, unless you have the --force option"
end
-
+
end
#Check iso file
@@ -58,4 +58,4 @@ def build(build_options={})
end #Module
end #Module
-end #Module
+end #Module
View
12 lib/veewee/builder/vmfusion/definition.rb
@@ -0,0 +1,12 @@
+require 'veewee/builder/core/definition'
+
+module Veewee::Builder
+ module Vmfusion
+
+ class Definition < ::Veewee::Builder::Core::Definition
+ def initialize(name,env)
+ super(name,env)
+ end
+ end
+ end
+end
View
124 lib/veewee/builder/vmfusion/helper/console_type.rb
@@ -6,125 +6,17 @@
module Veewee
module Builder
module Vmfusion
- def console_type(command,type_options={})
- send_sequence(command)
- end
-
- def send_sequence(sequence)
- puts
- counter=0
- sequence.each { |s|
- counter=counter+1
-
- s.gsub!(/%IP%/,Veewee::Util::Tcp.local_ip);
- s.gsub!(/%PORT%/,@definition.kickstart_port);
- s.gsub!(/%NAME%/, @box_name);
- puts "Typing:[#{counter}]: "+s
-
- keycodes=string_to_vnccode(s)
- Net::VNC.open "localhost:20" do |vnc|
-
- keycodes.each do |keycode|
- if keycode==:wait
- sleep 1
- else
- send_keycode(vnc,keycode)
- end
- end
- end
- }
-
- puts "Done typing."
- puts
-
- end
-
- def send_keycode(vnc,keycode)
- uppercase=%w{: _ & " >}
-
- if keycode.is_a?(Symbol)
- vnc.key_press keycode
- else
- if uppercase.include?(keycode)
- vnc.key_down :shift
- vnc.key_down keycode
- vnc.key_up :shift
- else
- vnc.type keycode
- end
-
- end
-
- end
-
-
- def string_to_vnccode(thestring)
+ def console_type(sequence,type_options={})
+ sequence.each { |s|
+ s.gsub!(/%IP%/,Veewee::Util::Tcp.local_ip);
+ s.gsub!(/%PORT%/,@definition.kickstart_port);
+ s.gsub!(/%NAME%/, @box_name);
+ }
+ vnc_type(sequence,"localhost",20)
- # http://code.google.com/p/ruby-vnc/source/browse/trunk/data/keys.yaml
-
- special=Hash.new
- # Specific veewee
- special['<Wait>'] = :wait
-
- # VNC Codes
- special['<Enter>'] = :return
- special['<Return>'] = :return
- special['<Esc>'] = :escape
-
- # These still need some work!
- special['<Backspace>'] = :backspace
- special['<Spacebar>'] = ' '
- special['<Tab>'] = :tab
- # Hmm, what would the equivalent be here
- special['<KillX>'] = '1d 38 0e';
-
- special['<Up>'] = :up
- special['<Down>'] = :down
- special['<PageUp>'] = :page_up
- special['<PageDown>'] = :page_down
- special['<End>'] = :end
- special['<Insert>'] = :insert
- special['<Delete>'] = :delete
- special['<Left>'] = :left
- special['<Right>'] = :right
- special['<Home>'] = :home
-
- special['<F1>'] = :f1
- special['<F2>'] = :f2
- special['<F3>'] = :f3
- special['<F4>'] = :f4
- special['<F5>'] = :f5
- special['<F6>'] = :f6
- special['<F7>'] = :f7
- special['<F8>'] = :f8
- special['<F9>'] = :f9
- special['<F10>'] = :f10
-
- keycodes=Array.new
- thestring.gsub!(/ /,"<Spacebar>")
+ end
- until thestring.length == 0
- nospecial=true;
- special.keys.each { |key|
- if thestring.start_with?(key)
- #take thestring
- #check if it starts with a special key + pop special string
- keycodes<<special[key];
- thestring=thestring.slice(key.length,thestring.length-key.length)
- nospecial=false;
- break;
- end
- }
- if nospecial
- code = thestring.slice(0,1)
- keycodes << code
- #pop one
- thestring=thestring.slice(1,thestring.length-1)
- end
- end
- return keycodes
- end
end #Module
end #Module
View
17 lib/veewee/builder/vmfusion/helper/vm.rb
@@ -1,7 +1,7 @@
module Veewee
module Builder
module Vmfusion
-
+
def create_vm
FileUtils.mkdir_p(vm_path)
current_dir=FileUtils.pwd
@@ -10,22 +10,25 @@ def create_vm
aFile.write(vmx_template)
aFile.close
FileUtils.chdir(current_dir)
-
+
end
-
+
def start_vm(mode)
#mode can be gui or nogui
- Veewee::Util::Shell.execute("#{fusion_path.shellescape}/vmrun -T ws start '#{vmx_file_path}' #{mode}")
+ raw=::Fission::VM.new(name)
+ raw.start
end
def stop_vm()
- Veewee::Util::Shell.execute("#{fusion_path.shellescape}/vmrun -T ws stop '#{vmx_file_path}' soft")
+ raw=::Fission::VM.new(name)
+ raw.stop
end
def halt_vm()
- Veewee::Util::Shell.execute("#{fusion_path.shellescape}/vmrun -T ws stop '#{vmx_file_path}' hard")
+ raw=::Fission::VM.new(name)
+ raw.halt
end
-
+
end
end
end
View
55 lib/veewee/cli.rb
@@ -0,0 +1,55 @@
+require 'thor'
+
+module Veewee
+ # Entrypoint for the Mccloud CLI. This class should never be
+ # initialized directly (like a typical Thor class). Instead,
+ # use {Environment#cli} to invoke the CLI.
+ #
+ # # Defining Custom CLI Commands
+ #
+ # If you're looking to define custom CLI commands, then look at
+ # one of the two following classes:
+ #
+ # * {Command::Base} - Implementing a single command such as `mccloud up`, e.g.
+ # one without subcommands. Also take a look at {Command::NamedBase}.
+ # * {Command::GroupBase} - Implementing a command with subcommands, such as
+ # `mccloud box`, which has the `list`, `add`, etc. subcommands.
+ #
+ # The above linked classes contain the main documentation for each
+ # type of command.
+ class CLI < Thor
+ # Registers the given class with the CLI so it can be accessed.
+ # The class must be a subclass of either {Command::Base} or {Command::GroupBase}.
+ # Don't call this method directly, instead call the {Command::Base.register}
+ # or {Command::GroupBase.register} methods.
+ #
+ # @param [Class] klass Command class
+ # @param [String] name Command name, accessed at `mccloud NAME`
+ # @param [String] usage Command usage, such as "mccloud NAME [--option]"
+ # @param [String] description Description of the command shown during the
+ # command listing.
+ # @param [Hash] opts Other options (not gone into detail here, look at
+ # the source instead).
+ def self.register(klass, name, usage, description, opts=nil)
+ opts ||= {}
+
+ if klass <= Command::GroupBase
+ # A subclass of GroupBase is a subcommand, since it contains
+ # many smaller commands within it.
+ desc usage, description, opts
+ subcommand name, klass
+ elsif klass <= Command::Base
+ # A subclass of Base is a single command, since it
+ # is invoked as a whole (as Thor::Group)
+ desc usage, description, opts
+ define_method(name) { |*args| invoke klass, args }
+ end
+
+ if opts[:alias]
+ # Alises are defined for this command, so properly alias the
+ # newly defined method/subcommand:
+ map opts[:alias] => name
+ end
+ end
+ end
+end #Mccloud
View
11 lib/veewee/command.rb
@@ -0,0 +1,11 @@
+module Veewee
+ module Command
+ autoload :Base, 'veewee/command/base'
+ autoload :GroupBase, 'veewee/command/group_base'
+ autoload :Helpers, 'veewee/command/helpers'
+ autoload :NamedBase, 'veewee/command/named_base'
+ end
+end
+
+# The built-in commands must always be loaded
+require 'veewee/command/version'
View
106 lib/veewee/command/base.rb
@@ -0,0 +1,106 @@
+require 'thor/group'
+require 'thor/actions'
+
+module Veewee
+ module Command
+ # A {Base} is the superclass for all commands which are single
+ # commands, e.g. `veewee init`, `veewee up`. Not commands like
+ # `veewee box add`. For commands which have more subcommands, use
+ # a {GroupBase}.
+ #
+ # A {Base} is a subclass of `Thor::Group`, so view the documentation
+ # there on how to add arguments, descriptions etc. The important note
+ # about this is that when invoked, _all public methods_ will be called
+ # in the order they are defined. If you don't want a method called when
+ # the command is invoked, it must be made `protected` or `private`.
+ #
+ # The best way to get examples of how to create your own command is to
+ # view the various Veewee commands, which are relatively simple, and
+ # can be found in the Veewee source tree at `lib/veewee/command/`.
+ #
+ # # Defining a New Command
+ #
+ # To define a new single command, create a new class which inherits
+ # from this class, then call {register} to register the command. That's
+ # it! When the command is invoked, _all public methods_ will be called.
+ # Below is an example `SayHello` class:
+ #
+ # class SayHello < Veewee::Command::Base
+ # register "hello", "Says hello"
+ #
+ # def hello
+ # env.ui.info "Hello"
+ # end
+ # end
+ #
+ # In this case, the above class is invokable via `veewee hello`. To give
+ # this a try, just copy and paste the above into a Veeweefile somewhere.
+ # The command will be available for that project!
+ #
+ # Also note that the above example uses `env.ui` to output. It is recommended
+ # you use this instead of raw "puts" since it is configurable and provides
+ # additional functionality, such as colors and asking for user input. See
+ # the {UI} class for more information.
+ #
+ # ## Defining Command-line Options
+ #
+ # Most command line actions won't be as simple as `veewee hello`, and will
+ # probably require parameters or switches. Luckily, Thor makes adding these
+ # easy:
+ #
+ # class SayHello < Veewee::Command::Base
+ # register "hello", "Says hello"
+ # argument :name, :type => :string
+ #
+ # def hello
+ # env.ui.info "Hello, #{name}"
+ # end
+ # end
+ #
+ # Then, the above can be invoked with `veewee hello Mitchell` which would
+ # output "Hello, Mitchell." If instead you're looking for switches, such as
+ # "--name Mitchell", then take a look at `class_option`, an example of which
+ # can be found in the {PackageCommand}.
+ class Base < Thor::Group
+ include Thor::Actions
+ include Helpers
+
+ attr_reader :env
+
+ # Register the command with the main Veewee CLI under the
+ # given name. The name will be used for accessing it from the CLI,
+ # so if you name it "lamp", then the command to invoke this
+ # will be `veewee lamp`.
+ #
+ # The description is used when the help is listed, and is meant to be
+ # a brief (one sentence) description of what the command does.
+ #
+ # Some additional options may be passed in as the last parameter:
+ #
+ # * `:alias` - If given as an array or string, these will be aliases
+ # for the same command. For example, `veewee version` is also
+ # `veewee --version` and `veewee -v`
+ #
+ # @param [String] usage
+ # @param [String] description
+ # @param [Hash] opts
+ def self.register(usage, description, opts=nil)
+ desc description
+ ::Veewee::CLI.register(self, extract_name_from_usage(usage), usage, desc, opts)
+ end
+
+ def initialize(*args)
+ super
+ initialize_environment(*args)
+ end
+
+ protected
+
+ # Extracts the name of the command from a usage string. Example:
+ # `init [box_name] [box_url]` becomes just `init`.
+ def self.extract_name_from_usage(usage)
+ /^([-_a-zA-Z0-9]+)(\s+(.+?))?$/.match(usage).to_a[1]
+ end
+ end
+ end
+end
View
107 lib/veewee/command/group_base.rb
@@ -0,0 +1,107 @@
+require 'thor'
+require 'thor/actions'
+
+module Veewee
+ module Command
+ # A {GroupBase} is the superclass which should be used if you're
+ # creating a CLI command which has subcommands such as `veewee box`,
+ # which has subcommands such as `add`, `remove`, `list`. If you're
+ # creating a simple command which has no subcommands, such as `veewee up`,
+ # then use {Base} instead.
+ #
+ # Unlike {Base}, where all public methods are executed, in a {GroupBase},
+ # each public method defines a separate task which can be invoked. The best
+ # way to get examples of how to create a {GroupBase} command is to look
+ # at the built-in commands, such as {BoxCommand}.
+ #
+ # # Defining a New Command
+ #
+ # To define a new command with subcommands, create a new class which inherits
+ # from this class, then call {register} to register the command. That's it! When
+ # the command is invoked, the method matching the subcommand is invoked. An
+ # example is shown below:
+ #
+ # class SayCommand < Veewee::Command::GroupBase
+ # register "say", "Say hello or goodbye"
+ #
+ # desc "hello", "say hello"
+ # def hello
+ # env.ui.info "Hello"
+ # end
+ #
+ # desc "goodbye", "say goodbye"
+ # def goodbye
+ # env.ui.info "Goodbye"
+ # end
+ # end
+ #
+ # In this case, the above class is invokable via `veewee say hello` or
+ # `veewee say goodbye`. To give it a try yourself, just copy and paste
+ # the above into a Veeweefile somewhere, and run `veewee` from within
+ # that directory. You should see the new command!
+ #
+ # Also notice that in the above, each task follows a `desc` call. This
+ # call is used to provide usage and description for each task, and is
+ # required.
+ #
+ # ## Defining Command-line Options
+ #
+ # ### Arguments
+ #
+ # To define arguments to your commands, such as `veewee say hello mitchell`,
+ # then you simply define them as arguments to the method implementing the
+ # task. An example is shown below (only the method, to keep things brief):
+ #
+ # def hello(name)
+ # env.ui.info "Hello, #{name}"
+ # end
+ #
+ # Then, if `veewee say hello mitchell` was called, then the output would
+ # be "Hello, mitchell"
+ #
+ # ### Switches or Other Options
+ #
+ # TODO
+ class GroupBase < Thor
+ include Thor::Actions
+ include Helpers
+
+ attr_reader :env
+
+ # Register the command with the main Veewee CLI under the given
+ # usage. The usage will be used for accessing it from the CLI,
+ # so if you give it a usage of `lamp [subcommand]`, then the command
+ # to invoke this will be `veewee lamp` (with a subcommand).
+ #
+ # The description is used when a listing of the commands is given
+ # and is meant to be a brief (one sentence) description of what this
+ # command does.
+ #
+ # Some additional options may be passed in as the last parameter:
+ #
+ # * `:alias` - If given as an array or string, these will be aliases
+ # for the same command. For example, `veewee version` is also
+ # `veewee --version` and `veewee -v`
+ #
+ # @param [String] usage
+ # @param [String] description
+ # @param [Hash] opts
+ def self.register(usage, description, opts=nil)
+ @_name