moob 0.2.0 → 0.3.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.
data/bin/moob CHANGED
@@ -4,7 +4,7 @@ require 'optparse'
4
4
  require 'moob'
5
5
 
6
6
  options = {
7
- :action => :jnlp,
7
+ :actions => [:jnlp],
8
8
  :type => :auto,
9
9
  :machines => [],
10
10
  :password => ENV['password']
@@ -24,10 +24,10 @@ OptionParser.new do |opts|
24
24
  end
25
25
  end
26
26
 
27
- opts.on '-a', '--action t',
28
- 'Action to perform, \'list\' to list',
27
+ opts.on '-a', '--actions a,b,c', Array,
28
+ 'Actions to perform, \'list\' to list',
29
29
  'Defaults to jnlp' do |a|
30
- if a == 'list'
30
+ if a == ['list']
31
31
  Moob::TYPES.each do |sym, klass|
32
32
  if klass.actions
33
33
  puts "#{sym}:"
@@ -40,7 +40,7 @@ OptionParser.new do |opts|
40
40
  end
41
41
  exit 0
42
42
  else
43
- options[:action] = a.to_sym
43
+ options[:actions] = a
44
44
  end
45
45
  end
46
46
 
@@ -76,22 +76,29 @@ begin
76
76
  options[:machines].each do |h|
77
77
  lom = Moob.lom options[:type], h, options
78
78
 
79
- puts "Trying to authenticate to #{h}..." if $VERBOSE
79
+ Moob.inform "Trying to authenticate to #{h}..."
80
80
  lom.authenticate
81
- puts "Authenticated on #{h}." if $VERBOSE
81
+ Moob.inform "Authenticated on #{h}."
82
82
 
83
- case options[:action]
84
- when :jnlp
85
- Moob.start_jnlp lom
86
- else
87
- res = lom.send options[:action]
88
- puts res if res
83
+ options[:actions].each do |action|
84
+ action = action.to_sym
85
+ Moob.inform "Trying to perform #{action} on #{h}..."
86
+ case action
87
+ when :jnlp
88
+ Moob.start_jnlp lom
89
+ else
90
+ res = lom.send action
91
+ puts res if res
92
+ end
93
+ Moob.inform "Performed #{action} on #{h}."
89
94
  end
95
+
96
+ lom.logout
90
97
  end
91
98
  puts 'There might be a delay before Java Web Start shows up...' if options[:action] == :jnlp
92
99
 
93
100
  rescue Exception => e
94
- $stderr.puts "\033[31mFailure (#{e.class}): #{e}\033[0m\n\n" \
101
+ $stderr.puts "\033[31mFailure: #{e.class} (#{e})\033[0m\n\n" \
95
102
  "Backtrace to provide in any support request:\033[2;34m"
96
103
  $stderr.puts e.backtrace
97
104
  $stderr.puts "\033[0m"
@@ -1,5 +1,5 @@
1
1
  module Moob
2
- VERSION = [0,2,0]
2
+ VERSION = [0,3,0]
3
3
 
4
4
  class ResponseError < Exception
5
5
  def initialize response
@@ -25,10 +25,10 @@ module Moob
25
25
  case type
26
26
  when :auto
27
27
  TYPES.find do |sym, klass|
28
- puts "Trying type #{sym}..." if $VERBOSE
28
+ Moob.inform "Trying type #{sym}..."
29
29
  lom = klass.new hostname, options
30
30
  if lom.detect
31
- puts "Type #{sym} detected." if $VERBOSE
31
+ Moob.inform "Type #{sym} detected."
32
32
  return lom
33
33
  end
34
34
  false
@@ -46,11 +46,15 @@ module Moob
46
46
  raise RuntimeError.new "Invalid JNLP file (\"#{jnlp}\")"
47
47
  end
48
48
 
49
- filepath = "/tmp/#{lom.hostname}.jnlp"
49
+ filepath = "/tmp/#{lom.hostname}_#{Time.now.to_i}.jnlp"
50
50
  File.open filepath, 'w' do |f|
51
51
  f.write jnlp
52
52
  end
53
53
 
54
- raise Exception.new "javaws failed" unless system "javaws #{filepath} &"
54
+ raise Exception.new "javaws failed" unless system "javaws -wait #{filepath}"
55
+ end
56
+
57
+ def self.inform msg
58
+ $stderr.puts "\033[36m#{msg}\033[0m" if $VERBOSE
55
59
  end
56
60
  end
@@ -1,6 +1,7 @@
1
1
  require 'socket'
2
2
  require 'cgi'
3
3
  require 'patron'
4
+ require 'json'
4
5
  require 'set'
5
6
 
6
7
  class Moob::BaseLom
@@ -20,6 +21,9 @@ class Moob::BaseLom
20
21
  @session.insecure = true
21
22
  end
22
23
 
24
+ def logout
25
+ end
26
+
23
27
  attr_reader :hostname, :username
24
28
 
25
29
  def detect
@@ -35,7 +39,7 @@ class Moob::BaseLom
35
39
  end
36
40
 
37
41
  def self.action sym, descr
38
- @actions ||= {}
39
- @actions[sym] = descr
42
+ @actions ||= []
43
+ @actions << [sym, descr]
40
44
  end
41
45
  end
@@ -52,6 +52,8 @@ class Idrac6 < BaseLom
52
52
  v6DHCPServers
53
53
  v6DNS1
54
54
  v6DNS2
55
+ vmBootOnce
56
+ firstBootDevice
55
57
  NicEtherMac1
56
58
  NicEtherMac2
57
59
  NicEtherMac3
@@ -87,6 +89,12 @@ class Idrac6 < BaseLom
87
89
  return self
88
90
  end
89
91
 
92
+ def logout
93
+ out = @session.get 'data/logout'
94
+ raise ResponseError.new out unless out.status == 200
95
+ return self
96
+ end
97
+
90
98
  def detect
91
99
  begin
92
100
  home = @session.get 'login.html'
@@ -118,26 +126,46 @@ class Idrac6 < BaseLom
118
126
  return viewer.body
119
127
  end
120
128
 
121
- def power_action action
129
+ def power_control action
122
130
  req = @session.post "data?set=pwState:#{action}", {}
123
131
  raise ResponseError.new req unless req.status == 200
124
- raise Exception.new 'The answer looks wrong' unless req.body =~ /<status>ok<\/status>/
125
132
  return nil
126
133
  end
127
134
 
128
- action :poff, 'Power Off System'
129
- action :pon, 'Power On System'
130
- action :pcycle, 'Power Cycle System (cold boot)'
131
- action :reboot, 'Reset System (warm boot)'
132
- action :nmi, 'NMI (Non-Masking Interrupt)'
133
- action :shudown, 'Graceful Shutdown'
135
+ def boot_on level
136
+ req = @session.post "data?set=vmBootOnce:1,firstBootDevice:#{level}", {}
137
+ raise ResponseError.new req unless req.status == 200
138
+ return nil
139
+ end
140
+
141
+ [
142
+ [0, :poff, 'Power Off System'],
143
+ [1, :pon, 'Power On System'],
144
+ [2, :pcycle, 'Power Cycle System (cold boot)'],
145
+ [3, :preset, 'Reset System (warm boot)'],
146
+ [4, :nmi, 'NMI (Non-Masking Interrupt)'],
147
+ [5, :shutdown, 'Graceful Shutdown']
148
+ ].each do |code, name, desc|
149
+ action name, desc
150
+ class_eval %{def #{name}; power_control #{code}; end}
151
+ end
134
152
 
135
- def poff; power_action 0; end
136
- def pon; power_action 1; end
137
- def pcycle; power_action 2; end
138
- def reboot; power_action 3; end
139
- def nmi; power_action 4; end
140
- def shutdown; power_action 5; end
153
+ [
154
+ [0, :bnone, 'Do not change the next boot'],
155
+ [1, :bpxe, 'Boot on PXE once'],
156
+ [6, :bbios, 'Boot on BIOS setup once'],
157
+ [15, :blfloppy, 'Boot on Local Floppy/Primary Removable Media once'],
158
+ [5, :blcd, 'Boot on Local CD/DVD once'],
159
+ [2, :blhd, 'Boot on Hard Drive once'],
160
+ [9, :biscsi, 'Boot on NIC BEV iSCSI once'],
161
+ [7, :bvfloppy, 'Boot on Virtual Floppy once'],
162
+ [8, :bvcd, 'Boot on Virtual CD/DVD/ISO once'],
163
+ [16, :blsd, 'Boot on Local SD Card once'],
164
+ [11, :bvflash, 'Boot on vFlash once']
165
+ ].each do |code, name, desc|
166
+ action name, desc
167
+ class_eval %{def #{name}; boot_on #{code}; end}
168
+ end
141
169
 
142
170
  def get_infos keys
143
171
  infos = @session.post "data?get=#{keys.join(',')}", {}
@@ -168,9 +196,7 @@ class Idrac6 < BaseLom
168
196
 
169
197
  action :infos, 'Get system information'
170
198
  def infos
171
- return get_infos(INFO_FIELDS).collect do |k,v|
172
- "#{k}: #{v}"
173
- end.join "\n"
199
+ return JSON.pretty_generate get_infos INFO_FIELDS
174
200
  end
175
201
  end
176
202
  end
@@ -56,11 +56,11 @@ class Megatrends < BaseLom
56
56
  return nil
57
57
  end
58
58
 
59
- action :poff, 'Power Off'
60
- action :pon, 'Power On'
61
- action :pcycle, 'Power Cycle'
62
- action :preset, 'Power Reset'
63
- action :soft_poff, 'Soft Power Off'
59
+ action :poff, 'Power Off'
60
+ action :pon, 'Power On'
61
+ action :pcycle, 'Power Cycle'
62
+ action :preset, 'Power Reset'
63
+ action :shutdown, 'Soft Power Off'
64
64
  def poff; power_action 0; end
65
65
  def pon; power_action 1; end
66
66
  def pcycle; power_action 2; end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moob
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 0
8
- - 2
7
+ - 3
9
8
  - 0
10
- version: 0.2.0
9
+ version: 0.3.0
11
10
  platform: ruby
12
11
  authors:
13
12
  - Pierre Carrier
@@ -22,11 +21,9 @@ dependencies:
22
21
  name: patron
23
22
  prerelease: false
24
23
  requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
24
  requirements:
27
25
  - - ~>
28
26
  - !ruby/object:Gem::Version
29
- hash: 19
30
27
  segments:
31
28
  - 0
32
29
  - 4
@@ -34,6 +31,20 @@ dependencies:
34
31
  version: 0.4.14
35
32
  type: :runtime
36
33
  version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: json
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 5
44
+ - 3
45
+ version: 1.5.3
46
+ type: :runtime
47
+ version_requirements: *id002
37
48
  description: Control systems using Web-based out-of-band managers without a browser
38
49
  email:
39
50
  - pierre@gcarrier.fr
@@ -61,20 +72,16 @@ rdoc_options: []
61
72
  require_paths:
62
73
  - lib
63
74
  required_ruby_version: !ruby/object:Gem::Requirement
64
- none: false
65
75
  requirements:
66
76
  - - ">="
67
77
  - !ruby/object:Gem::Version
68
- hash: 3
69
78
  segments:
70
79
  - 0
71
80
  version: "0"
72
81
  required_rubygems_version: !ruby/object:Gem::Requirement
73
- none: false
74
82
  requirements:
75
83
  - - ">="
76
84
  - !ruby/object:Gem::Version
77
- hash: 31
78
85
  segments:
79
86
  - 1
80
87
  - 2
@@ -83,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
90
  requirements: []
84
91
 
85
92
  rubyforge_project: moob
86
- rubygems_version: 1.6.2
93
+ rubygems_version: 1.3.6
87
94
  signing_key:
88
95
  specification_version: 3
89
96
  summary: Manage Out-Of-Band!