Skip to content
Browse files

- Restructured the whole project, no real features added

- Added tests to verify part of the behavior using sysrescue CD
  • Loading branch information...
1 parent d3cb25a commit cf8d27c6a225c7fa13432d0b62759664bb994472 @jedi4ever committed Jul 17, 2011
View
4 Gemfile
@@ -3,3 +3,7 @@ source "http://rubygems.org"
gem "veewee", :path => "."
#gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
+
+group :test do
+ gem "rake"
+end
View
2 Gemfile.lock
@@ -39,6 +39,7 @@ GEM
Platform (>= 0.4.0)
open4 (>= 0.4.0)
progressbar (0.9.1)
+ rake (0.8.7)
rspec (2.5.0)
rspec-core (~> 2.5.0)
rspec-expectations (~> 2.5.0)
@@ -65,4 +66,5 @@ PLATFORMS
ruby
DEPENDENCIES
+ rake
veewee!
View
21 License
@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright (c) 2010 Patrick Debois
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
26 Rakefile
@@ -3,27 +3,17 @@ require 'bundler'
require 'bundler/setup'
Bundler::GemHelper.install_tasks
-#Setup some base variables to use
-veewee_dir= "."
-definition_dir= File.expand_path(File.join(veewee_dir, "definitions"))
-lib_dir= File.expand_path(File.join(veewee_dir, "lib"))
-box_dir= File.expand_path(File.join(veewee_dir, "boxes"))
-template_dir=File.expand_path(File.join(veewee_dir, "templates"))
-vbox_dir=File.expand_path(File.join(veewee_dir, "tmp"))
-tmp_dir=File.expand_path(File.join(veewee_dir, "tmp"))
-iso_dir=File.expand_path(File.join(veewee_dir, "iso"))
+desc 'Default: run tests'
+task :default => :test
+require 'rake/testtask'
+Bundler::GemHelper.install_tasks
-#Load Veewee::Session libraries
-Dir.glob(File.join(lib_dir, '**','*.rb')).each {|f|
- require f }
-
-#Initialize
-Veewee::Session.setenv({:veewee_dir => veewee_dir, :definition_dir => definition_dir,
- :template_dir => template_dir, :iso_dir => iso_dir, :box_dir => box_dir, :tmp_dir => tmp_dir})
-desc 'Default: list templates'
-task :default => [:templates]
+Rake::TestTask.new do |t|
+ t.libs << "test"
+ t.pattern = 'test/**/*_test.rb'
+end
desc 'List templates'
task :templates do
View
5 lib/vagrant_init.rb
@@ -1,6 +1,7 @@
begin
- require 'veewee'
+ require 'vagrant'
+ require 'veewee/vagrant/command'
rescue LoadError
require 'rubygems'
- require 'veewee'
+ require 'veewee/vagrant/command'
end
View
3 lib/veewee.rb
@@ -1,2 +1 @@
-require 'vagrant'
-require 'veewee/command'
+require 'veewee/session'
View
70 lib/veewee/definition.rb
@@ -0,0 +1,70 @@
+module Veewee
+ class Definition
+
+ def initialize(options)
+
+ defaults={
+ :cpu_count => '1',
+ :memory_size=> '256',
+ :disk_size => '10240',
+ :disk_format => 'VDI',
+ :hostiocache => 'off' ,
+ :os_type_id => 'Ubuntu',
+ :iso_file => "ubuntu-10.10-server-i386.iso", :iso_src => "",:iso_md5 => "",
+ :iso_download_timeout => 1000,
+ :boot_wait => "10", :boot_cmd_sequence => [ "boot"],
+ :kickstart_port => "7122", :kickstart_ip => "127.0.0.1", :kickstart_timeout => 10000,
+ :ssh_login_timeout => "100",: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",
+ :postinstall_files => [ "postinstall.sh"],:postinstall_timeout => 10000,
+ :floppy_files => nil,
+ :kickstart_file => nil,
+ :iso_download_instructions => nil
+ }
+
+ options=defaults.merge(options)
+
+ #we need to inject all keys as instance variables & attr_accessors
+ options.keys.each do |key|
+ instance_variable_set("@#{key.to_s}",options[key])
+ # http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/41730
+ #type.__send__(:attr_accessor,key)
+ self.class.send(:attr_accessor,key)
+ end
+
+ end
+
+ def self.load(name,definition_dir)
+ if self.definition_exists?(name,definition_dir)
+ definition_file=File.join(definition_dir,name,"definition.rb")
+ begin
+ require definition_file
+ rescue LoadError
+ puts "Error loading definition of #{name}"
+ exit
+ end
+ else
+ puts "Error: definition for basebox '#{name}' does not exist."
+ exit
+ end
+ return Veewee::Definition.new(Veewee::Session.get_loaded_definition)
+ end
+
+
+ private
+ def self.definition_exists?(name,definition_dir)
+ if File.directory?(File.join(definition_dir,name))
+ if File.exists?(File.join(definition_dir,name,'definition.rb'))
+ return true
+ else
+ return false
+ end
+ else
+ return false
+ end
+ end
+
+ end #End Class
+end #End Module
View
81 lib/veewee/export.rb
@@ -1,81 +0,0 @@
-require 'pathname'
-module Veewee
- class Export
-
-# Shellutil.execute("vagrant package --base #{vmname} --include /tmp/Vagrantfile --output /tmp/#{vmname}.box", {:progress => "on"})
-
- def self.vagrant(boxname,boxdir,definition)
-
- #Check if box already exists
- vm=VirtualBox::VM.find(boxname)
- if vm.nil?
- puts "#{boxname} is not found, maybe you need to build first?"
- exit
- end
- #We need to shutdown first
- if vm.running?
- puts "Vagrant requires the box to be shutdown, before it can export"
- puts "Sudo also needs to work for user #{definition[:ssh_user]}"
- puts "Performing a clean shutdown now."
- ssh_options={ :user => definition[:ssh_user], :port => definition[:ssh_host_port], :password => definition[:ssh_password],
- :timeout => definition[:ssh_timeout]}
-
- Veewee::Ssh.execute("localhost","sudo #{definition[:shutdown_cmd]}",ssh_options)
-
- #Wait for state poweroff
- while (vm.running?) do
- print '.'
- sleep 1
- end
- puts
- puts "Machine #{boxname} is powered off cleanly"
- end
-
- #Vagrant requires a relative path for output of boxes
-
- #4.0.x. not using boxes as a subdir
- boxdir=Pathname.new(Dir.pwd)
-
- full_path=File.join(boxdir,boxname+".box")
- path1=Pathname.new(full_path)
- path2=Pathname.new(Dir.pwd)
- box_path=path1.relative_path_from(path2).to_s
-
- if File.exists?("#{box_path}")
- puts "box #{boxname}.box already exists"
- exit
- end
-
- puts "Excuting vagrant voodoo:"
- export_command="vagrant package --base '#{boxname}' --output '#{box_path}'"
- puts "#{export_command}"
- Veewee::Shell.execute("#{export_command}") #hmm, needs to get the gem_home set?
- puts
-
- #add_ssh_nat_mapping back!!!!
-
- puts "To import it into vagrant type:"
- puts "vagrant box add '#{boxname}' '#{box_path}'"
- puts ""
- puts "To use it:"
- puts "vagrant init '#{boxname}'"
- puts "vagrant up"
- puts "vagrant ssh"
- end
-
- end
-end
-
-
-# #currently vagrant has a problem with the machine up, it calculates the wrong port to ssh to poweroff the system
-# thebox.execute("shutdown -h now")
-# thebox.wait_for_state("poweroff")
-
-# Shellutil.execute("echo 'Vagrant::Config.run do |config|' > /tmp/Vagrantfile")
-# Shellutil.execute("echo ' config.ssh.forwarded_port_key = \"ssh\"' >> /tmp/Vagrantfile")
-# Shellutil.execute("echo ' config.vm.forward_port(\"ssh\",22,#{host_port})' >> /tmp/Vagrantfile")
-# Shellutil.execute("echo 'end' >> /tmp/Vagrantfile")
-
-
-#vagrant export disables the machine
-# thebox.ssh_enable_vmachine({:hostport => host_port , :guestport => 22} )
View
82 lib/veewee/provider/core/iso.rb
@@ -0,0 +1,82 @@
+module Veewee
+ module Provider
+ module Core
+
+ require 'open-uri'
+ require 'progressbar'
+ require 'highline/import'
+ require 'digest/md5'
+
+ #TODO move to veewee definition?
+
+ def download_progress(url,localfile)
+ pbar = nil
+ URI.parse(url).open(
+ :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)
+ }
+ }
+
+ 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
+
+ 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
+
+ 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
+
+ end
+ end #Module
+ end #Module
+ end #Module
View
25 lib/veewee/provider/core/transaction.rb
@@ -0,0 +1,25 @@
+module Veewee
+ 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])
+ else
+ if snapshot_version_exists(@vmname,name)
+ rollback_snapshot(@vmname,name)
+ #rollback to snapshot prior to this one
+ end
+ yield
+ create_snapshot_vmachine(@vmname,name+"-"+options[:checksum])
+ end
+ #end
+ end
+
+
+end
+end
+
+
View
55 lib/veewee/provider/virtualbox.rb
@@ -0,0 +1,55 @@
+require 'veewee/provider/virtualbox/build'
+require 'veewee/provider/virtualbox/destroy'
+require 'veewee/provider/core/iso'
+require 'virtualbox'
+
+module Veewee
+ class Virtualbox
+ include Veewee::Provider::Core
+ include Veewee::Provider::Virtualbox
+
+ def initialize(boxname,definition,environment)
+ @vboxcmd=determine_vboxcmd
+ @definition=definition
+ @boxname=boxname
+ @environment=environment
+ end
+
+ def determine_vboxcmd
+ return "VBoxManage"
+ end
+
+ def suppress_messages
+ #Setting this annoying messages to register
+ VirtualBox::ExtraData.global["GUI/RegistrationData"]="triesLeft=0"
+ VirtualBox::ExtraData.global["GUI/UpdateDate"]="1 d, 2009-09-20"
+ VirtualBox::ExtraData.global["GUI/SuppressMessages"]="confirmInputCapture,remindAboutAutoCapture,remindAboutMouseIntegrationOff"
+ VirtualBox::ExtraData.global["GUI/UpdateCheckCount"]="60"
+ update_date=Time.now+86400
+ VirtualBox::ExtraData.global["GUI/UpdateDate"]="1 d, #{update_date.year}-#{update_date.month}-#{update_date.day}, stable"
+ VirtualBox::ExtraData.global.save
+ end
+
+ def add_ssh_nat_mapping
+ vm=VirtualBox::VM.find(@boxname)
+ #Map SSH Ports
+ # command => "${vboxcmd} modifyvm '${vname}' --natpf1 'guestssh,tcp,,${hostsshport},,${guestsshport}'",
+ port = VirtualBox::NATForwardedPort.new
+ port.name = "guestssh"
+ port.guestport = @definition.ssh_guest_port.to_i
+ port.hostport = @definition.ssh_host_port.to_i
+ vm.network_adapters[0].nat_driver.forwarded_ports << port
+ port.save
+ vm.save
+ end
+
+ def self.list_ostypes
+ puts
+ puts "Available os types:"
+ VirtualBox::Global.global.lib.virtualbox.guest_os_types.collect { |os|
+ puts "#{os.id}: #{os.description}"
+ }
+ end
+
+ end
+end
View
194 lib/veewee/provider/virtualbox/build.rb
@@ -0,0 +1,194 @@
+require 'veewee/util/shell'
+require 'veewee/util/tcp'
+require 'veewee/util/web'
+require 'veewee/util/ssh'
+
+require 'veewee/provider/virtualbox/util/create'
+require 'veewee/provider/virtualbox/util/snapshots'
+require 'veewee/provider/virtualbox/util/transaction'
+require 'veewee/provider/virtualbox/util/scancode'
+
+module Veewee
+ module Provider
+ module Virtualbox
+
+ def build
+ options={}
+ options = { "force" => true, "format" => "vagrant", "nogui" => false }.merge(options)
+
+ #Command to execute locally
+
+ ssh_options={
+ :user => @definition.ssh_user,
+ :port => @definition.ssh_host_port,
+ :password => @definition.ssh_password,
+ :timeout => @definition.ssh_login_timeout.to_i
+ }
+
+ #Suppress those annoying virtualbox messages
+ suppress_messages
+
+ #Check iso file
+ verify_iso(@definition.iso_file)
+
+
+ vm=VirtualBox::VM.find(@boxname)
+
+ # 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 #{@boxname}"
+ #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"
+ exit
+ end
+ sleep 3
+ end
+
+
+ if (options["force"]==false)
+ puts "The box is already there, we can't destroy it"
+ else
+ puts "Forcing build by destroying #{@boxname} machine"
+ destroy_vm
+ end
+
+ 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
+
+
+ #checksums=calculate_checksums(@definition,boxname)
+ checksums=[ "XXX"]
+ transaction("0-initial-#{checksums[0]}",checksums) do
+
+ #Create the Virtualmachine and set all the memory and other stuff
+ create_vm
+ add_shared_folder
+
+ #Create a disk with the same name as the boxname
+ create_disk
+
+ #These command actually call the commandline of Virtualbox, I hope to use the virtualbox-ruby library in the future
+ add_ide_controller
+ add_sata_controller
+ attach_disk
+ mount_isofile
+ add_ssh_nat_mapping
+ create_floppy
+
+ #Starting machine
+
+ if (options["nogui"]==true)
+ start_vm("vrdp")
+ else
+ start_vm("gui")
+ end
+
+ #waiting for it to boot
+ puts "Waiting for the machine to boot"
+ sleep @definition.boot_wait.to_i
+
+ send_sequence(@definition.boot_cmd_sequence)
+
+ kickstartfile=@definition.kickstart_file
+ if kickstartfile.nil? || kickstartfile.length == 0
+ puts "Skipping webserver as no kickstartfile was specified"
+ else
+ 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 kickstartfile.is_a? String
+ Veewee::Util::Web.wait_for_request(kickstartfile,{:port => @definition.kickstart_port,
+ :host => @definition.kickstart_ip, :timeout => @definition.kickstart_timeout,
+ :web_dir => File.join(@environment.definition_dir,@boxname)})
+ end
+ if kickstartfile.is_a? Array
+ kickstartfiles=kickstartfile
+ kickstartfiles.each do |kickfile|
+ Veewee::Util::Web.wait_for_request(kickfile,{:port => @definition.kickstart_port,
+ :host => @definition.kickstart_ip, :timeout => @definition.kickstart_timeout,
+ :web_dir => File.join(@environment.definition_dir,@boxname)})
+ end
+ end
+ end
+
+
+
+
+ Veewee::Util::Ssh.when_ssh_login_works("localhost",ssh_options) do
+ #Transfer version of Virtualbox to $HOME/.vbox_version
+ versionfile=Tempfile.open("vbox.version")
+ versionfile.puts "#{VirtualBox::Global.global.lib.virtualbox.version.split('_')[0]}"
+ versionfile.rewind
+ begin
+ Veewee::Util::Ssh.transfer_file("localhost",versionfile.path,".vbox_version", ssh_options)
+ rescue RuntimeError
+ puts "error transfering file, possible not enough permissions to write?"
+ exit
+ end
+ puts ""
+ versionfile.close
+ versionfile.delete
+ end
+ return
+ exit #DEBUGGING
+
+ end #initial Transaction
+
+
+
+ counter=1
+ @definition[:postinstall_files].each do |postinstall_file|
+
+ filename=File.join(environment.definition_dir,boxname,postinstall_file)
+
+ transaction(boxname,"#{counter}-#{postinstall_file}-#{checksums[counter]}",checksums) do
+
+ Veewee::Ssh.when_ssh_login_works("localhost",ssh_options) do
+ begin
+ Veewee::Ssh.transfer_file("localhost",filename,File.basename(filename),ssh_options)
+ rescue RuntimeError
+ puts "error transfering file, possible not enough permissions to write?"
+ exit
+ end
+ command=@definition[:sudo_cmd]
+ newcommand=command.gsub(/%p/,"#{definition[:ssh_password]}")
+ newcommand.gsub!(/%u/,"#{definition[:ssh_user]}")
+ newcommand.gsub!(/%f/,"#{postinstall_file}")
+ puts "***#{newcommand}"
+ Veewee::Ssh.execute("localhost","#{newcommand}",ssh_options)
+ end
+
+ end
+ counter+=1
+
+ end
+
+ puts "#{boxname} was build succesfully. "
+ puts ""
+ puts "Now you can: "
+ puts "- verify your box by running : vagrant basebox validate #{boxname}"
+ puts "- export your vm to a .box fileby running : vagrant basebox export #{boxname}"
+
+ end
+
+ def start_vm(mode)
+ vm=VirtualBox::VM.find(@boxname)
+ vm.start(mode)
+ end
+
+ end #Module
+ end #Module
+ end #Module
View
72 lib/veewee/provider/virtualbox/destroy.rb
@@ -0,0 +1,72 @@
+module Veewee
+ module Provider
+ module Virtualbox
+
+ def destroy_vm
+
+ #:destroy_medium => :delete, will delete machine + all media attachments
+ #vm.destroy(:destroy_medium => :delete)
+ ##vm.destroy(:destroy_image => true)
+
+ #VBoxManage unregistervm "test-machine" --delete
+ #because the destroy does remove the .vbox file on 4.0.x
+ #PDB
+ #vm.destroy()
+
+ vm=VirtualBox::VM.find(@boxname)
+
+ if (!vm.nil? && !(vm.powered_off?))
+ puts "Shutting down vm #{@boxname}"
+ #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"
+ exit
+ end
+ sleep 3
+ end
+
+ command="#{@vboxcmd} unregistervm '#{@boxname}' --delete"
+ puts command
+ puts "Deleting vm #{@boxname}"
+
+ #Exec and system stop the execution here
+ Veewee::Util::Shell.execute("#{command}")
+ sleep 1
+
+ #if the disk was not attached when the machine was destroyed we also need to delete the disk
+ location=@boxname+"."+@definition.disk_format.downcase
+ found=false
+ VirtualBox::HardDrive.all.each do |d|
+ if d.location.match(/#{location}/)
+
+ if File.exists?(d.location)
+ command="#{@vboxcmd} closemedium disk '#{d.location}' --delete"
+ else
+ command="#{@vboxcmd} closemedium disk '#{d.location}'"
+ end
+
+ #command="#{@vboxcmd} closemedium disk '#{d.location}' --delete"
+ puts "Deleting disk #{d.location}"
+ puts "#{command}"
+
+ Veewee::Util::Shell.execute("#{command}")
+
+ if File.exists?(d.location)
+ puts "We tried to delete the disk file via virtualbox '#{d.location} but failed"
+ puts "Removing it manually"
+ FileUtils.rm(d.location)
+ exit
+ end
+ #v.3
+ #d.destroy(true)
+ break
+ end
+ end
+ end
+
+ end #Module
+ end #Module
+end #Module
View
86 lib/veewee/provider/virtualbox/export_vagrant.rb
@@ -0,0 +1,86 @@
+require 'pathname'
+module Veewee
+ module Provider
+ module Virtualbox
+
+ # Shellutil.execute("vagrant package --base #{vmname} --include /tmp/Vagrantfile --output /tmp/#{vmname}.box", {:progress => "on"})
+
+ def export_vagrant
+
+ #Check if box already exists
+ vm=VirtualBox::VM.find(@boxname)
+ if vm.nil?
+ puts "#{@boxname} is not found, maybe you need to build first?"
+ exit
+ end
+ #We need to shutdown first
+ if vm.running?
+ puts "Vagrant requires the box to be shutdown, before it can export"
+ puts "Sudo also needs to work for user #{definition[:ssh_user]}"
+ puts "Performing a clean shutdown now."
+ ssh_options={ :user => definition[:ssh_user], :port => definition[:ssh_host_port], :password => definition[:ssh_password],
+ :timeout => definition[:ssh_timeout]}
+
+ Veewee::Ssh.execute("localhost","sudo #{definition[:shutdown_cmd]}",ssh_options)
+
+ #Wait for state poweroff
+ while (vm.running?) do
+ print '.'
+ sleep 1
+ end
+ puts
+ puts "Machine #{@boxname} is powered off cleanly"
+ end
+
+ #Vagrant requires a relative path for output of boxes
+
+ #4.0.x. not using boxes as a subdir
+ boxdir=Pathname.new(Dir.pwd)
+
+ full_path=File.join(boxdir,@boxname+".box")
+ path1=Pathname.new(full_path)
+ path2=Pathname.new(Dir.pwd)
+ box_path=path1.relative_path_from(path2).to_s
+
+ if File.exists?("#{box_path}")
+ puts "box #{boxname}.box already exists"
+ exit
+ end
+
+ puts "Excuting vagrant voodoo:"
+ export_command="vagrant package --base '#{@boxname}' --output '#{box_path}'"
+ puts "#{export_command}"
+ Veewee::Shell.execute("#{export_command}") #hmm, needs to get the gem_home set?
+ puts
+
+ #add_ssh_nat_mapping back!!!!
+ #vagrant removes the mapping
+ #we need to restore it in order to be able to login again
+ add_ssh_nat_mapping(boxname)
+
+ puts "To import it into vagrant type:"
+ puts "vagrant box add '#{@boxname}' '#{box_path}'"
+ puts ""
+ puts "To use it:"
+ puts "vagrant init '#{@boxname}'"
+ puts "vagrant up"
+ puts "vagrant ssh"
+ end
+
+ end #Module
+ end #Module
+ end #Module
+
+
+ # #currently vagrant has a problem with the machine up, it calculates the wrong port to ssh to poweroff the system
+ # thebox.execute("shutdown -h now")
+ # thebox.wait_for_state("poweroff")
+
+ # Shellutil.execute("echo 'Vagrant::Config.run do |config|' > /tmp/Vagrantfile")
+ # Shellutil.execute("echo ' config.ssh.forwarded_port_key = \"ssh\"' >> /tmp/Vagrantfile")
+ # Shellutil.execute("echo ' config.vm.forward_port(\"ssh\",22,#{host_port})' >> /tmp/Vagrantfile")
+ # Shellutil.execute("echo 'end' >> /tmp/Vagrantfile")
+
+
+ #vagrant export disables the machine
+ # thebox.ssh_enable_vmachine({:hostport => host_port , :guestport => 22} )
View
200 lib/veewee/provider/virtualbox/util/create.rb
@@ -0,0 +1,200 @@
+require 'tempfile'
+
+module Veewee
+ module Provider
+ module Virtualbox
+
+ def create_vm
+
+ #Verifying the os.id with the :os_type_id specified
+ matchfound=false
+ VirtualBox::Global.global.lib.virtualbox.guest_os_types.collect { |os|
+ if @definition.os_type_id == os.id
+ matchfound=true
+ end
+ }
+ unless matchfound
+ puts "The ostype: #{@definition.os_type_id} is not available in your Virtualbox version"
+ exit
+ end
+
+ vm=VirtualBox::VM.find(@boxname)
+
+ if (!vm.nil? && !(vm.powered_off?))
+ puts "shutting down box"
+ #We force it here, maybe vm.shutdown is cleaner
+ vm.stop
+ end
+
+ if !vm.nil?
+ puts "Box already exists"
+ #vm.stop
+ #vm.destroy
+ else
+ #TODO One day ruby-virtualbox will be able to handle this creation
+ #Box does not exist, we can start to create it
+
+ command="#{@vboxcmd} createvm --name '#{@boxname}' --ostype '#{@definition.os_type_id}' --register"
+
+ #Exec and system stop the execution here
+ Veewee::Util::Shell.execute("#{command}")
+
+ # Modify the vm to enable or disable hw virtualization extensions
+ vm_flags=%w{pagefusion acpi ioapic pae hpet hwvirtex hwvirtexcl nestedpaging largepages vtxvpid synthxcpu rtcuseutc}
+
+ vm_flags.each do |vm_flag|
+ if @definition.instance_variable_defined?("@#{vm_flag}")
+ vm_flag_value=@definition.instance_variable_get(vm_flag.to_sym)
+ puts "Setting VM Flag #{vm_flag} to #{vm_flag_value}"
+ command="#{@vboxcmd} modifyvm #{@boxname} --#{vm_flag.to_s} #{vm_flag_value}"
+ Veewee::Shell.execute("#{command}")
+ end
+ end
+
+
+ end
+
+ vm=VirtualBox::VM.find(@boxname)
+ if vm.nil?
+ puts "we tried to create a box or a box was here before"
+ puts "but now it's gone"
+ exit
+ end
+
+ #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=@boxname
+
+ puts "Creating vm #{vm.name} : #{vm.memory_size}M - #{vm.cpu_count} CPU - #{vm.os_type_id}"
+ #setting bootorder
+ vm.boot_order[0]=:hard_disk
+ vm.boot_order[1]=:dvd
+ vm.boot_order[2]=:null
+ vm.boot_order[3]=:null
+ vm.validate
+ vm.save
+
+ end
+
+
+ def add_shared_folder
+
+ command="#{@vboxcmd} sharedfolder add '#{@boxname}' --name 'veewee-validation' --hostpath '#{File.expand_path(@environment.validation_dir)}' --automount"
+ Veewee::Util::Shell.execute("#{command}")
+
+ end
+
+ def create_floppy
+ # Todo Check for java
+ # Todo check output of commands
+
+ # Check for floppy
+ unless @definition.floppy_files.nil?
+ require 'tmpdir'
+ temp_dir=Dir.tmpdir
+ @definition.floppy_files.each do |filename|
+ full_filename=full_filename=File.join(@environment.definition_dir,@boxname,filename)
+ FileUtils.cp("#{full_filename}","#{temp_dir}")
+ end
+ javacode_dir=File.expand_path(File.join(__FILE__,'..','..','java'))
+ floppy_file=File.join(@environment.definition_dir,@boxname,"virtualfloppy.vfd")
+ command="java -jar #{javacode_dir}/dir2floppy.jar '#{temp_dir}' '#{floppy_file}'"
+ puts "#{command}"
+ Veewee::Util::Shell.execute("#{command}")
+
+ # Create floppy controller
+ command="#{@vboxcmd} storagectl '#{@boxname}' --name 'Floppy Controller' --add floppy"
+ puts "#{command}"
+ Veewee::Util::Shell.execute("#{command}")
+
+ # Attach floppy to machine (the vfd extension is crucial to detect msdos type floppy)
+ command="#{@vboxcmd} storageattach '#{@boxname}' --storagectl 'Floppy Controller' --port 0 --device 0 --type fdd --medium '#{floppy_file}'"
+ puts "#{command}"
+ Veewee::Util::Shell.execute("#{command}")
+
+ end
+ end
+
+ 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(boxname)
+ location=@boxname+"."+@definition.disk_format.downcase
+
+ found=false
+ VirtualBox::HardDrive.all.each do |d|
+ if !d.location.match(/#{location}/).nil?
+ found=true
+ break
+ end
+ end
+
+ if !found
+ puts "Creating new harddrive of size #{@definition.disk_size.to_i} "
+
+ #newdisk=VirtualBox::HardDrive.new
+ #newdisk.format=@definition[:disk_format]
+ #newdisk.logical_size=@definition[:disk_size].to_i
+
+ #newdisk.location=location
+ ##PDB: again problems with the virtualbox GEM
+ ##VirtualBox::Global.global.max_vdi_size=1000000
+ #newdisk.save
+
+ command="#{@vboxcmd} list systemproperties|grep '^Default machine'|cut -d ':' -f 2|sed -e 's/^[ ]*//'"
+ results=IO.popen("#{command}")
+ place=results.gets.chop
+ results.close
+
+ command ="#{@vboxcmd} createhd --filename '#{place}/#{@boxname}/#{@boxname}.#{@definition.disk_format.downcase}' --size '#{@definition.disk_size.to_i}' --format #{@definition.disk_format.downcase} > /dev/null"
+ puts "#{command}"
+ Veewee::Util::Shell.execute("#{command}")
+
+ end
+
+ end
+
+ def add_ide_controller
+ #unless => "${vboxcmd} showvminfo '${vname}' | grep 'IDE Controller' "
+ command ="#{@vboxcmd} storagectl '#{@boxname}' --name 'IDE Controller' --add ide"
+ Veewee::Util::Shell.execute("#{command}")
+ end
+
+ def add_sata_controller
+ #unless => "${vboxcmd} showvminfo '${vname}' | grep 'SATA Controller' ";
+ command ="#{@vboxcmd} storagectl '#{@boxname}' --name 'SATA Controller' --add sata --hostiocache #{@definition.hostiocache}"
+ Veewee::Util::Shell.execute("#{command}")
+ end
+
+
+ def attach_disk
+ location=@boxname+"."+@definition.disk_format.downcase
+
+ command="#{@vboxcmd} list systemproperties|grep '^Default machine'|cut -d ':' -f 2|sed -e 's/^[ ]*//'"
+ results=IO.popen("#{command}")
+ place=results.gets.chop
+ results.close
+
+ location="#{place}/#{@boxname}/"+location
+ puts "Attaching disk: #{location}"
+
+ #command => "${vboxcmd} storageattach '${vname}' --storagectl 'SATA Controller' --port 0 --device 0 --type hdd --medium '${vname}.vdi'",
+ command ="#{@vboxcmd} storageattach '#{@boxname}' --storagectl 'SATA Controller' --port 0 --device 0 --type hdd --medium '#{location}'"
+ Veewee::Util::Shell.execute("#{command}")
+
+ end
+
+ def mount_isofile
+ full_iso_file=File.join(@environment.iso_dir,@definition.iso_file)
+ puts "Mounting cdrom: #{full_iso_file}"
+ #command => "${vboxcmd} storageattach '${vname}' --storagectl 'IDE Controller' --type dvddrive --port 1 --device 0 --medium '${isodst}' ";
+ command ="#{@vboxcmd} storageattach '#{@boxname}' --storagectl 'IDE Controller' --type dvddrive --port 1 --device 0 --medium '#{full_iso_file}'"
+ Veewee::Util::Shell.execute("#{command}")
+ end
+
+
+ end #End Module
+ end #End Module
+end #End Module
View
51 lib/veewee/provider/virtualbox/util/scancode.rb
@@ -0,0 +1,51 @@
+require 'veewee/util/scancode'
+require 'veewee/util/tcp'
+
+module Veewee
+ module Provider
+ module Virtualbox
+
+ 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%/, @boxname);
+ puts "Typing:[#{counter}]: "+s
+
+ keycodes=Veewee::Util::Scancode.string_to_keycode(s)
+
+ # VBox seems to have issues with sending the scancodes as one big
+ # .join()-ed string. It seems to get them out or order or ignore some.
+ # A workaround is to send the scancodes one-by-one.
+ codes=""
+ for keycode in keycodes.split(' ') do
+ unless keycode=="wait"
+ send_keycode(keycode)
+ sleep 0.01
+ else
+ sleep 1
+ end
+ end
+ #sleep after each sequence (needs to be param)
+ sleep 1
+ }
+
+ puts "Done typing."
+ puts
+
+ end
+
+ def send_keycode(keycode)
+ command= "#{@vboxcmd} controlvm '#{@boxname}' keyboardputscancode #{keycode}"
+ #puts "#{command}"
+ IO.popen("#{command}") { |f| print '' }
+ end
+
+ end #Module
+ end #Module
+end #Module
+
View
103 lib/veewee/provider/virtualbox/util/snapshots.rb
@@ -0,0 +1,103 @@
+require 'veewee/util/shell'
+require 'veewee/util/tcp'
+
+module Veewee
+ module Provider
+ module Virtualbox
+
+ def remove_snapshot_vmachine(vmname,snapname)
+ Veewee::Shell.execute("#{@vboxcmd} snapshot '#{vmname}' delete '#{snapname}'")
+ end
+
+ def create_snapshot_vmachine(vmname,snapname)
+ Veewee::Shell.execute("#{@vboxcmd} snapshot '#{vmname}' take '#{snapname}'")
+ end
+
+ def load_snapshot_vmachine(vmname,snapname)
+ #if it running , shutdown first
+ if (state_vmachine(vmname)=="running")
+ stop_vmachine(vmname)
+ end
+
+ Veewee::Shell.execute("#{@vboxcmd} snapshot '#{vmname}' restore '#{snapname}'")
+ #sometimes it takes some time to shutdown
+ sleep 2
+ Veewee::Shell.execute("#{@vboxcmd} startvm '#{vmname}'")
+ end
+
+ def snapshot_exists(vmname,snapname)
+ list_snapshots(vmname).each { |name|
+ if (name==snapname) then
+ return true
+ end
+ }
+ return false
+ end
+
+ def snapshot_version_exists(vmname,snapname)
+ list_snapshots(vmname).each { |name|
+ if name.match(/^#{snapname}-/) then
+ return true
+ end
+ }
+ return false
+ end
+
+ def self.rollback_snapshot(vmname,snapname)
+ delete_flag=false
+ @vboxcmd=Veewee::Session.determine_vboxcmd
+
+ savestate_recover=false
+ if (state_vmachine(vmname)=="running")
+ Veewee::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' savestate")
+ savestate_recover=true
+ end
+
+ list_snapshots(vmname).each { |name|
+ if name.match(/^#{snapname}-/) then
+ delete_flag=true
+ end
+ if (delete_flag) then
+ remove_snapshot_vmachine(vmname,name)
+ sleep 1
+ end
+ }
+
+
+ sleep 2
+
+ Veewee::Shell.execute("#{@vboxcmd} startvm '#{vmname}'")
+
+ if (savestate_recover)
+ #Recovering from savestate nukes the network! This trick seem to work
+ #Also within the vm /etc/init.d/networking restart , but that is OS specific
+ #http://www.virtualbox.org/ticket/5666
+ #http://www.virtualbox.org/ticket/5654
+ #This is supposed to be fixed: http://www.virtualbox.org/changeset/25205 but alas
+ Veewee::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' nic1 nat")
+ Veewee::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' setlinkstate1 off")
+ Veewee::Shell.execute("#{@vboxcmd} controlvm '#{vmname}' setlinkstate1 on")
+ sleep 2
+
+ #hmmm, virtualbox => when recovering from a restore , it looses the nat settings!!! So we need to do this again!!
+ #thebox.ssh_enable_vmachine({:hostport => host_port , :guestport => 22} )
+ #http://www.virtualbox.org/changeset/25402
+ #[25402]: NAT: re-establish port-forwarding after savestate / restore state
+
+ end
+
+ end
+
+
+ def self.list_snapshots(vmname)
+ @vboxcmd=Veewee::Session.determine_vboxcmd
+
+ snapshotresult=Veewee::Shell.execute("#{@vboxcmd} showvminfo --machinereadable '#{vmname}' |grep ^SnapshotName| cut -d '=' -f 2").stdout
+ snapshotlist=snapshotresult.gsub(/\"/,'').split(/\n/)
+ return snapshotlist
+ end
+
+ end #Module
+ end #Module
+end #Module
+
View
133 lib/veewee/provider/virtualbox/util/transaction.rb
@@ -0,0 +1,133 @@
+require 'veewee/util/shell'
+require 'veewee/util/tcp'
+
+module Veewee
+ module Provider
+ module Virtualbox
+
+ def transaction(step_name,checksums,&block)
+
+ current_step_nr=step_name.split("-")[0].to_i
+
+ vm=VirtualBox::VM.find(@boxname)
+ snapnames=Array.new
+
+ #If vm exists , look for snapshots
+ if !vm.nil?
+ start_snapshot=vm.root_snapshot
+ snapshot=start_snapshot
+ counter=0
+
+ while (snapshot!=nil)
+ #puts "#{counter}:#{snapshot.name}"
+ snapnames[counter]=snapshot.name
+ counter=counter+1
+ snapshot=snapshot.children[0]
+ end
+ end
+
+ #find the last snapshot matching the state
+ counter=[snapnames.length, checksums.length].min-1
+ last_good_state=counter
+ for c in 0..counter do
+ #puts "#{c}- #{snapnames[c]} - #{checksums[c]}"
+ if !snapnames[c].match("#{c}.*-#{checksums[c]}")
+ # puts "we found a bad state"
+ last_good_state=c-1
+ break
+ end
+ end
+ #puts "Last good state: #{last_good_state}"
+
+ if (current_step_nr < last_good_state)
+ #puts "fast forwarding #{step_name}"
+ return
+ end
+
+ #puts "Current step: #{current_step_nr}"
+ if (current_step_nr == last_good_state)
+ if vm.running?
+ vm.stop
+ end
+
+ #invalidate later snapshots
+ #puts "remove old snapshots"
+
+ for s in (last_good_state+1)..(snapnames.length-1)
+ puts "Removing step [#{s}] snapshot as it is no more valid"
+ snapshot=vm.find_snapshot(snapnames[s])
+ snapshot.destroy
+ #puts snapshot
+ end
+
+ vm.reload
+ puts "Loading step #{current_step_nr} snapshots as it has not changed"
+ sleep 2
+ goodsnap=vm.find_snapshot(snapnames[last_good_state])
+ goodsnap.restore
+ sleep 2
+ #TODO:Restore snapshot!!!
+ vm.start
+ sleep 4
+ puts "Starting machine"
+ end
+
+ #puts "last good state #{last_good_state}"
+
+
+ if (current_step_nr > last_good_state)
+
+ if (last_good_state==-1)
+ #no initial snapshot is found, clean machine!
+ vm=VirtualBox::VM.find(@boxname)
+
+ if !vm.nil?
+ if vm.running?
+ puts "Stopping machine"
+ vm.stop
+ while vm.running?
+ sleep 1
+ end
+ end
+
+ #detaching cdroms (used to work in 3.x)
+ # vm.medium_attachments.each do |m|
+ # if m.type==:dvd
+ # #puts "Detaching dvd"
+ # m.detach
+ # end
+ # end
+
+ vm.reload
+ puts "We found no good state so we are destroying the previous machine+disks"
+ destroy_vm
+ end
+
+ end
+
+ #puts "(re-)executing step #{step_name}"
+
+
+ yield
+
+ #Need to look it up again because if it was an initial load
+ vm=VirtualBox::VM.find(@boxname)
+ puts "Step [#{current_step_nr}] was succesfully - saving state"
+ vm.save_state
+ sleep 2 #waiting for it to be ok
+ #puts "about to snapshot #{vm}"
+ #take snapshot after succesful execution
+ vm.take_snapshot(step_name,"snapshot taken by veewee")
+ sleep 2 #waiting for it to be started again
+ vm.start
+ end
+
+ #pp snapnames
+ end
+
+ def transaction(step_name,checksums,&block)
+ yield
+ end
+ end #Module
+ end #Module
+end #Module
View
151 lib/veewee/scancode.rb
@@ -1,151 +0,0 @@
-module Veewee
- class Scancode
-
- def self.send_sequence(vboxcmd,vname,sequence,webport)
- puts
- counter=0
- sequence.each { |s|
- counter=counter+1
-
- s.gsub!(/%IP%/,Veewee::Session.local_ip);
- s.gsub!(/%PORT%/,webport);
- s.gsub!(/%NAME%/, vname);
- puts "Typing:[#{counter}]: "+s
-
- keycodes=string_to_keycode(s)
-
- # VBox seems to have issues with sending the scancodes as one big
- # .join()-ed string. It seems to get them out or order or ignore some.
- # A workaround is to send the scancodes one-by-one.
- codes=""
- for keycode in keycodes.split(' ') do
-
- unless keycode=="wait"
- send_keycode(vboxcmd,vname,keycode)
- sleep 0.01
- else
- sleep 1
- end
- end
- #sleep after each sequence (needs to be param)
- sleep 1
- }
-
- puts "Done typing."
- puts
-
- end
-
- def self.send_keycode(vboxcmd,vname,keycode)
- command= "#{vboxcmd} controlvm '#{vname}' keyboardputscancode #{keycode}"
- #puts "#{command}"
- IO.popen("#{command}") { |f| print '' }
- end
-
- def self.string_to_keycode(thestring)
-
- #http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
-
- k=Hash.new
- k['1'] = '02 82' ; k['2'] = '03 83' ; k['3'] = '04 84'; k['4']= '05 85' ;
- k['5']='06 86'; k['6'] = '07 87' ; k['7'] = '08 88'; k['8'] = '09 89'; k['9']= '0a 8a';
- k['0']='0b 8b'; k['-'] = '0c 8c'; k['='] = '0d 8d' ;
- k['Tab'] = '0f 8f';
- k['q'] = '10 90' ; k['w'] = '11 91' ; k['e'] = '12 92';
- k['r'] = '13 93' ; k['t'] = '14 94' ; k['y'] = '15 95';
- k['u']= '16 96' ; k['i']='17 97'; k['o'] = '18 98' ; k['p'] = '19 99' ;
-
- k['Q'] = '2a 10 aa' ; k['W'] = '2a 11 aa' ; k['E'] = '2a 12 aa'; k['R'] = '2a 13 aa' ; k['T'] = '2a 14 aa' ; k['Y'] = '2a 15 aa'; k['U']= '2a 16 aa' ; k['I']='2a 17 aa'; k['O'] = '2a 18 aa' ; k['P'] = '2a 19 aa' ;
-
- k['a'] = '1e 9e'; k['s'] = '1f 9f' ; k['d'] = '20 a0' ; k['f'] = '21 a1'; k['g'] = '22 a2' ; k['h'] = '23 a3' ; k['j'] = '24 a4';
- k['k']= '25 a5' ; k['l']='26 a6';
- k['A'] = '2a 1e aa 9e'; k['S'] = '2a 1f aa 9f' ; k['D'] = '2a 20 aa a0' ; k['F'] = '2a 21 aa a1';
- k['G'] = '2a 22 aa a2' ; k['H'] = '2a 23 aa a3' ; k['J'] = '2a 24 aa a4'; k['K']= '2a 25 aa a5' ; k['L']='2a 26 aa a6';
-
- k[';'] = '27 a7' ;k['"']='2a 28 aa a8';k['\'']='28 a8';
-
- k['\\'] = '2b ab'; k['|'] = '2a 2b aa 8b';
-
- k['[']='1a 9a'; k[']']='1b 9b';
- k['<']='2a 33 aa b3'; k['>']='2a 34 aa b4';
- k['$']='2a 05 aa 85';
- k['+']='2a 0d aa 8d';
-
- k['z'] = '2c ac'; k['x'] = '2d ad' ; k['c'] = '2e ae' ; k['v'] = '2f af'; k['b'] = '30 b0' ; k['n'] = '31 b1' ;
- k['m'] = '32 b2';
- k['Z'] = '2a 2c aa ac'; k['X'] = '2a 2d aa ad' ; k['C'] = '2a 2e aa ae' ; k['V'] = '2a 2f aa af';
- k['B'] = '2a 30 aa b0' ; k['N'] = '2a 31 aa b1' ; k['M'] = '2a 32 aa b2';
-
- k[',']= '33 b3' ; k['.']='34 b4'; k['/'] = '35 b5' ;k[':'] = '2a 27 aa a7';
- k['%'] = '2a 06 aa 86'; k['_'] = '2a 0c aa 8c';
- k['&'] = '2a 08 aa 88';
- k['('] = '2a 0a aa 8a';
- k[')'] = '2a 0b aa 8b';
-
-
- special=Hash.new;
- special['<Enter>'] = '1c 9c';
- special['<Backspace>'] = '0e 8e';
- special['<Spacebar>'] = '39 b9';
- special['<Return>'] = '1c 9c'
- special['<Esc>'] = '01 81';
- special['<Tab>'] = '0f 8f';
- special['<KillX>'] = '1d 38 0e';
- special['<Wait>'] = 'wait';
-
- special['<Up>'] = '48 c8';
- special['<Down>'] = '50 d0';
- special['<PageUp>'] = '49 c9';
- special['<PageDown>'] = '51 d1';
- special['<End>'] = '4f cf';
- special['<Insert>'] = '52 d2';
- special['<Delete>'] = '53 d3';
- special['<Left>'] = '4b cb';
- special['<Right>'] = '4d cd';
- special['<Home>'] = '47 c7';
-
- special['<F1>'] = '3b';
- special['<F2>'] = '3c';
- special['<F3>'] = '3d';
- special['<F4>'] = '3e';
- special['<F5>'] = '3f';
- special['<F6>'] = '40';
- special['<F7>'] = '41';
- special['<F8>'] = '42';
- special['<F9>'] = '43';
- special['<F10>'] = '44';
-
- keycodes=''
- 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=keycodes+special[key]+' ';
- thestring=thestring.slice(key.length,thestring.length-key.length)
- nospecial=false;
- break;
- end
- }
- if nospecial
- code=k[thestring.slice(0,1)]
- if !code.nil?
- keycodes=keycodes+code+' '
- else
- puts "no scan code for #{thestring.slice(0,1)}"
- end
- #pop one
- thestring=thestring.slice(1,thestring.length-1)
- end
- end
-
- return keycodes
- end
-
- end
-end
-
-
View
982 lib/veewee/session.rb
@@ -1,907 +1,197 @@
-require 'digest/md5'
-require 'socket'
-require 'net/scp'
-require 'pp'
-require 'open-uri'
-require 'progressbar'
-require 'highline/import'
+require 'veewee/definition'
+require 'veewee/provider/virtualbox'
require 'tempfile'
require 'virtualbox'
-module Veewee
+module Veewee
+
class Session
- attr_accessor :veewee_dir
- attr_accessor :definition_dir
- attr_accessor :template_dir
- attr_accessor :iso_dir
- attr_accessor :name
- attr_accessor :definition
-
- def self.setenv(env)
- @veewee_dir=env[:veewee_dir]
- @definition_dir=env[:definition_dir]
- @template_dir=env[:template_dir]
- @validation_dir=env[:validation_dir]
- @box_dir=env[:box_dir]
- @iso_dir=env[:iso_dir]
- @tmp_dir=env[:tmp_dir]
- end
-
- def self.declare(options)
- defaults={
- :cpu_count => '1', :memory_size=> '256',
- :disk_size => '10240', :disk_format => 'VDI', :hostiocache => 'off' ,
- :os_type_id => 'Ubuntu',
- :iso_file => "ubuntu-10.10-server-i386.iso", :iso_src => "", :iso_md5 => "", :iso_download_timeout => 1000,
- :boot_wait => "10", :boot_cmd_sequence => [ "boot"],
- :kickstart_port => "7122", :kickstart_ip => self.local_ip, :kickstart_timeout => 10000,
- :ssh_login_timeout => "100",: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",
- :postinstall_files => [ "postinstall.sh"],:postinstall_timeout => 10000}
-
- @definition=defaults.merge(options)
-
- end
-
- def self.define(boxname,template_name,options = {})
- #Check if template_name exists
+ attr_accessor :session_dir
+ attr_accessor :definition_dir
+ attr_accessor :iso_dir
+ attr_accessor :tmp_dir
+ attr_accessor :box_dir
- options = { "force" => false, "format" => "vagrant" }.merge(options)
-
- if File.directory?(File.join(@template_dir,template_name))
- else
- puts "This template can not be found, use vagrant basebox templates to list all templates"
- exit
- end
- if !File.exists?(@definition_dir)
- FileUtils.mkdir(@definition_dir)
- end
- if File.directory?(File.join(@definition_dir,boxname))
- if !options["force"]
- puts "The definition for #{boxname} already exists. Use --force to overwrite"
- exit
- end
- else
- FileUtils.mkdir(File.join(@definition_dir,boxname))
- end
- FileUtils.cp_r(File.join(@template_dir,template_name,'.'),File.join(@definition_dir,boxname))
- puts "The basebox '#{boxname}' has been successfully created from the template ''#{template_name}'"
- puts "You can now edit the definition files stored in definitions/#{boxname}"
- puts "or build the box with:"
- if (options["format"]=='vagrant')
- puts "vagrant basebox build '#{boxname}'"
- end
- if (options["format"]=='veewee')
- puts "veewee build '#{boxname}'"
- end
+ attr_accessor :veewee_dir
+ attr_accessor :template_dir
+ attr_accessor :validation_dir
+ @loaded_definition=nil
+ def self.get_loaded_definition
+ @loaded_definition
end
-
-
-
-
- def self.definition_exists?(boxname)
- if File.directory?(File.join(@definition_dir,boxname))
- if File.exists?(File.join(@definition_dir,boxname,'definition.rb'))
- return true
- else
- return false
- end
- else
- return false
- end
-
+
+ def initialize(settings={})
+ @session_dir=settings[:session_dir]||Dir.pwd
+ @definition_dir=settings[:definition_dir]||File.join(@session_dir,"definitions")
+ @iso_dir=settings[:iso_dir]||File.join(@session_dir,"iso")
+ @box_dir=settings[:box_dir]||File.join(@session_dir,"boxes")
+ @tmp_dir=settings[:tmp_dir]||File.join(@session_dir,"tmp")
+ @validation_dir=settings[:validation_dir]||File.expand_path(File.join(File.dirname(__FILE__),"..","..", "validation"))
+ @template_dir=settings[:template_dir]||File.expand_path(File.join(File.dirname(__FILE__),"..","..", "templates"))
+ return self
end
-
- def self.undefine(boxname)
- name_dir=File.join(@definition_dir,boxname)
- if File.directory?(name_dir)
- #TODO: Needs to be more defensive!!
- puts "Removing definition #{boxname}"
- FileUtils.rm_rf(name_dir)
- else
- puts "Can not undefine , definition #{boxname} does not exist"
- exit
- end
- end
-
- def self.list_templates( options = { :format => 'vagrant'})
- puts "The following templates are available:"
- subdirs=Dir.glob("#{@template_dir}/*")
- subdirs.each do |sub|
- if File.directory?("#{sub}")
- definition=Dir.glob("#{sub}/definition.rb")
- if definition.length!=0
- name=sub.sub(/#{@template_dir}\//,'')
- if (options[:format]=='vagrant')
- puts "vagrant basebox define '<boxname>' '#{name}'"
- end
- if (options[:format]=='veewee')
- puts "veewee define '<boxname>' '#{name}'"
- end
- end
- end
- end
- end
-
- def self.list_boxes
- puts "Not yet implemented"
+
+ def get_definition(name)
+ # This should be locked (it loads the declare in a class var and then reads it into this session)
+ definition=Veewee::Definition.load(name,@definition_dir)
+ return definition
end
- def self.list_definitions
- puts "The following defined baseboxes exist:"
- subdirs=Dir.glob("#{@definition_dir}/*")
- subdirs.each do |sub|
- puts "- "+File.basename(sub)
- end
- end
- def self.clean
- puts "Not yet implemented"
+ # For backwards compatible reasons
+ # Shoud not be called directly
+ def self.declare(options)
+ @loaded_definition=options
end
- def self.verify_iso(filename,autodownload = false)
- if File.exists?(File.join(@iso_dir,filename))
- puts
- puts "Verifying the isofile #{filename} is ok."
- else
-
- full_path=File.join(@iso_dir,filename)
- path1=Pathname.new(full_path)
- path2=Pathname.new(Dir.pwd)
- rel_path=path1.relative_path_from(path2).to_s
-
- 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
-
- 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?(@iso_dir)
- puts "Creating an iso directory"
- FileUtils.mkdir(@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
-
+ def self.get_provider(name)
+ Object.const_get("Veewee").const_get("Virtualbox")
end
+
+ def build(name,definition)
+ options={}
+ defaults={ :provider_type => "Virtualbox" }
+ options=defaults.merge(options)
+ provider=Veewee::Session.get_provider(options[:provider_type]).new(name,definition,self)
+
+ #verify_postinstalls
+ #verify it all
+
- def self.export_box(boxname)
- #Now we have to load the definition (reads definition.rb)
- load_definition(boxname)
-
- Veewee::Export.vagrant(boxname,@box_dir,@definition)
- #vagrant removes the mapping
- #we need to restore it in order to be able to login again
- add_ssh_nat_mapping(boxname)
-
+ provider.build
end
-
- def self.remove_box(boxname)
- puts "Not yet implemented"
+
+ def destroy(name,definition)
+ options={}
+ defaults={ :provider_type => "Virtualbox" }
+ options=defaults.merge(options)
+ provider=Veewee::Session.get_provider(options[:provider_type]).new(name,definition,self)
+ provider.destroy_vm
end
+
+ def self.define(boxname,template_name,options = {})
+ #Check if template_name exists
- def self.build(boxname,options)
-
- options = { "force" => false, "format" => "vagrant", "nogui" => false }.merge(options)
-
- #Now we have to load the definition (reads definition.rb)
- load_definition(boxname)
-
- #Command to execute locally
- @vboxcmd=determine_vboxcmd
-
- ssh_options={ :user => @definition[:ssh_user], :port => @definition[:ssh_host_port], :password => @definition[:ssh_password],
- :timeout => @definition[:ssh_timeout]}
-
- #Suppress those annoying virtualbox messages
- suppress_messages
+ options = { "force" => false, "format" => "vagrant" }.merge(options)
-
- vm=VirtualBox::VM.find(boxname)
-
- if (!vm.nil? && (vm.saved?))
- puts "Removing save state"
- vm.discard_state
- vm.reload
- end
-
- if (!vm.nil? && !(vm.powered_off?))
- puts "Shutting down vm #{boxname}"
- #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"
- exit
- end
- sleep 3
- end
-
-
- verify_iso(@definition[:iso_file])
-
- if (options["force"]==false)
+ if File.directory?(File.join(@template_dir,template_name))
else
- puts "Forcing build by destroying #{boxname} machine"
- destroy_vm(boxname)
- end
-
- if Veewee::Utils.is_port_open?("localhost", @definition[:ssh_host_port])
- puts "Hmm, the port #{@definition[:ssh_host_port]} is open. And we shut down?"
+ puts "This template can not be found, use vagrant basebox templates to list all templates"
exit
end
+ if !File.exists?(@definition_dir)
+ FileUtils.mkdir(@definition_dir)
+ end
- checksums=calculate_checksums(@definition,boxname)
-
- transaction(boxname,"0-initial-#{checksums[0]}",checksums) do
-
- #Create the Virtualmachine and set all the memory and other stuff
- create_vm(boxname)
-
- #Create a disk with the same name as the boxname
- create_disk(boxname)
-
-
- #These command actually call the commandline of Virtualbox, I hope to use the virtualbox-ruby library in the future
- add_ide_controller(boxname)
- add_sata_controller(boxname)
- attach_disk(boxname)
- mount_isofile(boxname,@definition[:iso_file])
- add_ssh_nat_mapping(boxname)
-
- #Starting machine
-
- if (options["nogui"]==true)
- start_vm(boxname,"vrdp")
- else
- start_vm(boxname,"gui")
- end
-
- #waiting for it to boot
- puts "Waiting for the machine to boot"
- sleep @definition[:boot_wait].to_i
-
- Veewee::Scancode.send_sequence("#{@vboxcmd}","#{boxname}",@definition[:boot_cmd_sequence],@definition[:kickstart_port])
-
- kickstartfile=@definition[:kickstart_file]
- if kickstartfile.nil? || kickstartfile.length == 0
- puts "Skipping webserver as no kickstartfile was specified"
- else
- 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 kickstartfile.is_a? String
- Veewee::Web.wait_for_request(kickstartfile,{:port => @definition[:kickstart_port],
- :host => @definition[:kickstart_ip], :timeout => @definition[:kickstart_timeout],
- :web_dir => File.join(@definition_dir,boxname)})
- end
- if kickstartfile.is_a? Array
- kickstartfiles=kickstartfile
- kickstartfiles.each do |kickfile|
- Veewee::Web.wait_for_request(kickfile,{:port => @definition[:kickstart_port],
- :host => @definition[:kickstart_ip], :timeout => @definition[:kickstart_timeout],
- :web_dir => File.join(@definition_dir,boxname)})
- end
- end
- end
-
-
- Veewee::Ssh.when_ssh_login_works("localhost",ssh_options) do
- #Transfer version of Virtualbox to $HOME/.vbox_version
- versionfile=Tempfile.open("vbox.version")
- versionfile.puts "#{VirtualBox::Global.global.lib.virtualbox.version.split('_')[0]}"
- versionfile.rewind
- begin
- Veewee::Ssh.transfer_file("localhost",versionfile.path,".vbox_version", ssh_options)
- rescue RuntimeError
- puts "error transfering file, possible not enough permissions to write?"
- exit
- end
- puts ""
- versionfile.close
- versionfile.delete
- end
- end #initial Transaction
-
-
- counter=1
- @definition[:postinstall_files].each do |postinstall_file|
-
-
- filename=File.join(@definition_dir,boxname,postinstall_file)
-
- transaction(boxname,"#{counter}-#{postinstall_file}-#{checksums[counter]}",checksums) do
-
- Veewee::Ssh.when_ssh_login_works("localhost",ssh_options) do
- begin
- Veewee::Ssh.transfer_file("localhost",filename,File.basename(filename),ssh_options)
- rescue RuntimeError
- puts "error transferring file, possible not enough permissions to write?"
- exit
- end
- command=@definition[:sudo_cmd]
- newcommand=command.gsub(/%p/,"#{@definition[:ssh_password]}")
- newcommand.gsub!(/%u/,"#{@definition[:ssh_user]}")
- newcommand.gsub!(/%f/,"#{postinstall_file}")
- puts "***#{newcommand}"
- Veewee::Ssh.execute("localhost","#{newcommand}",ssh_options)
- end
-
- end
- counter+=1
-
- end
-
- puts "#{boxname} was built successfully. "
- puts ""
- puts "Now you can: "
- puts "- verify your box by running : vagrant basebox validate #{boxname}"
- puts "- export your vm to a .box file by running : vagrant basebox export #{boxname}"
-
- end
-
-
- def self.determine_vboxcmd
- return "VBoxManage"
- end
-
- def self.start_vm(boxname,mode)
- vm=VirtualBox::VM.find(boxname)
- vm.start(mode)
- end
-
- def self.load_definition(boxname)
-
- if definition_exists?(boxname)
- definition_file=File.join(@definition_dir,boxname,"definition.rb")
- begin
- require definition_file
- rescue LoadError
- puts "Error loading definition of #{boxname}"
- exit
- end
- else
- puts "Error: definition for basebox '#{boxname}' does not exist."
- list_definitions
- exit
- end
- end
-
- def self.add_ssh_nat_mapping(boxname)
- vm=VirtualBox::VM.find(boxname)
- #Map SSH Ports
- # command => "${vboxcmd} modifyvm '${vname}' --natpf1 'guestssh,tcp,,${hostsshport},,${guestsshport}'",
- port = VirtualBox::NATForwardedPort.new
- port.name = "guestssh"
- port.guestport = @definition[:ssh_guest_port].to_i
- port.hostport = @definition[:ssh_host_port].to_i
- vm.network_adapters[0].nat_driver.forwarded_ports << port
- port.save
- vm.save
- end
-
- def self.destroy_vm(boxname)
-
- load_definition(boxname)
- @vboxcmd=determine_vboxcmd
- #:destroy_medium => :delete, will delete machine + all media attachments
- #vm.destroy(:destroy_medium => :delete)
- ##vm.destroy(:destroy_image => true)
-
- #VBoxManage unregistervm "test-machine" --delete
- #because the destroy does remove the .vbox file on 4.0.x
- #PDB
- #vm.destroy()
-
-
-
- vm=VirtualBox::VM.find(boxname)
-
- if (!vm.nil? && !(vm.powered_off?))
- puts "Shutting down vm #{boxname}"
- #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"
- exit
- end
- sleep 3
- end
-
-
- command="#{@vboxcmd} unregistervm '#{boxname}' --delete"
- puts command
- puts "Deleting vm #{boxname}"
-
- #Exec and system stop the execution here
- Veewee::Shell.execute("#{command}")
- sleep 1
-
- #if the disk was not attached when the machine was destroyed we also need to delete the disk
- location=boxname+"."+@definition[:disk_format].downcase
- found=false
- VirtualBox::HardDrive.all.each do |d|
- if d.location.match(/#{location}/)
-
- if File.exists?(d.location)
- command="#{@vboxcmd} closemedium disk '#{d.location}' --delete"
- else
- command="#{@vboxcmd} closemedium disk '#{d.location}'"
- end
-
- #command="#{@vboxcmd} closemedium disk '#{d.location}' --delete"
- puts "Deleting disk #{d.location}"
- puts "#{command}"
-
- Veewee::Shell.execute("#{command}")
- if File.exists?(d.location)
- puts "We tried to delete the disk file via virtualbox '#{d.location} but failed"
- puts "Removing it manually"
- FileUtils.rm(d.location)
+ if File.directory?(File.join(@definition_dir,boxname))
+ if !options["force"]
+ puts "The definition for #{boxname} already exists. Use --force to overwrite"
exit
end
- #v.3
- #d.destroy(true)
- break
+ else
+ FileUtils.mkdir(File.join(@definition_dir,boxname))
end
- end
- end
-
- def self.create_vm(boxname,force=false)
-
- #Verifying the os.id with the :os_type_id specified
- matchfound=false
- VirtualBox::Global.global.lib.virtualbox.guest_os_types.collect { |os|
- if @definition[:os_type_id] == os.id
- matchfound=true
+<<
+ FileUtils.cp_r(File.join(@template_dir,template_name,'.'),File.join(@definition_dir,boxname))
+ puts "The basebox '#{boxname}' has been succesfully created from the template ''#{template_name}'"
+ puts "You can now edit the definition files stored in definitions/#{boxname}"
+ puts "or build the box with:"
+ if (options["format"]=='vagrant')
+ puts "vagrant basebox build '#{boxname}'"
end
- }
- unless matchfound
- puts "The ostype: #{@definition[:os_type_id]} is not available in your Virtualbox version"
- exit
- end
-
-
- vm=VirtualBox::VM.find(boxname)
-
- if (!vm.nil? && !(vm.powered_off?))
- puts "shutting down box"
- #We force it here, maybe vm.shutdown is cleaner
- vm.stop
- end
-
- if !vm.nil?
- puts "Box already exists"
- #vm.stop
- #vm.destroy
- else
- #TODO One day ruby-virtualbox will be able to handle this creation
- #Box does not exist, we can start to create it
-
- command="#{@vboxcmd} createvm --name '#{boxname}' --ostype '#{@definition[:os_type_id]}' --register"
-
- #Exec and system stop the execution here
- Veewee::Shell.execute("#{command}")
-
- # Modify the vm to enable or disable hw virtualization extensions
- vm_flags=%w{pagefusion acpi ioapic pae hpet hwvirtex hwvirtexcl nestedpaging largepages vtxvpid synthxcpu rtcuseutc}
-
- vm_flags.each do |vm_flag|
- unless @definition[vm_flag.to_sym].nil?
- puts "Setting VM Flag #{vm_flag} to #{@definition[vm_flag.to_sym]}"
- command="#{@vboxcmd} modifyvm #{boxname} --#{vm_flag.to_s} #{@definition[vm_flag.to_sym]}"
- Veewee::Shell.execute("#{command}")
- end
+ if (options["format"]=='veewee')
+ puts "veewee build '#{boxname}'"
end
- # Todo Check for java
- # Todo check output of commands
-
- # Check for floppy
- unless @definition[:floppy_files].nil?
- require 'tmpdir'
- temp_dir=Dir.tmpdir
- @definition[:floppy_files].each do |filename|
- full_filename=full_filename=File.join(@definition_dir,boxname,filename)
- FileUtils.cp("#{full_filename}","#{temp_dir}")
- end
- javacode_dir=File.expand_path(File.join(__FILE__,'..','..','java'))
- floppy_file=File.join(@definition_dir,boxname,"virtualfloppy.vfd")
- command="java -jar #{javacode_dir}/dir2floppy.jar '#{temp_dir}' '#{floppy_file}'"
- puts "#{command}"
- Veewee::Shell.execute("#{command}")
-
- # Create floppy controller
- command="#{@vboxcmd} storagectl '#{boxname}' --name 'Floppy Controller' --add floppy"
- puts "#{command}"
- Veewee::Shell.execute("#{command}")
-
- # Attach floppy to machine (the vfd extension is crucial to detect msdos type floppy)
- command="#{@vboxcmd} storageattach '#{boxname}' --storagectl 'Floppy Controller' --port 0 --device 0 --type fdd --medium '#{floppy_file}'"
- puts "#{command}"
- Veewee::Shell.execute("#{command}")
-
- end
-
-
- #Exec and system stop the execution here
- Veewee::Shell.execute("#{command}")
-
- command="#{@vboxcmd} sharedfolder add '#{boxname}' --name 'veewee-validation' --hostpath '#{File.expand_path(@validation_dir)}' --automount"
-
- Veewee::Shell.execute("#{command}")
-
end
- vm=VirtualBox::VM.find(boxname)
- if vm.nil?
- puts "we tried to create a box or a box was here before"
- puts "but now it's gone"
- exit
- end
-
- #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=boxname
-
- puts "Creating vm #{vm.name} : #{vm.memory_size}M - #{vm.cpu_count} CPU - #{vm.os_type_id}"
- #setting bootorder
- vm.boot_order[0]=:hard_disk
- vm.boot_order[1]=:dvd
- vm.boot_order[2]=:null
- vm.boot_order[3]=:null
- vm.validate
- vm.save
-
- end
-
- def self.create_disk(boxname)
- #Now check the disks
- #Maybe one day we can use the name, now we have to check location
- #disk=VirtualBox::HardDrive.find(boxname)
- location=boxname+"."+@definition[:disk_format].downcase
-
- found=false
- VirtualBox::HardDrive.all.each do |d|
- if !d.location.match(/#{location}/).nil?
- found=true
- break
+ def self.undefine(boxname)
+ name_dir=File.join(@definition_dir,boxname)
+ if File.directory?(name_dir)
+ #TODO: Needs to be more defensive!!
+ puts "Removing definition #{boxname}"
+ FileUtils.rm_rf(name_dir)
+ else
+ puts "Can not undefine , definition #{boxname} does not exist"
+ exit
end
end
- @vboxcmd=determine_vboxcmd
-
- if !found
- puts "Creating new harddrive of size #{@definition[:disk_size].to_i} "
-
- #newdisk=VirtualBox::HardDrive.new
- #newdisk.format=@definition[:disk_format]
- #newdisk.logical_size=@definition[:disk_size].to_i
-
- #newdisk.location=location
- ##PDB: again problems with the virtualbox GEM
- ##VirtualBox::Global.global.max_vdi_size=1000000
- #newdisk.save
-
- command="#{@vboxcmd} list systemproperties|grep '^Default machine'|cut -d ':' -f 2|sed -e 's/^[ ]*//'"
- results=IO.popen("#{command}")
- place=results.gets.chop
- results.close
-
- command ="#{@vboxcmd} createhd --filename '#{place}/#{boxname}/#{boxname}.#{@definition[:disk_format].downcase}' --size '#{@definition[:disk_size].to_i}' --format #{@definition[:disk_format].downcase} > /dev/null"
- puts "#{command}"
- Veewee::Shell.execute("#{command}")
-
- end
-
- end
-
- def self.add_ide_controller(boxname)
- #unless => "${vboxcmd} showvminfo '${vname}' | grep 'IDE Controller' "
- command ="#{@vboxcmd} storagectl '#{boxname}' --name 'IDE Controller' --add ide"
- Veewee::Shell.execute("#{command}")
- end
-
-