virtualman 1.1.9 → 2.0.0

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.
@@ -2,7 +2,8 @@
2
2
 
3
3
  ####Required
4
4
  require 'virtualman'
5
- include Interractive
5
+
6
+ repl = Virtualman::Interactive::REPL.new
6
7
 
7
8
  menu = ["clone","cook","ssh","add","delete","bootify","exit"]
8
9
 
@@ -11,8 +12,11 @@ choice = "0"
11
12
  while choice != "exit"
12
13
  puts "----VirtualMan----"
13
14
  puts "Please select an action to do with your VM."
14
- choice = Menu.unic_run(menu)
15
- Interractive.send(choice)
15
+ choice = Virtualman::Interactive::Menu.unic_run(menu)
16
+
17
+ if choice != "exit"
18
+ repl.send(choice)
19
+ end
16
20
  end
17
21
 
18
22
  puts "Thank you come again!"
@@ -1,5 +1,8 @@
1
- require 'virtualman/menu'
2
- require 'virtualman/vm'
3
- require 'virtualman/vmlister'
4
- require 'virtualman/configuration'
5
- require 'virtualman/interractive'
1
+ module Virtualman
2
+ require 'virtualman/interactive/helper'
3
+ require 'virtualman/interactive/menu'
4
+ require 'virtualman/vm'
5
+ require 'virtualman/vmlister'
6
+ require 'virtualman/interactive/configuration'
7
+ require 'virtualman/interactive/REPL'
8
+ end
@@ -0,0 +1,124 @@
1
+ module Virtualman
2
+ module Interactive
3
+ class REPL
4
+ attr_reader :configuration
5
+
6
+ include Virtualman::Interactive::Helper
7
+
8
+ def initialize
9
+ @configuration = Virtualman::Interactive::Configuration.new
10
+ end
11
+
12
+ def clone
13
+ cloned_vm = self.clone_vm
14
+ self.start_vm(cloned_vm)
15
+ self.configuration.add_cloned_vm(cloned_vm)
16
+ end
17
+
18
+ def cook
19
+ puts "----Cook a clone!----"
20
+ puts "Which VM do you want to cook?"
21
+ role_path = self.configuration.options["role_path"]
22
+ cookbook_path = self.configuration.options["cookbook_path"]
23
+
24
+ selected_vm = self.choose_vm "cloned_vms"
25
+
26
+ puts "Which role do you want to give?"
27
+
28
+ role = self.choose "roles"
29
+
30
+ user="root"
31
+
32
+ if self.start_vm(selected_vm)
33
+ cmd = "ssh #{user}@#{selected_vm.ip} '/usr/local/bin/chef-solo -j #{role_path}#{role["name"]}.json -r #{cookbook_path}'"
34
+ puts cmd
35
+ Kernel.system(cmd)
36
+ end
37
+
38
+ puts "Thanks!"
39
+ end
40
+
41
+ def ssh
42
+ puts "----SSH to cloned VM----"
43
+ puts "Which VM do you want to ssh?"
44
+
45
+ selected_vm = self.choose_vm "cloned_vms"
46
+
47
+ puts "With which user? [root]"
48
+ user = Menu.ask
49
+
50
+ if user.empty?
51
+ user = "root"
52
+ end
53
+
54
+ if self.start_vm(selected_vm)
55
+ cmd = "ssh #{user}@#{selected_vm.ip}"
56
+ Kernel.exec(cmd)
57
+ end
58
+ end
59
+
60
+ def delete
61
+ puts "----Delete a cloned VM----"
62
+ puts "Which VM delete?"
63
+
64
+ selected_vm = self.choose_vm "cloned_vms"
65
+
66
+ puts "!!YOU ARE ABOUT TO DELETE PEMANENTLY DELETE #{selected_vm.name}!!"
67
+ puts "Are you sure? (yes/[no])"
68
+
69
+ choice = Menu.ask
70
+
71
+ if choice == "yes"
72
+ selected_vm.stop!
73
+
74
+ selected_vm.manage("unregistervm","--delete")
75
+
76
+ self.configuration.delete_cloned_vm(selected_vm)
77
+ else
78
+ puts "VM not deleted!"
79
+ end
80
+ end
81
+
82
+ def add
83
+ puts "----Add a VM----"
84
+ puts "Give the path of the OVA file you want to add"
85
+ puts "(An OVA file represents a Virtual Machine)"
86
+
87
+ path = Menu.ask
88
+
89
+ cmd = "VBoxManage import #{path}"
90
+ puts cmd
91
+ `#{cmd}`
92
+
93
+ if $?.exitstatus == 0
94
+ added_vm = Vm.new(File.basename("#{path}",".*"))
95
+ self.configuration.add_cloned_vm(added_vm)
96
+ else
97
+ puts "There was an error during the import"
98
+ end
99
+ end
100
+
101
+ def bootify
102
+ puts "----Start a VM at boot----"
103
+ puts "Initializing bootify...."
104
+ self.init_bootify
105
+ puts "Whcih VM do you want to add to your boot sequence?"
106
+
107
+ selected_vm = self.choose_vm "cloned_vms"
108
+
109
+ puts "We need to shutdown the VM to add to the boot list."
110
+ puts "Do you want to procedd now? (yes/[no])"
111
+
112
+ choice = Menu.ask
113
+
114
+ if choice == "yes"
115
+ selected_vm.stop!
116
+ selected_vm.manage("modifyvm", "--autostart-enabled on", "--autostart-delay 10")
117
+ puts "#{selected_vm.name} added to your boot sequence."
118
+ start_vm selected_vm
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,55 @@
1
+ require 'yaml'
2
+
3
+ module Virtualman
4
+ module Interactive
5
+ class Configuration
6
+
7
+ attr_reader :options, :filepath
8
+
9
+ def initialize
10
+ @filepath = File.join(ENV['HOME'],'.virtualman.rc.yaml')
11
+
12
+ if File.exists? @filepath
13
+ @options = YAML.load_file(@filepath)
14
+ else
15
+ STDERR.puts("No configuration file found here ~/.vm_to_clone.rc.yaml")
16
+ STDERR.puts("Thanks to create this file before continuing!")
17
+ STDERR.puts "Config file example:"
18
+ STDERR.puts "---"
19
+ STDERR.puts "source_vm:"
20
+ STDERR.puts " - name: Debian"
21
+ STDERR.puts " snapshot: ready to clone!"
22
+ STDERR.puts " - name: Gentoo"
23
+ STDERR.puts " snapshot: almost ready"
24
+ STDERR.puts "role_path: http://path/to/your/role/fodler"
25
+ STDERR.puts "cookbook_path: http://path/to/your/cookbooks.tar.gz"
26
+ STDERR.puts "roles:"
27
+ STDERR.puts "- devtest"
28
+ STDERR.puts "- devtest_jenkins"
29
+ STDERR.puts "- build_pkg_devtest_jenkins"
30
+ Kernel.abort("No configuration file found here ~/.vm_to_clone.rc.yaml")
31
+ end
32
+ end
33
+
34
+ def record_conf(msg)
35
+ File.open(@filepath, "w") {|f| f.write(@options.to_yaml) }
36
+ puts "#{msg} to your configuration file"
37
+ end
38
+
39
+ def add_cloned_vm(vm_cloned)
40
+ if @options["cloned_vms"] != nil
41
+ @options["cloned_vms"] << {"name" => vm_cloned.name}
42
+ else
43
+ @options.merge!({"cloned_vms" => [{"name" => vm_cloned.name}]})
44
+ end
45
+ record_conf("VM #{vm_cloned.name} has been saved")
46
+ end
47
+
48
+ def delete_cloned_vm(vm_cloned)
49
+ @options["cloned_vms"].reject!{|vm| vm == {"name" => vm_cloned.name.gsub(/\"/,'')} }
50
+ record_conf("VM #{vm_cloned.name} has been deleted")
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,209 @@
1
+ module Virtualman
2
+ module Interactive
3
+ module Helper
4
+ require 'fileutils'
5
+ require 'erb'
6
+
7
+ extend self
8
+
9
+ def choose source
10
+
11
+ list = Array.new
12
+ self.configuration.options[source].each do |option|
13
+ list << option["name"]
14
+ end
15
+ list << "exit"
16
+
17
+ choice = Menu.unic_run(list)
18
+
19
+ exit 0 if choice == "exit"
20
+
21
+ self.configuration.options[source].each_with_index do |option,index|
22
+ if option["name"] == choice
23
+ return self.configuration.options[source][index]
24
+ end
25
+ end
26
+
27
+ end
28
+
29
+ #Source can be either source_vms or clonned_vms
30
+ def choose_vm source
31
+ vm_choice = choose source
32
+ return Vm.new("#{vm_choice["name"]}")
33
+
34
+ end
35
+
36
+ def clone_vm
37
+ puts "----Clone_VM----"
38
+ puts "Which VM do you want to clone?"
39
+
40
+ vm_choice = choose "source_vms"
41
+ vm_to_clone = Vm.new("\"#{vm_choice["name"]}\"")
42
+
43
+ puts "How do you want to name your freshly spawned VM?"
44
+ vm_name = Menu.ask
45
+
46
+ options = "--snapshot \"#{vm_choice["snapshot"]}\" --name \"#{vm_name}\" --register"
47
+ vm_to_clone.manage("clonevm", options)
48
+ vm_cloned = Vm.new(vm_name)
49
+ return vm_cloned
50
+ end
51
+
52
+ def start_vm(vm)
53
+ if !vm.running?
54
+ puts "Do you want to start the VM? headless?"
55
+ puts "(default is no)"
56
+ puts "yes/headless/[no]"
57
+
58
+ answer = Menu.ask
59
+
60
+ if answer == "headless"
61
+ option = "--type headless"
62
+ puts "The VM is booting headless"
63
+ elsif answer == "yes"
64
+ option = ""
65
+ puts "The VM is booting"
66
+ else
67
+ puts "The vm will not be started"
68
+ return false
69
+ end
70
+
71
+ vm.manage("startvm", option)
72
+
73
+ Kernel.print "Waiting for the VM to get an IP"
74
+ while !vm.ip
75
+ Kernel.print "."
76
+ Kernel.sleep (1)
77
+ end
78
+ Kernel.print "\n"
79
+ end
80
+
81
+ return vm.running?
82
+ end
83
+
84
+
85
+
86
+ def check_chmod_script
87
+ script = "/Applications/VirtualBox.app/Contents/MacOS/VBoxAutostartDarwin.sh"
88
+ permission = Kernel.sprintf("%o", File.world_readable?(script) )
89
+ if permission != "744"
90
+ puts "Changing file permission of #{script}, to allow it to be executable"
91
+ puts "Thanks to provide your admin password."
92
+ File.chmod(0744, script)
93
+ end
94
+ end
95
+
96
+ def integrate_template filename, path, template_string, *variables
97
+ template = ERB.new(template_string, 0, "%<>")
98
+
99
+ templated = template.result(binding)
100
+
101
+ File.open("/tmp/#{filename}", 'w') { |file| file.write(templated) }
102
+
103
+ if File.exist?(path+filename)
104
+ diff = `diff #{path}#{filename} /tmp/#{filename}`
105
+ result = $?
106
+ if result != 0
107
+ puts "We are trying to install the previous file but there are differences"
108
+ puts "here are the differences"
109
+ puts "#{diff}"
110
+ puts "Do you want to override the original?"
111
+ puts "yes/[no]"
112
+
113
+ answer = Menu.ask
114
+
115
+ if answer != "yes"
116
+ return false
117
+ end
118
+ else
119
+ return true
120
+ end
121
+ end
122
+
123
+ puts "Installing the file #{path}#{filename}..."
124
+ puts "Please povide your password :"
125
+
126
+ output = `sudo cp /tmp/#{filename} #{path}#{filename}`
127
+ result = $?
128
+ if result == 0
129
+ return true
130
+ else
131
+ Kernel.abort(output)
132
+ end
133
+ end
134
+
135
+ def check_plist_file
136
+ puts "Checking plist file..."
137
+ plist_file = "org.virtualbox.vboxautostart.plist"
138
+ plist_path = "/Library/LaunchDaemons/"
139
+
140
+ plist_template = %q{
141
+ <?xml version="1.0" encoding="UTF-8"?>
142
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
143
+ <plist version="1.0">
144
+ <dict>
145
+ <key>Disabled</key>
146
+ <false/>
147
+ <key>KeepAlive</key>
148
+ <false/>
149
+ <key>Label</key>
150
+ <string>org.virtualbox.vboxautostart</string>
151
+ <key>ProgramArguments</key>
152
+ <array>
153
+ <string>/Applications/VirtualBox.app/Contents/MacOS/VBoxAutostartDarwin.sh</string>
154
+ <string>--start</string>
155
+ <string>/etc/vbox/autostart.cfg</string>
156
+ </array>
157
+ <key>RunAtLoad</key>
158
+ <true/>
159
+ <key>debug</key>
160
+ <true/>
161
+ </dict>
162
+ </plist>
163
+ }
164
+
165
+ if self.integrate_template(plist_file, plist_path, plist_template)
166
+ puts "loading the plist file"
167
+ puts "Thanks to provide your admin password."
168
+ `sudo launchctl load #{plist_path}#{plist_file}`
169
+ end
170
+ end
171
+
172
+
173
+ def check_conf_file
174
+ puts "Checking conf file..."
175
+ conf_file = "autostart.cfg"
176
+ conf_path = "/etc/vbox/"
177
+
178
+ conf_template = %q{
179
+ # Default policy is to deny starting a VM, the other option is "allow".
180
+ default_policy = deny
181
+
182
+ # <%= variables[0] %> is allowed to start virtual machines but starting them
183
+ # will be delayed for 10 seconds
184
+ <%= variables[0] %> = {
185
+ allow = true
186
+ startup_delay = 10
187
+ }
188
+ }.gsub(/^ /, '')
189
+
190
+ username = `whoami`.strip
191
+
192
+ integrate_template(conf_file, conf_path, conf_template, username)
193
+ end
194
+
195
+ def init_bootify
196
+
197
+ #check plist file
198
+ check_plist_file
199
+
200
+ #Check chmod of the bash script
201
+ check_chmod_script
202
+
203
+ #Check the conf file
204
+ check_conf_file
205
+
206
+ end
207
+ end
208
+ end
209
+ end
@@ -23,34 +23,41 @@
23
23
 
24
24
  #Forked from https://github.com/cldwalker/menu
25
25
 
26
- module Menu
27
- extend self
26
+ module Virtualman
27
+ module Interactive
28
+ module Menu
29
+ extend self
30
+
31
+ def ask
32
+ $stdin.reopen '/dev/tty'
33
+ $stdin.gets.chomp
34
+ end
35
+
36
+ def unic_prompt(lines)
37
+ ljust_size = lines.size.to_s.size + 1
38
+ lines.each_with_index {|obj,i|
39
+ puts "#{i+1}.".ljust(ljust_size) + " " +obj
40
+ }
41
+ print "\nSpecify your choice\nChoose: "
42
+ end
43
+
44
+ def unic_answer(array, input)
45
+ if input[/(\d+)/]
46
+ index = input.to_i - 1
47
+ if array[index]
48
+ return array[index]
49
+ end
50
+ end
51
+
52
+ Kernel.abort "#{input} is an invalid choice."
53
+ end
54
+
55
+ def unic_run(array)
56
+ unic_prompt(array)
57
+ answer = ask
58
+ return unic_answer(array, answer)
59
+ end
28
60
 
29
- def ask
30
- $stdin.reopen '/dev/tty'
31
- $stdin.gets.chomp
32
- end
33
-
34
- def unic_run(array)
35
- unic_prompt(array)
36
- answer = ask
37
- return unic_answer(array, answer)
38
- end
39
-
40
- def unic_answer(array, input)
41
- if input[/(\d+)/]
42
- index = $1.to_i - 1
43
- return array[index] if array[index]
44
- else
45
- abort("`#{input}' is an invalid choice.")
46
61
  end
47
62
  end
48
-
49
- def unic_prompt(lines)
50
- ljust_size = lines.size.to_s.size + 1
51
- lines.each_with_index {|obj,i|
52
- puts "#{i+1}.".ljust(ljust_size) + " " +obj
53
- }
54
- print "\nSpecify your choice\nChoose: "
55
- end
56
63
  end
@@ -1,62 +1,65 @@
1
- # Implement a way to interact with the VirtualBox command line tool.
2
- # Each #Vm is a Class that contains the #name of the VM. With that
3
- # name you can then interact with it through VBoxManage for example
1
+ module Virtualman
2
+ # Implement a way to interact with the VirtualBox command line tool.
3
+ # Each #Vm is a Class that contains the #name of the VM. With that
4
+ # name you can then interact with it through VBoxManage for example
4
5
 
5
- class Vm
6
+ class Vm
6
7
 
7
- # This attribute contains the name of the VM in VirtualBox.
8
- attr_reader :name
8
+ # This attribute contains the name of the VM in VirtualBox.
9
+ attr_reader :name
9
10
 
10
- # A #Vm is just described by it's name.
11
- # *type is for further needs
12
- def initialize(vm_name, *type)
13
- @name = vm_name
14
- end
15
-
16
- # Returns a boolean whether the VM is running or not
17
- def running?
18
- !`VBoxManage showvminfo #{name} | grep State | grep running`.empty?
19
- end
20
-
21
- # A general method to interact with the VM.
22
- # action is the kind of action to request to VBoxManage
23
- # *param is a list of options
24
- def manage(action, *param)
25
- puts "VBoxManage #{action} #{@name} #{param.join(" ")}"
26
- puts `VBoxManage #{action} #{@name} #{param.join(" ")}`
27
- end
11
+ # A #Vm is just described by it's name.
12
+ # *type is for further needs
13
+ def initialize(vm_name, *type)
14
+ @name = vm_name
15
+ end
28
16
 
29
- # A method to stop properly a vm
30
- # It assumes that you have the name of the VM on your personnal hosts file or DNS
31
- # It can be modified to use GuestAdditions instead
32
- def stop!
33
- $stdout.sync = true
34
- if self.running?
35
- `ssh root@#{self.ip} "shutdown -h now"`
36
- puts "Waiting for complete shutdown of #{self.name}"
37
- while self.running?
38
- print "."
39
- sleep (1)
17
+ # A general method to interact with the VM.
18
+ # action is the kind of action to request to VBoxManage
19
+ # *param is a list of options
20
+ def manage(action, *param)
21
+ #puts "VBoxManage #{action} #{@name} #{param.join(" ")}"
22
+ output = `VBoxManage #{action} \"#{@name}\" #{param.join(" ")} 2>&1`
23
+ if $?.exitstatus != 0
24
+ Kernel.abort(output)
25
+ else
26
+ return output
40
27
  end
41
- sleep (5)
42
28
  end
43
29
 
44
- end
30
+ # Returns a boolean whether the VM is running or not
31
+ def running?
32
+ return !self.manage("showvminfo").split("\n").grep(/running/).empty?
33
+ end
45
34
 
46
- # return the ip of the VM if it is running. O if it is not.
47
- def ip
48
- if self.running?
49
- options = "enumerate #{self.name} | grep IP | cut -d , -f 2 | cut -d : -f 2"
50
- cmd_ip = "VBoxManage guestproperty #{options}"
51
- ip = `#{cmd_ip}`.strip
52
- if ip.match /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/
53
- return ip
35
+ # return the ip of the VM if it is running. O if it is not or if the ip is not correct.
36
+ def ip
37
+ if self.running?
38
+ ip = self.manage("guestproperty enumerate").split("\n").grep(/IP/)[0].split(",")[1].sub(/^ value: /, '')
39
+ if ip.match /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/
40
+ return ip
41
+ else
42
+ return false
43
+ end
54
44
  else
45
+ puts "The VM is not running, cannot determine IP"
55
46
  return false
56
47
  end
57
- else
58
- puts "The VM is not running, cannot determine IP"
59
- return false
48
+ end
49
+
50
+ # A method to stop properly a vm
51
+ # It assumes that you can access to the VM with root and ssh_keys
52
+ def stop!
53
+ if self.running?
54
+ `ssh root@#{self.ip} "shutdown -h now"`
55
+ print "Waiting for complete shutdown of #{self.name}"
56
+ while self.running?
57
+ print "."
58
+ sleep (1)
59
+ end
60
+ sleep (5)
61
+ print("\n")
62
+ end
60
63
  end
61
64
  end
62
65
  end
@@ -1,58 +1,60 @@
1
- # Create an array that contains all the #Vm from VirtualBox
2
- # And implement methods to play with it as a whole.
3
- class VmLister < Array
4
-
5
- # Return an array with the list returned by the command "VBoxManage list vms"
6
- # The argument *type will be used later (to specify a remote host for instance)
7
- def perform_list(*type)
8
- vm_list = `VBoxManage list vms`.split(/\n/).collect {|e| e[/".*"/]}
9
- return vm_list
10
- end
1
+ module Virtualman
2
+ # Create an array that contains all the #Vm from VirtualBox
3
+ # And implement methods to play with it as a whole.
4
+ class VmLister < Array
5
+
6
+ # Return an array with the list returned by the command "VBoxManage list vms"
7
+ # The argument *type will be used later (to specify a remote host for instance)
8
+ def perform_list(*type)
9
+ vm_list = `VBoxManage list vms`.split(/\n/).collect {|e| e[/".*"/]}
10
+ return vm_list
11
+ end
11
12
 
12
- # Populate the array with the method perform_list
13
- # The argument *type will be used later (to specify a remote host for instance)
14
- def populate!(*type)
15
- self.perform_list.each {|vm| self << Vm.new(vm)}
16
- end
13
+ # Populate the array with the method perform_list
14
+ # The argument *type will be used later (to specify a remote host for instance)
15
+ def populate!(*type)
16
+ self.perform_list.each {|vm| self << Vm.new(vm)}
17
+ end
17
18
 
18
- # A simple lister
19
- def list
20
- self.each {|vm| puts "#{vm.name}"}
21
- end
19
+ # A simple lister
20
+ def list
21
+ self.each {|vm| puts "#{vm.name}"}
22
+ end
22
23
 
23
- # Get the IP of each running vm.
24
- def ip
25
- self.each {|vm| puts vm.ip}
26
- end
24
+ # Get the IP of each running vm.
25
+ def ip
26
+ self.each {|vm| puts vm.ip}
27
+ end
27
28
 
28
- # This methods returns a #VmLister object but just with the running VMs of the list.
29
- def running?
30
- running_vms = VmLister.new
31
- self.collect {|vm| running_vms << vm if vm.running?}
32
- return running_vms
33
- end
29
+ # This methods returns a #VmLister object but just with the running VMs of the list.
30
+ def running?
31
+ running_vms = VmLister.new
32
+ self.collect {|vm| running_vms << vm if vm.running?}
33
+ return running_vms
34
+ end
34
35
 
35
- # A general method to interact with the VBoxManage tool
36
- # the block param could be useful for advanced links between your script and this class
37
- def manage(action, *param, &block)
38
- self.each do |vm|
39
- block_param = block.call(vm.name) if block_given?
36
+ # A general method to interact with the VBoxManage tool
37
+ # the block param could be useful for advanced links between your script and this class
38
+ def manage(action, *param, &block)
39
+ self.each do |vm|
40
+ block_param = block.call(vm.name) if block_given?
40
41
 
41
- vm.manage(action, param, block_param)
42
+ vm.manage(action, param, block_param)
43
+ end
42
44
  end
43
- end
44
45
 
45
- # A method to automatically export the list of VMs
46
- def backup!(folder)
47
- self.each {|vm| vm.stop!}
48
- sleep (5)
46
+ # A method to automatically export the list of VMs
47
+ def backup!(folder)
48
+ self.each {|vm| vm.stop!}
49
+ sleep (5)
49
50
 
50
- self.each do |vm|
51
- filename = Time.now().strftime("#{vm.name.delete "\""}_%Y%m%dT%H%M")
52
- vm.manage("export","-o #{folder}/#{filename}.ova")
53
- sleep(5)
54
- end
51
+ self.each do |vm|
52
+ filename = Time.now().strftime("#{vm.name.delete "\""}_%Y%m%dT%H%M")
53
+ vm.manage("export","-o #{folder}/#{filename}.ova")
54
+ sleep(5)
55
+ end
55
56
 
56
- self.each {|vm| vm.manage("startvm", "--type headless")}
57
+ self.each {|vm| vm.manage("startvm", "--type headless")}
58
+ end
57
59
  end
58
- end
60
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: virtualman
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.9
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,9 +9,9 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-06 00:00:00.000000000 Z
12
+ date: 2012-11-15 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: An interactive tool to manage quickly your VMs
14
+ description: An interactive tool, and library to manage quickly your VMs
15
15
  email: pierre.ozoux@gmail.com
16
16
  executables:
17
17
  - virtualman
@@ -19,11 +19,12 @@ extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - lib/virtualman.rb
22
- - lib/virtualman/configuration.rb
23
- - lib/virtualman/interractive.rb
24
- - lib/virtualman/menu.rb
22
+ - lib/virtualman/interactive/configuration.rb
23
+ - lib/virtualman/interactive/REPL.rb
24
+ - lib/virtualman/interactive/menu.rb
25
25
  - lib/virtualman/vm.rb
26
26
  - lib/virtualman/vmlister.rb
27
+ - lib/virtualman/interactive/helper.rb
27
28
  - bin/virtualman
28
29
  homepage: http://rubygems.org/gems/virtualman
29
30
  licenses: []
@@ -1,51 +0,0 @@
1
- require 'yaml'
2
-
3
- module Configuration
4
-
5
- def config_file
6
- File.join(ENV['HOME'],'.virtualman.rc.yaml')
7
- end
8
-
9
- def load_conf
10
- if File.exists? config_file
11
- config_options = YAML.load_file(config_file)
12
- else
13
- STDERR.puts "No configuration file found here ~/.vm_to_clone.rc.yaml"
14
- STDERR.puts "Config file example:"
15
- STDERR.puts "---"
16
- STDERR.puts "source_vm:"
17
- STDERR.puts " - name: Debian"
18
- STDERR.puts " snapshot: ready to clone!"
19
- STDERR.puts " - name: Gentoo"
20
- STDERR.puts " snapshot: almost ready"
21
- STDERR.puts "role_path: http://path/to/your/role/fodler"
22
- STDERR.puts "cookbook_path: http://path/to/your/cookbooks.tar.gz"
23
- STDERR.puts "roles:"
24
- STDERR.puts "- devtest"
25
- STDERR.puts "- devtest_jenkins"
26
- STDERR.puts "- build_pkg_devtest_jenkins"
27
- end
28
- return config_options
29
- end
30
-
31
- def record_conf(vm_cloned, *param)
32
- conf = load_conf()
33
-
34
- if param[0] == "delete"
35
- verb = "deleted"
36
- conf["cloned_vms"].reject!{|vm| vm == {"name" => vm_cloned.name.gsub(/\"/,'')} }
37
- else
38
- verb = "saved"
39
-
40
- if conf["cloned_vms"]
41
- conf["cloned_vms"] << {"name" => vm_cloned.name}
42
- else
43
- conf.merge!({"cloned_vms" => {"name" => vm_cloned.name}})
44
- end
45
- end
46
-
47
- File.open(config_file, "w") {|f| f.write(conf.to_yaml) }
48
- puts "VM #{vm_cloned.name} has been #{verb} in your configuration file."
49
- end
50
-
51
- end
@@ -1,226 +0,0 @@
1
- require 'open3'
2
- require 'erb'
3
-
4
- module Interractive
5
- include Configuration
6
-
7
- def choosed_option(array,choice,attribute_to_check)
8
- array.each_with_index do |option,index|
9
- if option[attribute_to_check] == choice
10
- return array[index]
11
- end
12
- end
13
- end
14
-
15
- def choose options, *attribute_to_check
16
- options_array = Configuration.load_conf[options]
17
- if attribute_to_check.empty?
18
- return Menu.unic_run(options_array)
19
- else
20
- list = Array.new
21
- options_array.each do |option|
22
- list << option[attribute_to_check[0]]
23
- end
24
- list << "exit"
25
-
26
- choice = Menu.unic_run(list)
27
-
28
- exit 0 if choice == "exit"
29
-
30
- return choosed_option(options_array,choice,attribute_to_check[0])
31
- end
32
- end
33
-
34
- def choose_vm source
35
- vm_choice = choose source, "name"
36
- vm_choosed = Vm.new("\"#{vm_choice["name"]}\"")
37
- return vm_choosed
38
- end
39
-
40
- def clone_vm
41
- puts "----Clone_VM----"
42
- puts "Which VM do you want to clone?"
43
-
44
- vm_choice = choose "source_vms", "name"
45
- vm_to_clone = Vm.new("\"#{vm_choice["name"]}\"")
46
-
47
- puts "How do you want to name your freshly spawned VM?"
48
- vm_name = Menu.ask
49
-
50
- options = "--snapshot \"#{vm_choice["snapshot"]}\" --name \"#{vm_name}\" --register"
51
- vm_to_clone.manage("clonevm", options)
52
-
53
- vm_cloned = Vm.new(vm_name)
54
- return vm_cloned
55
- end
56
-
57
- def start_vm(vm)
58
- if !vm.running?
59
- puts "Do you want to start the VM? headless?"
60
- puts "(default is no)"
61
- puts "yes/headless/[no]"
62
-
63
- answer = Menu.ask
64
-
65
- if answer == "headless"
66
- option = "--type headless"
67
- puts "The VM is booting headless"
68
- elsif answer == "yes"
69
- option = ""
70
- puts "The VM is booting"
71
- else
72
- puts "The vm will not be started"
73
- return vm
74
- end
75
-
76
- vm.manage("startvm", option)
77
-
78
- print "Waiting for the VM to get an IP"
79
- while !vm.ip
80
- print "."
81
- sleep (1)
82
- end
83
- print "\n"
84
- end
85
-
86
- return vm.running?
87
- end
88
-
89
- def clone
90
- cloned_vm = clone_vm
91
- start_vm(cloned_vm)
92
- record_conf(cloned_vm)
93
- end
94
-
95
- def cook
96
- puts "----Cook a clone!----"
97
- puts "Which VM do you want to cook?"
98
- role_path = load_conf["role_path"]
99
- cookbook_path = load_conf["cookbook_path"]
100
-
101
- selected_vm = choose_vm "cloned_vms"
102
-
103
- puts "Which role do you want to give?"
104
-
105
- role = choose "roles"
106
-
107
- user="root"
108
-
109
- if start_vm(selected_vm)
110
- cmd = "ssh #{user}@#{selected_vm.ip} '/usr/local/bin/chef-solo -j #{role_path}#{role}.json -r #{cookbook_path}'"
111
- p cmd
112
- system(cmd)
113
- end
114
-
115
- puts "Thanks!"
116
- end
117
-
118
- def ssh
119
- puts "----SSH to cloned VM----"
120
- puts "Which VM do you want to ssh?"
121
-
122
- selected_vm = choose_vm "cloned_vms"
123
-
124
- puts "With which user? [root]"
125
- user = Menu.ask
126
-
127
- if user.empty?
128
- user = "root"
129
- end
130
-
131
- if start_vm(selected_vm)
132
- cmd = "ssh #{user}@#{selected_vm.ip}"
133
- exec (cmd)
134
- end
135
- end
136
-
137
- def delete
138
- puts "----Delete a cloned VM----"
139
- puts "Which VM delete?"
140
-
141
- selected_vm = choose_vm "cloned_vms"
142
-
143
- puts "!!YOU ARE ABOUT TO DELETE PEMANENTLY DELETE #{selected_vm.name}!!"
144
- puts "Are you sure? (yes/[no])"
145
-
146
- choice = Menu.ask
147
-
148
- if choice == "yes"
149
- selected_vm.stop!
150
-
151
- selected_vm.manage("unregistervm","--delete")
152
-
153
- record_conf(selected_vm, "delete")
154
- end
155
- end
156
-
157
- def add
158
- puts "----Add a VM----"
159
- puts "Give the path of the OVA file you want to add"
160
- puts "(An OVA file represents a Virtual Machine)"
161
-
162
- path = Menu.ask
163
-
164
- cmd = "VBoxManage import #{path}"
165
- p cmd
166
- system(cmd)
167
-
168
- added_vm = Vm.new(File.basename("#{path}",".*"))
169
- record_conf(added_vm)
170
- end
171
-
172
- def bootify
173
- puts "----Start a VM at boot----"
174
- puts "Whcih VM do you want to add to your boot sequence?"
175
-
176
- selected_vm = choose_vm "cloned_vms"
177
-
178
- # Create template.
179
- template_plist = %q{
180
- <?xml version="1.0" encoding="UTF-8"?>
181
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
182
- <plist version="1.0">
183
- <dict>
184
- <key>Label</key>
185
- <string>org.virtualman.<%= vmname %></string>
186
- <key>ProgramArguments</key>
187
- <array>
188
- <string>VBoxManage</string>
189
- <string>startvm</string>
190
- <string><%= vmname %></string>
191
- <string>--type</string>
192
- <string>headless</string>
193
- </array>
194
- <key>RunAtLoad</key>
195
- <true/>
196
- <key>UserName</key>
197
- <string><%= username %></string>
198
- <key>debug</key>
199
- <true/>
200
- </dict>
201
- </plist>
202
- }.gsub(/^ /, '')
203
-
204
- plist = ERB.new(template_plist, 0, "%<>")
205
-
206
- # Set up template data.
207
-
208
- vmname = selected_vm.name.gsub(/\"/,'')
209
- username = `whoami`.strip
210
-
211
- # Produce result.
212
-
213
- vm_plist = plist.result(binding)
214
-
215
- plist_filename = "org.virtualman.#{vmname}.plist"
216
- tmp_file = "/tmp/#{plist_filename}"
217
- path = "/Library/LaunchDaemons/"
218
-
219
- File.open(tmp_file, 'w') { |file| file.write(vm_plist) }
220
-
221
- `sudo cp #{tmp_file} #{path};sudo launchctl load #{path}#{plist_filename}`
222
-
223
- puts "#{vmname} added to your boot sequence."
224
- end
225
-
226
- end