veewee 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +7 -0
- data/.rvmrc +2 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +53 -0
- data/README.md +124 -0
- data/Rakefile +92 -0
- data/bin/veewee +79 -0
- data/iso/.gitignore +2 -0
- data/lib/vagrant_init.rb +1 -0
- data/lib/veewee/command.rb +66 -0
- data/lib/veewee/config.rb +5 -0
- data/lib/veewee/export.rb +81 -0
- data/lib/veewee/scancode.rb +108 -0
- data/lib/veewee/session.rb +712 -0
- data/lib/veewee/shell.rb +54 -0
- data/lib/veewee/ssh.rb +164 -0
- data/lib/veewee/transaction.rb +112 -0
- data/lib/veewee/version.rb +3 -0
- data/lib/veewee/web.rb +48 -0
- data/lib/veewee.rb +2 -0
- data/templates/CentOS-4.8-i386/definition.rb +14 -0
- data/templates/CentOS-4.8-i386/ks.cfg +45 -0
- data/templates/CentOS-4.8-i386/postinstall.sh +47 -0
- data/templates/CentOS-5.5-i386/definition.rb +16 -0
- data/templates/CentOS-5.5-i386/ks.cfg +45 -0
- data/templates/CentOS-5.5-i386/postinstall.sh +48 -0
- data/templates/CentOS-5.5-i386-netboot/definition.rb +17 -0
- data/templates/CentOS-5.5-i386-netboot/ks.cfg +45 -0
- data/templates/CentOS-5.5-i386-netboot/postinstall.sh +48 -0
- data/templates/ubuntu-10.04.1-server-amd64/definition.rb +25 -0
- data/templates/ubuntu-10.04.1-server-amd64/postinstall.sh +33 -0
- data/templates/ubuntu-10.04.1-server-amd64/preseed.cfg +87 -0
- data/templates/ubuntu-10.04.1-server-i386/definition.rb +25 -0
- data/templates/ubuntu-10.04.1-server-i386/postinstall.sh +43 -0
- data/templates/ubuntu-10.04.1-server-i386/postinstall2.sh +9 -0
- data/templates/ubuntu-10.04.1-server-i386/preseed.cfg +87 -0
- data/templates/ubuntu-10.10-server-amd64/definition.rb +25 -0
- data/templates/ubuntu-10.10-server-amd64/postinstall.sh +43 -0
- data/templates/ubuntu-10.10-server-amd64/postinstall2.sh +9 -0
- data/templates/ubuntu-10.10-server-amd64/preseed.cfg +87 -0
- data/templates/ubuntu-10.10-server-i386/definition.rb +25 -0
- data/templates/ubuntu-10.10-server-i386/postinstall.sh +43 -0
- data/templates/ubuntu-10.10-server-i386/postinstall2.sh +9 -0
- data/templates/ubuntu-10.10-server-i386/preseed.cfg +87 -0
- data/trials/docu-vbox.txt +83 -0
- data/trials/f.rb +29 -0
- data/trials/t.rb +15 -0
- data/veewee.gemspec +30 -0
- metadata +219 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
data/Gemfile
ADDED
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
data/lib/vagrant_init.rb
ADDED
@@ -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,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
|
+
|