virtualman 1.1.7 → 1.1.8
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/bin/virtualman +4 -6
- data/lib/virtualman.rb +2 -2
- data/lib/virtualman/configuration.rb +51 -0
- data/lib/virtualman/interractive.rb +182 -102
- data/lib/virtualman/menu.rb +0 -2
- data/lib/virtualman/vmlister.rb +1 -1
- metadata +4 -5
- data/lib/virtualman/conf.rb +0 -46
data/bin/virtualman
CHANGED
@@ -2,19 +2,17 @@
|
|
2
2
|
|
3
3
|
####Required
|
4
4
|
require 'virtualman'
|
5
|
+
include Interractive
|
5
6
|
|
6
|
-
menu = ["clone","cook","
|
7
|
+
menu = ["clone","cook","ssh","add","delete","bootify","exit"]
|
7
8
|
|
8
|
-
|
9
|
-
puts "Please select an action to do with your VM."
|
10
|
-
|
11
|
-
choice = Menu.unic_run(menu)
|
9
|
+
choice = "0"
|
12
10
|
|
13
11
|
while choice != "exit"
|
14
|
-
send(choice)
|
15
12
|
puts "----VirtualMan----"
|
16
13
|
puts "Please select an action to do with your VM."
|
17
14
|
choice = Menu.unic_run(menu)
|
15
|
+
Interractive.send(choice)
|
18
16
|
end
|
19
17
|
|
20
18
|
puts "Thank you come again!"
|
data/lib/virtualman.rb
CHANGED
@@ -0,0 +1,51 @@
|
|
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,146 +1,226 @@
|
|
1
1
|
require 'open3'
|
2
|
+
require 'erb'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
7
12
|
end
|
8
13
|
end
|
9
|
-
end
|
10
14
|
|
11
|
-
def choose options, *attribute_to_check
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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])
|
19
31
|
end
|
20
|
-
choice = Menu.unic_run(list)
|
21
|
-
return choosed_option(options_array,choice,attribute_to_check[0])
|
22
32
|
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def clone_vm
|
26
|
-
puts "----Clone_VM----"
|
27
|
-
puts "Which VM do you want to clone?"
|
28
33
|
|
29
|
-
|
30
|
-
|
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
|
31
39
|
|
32
|
-
|
33
|
-
|
40
|
+
def clone_vm
|
41
|
+
puts "----Clone_VM----"
|
42
|
+
puts "Which VM do you want to clone?"
|
34
43
|
|
35
|
-
|
36
|
-
|
44
|
+
vm_choice = choose "source_vms", "name"
|
45
|
+
vm_to_clone = Vm.new("\"#{vm_choice["name"]}\"")
|
37
46
|
|
38
|
-
|
39
|
-
|
40
|
-
end
|
47
|
+
puts "How do you want to name your freshly spawned VM?"
|
48
|
+
vm_name = Menu.ask
|
41
49
|
|
42
|
-
|
43
|
-
|
44
|
-
puts "Do you want to start the VM? headless?"
|
45
|
-
puts "(default is no)"
|
46
|
-
puts "yes/headless/[no]"
|
50
|
+
options = "--snapshot \"#{vm_choice["snapshot"]}\" --name \"#{vm_name}\" --register"
|
51
|
+
vm_to_clone.manage("clonevm", options)
|
47
52
|
|
48
|
-
|
53
|
+
vm_cloned = Vm.new(vm_name)
|
54
|
+
return vm_cloned
|
55
|
+
end
|
49
56
|
|
50
|
-
|
51
|
-
|
52
|
-
puts "
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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"
|
59
84
|
end
|
60
85
|
|
61
|
-
vm.
|
86
|
+
return vm.running?
|
87
|
+
end
|
62
88
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
68
|
-
print "\n"
|
89
|
+
def clone
|
90
|
+
cloned_vm = clone_vm
|
91
|
+
start_vm(cloned_vm)
|
92
|
+
record_conf(cloned_vm)
|
69
93
|
end
|
70
94
|
|
71
|
-
|
72
|
-
|
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"]
|
73
100
|
|
74
|
-
|
75
|
-
cloned_vm = clone_vm
|
76
|
-
start_vm(cloned_vm)
|
77
|
-
record_conf(cloned_vm)
|
78
|
-
end
|
101
|
+
selected_vm = choose_vm "cloned_vms"
|
79
102
|
|
80
|
-
|
81
|
-
puts "----Cook a clone!----"
|
82
|
-
puts "Which VM do you want to cook?"
|
83
|
-
role_path = load_conf["role_path"]
|
84
|
-
cookbook_path = load_conf["cookbook_path"]
|
103
|
+
puts "Which role do you want to give?"
|
85
104
|
|
86
|
-
|
105
|
+
role = choose "roles"
|
87
106
|
|
88
|
-
|
107
|
+
user="root"
|
89
108
|
|
90
|
-
|
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
|
91
114
|
|
92
|
-
|
115
|
+
puts "Thanks!"
|
116
|
+
end
|
93
117
|
|
94
|
-
|
118
|
+
def ssh
|
119
|
+
puts "----SSH to cloned VM----"
|
120
|
+
puts "Which VM do you want to ssh?"
|
95
121
|
|
96
|
-
|
97
|
-
cmd = "ssh #{user}@#{selected_vm.ip} '/usr/local/bin/chef-solo -j #{role_path}#{role}.json -r #{cookbook_path}'"
|
98
|
-
p cmd
|
99
|
-
system(cmd)
|
100
|
-
end
|
122
|
+
selected_vm = choose_vm "cloned_vms"
|
101
123
|
|
102
|
-
|
103
|
-
|
124
|
+
puts "With which user? [root]"
|
125
|
+
user = Menu.ask
|
104
126
|
|
105
|
-
|
106
|
-
|
107
|
-
|
127
|
+
if user.empty?
|
128
|
+
user = "root"
|
129
|
+
end
|
108
130
|
|
109
|
-
|
131
|
+
if start_vm(selected_vm)
|
132
|
+
cmd = "ssh #{user}@#{selected_vm.ip}"
|
133
|
+
exec (cmd)
|
134
|
+
end
|
135
|
+
end
|
110
136
|
|
111
|
-
|
137
|
+
def delete
|
138
|
+
puts "----Delete a cloned VM----"
|
139
|
+
puts "Which VM delete?"
|
112
140
|
|
113
|
-
|
114
|
-
user = Menu.ask
|
141
|
+
selected_vm = choose_vm "cloned_vms"
|
115
142
|
|
116
|
-
|
117
|
-
|
118
|
-
end
|
143
|
+
puts "!!YOU ARE ABOUT TO DELETE PEMANENTLY DELETE #{selected_vm.name}!!"
|
144
|
+
puts "Are you sure? (yes/[no])"
|
119
145
|
|
120
|
-
|
121
|
-
cmd = "ssh #{user}@#{selected_vm.ip}"
|
122
|
-
exec (cmd)
|
123
|
-
end
|
124
|
-
end
|
146
|
+
choice = Menu.ask
|
125
147
|
|
126
|
-
|
127
|
-
|
128
|
-
puts "Which VM delete?"
|
148
|
+
if choice == "yes"
|
149
|
+
selected_vm.stop!
|
129
150
|
|
130
|
-
|
151
|
+
selected_vm.manage("unregistervm","--delete")
|
131
152
|
|
132
|
-
|
153
|
+
record_conf(selected_vm, "delete")
|
154
|
+
end
|
155
|
+
end
|
133
156
|
|
134
|
-
|
135
|
-
|
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)"
|
136
161
|
|
137
|
-
|
162
|
+
path = Menu.ask
|
138
163
|
|
139
|
-
|
140
|
-
|
164
|
+
cmd = "VBoxManage import #{path}"
|
165
|
+
p cmd
|
166
|
+
system(cmd)
|
141
167
|
|
142
|
-
|
168
|
+
added_vm = Vm.new(File.basename("#{path}",".*"))
|
169
|
+
record_conf(added_vm)
|
170
|
+
end
|
143
171
|
|
144
|
-
|
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 "#{vmnme} added to your boot sequence."
|
145
224
|
end
|
225
|
+
|
146
226
|
end
|
data/lib/virtualman/menu.rb
CHANGED
data/lib/virtualman/vmlister.rb
CHANGED
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.
|
4
|
+
version: 1.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,10 +9,9 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-05 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description:
|
15
|
-
appliance.
|
14
|
+
description: An interactive tool to manage quickly your VMs
|
16
15
|
email: pierre.ozoux@gmail.com
|
17
16
|
executables:
|
18
17
|
- virtualman
|
@@ -20,7 +19,7 @@ extensions: []
|
|
20
19
|
extra_rdoc_files: []
|
21
20
|
files:
|
22
21
|
- lib/virtualman.rb
|
23
|
-
- lib/virtualman/
|
22
|
+
- lib/virtualman/configuration.rb
|
24
23
|
- lib/virtualman/interractive.rb
|
25
24
|
- lib/virtualman/menu.rb
|
26
25
|
- lib/virtualman/vm.rb
|
data/lib/virtualman/conf.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
CONFIG_FILE = File.join(ENV['HOME'],'.virtualman.rc.yaml')
|
4
|
-
|
5
|
-
def load_conf
|
6
|
-
if File.exists? CONFIG_FILE
|
7
|
-
config_options = YAML.load_file(CONFIG_FILE)
|
8
|
-
else
|
9
|
-
STDERR.puts "No configuration file found here ~/.vm_to_clone.rc.yaml"
|
10
|
-
STDERR.puts "Config file example:"
|
11
|
-
STDERR.puts "---"
|
12
|
-
STDERR.puts "source_vm:"
|
13
|
-
STDERR.puts " - name: Debian"
|
14
|
-
STDERR.puts " snapshot: ready to clone!"
|
15
|
-
STDERR.puts " - name: Gentoo"
|
16
|
-
STDERR.puts " snapshot: almost ready"
|
17
|
-
STDERR.puts "role_path: http://path/to/your/role/fodler"
|
18
|
-
STDERR.puts "cookbook_path: http://path/to/your/cookbooks.tar.gz"
|
19
|
-
STDERR.puts "roles:"
|
20
|
-
STDERR.puts "- devtest"
|
21
|
-
STDERR.puts "- devtest_jenkins"
|
22
|
-
STDERR.puts "- build_pkg_devtest_jenkins"
|
23
|
-
end
|
24
|
-
return config_options
|
25
|
-
end
|
26
|
-
|
27
|
-
def record_conf(vm_cloned, *param)
|
28
|
-
conf = load_conf()
|
29
|
-
|
30
|
-
if param[0] == "delete"
|
31
|
-
verb = "deleted"
|
32
|
-
conf["cloned_vms"].reject!{|vm| vm == {"name" => vm_cloned.name} }
|
33
|
-
else
|
34
|
-
verb = "saved"
|
35
|
-
|
36
|
-
if conf["cloned_vms"]
|
37
|
-
conf["cloned_vms"] << {"name" => vm_cloned.name}
|
38
|
-
else
|
39
|
-
conf.merge!({"cloned_vms" => {"name" => vm_cloned.name}})
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
File.open(CONFIG_FILE, "w") {|f| f.write(conf.to_yaml) }
|
44
|
-
puts "VM #{vm_cloned.name} #{verb} in your configuration file"
|
45
|
-
|
46
|
-
end
|