veewee 0.1.0a → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,9 +2,4 @@ source "http://rubygems.org"
2
2
 
3
3
  gem "veewee", :path => "."
4
4
 
5
- gem 'net-ssh'
6
- gem 'virtualbox'
7
- gem 'popen4'
8
- gem 'vagrant'
9
- gem 'thor'
10
- gem 'highline'
5
+ #gem "vagrant", :git => "git://github.com/mitchellh/vagrant.git"
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- veewee (0.1.0a)
4
+ veewee (0.1.2)
5
5
  highline (~> 1.6.1)
6
6
  net-ssh (~> 2.1.0)
7
7
  popen4 (~> 0.1.2)
8
+ progressbar
8
9
  thor (~> 0.14.6)
9
10
  vagrant (~> 0.7.0)
10
11
 
@@ -29,6 +30,7 @@ GEM
29
30
  popen4 (0.1.2)
30
31
  Platform (>= 0.4.0)
31
32
  open4 (>= 0.4.0)
33
+ progressbar (0.9.0)
32
34
  rake (0.8.7)
33
35
  thor (0.14.6)
34
36
  vagrant (0.7.1)
@@ -48,10 +50,4 @@ PLATFORMS
48
50
  ruby
49
51
 
50
52
  DEPENDENCIES
51
- highline
52
- net-ssh
53
- popen4
54
- thor
55
- vagrant
56
53
  veewee!
57
- virtualbox
@@ -1,54 +1,44 @@
1
- # Veewee is currently broken due to changes in Virtualbox 4.x
2
- # We will fix them soon and move veewee to a plugin for vagrant
3
-
4
-
5
- VeeWee: the tool to easily build vagrant base boxes
6
- ===================================================
1
+ **VeeWee:** the tool to easily build vagrant base boxes
7
2
  Vagrant is a great tool to test new things or changes in a virtual machine(Virtualbox) using either chef or puppet.
8
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.
9
4
 
10
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.
11
6
 
12
7
  Before we can actually build the boxes, we need to take care of the minimal things to install:
13
- - Currently this is still a very much 'it works on my machine only' code
14
8
  - Have Virtualbox 4.x installed -> download it from http://download.virtualbox.org/virtualbox/
15
- - Have ruby and rubygems working
16
- - Have the rake gem installed -> gem install rake
17
-
18
- ALPHA CODE: -> you're on your own....
19
9
 
20
- ### WILL UPDATE SOON ####
21
10
 
11
+ ALPHA CODE: -> you're on your own....
22
12
 
23
- 1)Installation: (from source)
24
- ===========================
13
+ ## Installation:
14
+ __from source__
25
15
  $ git clone https://github.com/jedi4ever/veewee.git
26
16
  $ cd veewee
27
17
  $ gem install bundler
28
- $ bundle install
29
-
30
- Installation: (as a gem)
31
- ========================
32
- coming soon
33
-
34
- List all templates
35
- ===================
36
- $ rake templates
37
- the following templates are available:
38
- use rake define['<boxname>','CentOS-4.8-i386']
39
- use rake define['<boxname>','CentOS-5.5-i386']
40
- use rake define['<boxname>','ubuntu-10.04.1-server-i386']
41
- use rake define['<boxname>','ubuntu-10.10-server-i386']
42
-
43
- 3) Define a new box (ex. Ubuntu 10.10 server i386) - this is essentially making a copy based on the templates provided above.
44
- $ rake define['myubuntubox','ubuntu-10.10-server-i386']
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'
45
32
  template successfully copied
46
33
 
47
- -> This copies over the files in templates/ubuntu-10.10-server-i386 to definition/myubuntubox
34
+ -> This copies over the templates/ubuntu-10.10-server-i386 to definition/myubuntubox
35
+
48
36
  $ ls definitions/myubuntubox
49
37
  definition.rb postinstall.sh postinstall2.sh preseed.cfg
50
38
 
51
- 4) Optionally modify the definition.rb , postinstall.sh or preseed.cfg
39
+ ## Optionally modify the definition.rb , postinstall.sh or preseed.cfg
40
+
41
+ <pre>
52
42
  Veewee::Session.declare( {
53
43
  :cpu_count => '1', :memory_size=> '256',
54
44
  :disk_size => '10140', :disk_format => 'VDI',:disk_size => '10240' ,
@@ -75,35 +65,40 @@ Veewee::Session.declare( {
75
65
  :postinstall_files => [ "postinstall.sh"],:postinstall_timeout => "10000"
76
66
  }
77
67
  )
68
+ </pre>
78
69
 
79
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.
80
71
 
81
- 5) Put your isofile inside the $VEEWEE/iso directory or if you don't run
82
- $ rake build['myubuntubox]
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
83
77
 
84
- -> This will show you the iso to download
78
+ ## Build the new box:
79
+ $ vagrant basebox build 'myubuntubox'
85
80
 
86
- 6) Build the new box:
87
- $ rake build['myubuntubox]
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
88
89
 
89
- -> This will create a machine + disk according to the definition.rb
90
- -> Note: :os_type_id = The internal Name Virtualbox uses for that Distribution
91
- -> Mount the ISO File :iso_file
92
- -> Boot up the machine and wait for :boot_time
93
- -> Send the keystrokes in :boot_cmd_sequence
94
- -> Startup a webserver on :kickstart_port to wait for a request for the :kickstart_file
95
- -> Wait for ssh login to work with :ssh_user , :ssh_password
96
- -> Sudo execute the :postinstall_files
90
+ ## Export the vm to a .box file
91
+ $ vagrant basebox export 'myubuntubox'
97
92
 
98
- 7) Export the box into the boxes directory
99
- $ rake export['myubuntubox']
93
+ this is actually calling - vagrant package --base 'myubuntubox' --output 'boxes/myubuntubox.box'
100
94
 
101
- vagrant package --base 'myubuntubox' --output 'boxes/myubuntubox.box'
102
- vagrant box add 'myubuntubox' 'boxes/myubuntubox.box'
95
+ this will result in a myubuntubox.box
103
96
 
104
- -> This will show you the vagrant command to export and to add it your vagrant boxset
97
+ ## Add the box as one of your boxes
98
+ $ vagrant box add 'myubuntubox' 'myubuntubox.box'
105
99
 
106
- 8) Start vagrant init in another window (as we have set the Virtualbox env to tmp before)
100
+ ## Use it in vagrant
101
+ Start vagrant init in another window (as we have set the Virtualbox env to tmp before)
107
102
  $ To import it into vagrant type:
108
103
 
109
104
  To use it:
@@ -111,12 +106,14 @@ vagrant init 'myubuntubox'
111
106
  vagrant up
112
107
  vagrant ssh
113
108
 
114
- 9) If you have a setup working, share your 'definition' with me. That would be fun!
109
+ ## If you have a setup working, share your 'definition' with me. That would be fun!
115
110
 
116
111
  IDEAS:
112
+
117
113
  - Now you integrate this with your CI build to create a daily basebox
118
114
 
119
115
  FUTURE IDEAS:
116
+
120
117
  - use snapshots to fastforward initial boot, and every postinstall command
121
118
  - export to AMI too
122
119
  - provide for more failsafe execution, testing parameters
data/Rakefile CHANGED
@@ -3,36 +3,8 @@ require 'bundler'
3
3
  require 'bundler/setup'
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
- #We set this in the ENV file
7
- #ENV['GEM_PATH']=File.join(File.dirname(__FILE__),"gems")
8
- #ENV['GEM_HOME']=File.join(File.dirname(__FILE__),"gems")
9
-
10
- def check_environment
11
- begin
12
- require 'vagrant'
13
- rescue LoadError
14
- puts "you need to install dependencies:"
15
- puts "gem install vagrant"
16
- exit
17
- end
18
-
19
- begin
20
- require 'net/ssh'
21
- require 'virtualbox'
22
- require 'webrick'
23
- require 'popen4'
24
- rescue LoadError
25
- puts "hmm you had vagrant installed but are missing the net-ssh or virtualbox gem"
26
- puts "gem install virtualbox net-ssh POpen4"
27
- exit
28
- end
29
- end
30
-
31
- #See if all gems and so are installed
32
- check_environment
33
-
34
6
  #Setup some base variables to use
35
- veewee_dir= File.dirname(__FILE__)
7
+ veewee_dir= "."
36
8
  definition_dir= File.expand_path(File.join(veewee_dir, "definitions"))
37
9
  lib_dir= File.expand_path(File.join(veewee_dir, "lib"))
38
10
  box_dir= File.expand_path(File.join(veewee_dir, "boxes"))
@@ -41,8 +13,6 @@ vbox_dir=File.expand_path(File.join(veewee_dir, "tmp"))
41
13
  tmp_dir=File.expand_path(File.join(veewee_dir, "tmp"))
42
14
  iso_dir=File.expand_path(File.join(veewee_dir, "iso"))
43
15
 
44
- #needs to be moved to the config files to be allowed override
45
- ENV['VBOX_USER_HOME']=vbox_dir
46
16
 
47
17
  #Load Veewee::Session libraries
48
18
  Dir.glob(File.join(lib_dir, '**','*.rb')).each {|f|
data/bin/veewee CHANGED
@@ -30,6 +30,8 @@ Dir.glob(File.join(lib_dir, '**','*.rb')).each {|f|
30
30
  Veewee::Session.setenv({:veewee_dir => veewee_dir, :definition_dir => definition_dir,
31
31
  :template_dir => template_dir, :iso_dir => iso_dir, :box_dir => box_dir, :tmp_dir => tmp_dir})
32
32
 
33
+
34
+
33
35
  class VeeweeCLI < Thor
34
36
 
35
37
  desc "init [NAME] [TEMPLATE]", "initializes a box from a template"
@@ -67,10 +69,11 @@ class VeeweeCLI < Thor
67
69
 
68
70
  end
69
71
 
72
+
73
+
70
74
  version=VirtualBox.version
71
- if (version.match(/^4.x/))
72
- VeeweeCLI.start
75
+ if (version.match(/^4./))
76
+ VeeweeCLI.start
73
77
  else
74
- puts "veewee only supports VirtualBox 4.x"
78
+ puts "veewee only supports VirtualBox 4.x"
75
79
  end
76
-
data/lib/vagrant_init.rb CHANGED
@@ -1 +1 @@
1
- require 'veewee'
1
+ require 'veewee'
@@ -1,63 +1,66 @@
1
1
  require 'veewee/session'
2
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
+
3
7
  #Setup some base variables to use
4
- veewee_dir= File.expand_path(File.join(File.dirname(__FILE__),"..",".."))
5
- definition_dir= File.expand_path(File.join(".", "definitions"))
6
- lib_dir= File.expand_path(File.join(veewee_dir, "lib"))
7
- box_dir= File.expand_path(File.join(veewee_dir, "boxes"))
8
- template_dir=File.expand_path(File.join(veewee_dir, "templates"))
8
+ template_dir=File.expand_path(File.join(lib_dir,"..", "templates"))
9
9
 
10
- #vbox_dir=File.expand_path(File.join(veewee_dir, "tmp"))
10
+ veewee_dir="."
11
+ definition_dir= File.expand_path(File.join(veewee_dir, "definitions"))
11
12
  tmp_dir=File.expand_path(File.join(veewee_dir, "tmp"))
12
-
13
13
  iso_dir=File.expand_path(File.join(veewee_dir, "iso"))
14
-
15
- #needs to be moved to the config files to be allowed override
16
- #ENV['VBOX_USER_HOME']=vbox_dir
17
-
18
- #Load Veewee::Session libraries
19
- Dir.glob(File.join(lib_dir, '**','*.rb')).each {|f|
20
- require f }
14
+ box_dir=File.expand_path(File.join(veewee_dir, "boxes"))
21
15
 
22
16
  #Initialize
23
17
  Veewee::Session.setenv({:veewee_dir => veewee_dir, :definition_dir => definition_dir,
24
18
  :template_dir => template_dir, :iso_dir => iso_dir, :box_dir => box_dir, :tmp_dir => tmp_dir})
25
19
 
20
+ module Veewee
21
+ class Command < Vagrant::Command::GroupBase
22
+ register "basebox","Commands to manage baseboxes"
26
23
 
27
- module Vagrant
28
- module Command
29
- class BoxCommand < Vagrant::Command::GroupBase
30
- # Do not register anymore, as this registration is already done in Vagrant core
31
- # Since Ruby classes are 'open', we are just adding subcommands to the 'box' command
32
-
33
- desc "templates", "List the currently available box templates"
34
- def templates
35
- Veewee::Session.list_templates
36
- end
37
-
38
- desc "init BOXNAME TEMPLATE", "Define a new box starting from a template"
39
- def init(boxname, template)
40
- puts "Init a new box #{boxname}, starting from template #{template}"
41
- Veewee::Session.define(boxname,template)
42
- end
24
+ desc "templates", "List the currently available box templates"
25
+ def templates
26
+ Veewee::Session.list_templates
27
+ end
43
28
 
44
- desc "build BOXNAME", "Build the box BOXNAME"
45
- def build(boxname)
46
- puts "Building box #{boxname}"
47
- Veewee::Session.build(boxname)
48
- end
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
49
34
 
50
- desc "ostypes", "List the available Operating System types"
51
- def ostypes
52
- puts "Operating System types:"
53
- Veewee::Session.list_ostypes
54
- end
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
55
40
 
56
- desc "clean", "Clean all unfinished builds"
57
- def clean
58
- puts "Cleaning all unfinished builds"
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)
59
61
  end
60
-
61
- end
62
62
  end
63
+
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
@@ -2,11 +2,16 @@ module Veewee
2
2
  class Scancode
3
3
 
4
4
  def self.send_sequence(vboxcmd,vname,sequence)
5
-
5
+ puts
6
+ counter=0
6
7
  sequence.each { |s|
8
+ counter=counter+1
9
+
7
10
  s.gsub!(/%IP%/,Veewee::Session.local_ip);
8
11
  s.gsub!(/%PORT%/,'7122');
9
12
  s.gsub!(/%NAME%/, vname);
13
+ puts "Typing:[#{counter}]: "+s
14
+
10
15
  keycodes=string_to_keycode(s)
11
16
 
12
17
  # VBox seems to have issues with sending the scancodes as one big
@@ -21,13 +26,15 @@ module Veewee
21
26
  sleep 1
22
27
  }
23
28
 
29
+ puts "Done typing."
30
+ puts
24
31
 
25
32
  end
26
33
 
27
34
  def self.send_keycode(vboxcmd,vname,keycode)
28
35
  command= "#{vboxcmd} controlvm '#{vname}' keyboardputscancode #{keycode}"
29
36
  #puts "#{command}"
30
- IO.popen("#{command}") { |f| print '.' }
37
+ IO.popen("#{command}") { |f| print '' }
31
38
  end
32
39
 
33
40
  def self.string_to_keycode(thestring)
@@ -2,6 +2,10 @@ require 'digest/md5'
2
2
  require 'socket'
3
3
  require 'net/scp'
4
4
  require 'pp'
5
+ require 'open-uri'
6
+ require 'progressbar'
7
+ require 'highline/import'
8
+ require 'tempfile'
5
9
 
6
10
 
7
11
  module Veewee
@@ -41,25 +45,43 @@ module Veewee
41
45
 
42
46
  end
43
47
 
44
- def self.define(boxname,template_name)
48
+ def self.define(boxname,template_name,options = {})
45
49
  #Check if template_name exists
46
- #puts @veewee_dir
50
+
51
+ options = { "force" => false, "format" => "vagrant" }.merge(options)
52
+
47
53
  if File.directory?(File.join(@template_dir,template_name))
48
54
  else
49
- puts "this template can not be found, use vagrant box templates to list all templates"
55
+ puts "This template can not be found, use vagrant basebox templates to list all templates"
56
+ exit
50
57
  end
51
58
  if !File.exists?(@definition_dir)
52
59
  FileUtils.mkdir(@definition_dir)
53
60
  end
61
+
54
62
  if File.directory?(File.join(@definition_dir,boxname))
55
- puts "this definition already exists"
63
+ if !options["force"]
64
+ puts "The definition for #{boxname} already exists. Use --force to overwrite"
65
+ exit
66
+ end
56
67
  else
57
68
  FileUtils.mkdir(File.join(@definition_dir,boxname))
58
- FileUtils.cp_r(File.join(@template_dir,template_name,'.'),File.join(@definition_dir,boxname))
59
- puts "template succesfully copied"
60
69
  end
70
+ FileUtils.cp_r(File.join(@template_dir,template_name,'.'),File.join(@definition_dir,boxname))
71
+ puts "The basebox '#{boxname}' has been succesfully created from the template ''#{template_name}'"
72
+ puts "You can now edit the definition files stored in definitions/#{boxname}"
73
+ puts "or build the box with:"
74
+ if (options["format"]=='vagrant')
75
+ puts "vagrant basebox build '#{boxname}'"
76
+ end
77
+ if (options["format"]=='veewee')
78
+ puts "veewee build '#{boxname}'"
79
+ end
80
+
61
81
  end
62
82
 
83
+
84
+
63
85
 
64
86
  def self.definition_exists?(boxname)
65
87
  if File.directory?(File.join(@definition_dir,boxname))
@@ -85,15 +107,20 @@ module Veewee
85
107
  end
86
108
  end
87
109
 
88
- def self.list_templates
89
- puts "the following templates are available:"
110
+ def self.list_templates( options = { :format => 'vagrant'})
111
+ puts "The following templates are available:"
90
112
  subdirs=Dir.glob("#{@template_dir}/*")
91
113
  subdirs.each do |sub|
92
114
  if File.directory?("#{sub}")
93
115
  definition=Dir.glob("#{sub}/definition.rb")
94
116
  if definition.length!=0
95
117
  name=sub.sub(/#{@template_dir}\//,'')
96
- puts "vagrant box init '<boxname>' '#{name}'"
118
+ if (options[:format]=='vagrant')
119
+ puts "vagrant basebox define '<boxname>' '#{name}'"
120
+ end
121
+ if (options[:format]=='veewee')
122
+ puts "veewee define '<boxname>' '#{name}'"
123
+ end
97
124
  end
98
125
  end
99
126
  end
@@ -111,9 +138,10 @@ module Veewee
111
138
  puts "Not yet implemented"
112
139
  end
113
140
 
114
- def self.verify_iso(filename)
141
+ def self.verify_iso(filename,autodownload = false)
115
142
  if File.exists?(File.join(@iso_dir,filename))
116
- puts "isofile #{filename} is available"
143
+ puts
144
+ puts "Verifying the isofile #{filename} is ok."
117
145
  else
118
146
  full_path=File.join(@iso_dir,filename)
119
147
  path1=Pathname.new(full_path)
@@ -121,15 +149,23 @@ module Veewee
121
149
  rel_path=path1.relative_path_from(path2).to_s
122
150
 
123
151
  puts
124
- puts "Isofile is not found. The definition suggested the following URL to download:"
125
- puts "-url: #{@definition[:iso_src]}"
126
- puts "-md5: #{@definition[:iso_md5]}"
152
+ puts "The isofile is not found. The definition provided the following information:"
153
+ puts "- Download url: #{@definition[:iso_src]}"
154
+ puts "- Md5 Checksum: #{@definition[:iso_md5]}"
127
155
  puts ""
128
- puts "type:"
129
- puts "curl -C - -L '#{@definition[:iso_src]}' -o '#{rel_path}'"
130
- puts "md5 '#{rel_path}' "
131
- puts
132
- exit
156
+
157
+ question=ask("Download? (Yes/No)") {|q| q.default="No"}
158
+ if question.downcase == "yes"
159
+ download_progress(@definition[:iso_src],full_path)
160
+ else
161
+ puts "You have choosen for manual download: "
162
+ puts "curl -C - -L '#{@definition[:iso_src]}' -o '#{rel_path}'"
163
+ puts "md5 '#{rel_path}' "
164
+ puts
165
+ exit
166
+ end
167
+
168
+
133
169
  end
134
170
 
135
171
  end
@@ -145,7 +181,10 @@ module Veewee
145
181
  puts "Not yet implemented"
146
182
  end
147
183
 
148
- def self.build(boxname)
184
+ def self.build(boxname,options)
185
+
186
+ options = { "force" => false, "format" => "vagrant" }.merge(options)
187
+
149
188
  #Now we have to load the definition (reads definition.rb)
150
189
  load_definition(boxname)
151
190
 
@@ -160,9 +199,13 @@ module Veewee
160
199
 
161
200
  verify_iso(@definition[:iso_file])
162
201
 
202
+ if (options["force"]==false)
203
+ else
204
+ puts "Forcing build by destroying #{boxname} machine"
205
+ destroy_vm(boxname)
206
+ end
207
+
163
208
  checksums=calculate_checksums(@definition,boxname)
164
-
165
-
166
209
 
167
210
  transaction(boxname,"0-initial-#{checksums[0]}",checksums) do
168
211
 
@@ -187,11 +230,12 @@ module Veewee
187
230
 
188
231
 
189
232
  #waiting for it to boot
233
+ puts "Waiting for the machine to boot"
190
234
  sleep @definition[:boot_wait].to_i
191
235
 
192
- puts "sending keys"
193
236
  Veewee::Scancode.send_sequence("#{@vboxcmd}","#{boxname}",@definition[:boot_cmd_sequence])
194
237
 
238
+ puts "Starting a webserver on port #{@definition[:kickstart_port]}"
195
239
  #:kickstart_port => "7122", :kickstart_ip => self.local_ip, :kickstart_timeout => 1000,:kickstart_file => "preseed.cfg",
196
240
  Veewee::Web.wait_for_request(@definition[:kickstart_file],{:port => @definition[:kickstart_port],
197
241
  :host => @definition[:kickstart_ip], :timeout => @definition[:kickstart_timeout],
@@ -199,15 +243,16 @@ module Veewee
199
243
 
200
244
  Veewee::Ssh.when_ssh_login_works("localhost",ssh_options) do
201
245
  #Transfer version of Virtualbox to $HOME/.vbox_version
202
- versionfile=File.join(@tmp_dir,".vbox_version")
203
- File.open(versionfile, 'w') {|f| f.write("#{VirtualBox::Global.global.lib.virtualbox.version}") }
204
- Veewee::Ssh.transfer_file("localhost",versionfile,ssh_options)
246
+ versionfile=Tempfile.open("vbox.version")
247
+ versionfile.puts "#{VirtualBox::Global.global.lib.virtualbox.version}"
248
+ versionfile.rewind
249
+ Veewee::Ssh.transfer_file("localhost",versionfile.path,".vbox_version", ssh_options)
250
+ versionfile.close
251
+ versionfile.delete
205
252
  end
206
253
  end #initial Transaction
207
254
 
208
-
209
-
210
-
255
+
211
256
  counter=1
212
257
  @definition[:postinstall_files].each do |postinstall_file|
213
258
 
@@ -270,7 +315,58 @@ module Veewee
270
315
  vm.save
271
316
  end
272
317
 
273
- def self.create_vm(boxname)
318
+ def self.destroy_vm(boxname)
319
+
320
+ load_definition(boxname)
321
+
322
+ #:destroy_medium => :delete, will delete machine + all media attachments
323
+ #vm.destroy(:destroy_medium => :delete)
324
+ ##vm.destroy(:destroy_image => true)
325
+
326
+ #VBoxManage unregistervm "test-machine" --delete
327
+ #because the destroy does remove the .vbox file on 4.0.x
328
+ #PDB
329
+ #vm.destroy()
330
+
331
+
332
+
333
+ vm=VirtualBox::VM.find(boxname)
334
+
335
+ if (!vm.nil? && !(vm.powered_off?))
336
+ puts "Shutting down vm #{boxname}"
337
+ #We force it here, maybe vm.shutdown is cleaner
338
+ vm.stop
339
+ end
340
+ sleep 3
341
+
342
+ command="#{@vboxcmd} unregistervm '#{boxname}' --delete"
343
+
344
+ puts "Deleting vm #{boxname}"
345
+
346
+ #Exec and system stop the execution here
347
+ Veewee::Shell.execute("#{command}")
348
+ sleep 1
349
+
350
+ #if the disk was not attached when the machine was destroyed we also need to delete the disk
351
+ location=boxname+"."+@definition[:disk_format].downcase
352
+ found=false
353
+ VirtualBox::HardDrive.all.each do |d|
354
+ if !d.location.match(/#{location}/).nil?
355
+
356
+ command="#{@vboxcmd} closemedium disk '#{d.location}' --delete"
357
+ puts "Deleting disk #{d.location}"
358
+ Veewee::Shell.execute("#{command}")
359
+ #v.3
360
+ #d.destroy(true)
361
+ break
362
+ end
363
+ end
364
+
365
+
366
+
367
+ end
368
+
369
+ def self.create_vm(boxname,force=false)
274
370
 
275
371
  #Verifying the os.id with the :os_type_id specified
276
372
  matchfound=false
@@ -293,8 +389,8 @@ module Veewee
293
389
  vm.stop
294
390
  end
295
391
 
296
- if !vm.nil?
297
- puts "box already exists"
392
+ if !vm.nil?
393
+ puts "Box already exists"
298
394
  #vm.stop
299
395
  #vm.destroy
300
396
  else
@@ -302,11 +398,9 @@ module Veewee
302
398
  #Box does not exist, we can start to create it
303
399
 
304
400
  command="#{@vboxcmd} createvm --name '#{boxname}' --ostype '#{@definition[:os_type_id]}' --register"
305
- puts command
306
401
 
307
402
  #Exec and system stop the execution here
308
403
  Veewee::Shell.execute("#{command}")
309
- sleep 3
310
404
 
311
405
  end
312
406
 
@@ -322,7 +416,8 @@ module Veewee
322
416
  vm.os_type_id=@definition[:os_type_id]
323
417
  vm.cpu_count=@definition[:cpu_count].to_i
324
418
  vm.name=boxname
325
-
419
+
420
+ puts "Creating vm #{vm.name} : #{vm.memory_size}M - #{vm.cpu_count} CPU - #{vm.os_type_id}"
326
421
  #setting bootorder
327
422
  vm.boot_order[0]=:hard_disk
328
423
  vm.boot_order[1]=:dvd
@@ -348,7 +443,7 @@ module Veewee
348
443
  end
349
444
 
350
445
  if !found
351
- puts "creating new harddrive"
446
+ puts "Creating new harddrive of size #{@definition[:disk_size].to_i} "
352
447
 
353
448
  #newdisk=VirtualBox::HardDrive.new
354
449
  #newdisk.format=@definition[:disk_format]
@@ -364,8 +459,7 @@ module Veewee
364
459
  place=results.gets.chop
365
460
  results.close
366
461
 
367
- puts "#{command}"
368
- command ="#{@vboxcmd} createhd --filename '#{place}/#{boxname}/#{boxname}.#{@definition[:disk_format]}' --size '#{@definition[:disk_size].to_i}' --format #{@definition[:disk_format]}"
462
+ command ="#{@vboxcmd} createhd --filename '#{place}/#{boxname}/#{boxname}.#{@definition[:disk_format]}' --size '#{@definition[:disk_size].to_i}' --format #{@definition[:disk_format]} > /dev/null"
369
463
  Veewee::Shell.execute("#{command}")
370
464
 
371
465
  end
@@ -394,20 +488,17 @@ module Veewee
394
488
  results.close
395
489
 
396
490
  location="#{place}/#{boxname}/"+location
397
-
398
- puts "location=#{location}"
399
-
491
+ puts "Attaching disk: #{location}"
400
492
 
401
493
  #command => "${vboxcmd} storageattach '${vname}' --storagectl 'SATA Controller' --port 0 --device 0 --type hdd --medium '${vname}.vdi'",
402
494
  command ="#{@vboxcmd} storageattach '#{boxname}' --storagectl 'SATA Controller' --port 0 --device 0 --type hdd --medium '#{location}'"
403
- puts "#{command}"
404
495
  Veewee::Shell.execute("#{command}")
405
496
 
406
497
  end
407
498
 
408
499
  def self.mount_isofile(boxname,isofile)
409
500
  full_iso_file=File.join(@iso_dir,isofile)
410
- puts "#{full_iso_file}"
501
+ puts "Mounting cdrom: #{full_iso_file}"
411
502
  #command => "${vboxcmd} storageattach '${vname}' --storagectl 'IDE Controller' --type dvddrive --port 1 --device 0 --medium '${isodst}' ";
412
503
  command ="#{@vboxcmd} storageattach '#{boxname}' --storagectl 'IDE Controller' --type dvddrive --port 1 --device 0 --medium '#{full_iso_file}'"
413
504
  Veewee::Shell.execute("#{command}")
@@ -443,10 +534,7 @@ module Veewee
443
534
  puts "Available os types:"
444
535
  VirtualBox::Global.global.lib.virtualbox.guest_os_types.collect { |os|
445
536
  puts "#{os.id}: #{os.description}"
446
- }
447
-
448
- puts
449
-
537
+ }
450
538
  end
451
539
 
452
540
 
@@ -477,11 +565,28 @@ module Veewee
477
565
  end
478
566
  end
479
567
 
480
- pp checksums
481
568
  return checksums
482
569
 
483
570
  end
484
571
 
572
+ def self.download_progress(url,localfile)
573
+ pbar = nil
574
+ URI.parse(url).open(
575
+ :content_length_proc => lambda {|t|
576
+ if t && 0 < t
577
+ pbar = ProgressBar.new("Fetching file", t)
578
+ pbar.file_transfer_mode
579
+ end
580
+ },
581
+ :progress_proc => lambda {|s|
582
+ pbar.set s if pbar
583
+ }) { |src|
584
+ open("#{localfile}","wb") { |dst|
585
+ dst.write(src.read)
586
+ }
587
+ }
588
+
589
+ end
485
590
 
486
591
  def self.transaction(boxname,step_name,checksums,&block)
487
592
 
@@ -504,8 +609,6 @@ module Veewee
504
609
  end
505
610
  end
506
611
 
507
- pp snapnames
508
-
509
612
  #find the last snapshot matching the state
510
613
  counter=[snapnames.length, checksums.length].min-1
511
614
  last_good_state=counter
@@ -517,14 +620,14 @@ module Veewee
517
620
  break
518
621
  end
519
622
  end
520
- puts "Last good state: #{last_good_state}"
623
+ #puts "Last good state: #{last_good_state}"
521
624
 
522
625
  if (current_step_nr < last_good_state)
523
- puts "fast forwarding #{step_name}"
626
+ #puts "fast forwarding #{step_name}"
524
627
  return
525
628
  end
526
629
 
527
- puts "Current step: #{current_step_nr}"
630
+ #puts "Current step: #{current_step_nr}"
528
631
  if (current_step_nr == last_good_state)
529
632
  if vm.running?
530
633
  vm.stop
@@ -534,14 +637,14 @@ module Veewee
534
637
  #puts "remove old snapshots"
535
638
 
536
639
  for s in (last_good_state+1)..(snapnames.length-1)
537
- puts "removing snapname #{snapnames[s]}"
640
+ puts "Removing step [s] snapshot as it is no more valid"
538
641
  snapshot=vm.find_snapshot(snapnames[s])
539
642
  snapshot.destroy
540
643
  #puts snapshot
541
644
  end
542
645
 
543
646
  vm.reload
544
- puts "action load #{step_name}"
647
+ puts "Loading step #{current_step_nr} snapshots as it has not changed"
545
648
  sleep 2
546
649
  goodsnap=vm.find_snapshot(snapnames[last_good_state])
547
650
  goodsnap.restore
@@ -551,7 +654,7 @@ module Veewee
551
654
 
552
655
  end
553
656
 
554
- puts "last good state #{last_good_state}"
657
+ #puts "last good state #{last_good_state}"
555
658
 
556
659
 
557
660
  if (current_step_nr > last_good_state)
@@ -562,66 +665,41 @@ module Veewee
562
665
 
563
666
  if !vm.nil?
564
667
  if vm.running?
565
- puts "stopping machine"
668
+ puts "Stopping machine"
566
669
  vm.stop
567
670
  while vm.running?
568
671
  sleep 1
569
672
  end
570
673
  end
571
674
 
572
- #detaching cdroms
573
- vm.medium_attachments.each do |m|
574
- if m.type==:dvd
575
- puts "detaching dvd"
576
- m.detach
577
- end
578
- end
675
+ #detaching cdroms (used to work in 3.x)
676
+ # vm.medium_attachments.each do |m|
677
+ # if m.type==:dvd
678
+ # #puts "Detaching dvd"
679
+ # m.detach
680
+ # end
681
+ # end
579
682
 
580
683
  vm.reload
581
- puts "destroying machine+disks"
582
- #:destroy_medium => :delete, will delete machine + all media attachments
583
- #vm.destroy(:destroy_medium => :delete)
584
- ##vm.destroy(:destroy_image => true)
585
-
586
- #VBoxManage unregistervm "test-machine" --delete
587
- #because the destroy does remove the .vbox file on 4.0.x
588
- #PDB
589
- #vm.destroy()
590
-
591
- command="#{@vboxcmd} unregistervm '#{boxname}' --delete"
592
- puts command
593
-
594
- #Exec and system stop the execution here
595
- Veewee::Shell.execute("#{command}")
596
-
597
- #if the disk was not attached when the machine was destroyed we also need to delete the disk
598
- location=boxname+"."+@definition[:disk_format].downcase
599
- found=false
600
- VirtualBox::HardDrive.all.each do |d|
601
- if !d.location.match(/#{location}/).nil?
602
- d.destroy(true)
603
- break
604
- end
605
- end
684
+ puts "We found no good state so we are destroying the previous machine+disks"
685
+ destroy_vm(boxname)
606
686
  end
607
687
 
608
688
  end
609
689
 
610
- puts "(re-)executing step #{step_name}"
690
+ #puts "(re-)executing step #{step_name}"
611
691
 
612
692
 
613
693
  yield
614
- puts "seeking #{boxname}"
694
+
615
695
  #Need to look it up again because if it was an initial load
616
696
  vm=VirtualBox::VM.find(boxname)
617
- puts "saving state"
697
+ puts "Step [#{current_step_nr}] was succesfull - saving state"
618
698
  vm.save_state
619
- puts "waiting for 2 secs"
620
699
  sleep 2 #waiting for it to be ok
621
- puts "about to snapshot #{vm}"
700
+ #puts "about to snapshot #{vm}"
622
701
  #take snapshot after succesful execution
623
702
  vm.take_snapshot(step_name,"snapshot taken by veewee")
624
- puts "wait 2 secs before starting"
625
703
  sleep 2 #waiting for it to be started again
626
704
  vm.start
627
705
  end
data/lib/veewee/shell.rb CHANGED
@@ -15,7 +15,9 @@ module Veewee
15
15
  begin
16
16
  PTY.spawn( command ) do |r, w, pid|
17
17
  begin
18
- r.each { |line| print line;}
18
+ r.each { }
19
+ #r.each { |line| print line;}
20
+
19
21
  rescue Errno::EIO
20
22
  end
21
23
  end
data/lib/veewee/ssh.rb CHANGED
@@ -5,10 +5,11 @@ module Veewee
5
5
 
6
6
  defaults={ :port => '22', :timeout => 200 , :user => 'vagrant', :password => 'vagrant'}
7
7
 
8
- puts "checking if login works ssh => #{options[:port]}"
9
-
10
8
  options=defaults.merge(options)
11
9
 
10
+ puts
11
+ puts "Trying ssh login with user #{options[:user]} to sshd on port => #{options[:port]}"
12
+
12
13
  begin
13
14
  Timeout::timeout(options[:timeout]) do
14
15
  connected=false
@@ -33,11 +34,13 @@ module Veewee
33
34
  end
34
35
 
35
36
 
36
- def self.transfer_file(host,filename,options)
37
+ def self.transfer_file(host,filename,destination = '.' , options)
37
38
  Net::SSH.start( host,options[:user],options ) do |ssh|
38
- puts "Transferring #{filename} "
39
- ssh.scp.upload!( filename, '.' ) do |ch, name, sent, total|
40
- print "\r#{filename}: #{(sent.to_f * 100 / total.to_f).to_i}%"
39
+ puts "Transferring #{filename} to #{destination} "
40
+ ssh.scp.upload!( filename, destination ) do |ch, name, sent, total|
41
+ # print "\r#{destination}: #{(sent.to_f * 100 / total.to_f).to_i}%"
42
+ print "."
43
+
41
44
  end
42
45
  end
43
46
  puts
@@ -1,3 +1,3 @@
1
1
  module Veewee
2
- VERSION = "0.1.0a"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/veewee/web.rb CHANGED
@@ -14,7 +14,7 @@ module Veewee
14
14
  def do_GET(request,response)
15
15
  response['Content-Type']='text/plain'
16
16
  response.status = 200
17
-
17
+ puts "Serving file #{@localfile}"
18
18
  displayfile=File.open(@localfile,'r')
19
19
  content=displayfile.read()
20
20
  response.body=content
@@ -26,12 +26,19 @@ module Veewee
26
26
 
27
27
  def self.wait_for_request(filename,options={:timeout => 10, :web_dir => "", :port => 7125})
28
28
 
29
+ webrick_logger=WEBrick::Log.new("/dev/null", WEBrick::Log::INFO)
30
+
29
31
  web_dir=options[:web_dir]
30
32
  filename=filename
31
- s= HTTPServer.new(:Port => options[:port])
33
+ s= HTTPServer.new(
34
+ :Port => options[:port],
35
+ :Logger => webrick_logger,
36
+ :AccessLog => webrick_logger
37
+ )
32
38
  s.mount("/#{filename}", FileServlet,File.join(web_dir,filename))
33
39
  trap("INT"){
34
40
  s.shutdown
41
+ puts "Stopping webserver"
35
42
  exit
36
43
  }
37
44
  s.start
@@ -36,7 +36,7 @@ VBOX_VERSION=$(cat /home/vagrant/.vbox_version)
36
36
  cd /tmp
37
37
  wget http://download.virtualbox.org/virtualbox/$VBOX_VERSION/VBoxGuestAdditions_$VBOX_VERSION.iso
38
38
  mount -o loop VBoxGuestAdditions_$VBOX_VERSION.iso /mnt
39
- sh /mnt/VBoxLinuxAdditions-x86.run
39
+ sh /mnt/VBoxLinuxAdditions.run
40
40
  umount /mnt
41
41
 
42
42
  rm VBoxGuestAdditions_$VBOX_VERSION.iso
data/veewee.gemspec CHANGED
@@ -19,6 +19,9 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency "popen4", "~> 0.1.2"
20
20
  s.add_dependency "thor", "~> 0.14.6"
21
21
  s.add_dependency "highline", "~> 1.6.1"
22
+ s.add_dependency "progressbar"
23
+
24
+ s.add_development_dependency "bundler", ">= 1.0.0"
22
25
 
23
26
  s.files = `git ls-files`.split("\n")
24
27
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: veewee
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 5
5
- version: 0.1.0a
4
+ prerelease:
5
+ version: 0.1.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Patrick Debois
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-02-06 00:00:00 +01:00
14
+ date: 2011-02-07 00:00:00 +01:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -69,6 +69,28 @@ dependencies:
69
69
  type: :runtime
70
70
  prerelease: false
71
71
  version_requirements: *id005
72
+ - !ruby/object:Gem::Dependency
73
+ name: progressbar
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ type: :runtime
81
+ prerelease: false
82
+ version_requirements: *id006
83
+ - !ruby/object:Gem::Dependency
84
+ name: bundler
85
+ requirement: &id007 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.0.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: *id007
72
94
  description: Expand the 'vagrant box' command to support the creation of base boxes from scratch
73
95
  email:
74
96
  - patrick.debois@jedi.be
@@ -84,15 +106,14 @@ files:
84
106
  - .rvmrc
85
107
  - Gemfile
86
108
  - Gemfile.lock
87
- - README
109
+ - README.md
88
110
  - Rakefile
89
- - TODO
90
111
  - bin/veewee
91
- - gems/.gitignore
92
112
  - iso/.gitignore
93
113
  - lib/vagrant_init.rb
94
114
  - lib/veewee.rb
95
115
  - lib/veewee/command.rb
116
+ - lib/veewee/config.rb
96
117
  - lib/veewee/export.rb
97
118
  - lib/veewee/scancode.rb
98
119
  - lib/veewee/session.rb
@@ -125,7 +146,6 @@ files:
125
146
  - templates/ubuntu-10.10-server-i386/postinstall.sh
126
147
  - templates/ubuntu-10.10-server-i386/postinstall2.sh
127
148
  - templates/ubuntu-10.10-server-i386/preseed.cfg
128
- - tmp/.gitignore
129
149
  - trials/docu-vbox.txt
130
150
  - trials/f.rb
131
151
  - trials/t.rb
@@ -144,7 +164,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
164
  requirements:
145
165
  - - ">="
146
166
  - !ruby/object:Gem::Version
147
- hash: 1588562477501260201
167
+ hash: 1560906446498783228
148
168
  segments:
149
169
  - 0
150
170
  version: "0"
data/TODO DELETED
@@ -1 +0,0 @@
1
- Maybe use Bittorrent to download iso - http://rubytorrent.rubyforge.org/
data/gems/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- *
2
- !.gitignore
data/tmp/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- *
2
- !.gitignore