Class: OsCtl::Cli::Bisect
- Inherits:
-
Object
- Object
- OsCtl::Cli::Bisect
- Defined in:
- lib/osctl/cli/bisect.rb
Instance Attribute Summary collapse
-
#cols ⇒ Object
readonly
protected
Returns the value of attribute cols.
-
#cts ⇒ Object
readonly
protected
Returns the value of attribute cts.
-
#mutex ⇒ Object
readonly
protected
Returns the value of attribute mutex.
-
#suspend_action ⇒ Object
readonly
protected
Returns the value of attribute suspend_action.
Instance Method Summary collapse
- #action_reverse(action) ⇒ Object protected
- #action_str(action) ⇒ Object protected
- #ask_confirmation! ⇒ Object protected
- #ask_success? ⇒ Boolean protected
- #bisect ⇒ Object protected
- #execute_action_set(ct_set, action) ⇒ Object protected
-
#initialize(cts, suspend_action: nil, cols: nil) ⇒ Bisect
constructor
A new instance of Bisect.
- #print_set(ct_set) ⇒ Object protected
- #reset ⇒ Object
- #run ⇒ Object
Constructor Details
#initialize(cts, suspend_action: nil, cols: nil) ⇒ Bisect
Returns a new instance of Bisect.
8 9 10 11 12 13 |
# File 'lib/osctl/cli/bisect.rb', line 8 def initialize(cts, suspend_action: nil, cols: nil) @cts = cts @suspend_action = suspend_action @cols = cols @mutex = Mutex.new end |
Instance Attribute Details
#cols ⇒ Object (readonly, protected)
Returns the value of attribute cols.
39 40 41 |
# File 'lib/osctl/cli/bisect.rb', line 39 def cols @cols end |
#cts ⇒ Object (readonly, protected)
Returns the value of attribute cts.
39 40 41 |
# File 'lib/osctl/cli/bisect.rb', line 39 def cts @cts end |
#mutex ⇒ Object (readonly, protected)
Returns the value of attribute mutex.
39 40 41 |
# File 'lib/osctl/cli/bisect.rb', line 39 def mutex @mutex end |
#suspend_action ⇒ Object (readonly, protected)
Returns the value of attribute suspend_action.
39 40 41 |
# File 'lib/osctl/cli/bisect.rb', line 39 def suspend_action @suspend_action end |
Instance Method Details
#action_reverse(action) ⇒ Object (protected)
171 172 173 |
# File 'lib/osctl/cli/bisect.rb', line 171 def action_reverse(action) action == :suspend ? :resume : :suspend end |
#action_str(action) ⇒ Object (protected)
175 176 177 178 179 180 181 182 183 |
# File 'lib/osctl/cli/bisect.rb', line 175 def action_str(action) if suspend_action == :freeze action == :suspend ? 'freeze' : 'thaw' elsif suspend_action == :stop action == :suspend ? 'stop' : 'start' else raise "invalid action '#{suspend_action}'" end end |
#ask_confirmation! ⇒ Object (protected)
96 97 98 99 100 101 102 103 104 105 |
# File 'lib/osctl/cli/bisect.rb', line 96 def ask_confirmation! $stdout.write('Continue? [y/N]: ') $stdout.flush unless %w[y yes].include?($stdin.readline.strip.downcase) raise 'Aborted' end puts end |
#ask_success? ⇒ Boolean (protected)
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/osctl/cli/bisect.rb', line 107 def ask_success? loop do $stdout.write('Has the situation changed? [y/n]: ') $stdout.flush s = $stdin.readline.strip.downcase ret = nil if %w[y yes].include?(s) ret = true elsif %w[n no].include?(s) ret = false end puts return ret unless ret.nil? end end |
#bisect ⇒ Object (protected)
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/osctl/cli/bisect.rb', line 41 def bisect ct_set = @cts.clone action = :suspend loop do if ct_set.size == 1 execute_action_set(ct_set, :resume) if action == :resume ct = ct_set.first puts puts "Container identified: #{ct[:pool]}:#{ct[:id]}" break end left, right = ct_set.each_slice((ct_set.size / 2.0).round).to_a execute_action_set(left, action) puts if action == :suspend if ask_success? ct_set = left action = :resume execute_action_set(right, :resume) else ct_set = right action = :suspend execute_action_set(left, :resume) puts end elsif action == :resume if ask_success? ct_set = left action = :suspend execute_action_set(right, :resume) else ct_set = right action = :resume execute_action_set(left, :resume) puts end else raise 'programming error' end puts "Narrowed down to #{ct_set.size} containers" end end |
#execute_action_set(ct_set, action) ⇒ Object (protected)
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/osctl/cli/bisect.rb', line 129 def execute_action_set(ct_set, action) queue = Queue.new ct_set.each_with_index { |ct, i| queue << [i + 1, ct] } n = ct_set.length osctl_action = if suspend_action == :freeze action == :suspend ? :ct_freeze : :ct_unfreeze elsif suspend_action == :stop action == :suspend ? :ct_stop : :ct_start else raise "invalid action '#{suspend_action}'" end threads = Etc.nprocessors.times.map do Thread.new do c = OsCtl::Client.new c.open loop do begin i, ct = queue.pop(true) rescue ThreadError break end resp = c.cmd_response(osctl_action, pool: ct[:pool], id: ct[:id]) mutex.synchronize do puts "[#{i}/#{n}] #{action_str(action)} #{ct[:pool]}:#{ct[:id]} " \ "... #{resp.ok? ? 'ok' : "error: #{resp.}"}" end end c.close end end threads.each(&:join) end |
#print_set(ct_set) ⇒ Object (protected)
92 93 94 |
# File 'lib/osctl/cli/bisect.rb', line 92 def print_set(ct_set) OsCtl::Lib::Cli::OutputFormatter.print(ct_set, cols:, layout: :columns) end |
#reset ⇒ Object
33 34 35 |
# File 'lib/osctl/cli/bisect.rb', line 33 def reset execute_action_set(cts, :resume) end |
#run ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/osctl/cli/bisect.rb', line 15 def run print_set(cts) puts puts "Selected containers: #{cts.length}" puts "Suspend action: #{suspend_action}" puts ask_confirmation! begin bisect rescue StandardError, Interrupt puts puts 'Resuming all affected containers...' reset raise end end |