veewee 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +7 -0
  2. data/.rvmrc +2 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +53 -0
  5. data/README.md +124 -0
  6. data/Rakefile +92 -0
  7. data/bin/veewee +79 -0
  8. data/iso/.gitignore +2 -0
  9. data/lib/vagrant_init.rb +1 -0
  10. data/lib/veewee/command.rb +66 -0
  11. data/lib/veewee/config.rb +5 -0
  12. data/lib/veewee/export.rb +81 -0
  13. data/lib/veewee/scancode.rb +108 -0
  14. data/lib/veewee/session.rb +712 -0
  15. data/lib/veewee/shell.rb +54 -0
  16. data/lib/veewee/ssh.rb +164 -0
  17. data/lib/veewee/transaction.rb +112 -0
  18. data/lib/veewee/version.rb +3 -0
  19. data/lib/veewee/web.rb +48 -0
  20. data/lib/veewee.rb +2 -0
  21. data/templates/CentOS-4.8-i386/definition.rb +14 -0
  22. data/templates/CentOS-4.8-i386/ks.cfg +45 -0
  23. data/templates/CentOS-4.8-i386/postinstall.sh +47 -0
  24. data/templates/CentOS-5.5-i386/definition.rb +16 -0
  25. data/templates/CentOS-5.5-i386/ks.cfg +45 -0
  26. data/templates/CentOS-5.5-i386/postinstall.sh +48 -0
  27. data/templates/CentOS-5.5-i386-netboot/definition.rb +17 -0
  28. data/templates/CentOS-5.5-i386-netboot/ks.cfg +45 -0
  29. data/templates/CentOS-5.5-i386-netboot/postinstall.sh +48 -0
  30. data/templates/ubuntu-10.04.1-server-amd64/definition.rb +25 -0
  31. data/templates/ubuntu-10.04.1-server-amd64/postinstall.sh +33 -0
  32. data/templates/ubuntu-10.04.1-server-amd64/preseed.cfg +87 -0
  33. data/templates/ubuntu-10.04.1-server-i386/definition.rb +25 -0
  34. data/templates/ubuntu-10.04.1-server-i386/postinstall.sh +43 -0
  35. data/templates/ubuntu-10.04.1-server-i386/postinstall2.sh +9 -0
  36. data/templates/ubuntu-10.04.1-server-i386/preseed.cfg +87 -0
  37. data/templates/ubuntu-10.10-server-amd64/definition.rb +25 -0
  38. data/templates/ubuntu-10.10-server-amd64/postinstall.sh +43 -0
  39. data/templates/ubuntu-10.10-server-amd64/postinstall2.sh +9 -0
  40. data/templates/ubuntu-10.10-server-amd64/preseed.cfg +87 -0
  41. data/templates/ubuntu-10.10-server-i386/definition.rb +25 -0
  42. data/templates/ubuntu-10.10-server-i386/postinstall.sh +43 -0
  43. data/templates/ubuntu-10.10-server-i386/postinstall2.sh +9 -0
  44. data/templates/ubuntu-10.10-server-i386/preseed.cfg +87 -0
  45. data/trials/docu-vbox.txt +83 -0
  46. data/trials/f.rb +29 -0
  47. data/trials/t.rb +15 -0
  48. data/veewee.gemspec +30 -0
  49. metadata +219 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+ gems/*
3
+ iso/*
4
+ tmp/*
5
+ definitions/*
6
+ boxes/*
7
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm use ruby-1.9.2
2
+ rvm gemset use veewee
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "veewee", :path => "."
4
+
5
+ #gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
data/Gemfile.lock ADDED
@@ -0,0 +1,53 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ veewee (0.0.2)
5
+ highline (~> 1.6.1)
6
+ net-ssh (~> 2.1.0)
7
+ popen4 (~> 0.1.2)
8
+ progressbar
9
+ thor (~> 0.14.6)
10
+ vagrant (~> 0.7.0)
11
+
12
+ GEM
13
+ remote: http://rubygems.org/
14
+ specs:
15
+ Platform (0.4.0)
16
+ abstract (1.0.0)
17
+ archive-tar-minitar (0.5.2)
18
+ erubis (2.6.6)
19
+ abstract (>= 1.0.0)
20
+ ffi (0.6.3)
21
+ rake (>= 0.8.7)
22
+ highline (1.6.1)
23
+ i18n (0.5.0)
24
+ json (1.4.6)
25
+ mario (0.0.6)
26
+ net-scp (1.0.4)
27
+ net-ssh (>= 1.99.1)
28
+ net-ssh (2.1.0)
29
+ open4 (1.0.1)
30
+ popen4 (0.1.2)
31
+ Platform (>= 0.4.0)
32
+ open4 (>= 0.4.0)
33
+ progressbar (0.9.0)
34
+ rake (0.8.7)
35
+ thor (0.14.6)
36
+ vagrant (0.7.1)
37
+ archive-tar-minitar (= 0.5.2)
38
+ erubis (~> 2.6.6)
39
+ i18n (~> 0.5.0)
40
+ json (~> 1.4.6)
41
+ mario (~> 0.0.6)
42
+ net-scp (~> 1.0.4)
43
+ net-ssh (~> 2.1.0)
44
+ thor (~> 0.14.6)
45
+ virtualbox (~> 0.8.3)
46
+ virtualbox (0.8.3)
47
+ ffi (~> 0.6.3)
48
+
49
+ PLATFORMS
50
+ ruby
51
+
52
+ DEPENDENCIES
53
+ veewee!
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ **VeeWee:** the tool to easily build vagrant base boxes
2
+ Vagrant is a great tool to test new things or changes in a virtual machine(Virtualbox) using either chef or puppet.
3
+ The first step is to download an existing 'base box'. I believe this scares a lot of people as they don't know who or how this box was build. Therefore lots of people end up first building their own base box to use with vagrant.
4
+
5
+ Veewee tries to automate this and to share the knowledge and sources you need to create a basebox. Instead of creating custom ISO's from your favorite distribution, it leverages the 'keyboardputscancode' command of Virtualbox so send the actual 'boot prompt' keysequence to boot an existing iso.
6
+
7
+ Before we can actually build the boxes, we need to take care of the minimal things to install:
8
+ - Have Virtualbox 4.x installed -> download it from http://download.virtualbox.org/virtualbox/
9
+
10
+
11
+ ALPHA CODE: -> you're on your own....
12
+
13
+ ## Installation:
14
+ __from source__
15
+ $ git clone https://github.com/jedi4ever/veewee.git
16
+ $ cd veewee
17
+ $ gem install bundler
18
+ $ bundle install
19
+
20
+ __as a gem__
21
+ $ gem install veewee
22
+
23
+
24
+ ## List all templates
25
+ $ vagrant basebox templates
26
+
27
+ ## Define a new box (ex. Ubuntu 10.10 server i386)
28
+
29
+ this is essentially making a copy based on the templates provided above.
30
+
31
+ $ vagrant basebox define 'myubuntubox' 'ubuntu-10.10-server-i386'
32
+ template successfully copied
33
+
34
+ -> This copies over the templates/ubuntu-10.10-server-i386 to definition/myubuntubox
35
+
36
+ $ ls definitions/myubuntubox
37
+ definition.rb postinstall.sh postinstall2.sh preseed.cfg
38
+
39
+ ## Optionally modify the definition.rb , postinstall.sh or preseed.cfg
40
+
41
+ <pre>
42
+ Veewee::Session.declare( {
43
+ :cpu_count => '1', :memory_size=> '256',
44
+ :disk_size => '10140', :disk_format => 'VDI',:disk_size => '10240' ,
45
+ :os_type_id => 'Ubuntu',
46
+ :iso_file => "ubuntu-10.10-server-i386.iso",
47
+ :iso_src => "http://releases.ubuntu.com/maverick/ubuntu-10.10-server-i386.iso",
48
+ :iso_md5 => "ce1cee108de737d7492e37069eed538e",
49
+ :iso_download_timeout => "1000",
50
+ :boot_wait => "10",
51
+ :boot_cmd_sequence => [
52
+ '<Esc><Esc><Enter>',
53
+ '/install/vmlinuz noapic preseed/url=http://%IP%:%PORT%/preseed.cfg ',
54
+ 'debian-installer=en_US auto locale=en_US kbd-chooser/method=us ',
55
+ 'hostname=%NAME% ',
56
+ 'fb=false debconf/frontend=noninteractive ',
57
+ 'console-setup/ask_detect=false console-setup/modelcode=pc105 console-setup/layoutcode=us ',
58
+ 'initrd=/install/initrd.gz -- <Enter>'
59
+ ],
60
+ :kickstart_port => "7122", :kickstart_timeout => "10000",:kickstart_file => "preseed.cfg",
61
+ :ssh_login_timeout => "10000",:ssh_user => "vagrant", :ssh_password => "vagrant",:ssh_key => "",
62
+ :ssh_host_port => "2222", :ssh_guest_port => "22",
63
+ :sudo_cmd => "echo '%p'|sudo -S sh '%f'",
64
+ :shutdown_cmd => "shutdown -H",
65
+ :postinstall_files => [ "postinstall.sh"],:postinstall_timeout => "10000"
66
+ }
67
+ )
68
+ </pre>
69
+
70
+ If you need to change values in the templates, be sure to run the rake undefine, the rake define again to copy the changes across.
71
+
72
+ ## Put your isofile inside the $VEEWEE/iso directory or if you don't run
73
+ $ vagrant basebox build 'myubuntubox'
74
+
75
+ -> the build assumes your iso files are in 'currentdir'/iso
76
+ -> if it can not find it will suggest to download the iso for you
77
+
78
+ ## Build the new box:
79
+ $ vagrant basebox build 'myubuntubox'
80
+
81
+ - This will create a machine + disk according to the definition.rb
82
+ - Note: :os_type_id = The internal Name Virtualbox uses for that Distribution
83
+ - Mount the ISO File :iso_file
84
+ - Boot up the machine and wait for :boot_time
85
+ - Send the keystrokes in :boot_cmd_sequence
86
+ - Startup a webserver on :kickstart_port to wait for a request for the :kickstart_file
87
+ - Wait for ssh login to work with :ssh_user , :ssh_password
88
+ - Sudo execute the :postinstall_files
89
+
90
+ ## Export the vm to a .box file
91
+ $ vagrant basebox export 'myubuntubox'
92
+
93
+ this is actually calling - vagrant package --base 'myubuntubox' --output 'boxes/myubuntubox.box'
94
+
95
+ this will result in a myubuntubox.box
96
+
97
+ ## Add the box as one of your boxes
98
+ $ vagrant box add 'myubuntubox' 'myubuntubox.box'
99
+
100
+ ## Use it in vagrant
101
+ Start vagrant init in another window (as we have set the Virtualbox env to tmp before)
102
+ $ To import it into vagrant type:
103
+
104
+ To use it:
105
+ vagrant init 'myubuntubox'
106
+ vagrant up
107
+ vagrant ssh
108
+
109
+ ## If you have a setup working, share your 'definition' with me. That would be fun!
110
+
111
+ IDEAS:
112
+
113
+ - Now you integrate this with your CI build to create a daily basebox
114
+
115
+ FUTURE IDEAS:
116
+
117
+ - use snapshots to fastforward initial boot, and every postinstall command
118
+ - export to AMI too
119
+ - provide for more failsafe execution, testing parameters
120
+ - use more virtualbox ruby instead of calling the VBoxManage command
121
+ - Verify the installation with cucumber-nagios (ssh functionality)
122
+ - Do the same for Vmware Fusion
123
+
124
+ BUGS: Lots = Like I said it currently works for me, on my machine and with the correct magic sequence :)
data/Rakefile ADDED
@@ -0,0 +1,92 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'bundler/setup'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ #Setup some base variables to use
7
+ veewee_dir= "."
8
+ definition_dir= File.expand_path(File.join(veewee_dir, "definitions"))
9
+ lib_dir= File.expand_path(File.join(veewee_dir, "lib"))
10
+ box_dir= File.expand_path(File.join(veewee_dir, "boxes"))
11
+ template_dir=File.expand_path(File.join(veewee_dir, "templates"))
12
+ vbox_dir=File.expand_path(File.join(veewee_dir, "tmp"))
13
+ tmp_dir=File.expand_path(File.join(veewee_dir, "tmp"))
14
+ iso_dir=File.expand_path(File.join(veewee_dir, "iso"))
15
+
16
+
17
+ #Load Veewee::Session libraries
18
+ Dir.glob(File.join(lib_dir, '**','*.rb')).each {|f|
19
+ require f }
20
+
21
+ #Initialize
22
+ Veewee::Session.setenv({:veewee_dir => veewee_dir, :definition_dir => definition_dir,
23
+ :template_dir => template_dir, :iso_dir => iso_dir, :box_dir => box_dir, :tmp_dir => tmp_dir})
24
+
25
+ desc 'Default: list templates'
26
+ task :default => [:templates]
27
+
28
+ desc 'List templates'
29
+ task :templates do
30
+ Veewee::Session.list_templates
31
+ end
32
+
33
+ desc 'Define box'
34
+ task :define, [:boxname,:template_name] do |t,args|
35
+ if args.to_hash.size!=2
36
+ puts "needs two arguments: rake define['boxname','template_name']"
37
+ exit
38
+ end
39
+ Veewee::Session.define(args.boxname,args.template_name)
40
+ end
41
+
42
+ desc 'Undefine box'
43
+ task :undefine, [:boxname] do |t,args|
44
+ if args.to_hash.size!=1
45
+ puts "needs one arguments: rake undefine[\"yourname\"]"
46
+ exit
47
+ end
48
+ Veewee::Session.undefine(args.boxname)
49
+ end
50
+
51
+ desc 'List Definitions'
52
+ task :definitions do
53
+ Veewee::Session.list_definitions
54
+ end
55
+
56
+ desc 'Build box'
57
+ task :build, [:boxname] do |t,args|
58
+ if args.to_hash.size!=1
59
+ puts "needs one arguments: rake build['boxname']"
60
+ exit
61
+ end
62
+ Veewee::Session.build(args.boxname)
63
+ end
64
+
65
+ desc 'List boxes'
66
+ task :boxes do
67
+ Veewee::Session.list_boxes
68
+ end
69
+
70
+ desc 'Export box'
71
+ task :export, [:boxname] do |t,args|
72
+ if args.to_hash.size!=1
73
+ puts "needs one arguments: rake export['boxname']"
74
+ exit
75
+ end
76
+ Veewee::Session.export_box(args.boxname)
77
+ end
78
+
79
+ desc 'Remove box'
80
+ task :remove_box, [:boxname] do |t,args|
81
+ Veewee::Session.remove_box(args.boxname)
82
+ end
83
+
84
+ desc 'List ostypes available'
85
+ task :list_ostypes do |t,args|
86
+ Veewee::Session.list_ostypes
87
+ end
88
+
89
+ desc 'Clean all unfinished builds'
90
+ task :clean do
91
+ Veewee::Session.clean
92
+ end
data/bin/veewee ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'thor'
5
+ require 'bundler'
6
+ require 'virtualbox'
7
+ require 'veewee'
8
+
9
+
10
+ #Setup some base variables to use
11
+ veewee_dir= File.expand_path(File.join(File.dirname(__FILE__),".."))
12
+ definition_dir= File.expand_path(File.join(".", "definitions"))
13
+ lib_dir= File.expand_path(File.join(veewee_dir, "lib"))
14
+ box_dir= File.expand_path(File.join(veewee_dir, "boxes"))
15
+ template_dir=File.expand_path(File.join(veewee_dir, "templates"))
16
+
17
+ #vbox_dir=File.expand_path(File.join(veewee_dir, "tmp"))
18
+ tmp_dir=File.expand_path(File.join(veewee_dir, "tmp"))
19
+
20
+ iso_dir=File.expand_path(File.join(veewee_dir, "iso"))
21
+
22
+ #needs to be moved to the config files to be allowed override
23
+ #ENV['VBOX_USER_HOME']=vbox_dir
24
+
25
+ #Load Veewee::Session libraries
26
+ Dir.glob(File.join(lib_dir, '**','*.rb')).each {|f|
27
+ require f }
28
+
29
+ #Initialize
30
+ Veewee::Session.setenv({:veewee_dir => veewee_dir, :definition_dir => definition_dir,
31
+ :template_dir => template_dir, :iso_dir => iso_dir, :box_dir => box_dir, :tmp_dir => tmp_dir})
32
+
33
+
34
+
35
+ class VeeweeCLI < Thor
36
+
37
+ desc "init [NAME] [TEMPLATE]", "initializes a box from a template"
38
+ method_options :force => :boolean
39
+ def init(boxname=nil, template=nil)
40
+ if (boxname.nil?)
41
+ puts "please provide a boxname"
42
+ exit
43
+ end
44
+
45
+ puts "Init a new box #{boxname}, starting from template #{template}"
46
+ Veewee::Session.define(boxname,template)
47
+
48
+ end
49
+
50
+ desc "templates", "list the template available"
51
+ def templates
52
+ Veewee::Session.list_templates
53
+ end
54
+
55
+ desc "build [NAME]", "build the box defined"
56
+ method_options :force => :boolean
57
+ def build(boxname)
58
+ puts "Building box #{boxname}"
59
+ Veewee::Session.build(boxname)
60
+ end
61
+
62
+ desc "export [NAME]", "export the box"
63
+ method_options :force => :boolean
64
+ def export(boxname)
65
+ if (!boxname.nil?)
66
+ Veewee::Session.export_box(boxname)
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+
73
+
74
+ version=VirtualBox.version
75
+ if (version.match(/^4./))
76
+ VeeweeCLI.start
77
+ else
78
+ puts "veewee only supports VirtualBox 4.x"
79
+ end
data/iso/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *
2
+ !.gitignore
@@ -0,0 +1 @@
1
+ require 'veewee'
@@ -0,0 +1,66 @@
1
+ require 'veewee/session'
2
+
3
+ #Load Veewee::Session libraries
4
+ lib_dir= File.expand_path(File.join(File.dirname(__FILE__),"..","..", "lib"))
5
+ Dir.glob(File.join(lib_dir, '**','*.rb')).each {|f| require f }
6
+
7
+ #Setup some base variables to use
8
+ template_dir=File.expand_path(File.join(lib_dir,"..", "templates"))
9
+
10
+ veewee_dir="."
11
+ definition_dir= File.expand_path(File.join(veewee_dir, "definitions"))
12
+ tmp_dir=File.expand_path(File.join(veewee_dir, "tmp"))
13
+ iso_dir=File.expand_path(File.join(veewee_dir, "iso"))
14
+ box_dir=File.expand_path(File.join(veewee_dir, "boxes"))
15
+
16
+ #Initialize
17
+ Veewee::Session.setenv({:veewee_dir => veewee_dir, :definition_dir => definition_dir,
18
+ :template_dir => template_dir, :iso_dir => iso_dir, :box_dir => box_dir, :tmp_dir => tmp_dir})
19
+
20
+ module Veewee
21
+ class Command < Vagrant::Command::GroupBase
22
+ register "basebox","Commands to manage baseboxes"
23
+
24
+ desc "templates", "List the currently available box templates"
25
+ def templates
26
+ Veewee::Session.list_templates
27
+ end
28
+
29
+ desc "define BOXNAME TEMPLATE", "Define a new box starting from a template"
30
+ method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "overwrite the definition"
31
+ def define(boxname, template)
32
+ Veewee::Session.define(boxname,template,options)
33
+ end
34
+
35
+ desc "build BOXNAME", "Build the box BOXNAME"
36
+ method_option :force,:type => :boolean , :default => false, :aliases => "-f", :desc => "overwrite the basebox"
37
+ def build(boxname)
38
+ Veewee::Session.build(boxname,options)
39
+ end
40
+
41
+ desc "ostypes", "List the available Operating System types"
42
+ def ostypes
43
+ Veewee::Session.list_ostypes
44
+ end
45
+
46
+ desc "destroy BOXNAME", "Destroy the virtualmachine of a basebox"
47
+ def destroy(boxname)
48
+ puts Veewee::Session.destroy_vm(boxname)
49
+ end
50
+
51
+ desc "list", "Lists all defined boxes"
52
+ def list
53
+ Veewee::Session.list_definitions
54
+ end
55
+
56
+ desc "export [NAME]", "export the box"
57
+ method_options :force => :boolean
58
+ def export(boxname)
59
+ if (!boxname.nil?)
60
+ Veewee::Session.export_box(boxname)
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,5 @@
1
+ module Veewee
2
+ class BaseBoxConfig < Vagrant::Config::Base
3
+ configures :basebox
4
+ end
5
+ end
@@ -0,0 +1,81 @@
1
+ require 'pathname'
2
+ module Veewee
3
+ class Export
4
+
5
+ # Shellutil.execute("vagrant package --base #{vmname} --include /tmp/Vagrantfile --output /tmp/#{vmname}.box", {:progress => "on"})
6
+
7
+ def self.vagrant(boxname,boxdir,definition)
8
+
9
+ #Check if box already exists
10
+ vm=VirtualBox::VM.find(boxname)
11
+ if vm.nil?
12
+ puts "#{boxname} is not found, maybe you need to build first?"
13
+ exit
14
+ end
15
+ #We need to shutdown first
16
+ if vm.running?
17
+ puts "Vagrant requires the box to be shutdown, before it can export"
18
+ puts "Sudo also needs to work for user #{definition[:ssh_user]}"
19
+ puts "Performing a clean shutdown now."
20
+ ssh_options={ :user => definition[:ssh_user], :port => definition[:ssh_host_port], :password => definition[:ssh_password],
21
+ :timeout => definition[:ssh_timeout]}
22
+
23
+ Veewee::Ssh.execute("localhost","sudo #{definition[:shutdown_cmd]}",ssh_options)
24
+
25
+ #Wait for state poweroff
26
+ while (vm.running?) do
27
+ print '.'
28
+ sleep 1
29
+ end
30
+ puts
31
+ puts "Machine #{boxname} is powered off cleanly"
32
+ end
33
+
34
+ #Vagrant requires a relative path for output of boxes
35
+
36
+ #4.0.x. not using boxes as a subdir
37
+ boxdir=Pathname.new(Dir.pwd)
38
+
39
+ full_path=File.join(boxdir,boxname+".box")
40
+ path1=Pathname.new(full_path)
41
+ path2=Pathname.new(Dir.pwd)
42
+ box_path=path1.relative_path_from(path2).to_s
43
+
44
+ if File.exists?("#{box_path}")
45
+ puts "box #{boxname} already exists"
46
+ exit
47
+ end
48
+
49
+ puts "Excuting vagrant voodoo:"
50
+ export_command="vagrant package --base '#{boxname}' --output '#{box_path}'"
51
+ puts "#{export_command}"
52
+ Veewee::Shell.execute("#{export_command}") #hmm, needs to get the gem_home set?
53
+ puts
54
+
55
+ #add_ssh_nat_mapping back!!!!
56
+
57
+ puts "To import it into vagrant type:"
58
+ puts "vagrant box add '#{boxname}' '#{box_path}'"
59
+ puts ""
60
+ puts "To use it:"
61
+ puts "vagrant init '#{boxname}'"
62
+ puts "vagrant up"
63
+ puts "vagrant ssh"
64
+ end
65
+
66
+ end
67
+ end
68
+
69
+
70
+ # #currently vagrant has a problem with the machine up, it calculates the wrong port to ssh to poweroff the system
71
+ # thebox.execute("shutdown -h now")
72
+ # thebox.wait_for_state("poweroff")
73
+
74
+ # Shellutil.execute("echo 'Vagrant::Config.run do |config|' > /tmp/Vagrantfile")
75
+ # Shellutil.execute("echo ' config.ssh.forwarded_port_key = \"ssh\"' >> /tmp/Vagrantfile")
76
+ # Shellutil.execute("echo ' config.vm.forward_port(\"ssh\",22,#{host_port})' >> /tmp/Vagrantfile")
77
+ # Shellutil.execute("echo 'end' >> /tmp/Vagrantfile")
78
+
79
+
80
+ #vagrant export disables the machine
81
+ # thebox.ssh_enable_vmachine({:hostport => host_port , :guestport => 22} )
@@ -0,0 +1,108 @@
1
+ module Veewee
2
+ class Scancode
3
+
4
+ def self.send_sequence(vboxcmd,vname,sequence)
5
+ puts
6
+ counter=0
7
+ sequence.each { |s|
8
+ counter=counter+1
9
+
10
+ s.gsub!(/%IP%/,Veewee::Session.local_ip);
11
+ s.gsub!(/%PORT%/,'7122');
12
+ s.gsub!(/%NAME%/, vname);
13
+ puts "Typing:[#{counter}]: "+s
14
+
15
+ keycodes=string_to_keycode(s)
16
+
17
+ # VBox seems to have issues with sending the scancodes as one big
18
+ # .join()-ed string. It seems to get them out or order or ignore some.
19
+ # A workaround is to send the scancodes one-by-one.
20
+ codes=""
21
+ for keycode in keycodes.split(' ') do
22
+ send_keycode(vboxcmd,vname,keycode)
23
+ sleep 0.01
24
+ end
25
+ #sleep after each sequence (needs to be param)
26
+ sleep 1
27
+ }
28
+
29
+ puts "Done typing."
30
+ puts
31
+
32
+ end
33
+
34
+ def self.send_keycode(vboxcmd,vname,keycode)
35
+ command= "#{vboxcmd} controlvm '#{vname}' keyboardputscancode #{keycode}"
36
+ #puts "#{command}"
37
+ IO.popen("#{command}") { |f| print '' }
38
+ end
39
+
40
+ def self.string_to_keycode(thestring)
41
+
42
+ #http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
43
+
44
+ k=Hash.new
45
+ k['1'] = '02' ; k['2'] = '03' ; k['3'] = '04'; k['4']= '05' ;k['5']='06'; k['6'] = '07' ; k['7'] = '08'; k['8'] = '09'; k['9']= '0a'; k['0']='0b'; k['-'] = '0c'; k['='] = '0d' ;
46
+ k['Tab'] = '0f';
47
+ k['q'] = '10' ; k['w'] = '11' ; k['e'] = '12'; k['r'] = '13' ; k['t'] = '14' ; k['y'] = '15'; k['u']= '16' ; k['i']='17'; k['o'] = '18' ; k['p'] = '19' ;
48
+
49
+ 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' ;
50
+
51
+ k['a'] = '1e'; k['s'] = '1f' ; k['d'] = '20' ; k['f'] = '21'; k['g'] = '22' ; k['h'] = '23' ; k['j'] = '24'; k['k']= '25' ; k['l']='26'; k[';'] = '27'
52
+ k['A'] = '2a 1e aa'; k['S'] = '2a 1f aa' ; k['D'] = '2a 20 aa' ; k['F'] = '2a 21 aa'; k['G'] = '2a 22 aa' ; k['H'] = '2a 23 aa' ; k['J'] = '2a 24 aa'; k['K']= '2a 25 aa' ; k['L']='2a 26 aa';
53
+
54
+ k[';'] = '27' ;k['"']='28';
55
+
56
+ k['[']='1a'; k[']']='1b'
57
+
58
+ k['z'] = '2c'; k['x'] = '2d' ; k['c'] = '2e' ; k['v'] = '2f'; k['b'] = '30' ; k['n'] = '31' ; k['m'] = '32';
59
+ k['Z'] = '2a 2c aa'; k['X'] = '2a 2d aa' ; k['C'] = '2a 2e aa' ; k['V'] = '2a 2f aa'; k['B'] = '2a 30 aa' ; k['N'] = '2a 31 aa' ; k['M'] = '2a 32 aa';
60
+
61
+ k[',']= '33' ; k['.']='34'; k['/'] = '35' ;k[':'] = '2a 27 aa';
62
+ k['%'] = '2a 06 aa'; k['_'] = '2a 0c aa';
63
+
64
+ special=Hash.new;
65
+ special['<Enter>'] = '1c';
66
+ special['<Backspace>'] = '0e';
67
+ special['<Spacebar>'] = '39';
68
+ special['<Return>'] = '1c'
69
+ special['<Esc>'] = '01';
70
+ #special['<Up>'] = '01';
71
+ #special['<Down>'] = '01';
72
+ #special['<PageUp>'] = '01';
73
+ #special['<PageDown>'] = '01';
74
+
75
+ keycodes=''
76
+ thestring.gsub!(/ /,"<Spacebar>")
77
+
78
+ until thestring.length == 0
79
+ nospecial=true;
80
+ special.keys.each { |key|
81
+ if thestring.start_with?(key)
82
+ #take thestring
83
+ #check if it starts with a special key + pop special string
84
+ keycodes=keycodes+special[key]+' ';
85
+ thestring=thestring.slice(key.length,thestring.length-key.length)
86
+ nospecial=false;
87
+ break;
88
+ end
89
+ }
90
+ if nospecial
91
+ code=k[thestring.slice(0,1)]
92
+ if !code.nil?
93
+ keycodes=keycodes+code+' '
94
+ else
95
+ puts "no scan code for #{thestring.slice(0,1)}"
96
+ end
97
+ #pop one
98
+ thestring=thestring.slice(1,thestring.length-1)
99
+ end
100
+ end
101
+
102
+ return keycodes
103
+ end
104
+
105
+ end
106
+ end
107
+
108
+