vi_cli 0.1.0 → 0.1.1
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/History.txt +13 -0
- data/lib/VM.rb +10 -12
- data/lib/VMFolder.rb +5 -5
- data/lib/VcData.rb +20 -9
- data/lib/ViCli.rb +65 -28
- data/lib/ViCliConfig.rb +11 -11
- data/lib/ViGUI.rb +22 -5
- data/rakefile +1 -1
- metadata +3 -3
data/History.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
=== 0.1.1 / 2009-06-08
|
2
|
+
|
3
|
+
* 1 bug fix
|
4
|
+
* Fix changed login data was not applied
|
5
|
+
* 3 major anhancements:
|
6
|
+
* Add checks if task is available for current item state
|
7
|
+
* Add option for tasks with parameters
|
8
|
+
* Massive gui update behavior cleanup
|
9
|
+
* 3 minor enhancements:
|
10
|
+
* Display CDROM drive in VM hardware
|
11
|
+
* Prettify date in VM status display
|
12
|
+
* Saved state of vm-tree based on names of folders now
|
13
|
+
|
1
14
|
=== 0.1.0 / 2009-04-26
|
2
15
|
|
3
16
|
* First Public Release
|
data/lib/VM.rb
CHANGED
@@ -5,22 +5,16 @@ class VM
|
|
5
5
|
@ref = ref
|
6
6
|
@session = session
|
7
7
|
@name = name
|
8
|
-
@state_vars = ['vm_on','vm_off','is_templ']
|
9
|
-
@state_vars.map! {|i| "@"+i+"=nil" }
|
10
|
-
@color = 'grey'
|
11
8
|
end
|
12
9
|
def name
|
13
10
|
@name.strip
|
14
11
|
end
|
15
|
-
def refresh_state
|
16
|
-
@color = 'grey'
|
17
|
-
@state_vars.each {|i| self.instance_eval i } # XXX
|
18
|
-
end
|
19
12
|
def draw
|
20
13
|
yield [@name, self]
|
21
14
|
end
|
22
15
|
def color cached=nil
|
23
|
-
|
16
|
+
@color = @vm_on = @vm_off = @is_templ = nil unless cached.nil?
|
17
|
+
return @color unless @color.nil?
|
24
18
|
@color = is_templ ? 'blue' : vm_on ? 'green' : vm_off ? 'red' : 'yellow'
|
25
19
|
end
|
26
20
|
def vm_on
|
@@ -54,6 +48,10 @@ class VM
|
|
54
48
|
i = d['deviceInfo']
|
55
49
|
result = [i['label'].to_s,i['summary'].to_s]
|
56
50
|
end
|
51
|
+
if ['VirtualE1000','VirtualPCNet32','VirtualVmxnet','VirtualEthernetCard'].include? d.soap_type
|
52
|
+
i = d['deviceInfo']
|
53
|
+
result = [i['label'].to_s,i['summary'].to_s]
|
54
|
+
end
|
57
55
|
result unless result.nil?
|
58
56
|
end
|
59
57
|
end
|
@@ -68,7 +66,7 @@ class VM
|
|
68
66
|
qs = summary['quickStats']
|
69
67
|
guest = @ref['guest']
|
70
68
|
res = []
|
71
|
-
res << ['power state',runtime['powerState'].to_s+' since '+runtime['bootTime'].to_s]
|
69
|
+
res << ['power state',runtime['powerState'].to_s+' since '+runtime['bootTime'].to_s.sub(/T/,' ').sub(/\+.*/,'')]
|
72
70
|
res << ['host',get_host]
|
73
71
|
res << ['cpu usage',"#{qs['overallCpuUsage'].to_s} MHz / #{num} * #{@host_cpu.to_s} MHz"]
|
74
72
|
res << ['guest memory usage',"#{qs['guestMemoryUsage'].to_s} MB / #{mem} MB"]
|
@@ -97,10 +95,10 @@ class VM
|
|
97
95
|
res << [first ? 'notes' : '',a]
|
98
96
|
first = false
|
99
97
|
end
|
100
|
-
[res, get_hw_info.compact]
|
98
|
+
Hash[ :state => res, :hw => get_hw_info.compact ]
|
101
99
|
end
|
102
|
-
def execute_task task
|
103
|
-
@ref.send task.to_sym
|
100
|
+
def execute_task task, *args
|
101
|
+
@ref.send task.to_sym, *args
|
104
102
|
false
|
105
103
|
end
|
106
104
|
end
|
data/lib/VMFolder.rb
CHANGED
@@ -13,8 +13,8 @@ class VMFolder
|
|
13
13
|
@name.strip
|
14
14
|
end
|
15
15
|
def save_data
|
16
|
-
result =
|
17
|
-
@children.each { |c| result
|
16
|
+
result = { :collapsed => @collapsed }
|
17
|
+
@children.each { |c| result[c.name] = c.save_data if c.respond_to? :save_data }
|
18
18
|
result
|
19
19
|
end
|
20
20
|
def add_child child
|
@@ -24,10 +24,10 @@ class VMFolder
|
|
24
24
|
['fold', 'unfold','toggle_fold','fold_children'].include? task.to_s
|
25
25
|
end
|
26
26
|
def state
|
27
|
-
|
27
|
+
Hash[ :state => [], :hw => [] ]
|
28
28
|
end
|
29
|
-
def execute_task task
|
30
|
-
self.send task.to_sym if has_task? task
|
29
|
+
def execute_task task, *args
|
30
|
+
self.send task.to_sym, *args if has_task? task
|
31
31
|
true
|
32
32
|
end
|
33
33
|
def fold
|
data/lib/VcData.rb
CHANGED
@@ -23,12 +23,15 @@ class VcData
|
|
23
23
|
@save_data = save_data
|
24
24
|
@tree_changed = false
|
25
25
|
end
|
26
|
+
def find_entities type
|
27
|
+
@session.find_entities(type).collect {|ref| { :ref => ref, :name => @session.wrap(ref)['name'].to_s } }
|
28
|
+
end
|
26
29
|
def collect folder, save_data, indent=''
|
27
30
|
if folder.class.to_s == "VMware::Folder"
|
28
|
-
save_data =
|
31
|
+
save_data = { :collapsed => false } if !save_data.kind_of? Hash
|
29
32
|
i = 0
|
30
|
-
result = VMFolder.new folder, @session, indent+folder['name'], save_data[
|
31
|
-
folder.children.each { |c| i+=1; result.add_child collect c, save_data[
|
33
|
+
result = VMFolder.new folder, @session, indent+folder['name'], save_data[:collapsed] == true
|
34
|
+
folder.children.each { |c| i+=1; result.add_child collect c, save_data[c['name']], indent+' ' }
|
32
35
|
return result
|
33
36
|
end
|
34
37
|
if folder.kind_of? $mock.class and indent == ''
|
@@ -43,11 +46,22 @@ class VcData
|
|
43
46
|
i = @refs[index]
|
44
47
|
i.send sym if i.respond_to? sym
|
45
48
|
end
|
46
|
-
def execute_task index, task
|
47
|
-
@tree_changed = @refs[index].execute_task task
|
49
|
+
def execute_task index, task, *args
|
50
|
+
@tree_changed = @refs[index].execute_task task, *args
|
48
51
|
end
|
49
52
|
def get_tasks index, tasks
|
50
|
-
tasks.keys.collect { |t| (
|
53
|
+
tasks.keys.collect { |t| (check_task index, tasks[t]) ? t : nil }.compact
|
54
|
+
end
|
55
|
+
def check_task index, task
|
56
|
+
item = @refs[index]
|
57
|
+
t = task['action'] || task
|
58
|
+
return false unless item.has_task? t
|
59
|
+
return true if task.kind_of? String or task['check'].nil?
|
60
|
+
task['check'].each_pair do |k,v|
|
61
|
+
next unless item.respond_to? k.to_sym
|
62
|
+
return false if item.send(k.to_sym) != v
|
63
|
+
end
|
64
|
+
true
|
51
65
|
end
|
52
66
|
def get_colors cached=nil
|
53
67
|
@refs.collect {|i| i.color cached }
|
@@ -56,9 +70,6 @@ class VcData
|
|
56
70
|
@save_data = @folders.save_data if !@folders.nil?
|
57
71
|
@folders = collect @vm_folder, @save_data
|
58
72
|
end
|
59
|
-
def refresh_state dummy=nil
|
60
|
-
@refs.each {|i| i.refresh_state if i.respond_to? :refresh_state }
|
61
|
-
end
|
62
73
|
def vm_list
|
63
74
|
@refs.clear
|
64
75
|
list = []
|
data/lib/ViCli.rb
CHANGED
@@ -14,12 +14,8 @@ class ViCli
|
|
14
14
|
@watcher = Watcher.new
|
15
15
|
@model = VcData.new @config.login, @config.tree_state
|
16
16
|
@gui.setup self.method(:on_focus_callback)
|
17
|
-
@gui.set_status "Loading VM Folders ..."
|
18
|
-
@model.refresh_list
|
19
|
-
@gui.set_status "Loaded VM Folders"
|
20
|
-
draw_list
|
21
|
-
on_focus_callback @gui.current_list_index
|
22
17
|
setup_queues
|
18
|
+
load_folders
|
23
19
|
main_loop
|
24
20
|
@config.tree_state = @model.save_data
|
25
21
|
rescue => ex
|
@@ -29,66 +25,107 @@ class ViCli
|
|
29
25
|
print ex.backtrace.join "\n" if ex
|
30
26
|
end
|
31
27
|
end
|
32
|
-
def draw_list
|
33
|
-
@gui.
|
34
|
-
@gui.
|
35
|
-
@watcher.refresh_queue.push index unless index.nil?
|
28
|
+
def draw_list state
|
29
|
+
@gui.colors = @model.get_colors # state[:colors]
|
30
|
+
@gui.draw_list state[:vm_list] unless state[:vm_list].nil?
|
36
31
|
end
|
37
32
|
def on_focus_callback index
|
33
|
+
add_tasks index
|
34
|
+
#TODO needs cached data for state and hardware
|
35
|
+
draw_state Hash[ :state => [], :hw => [] ]
|
36
|
+
@gui.refresh
|
37
|
+
@watcher.refresh_queue.push @gui.current_list_index
|
38
|
+
end
|
39
|
+
def add_tasks index
|
38
40
|
tasks = @model.get_tasks index, @config.keys
|
39
41
|
callback = self.method :on_fire_callback
|
40
42
|
@gui.add_tasks callback, index, tasks
|
41
|
-
|
42
|
-
|
43
|
+
end
|
44
|
+
def prepare_arg arg
|
45
|
+
entities = @model.find_entities arg
|
46
|
+
return nil if entities.empty?
|
47
|
+
return entities.first[:ref] if entities.length == 1
|
48
|
+
selected = @gui.select entities.collect {|e| e[:name] }
|
49
|
+
entities.each {|e| return e[:ref] if e[:name] == selected }
|
43
50
|
end
|
44
51
|
def on_fire_callback index, key
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
52
|
+
action = @config.keys[key]
|
53
|
+
args = (action['args'] || []).collect {|arg| prepare_arg arg }
|
54
|
+
action = action['action'] || action
|
55
|
+
redraw = @model.execute_task index, action, *args
|
56
|
+
@gui.set_status "execute #{action} on #{@model.get :name, index}"
|
57
|
+
if redraw
|
58
|
+
draw_list Hash[ :vm_list => @model.vm_list ]#, :colors => @model.get_colors ]
|
59
|
+
add_tasks index
|
60
|
+
@gui.refresh
|
61
|
+
else
|
62
|
+
@watcher.refresh_queue.push @gui.current_list_index
|
63
|
+
end
|
64
|
+
end
|
65
|
+
def load_folders
|
66
|
+
@gui.set_status "Loading VM Folders ..."
|
67
|
+
@model.refresh_list
|
68
|
+
@gui.draw_list @model.vm_list
|
69
|
+
@watcher.refresh_queue.push @gui.current_list_index
|
70
|
+
@gui.set_status "Loaded VM Folders"
|
49
71
|
end
|
50
72
|
def handle_char char
|
51
73
|
return false if char.nil?
|
52
74
|
return true if char == ?q
|
53
75
|
@activity = true
|
54
|
-
@gui.enter_login if char == ?l
|
55
|
-
|
56
|
-
@gui.draw_list @model.vm_list if [269,360].include? char
|
76
|
+
@config.login = @gui.enter_login if char == ?l
|
77
|
+
load_folders if char == 269
|
57
78
|
@gui.handle_key char
|
58
79
|
@gui.refresh
|
59
80
|
false
|
60
81
|
end
|
61
|
-
def
|
82
|
+
def draw_all state
|
62
83
|
return if state.nil?
|
63
|
-
|
64
|
-
|
65
|
-
|
84
|
+
return if state[:index] != @gui.current_list_index
|
85
|
+
draw_list state
|
86
|
+
draw_state state
|
87
|
+
add_tasks state[:index]
|
66
88
|
@gui.refresh
|
67
89
|
end
|
68
|
-
def
|
90
|
+
def refresh_all x
|
69
91
|
return if x.nil?
|
70
92
|
@gui.draw_events @model.recent_events
|
71
93
|
@gui.refresh
|
72
|
-
@model.refresh_state
|
73
94
|
@watcher.refresh_queue.push @gui.current_list_index
|
74
95
|
return @activity = false if @activity
|
75
96
|
@gui.set_status ''
|
97
|
+
@gui.refresh
|
98
|
+
end
|
99
|
+
def draw_state state
|
100
|
+
@gui.add_state state[:state]
|
101
|
+
@gui.add_hardware state[:hw]
|
76
102
|
end
|
77
103
|
def setup_queues
|
78
104
|
#@watcher.register(:resize) { |q| loop { q.push sleep 5 } }
|
79
105
|
@watcher.register(:getchar) { |q| loop { q.push @gui.getchar } }
|
80
|
-
@watcher.register(:sleep)
|
106
|
+
@watcher.register(:sleep) do |q|
|
107
|
+
loop do
|
108
|
+
start = Time.now
|
109
|
+
@model.get_colors true
|
110
|
+
time = 5 - (Time.now - start)
|
111
|
+
q.push sleep(time > 0 ? time : 1)
|
112
|
+
end
|
113
|
+
end
|
81
114
|
@watcher.register(:state) do |q|
|
82
115
|
loop do
|
83
|
-
|
116
|
+
state = Hash[ :index => @watcher.refresh_queue.poop ]
|
117
|
+
# watch out for concurrency
|
118
|
+
# state[:vm_list] = @model.vm_list
|
119
|
+
state = state.update @model.get(:state, state[:index])
|
120
|
+
q.push state
|
84
121
|
end
|
85
122
|
end
|
86
123
|
end
|
87
124
|
def main_loop
|
88
125
|
while @watcher.wait
|
89
126
|
return if handle_char @watcher[:getchar].poop
|
90
|
-
|
91
|
-
|
127
|
+
draw_all @watcher[:state].poop
|
128
|
+
refresh_all @watcher[:sleep].poop
|
92
129
|
end
|
93
130
|
end
|
94
131
|
end
|
data/lib/ViCliConfig.rb
CHANGED
@@ -26,18 +26,18 @@ class ViCliConfig
|
|
26
26
|
def keys
|
27
27
|
return @config['keys'] unless @config['keys'].nil?
|
28
28
|
@config['keys'] = {
|
29
|
-
'&power on' => 'powerOnVM_Task',
|
30
|
-
'&unfold' => 'unfold',
|
31
|
-
'&
|
32
|
-
'
|
33
|
-
'
|
34
|
-
'
|
35
|
-
'
|
29
|
+
'&power on' => {'action' => 'powerOnVM_Task', 'check' => {'vm_on' => false, 'is_templ' => false} },
|
30
|
+
'&unfold' => {'action' => 'unfold', 'check' => {'collapsed' => true} },
|
31
|
+
'f&old' => {'action' => 'fold', 'check' => {'collapsed' => false} },
|
32
|
+
'&reboot guest' => {'action' => 'rebootGuest', 'check' => {'vm_on' => true} },
|
33
|
+
'convert to &virtual machine' => { 'action' => 'markAsVirtualMachine', 'args' => ['ResourcePool'], 'check' => {'is_templ' => true } },
|
34
|
+
'cut power' => {'action' => 'powerOffVM', 'check' => {'vm_on' => true} },
|
35
|
+
'&migrate' => {'action' => 'migrateVM_Task', 'args' => ['HostSystem'], 'check' => {'vm_on' => false} },
|
36
36
|
'fold &children' => 'fold_children',
|
37
|
-
'convert to &template' => 'markAsTemplate',
|
38
|
-
'suspend' => 'suspendVM_Task',
|
39
|
-
'reset' => 'resetVM_Task',
|
40
|
-
'&shutdown guest' => 'shutdownGuest',
|
37
|
+
'convert to &template' => {'action' => 'markAsTemplate', 'check' => {'vm_off' => true, 'is_templ' => false} },
|
38
|
+
'suspend' => {'action' => 'suspendVM_Task', 'check' => {'vm_on' => true} },
|
39
|
+
'reset' => {'action' => 'resetVM_Task', 'check' => {'vm_on' => true} },
|
40
|
+
'&shutdown guest' => {'action' => 'shutdownGuest', 'check' => {'vm_on' => true} },
|
41
41
|
}
|
42
42
|
end
|
43
43
|
def save
|
data/lib/ViGUI.rb
CHANGED
@@ -19,6 +19,20 @@ class ViGUI
|
|
19
19
|
@current_list_toprow = 0
|
20
20
|
@colors = []
|
21
21
|
end
|
22
|
+
def select choices
|
23
|
+
dialog = Form.new nil
|
24
|
+
list = Listbox.new dialog do
|
25
|
+
row 2
|
26
|
+
col 3
|
27
|
+
bgcolor 'white'
|
28
|
+
color 'black'
|
29
|
+
height 8
|
30
|
+
width 54
|
31
|
+
list_variable Variable.new choices
|
32
|
+
end
|
33
|
+
show_messagebox dialog, 'Please Select'
|
34
|
+
list.list[list.current_index]
|
35
|
+
end
|
22
36
|
def enter_login
|
23
37
|
dialog = Form.new nil
|
24
38
|
inputs = ['host','username','password']
|
@@ -37,11 +51,7 @@ class ViGUI
|
|
37
51
|
maxlen 99
|
38
52
|
end
|
39
53
|
end
|
40
|
-
|
41
|
-
MessageBox.new dialog do
|
42
|
-
title 'Login Configuration'
|
43
|
-
layout 14, 60, h/2 - 7, w/2 - 30
|
44
|
-
end
|
54
|
+
show_messagebox dialog, 'Login Configuration'
|
45
55
|
Hash[*inputs.collect{|i| [i,dialog.by_name[i].getvalue]}.flatten]
|
46
56
|
end
|
47
57
|
def get_h_w
|
@@ -50,6 +60,13 @@ class ViGUI
|
|
50
60
|
Ncurses.getmaxyx Ncurses.stdscr, h, w
|
51
61
|
return h[0] -2, w[0]
|
52
62
|
end
|
63
|
+
def show_messagebox dialog, title
|
64
|
+
h, w = get_h_w
|
65
|
+
MessageBox.new dialog do
|
66
|
+
title title
|
67
|
+
layout 14, 60, h/2 - 7, w/2 - 30
|
68
|
+
end
|
69
|
+
end
|
53
70
|
def setup focus_callback
|
54
71
|
@tw = tw = 40
|
55
72
|
h, w = get_h_w
|
data/rakefile
CHANGED
@@ -7,7 +7,7 @@ version = File.open('History.txt').gets[/\d+\.\d+.\d+/]
|
|
7
7
|
Hoe.new('vi_cli', version) do |p|
|
8
8
|
p.developer('SebDE', 'v1g46nr02@sneakemail.com')
|
9
9
|
p.extra_deps = [['rbcurse','>= 0.1.2']]
|
10
|
-
p.extra_deps = [['vi_api_lib','>= 0.1.
|
10
|
+
p.extra_deps = [['vi_api_lib','>= 0.1.2']]
|
11
11
|
end
|
12
12
|
|
13
13
|
task :default => :clean
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vi_cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SebDE
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-06-08 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.1.
|
23
|
+
version: 0.1.2
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: hoe
|