Class: Inprovise::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/inprovise/control.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeController

Returns a new instance of Controller.



145
146
147
148
# File 'lib/inprovise/control.rb', line 145

def initialize
  @targets = []
  @threads = []
end

Class Method Details

.cleanup!Object



128
129
130
131
132
133
# File 'lib/inprovise/control.rb', line 128

def cleanup!
  while !empty?
    head.cleanup rescue Exception $stderr.puts $!.backtrace
    shift
  end
end

.list_scripts(options) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/inprovise/control.rb', line 58

def list_scripts(options)
  load_schemes(options)
  $stdout.puts
  $stdout.puts '   PROVISIONING SCRIPTS'
  $stdout.puts '   ===================='
  Inprovise::ScriptIndex.default.scripts.sort.each do |scrname|
    script = Inprovise::ScriptIndex.default.get(scrname)
    if script.description || options[:all]
      script.describe.each {|l| $stdout.puts "   #{l}" }
    end
  end
end

.parse_config(cfglist, opts = {}) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/inprovise/control.rb', line 71

def parse_config(cfglist, opts = {})
  cfglist.inject(opts) do |rc, cfg|
    k,v = cfg.split('=')
    k = k.split('.')
    h = rc
    while k.size > 1
      hk = k.shift.to_sym
      raise ArgumentError, "Conflicting config category #{hk}" unless !h.has_key?(hk) || Hash === h[hk]
      h = (h[hk] ||= {})
    end
    h.store(k.shift.to_sym, get_value(v))
    rc
  end
end

.run(command, options, *args) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/inprovise/control.rb', line 86

def run(command, options, *args)
  begin
    case command
    when :add, :remove, :update
      target = args.shift
      if command == :remove
        run_infra_command(command, target, *args)
      else
        tgtcfg = parse_config(options[:config])
        tgtcfg[:credentials] = parse_config(options[:credential]) if target == :node && options.has_key?(:credential)
        run_infra_command(command, target, options, tgtcfg, *args)
      end
    else # :apply, :revert, :validate or :trigger
      load_schemes(options)
      # extract config
      cfg = parse_config(options[:config])
      cfg[:run_always] = true if options[:force]
      # get script/action
      sca = args.shift
      run_provisioning_command(command, sca, cfg, *args)
    end
  rescue Exception => e
    cleanup!
    raise e
  end
end

.run_infra_command(cmd, target, *args) ⇒ Object



135
136
137
# File 'lib/inprovise/control.rb', line 135

def run_infra_command(cmd, target, *args)
  add(Inprovise::Controller.new).send(:"#{cmd}_#{target}", *args)
end

.run_provisioning_command(command, script, cfg, *targets) ⇒ Object



139
140
141
# File 'lib/inprovise/control.rb', line 139

def run_provisioning_command(command, script, cfg, *targets)
  add(Inprovise::Controller.new).run_provisioning_command(command, script, cfg, *targets)
end

.wait!Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/inprovise/control.rb', line 113

def wait!
  ex = nil
  begin
    while !empty?
      head.wait
      shift
    end
  rescue Exception => e
    ex = e
  ensure
    cleanup!
    raise ex if ex
  end
end

Instance Method Details

#add_group(options, grpcfg, name) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/inprovise/control.rb', line 226

def add_group(options, grpcfg, name)
  options[:target].each {|t| raise ArgumentError, "Unknown target [#{t}]" unless Inprovise::Infrastructure.find(t) }
  grp = Inprovise::Infrastructure::Group.new(name, grpcfg)

  Inprovise.log.local("Adding #{grp}")

  options[:target].each do |t|
    tgt = Inprovise::Infrastructure.find(t)
    raise ArgumentError, "Unknown target #{t}" unless tgt
    tgt.add_to(grp)
  end
end

#add_node(options, nodecfg, name) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/inprovise/control.rb', line 186

def add_node(options, nodecfg, name)
  nodecfg.merge!({ host: options[:address] })
  @targets << (node = Inprovise::Infrastructure::Node.new(name, nodecfg))

  Inprovise.log.local("Adding #{node}")

  Inprovise::Sniffer.run_sniffers_for(node) if options[:sniff]

  options[:group].each do |g|
    grp = Inprovise::Infrastructure.find(g)
    raise ArgumentError, "Unknown group #{g}" unless grp
    node.add_to(grp)
  end
end

#cleanupObject



156
157
158
159
160
161
# File 'lib/inprovise/control.rb', line 156

def cleanup
  return if @targets.empty?
  Inprovise.log.local('Disconnecting...') if Inprovise.verbosity > 0
  @targets.each {|tgt| tgt.disconnect! }
  Inprovise.log.local('Done!') if Inprovise.verbosity > 0
end

#remove_group(*names) ⇒ Object



239
240
241
242
243
244
245
246
247
248
# File 'lib/inprovise/control.rb', line 239

def remove_group(*names)
  names.each do |name|
    grp = Inprovise::Infrastructure.find(name)
    raise ArgumentError, "Invalid group #{name}" unless grp && grp.is_a?(Inprovise::Infrastructure::Group)

    Inprovise.log.local("Removing #{grp}")

    Inprovise::Infrastructure.deregister(name)
  end
end

#remove_node(*names) ⇒ Object



201
202
203
204
205
206
207
208
209
210
# File 'lib/inprovise/control.rb', line 201

def remove_node(*names)
  names.each do |name|
    node = Inprovise::Infrastructure.find(name)
    raise ArgumentError, "Invalid node #{name}" unless node && node.is_a?(Inprovise::Infrastructure::Node)

    Inprovise.log.local("Removing #{node}")

    Inprovise::Infrastructure.deregister(name)
  end
end

#run_provisioning_command(command, cmdtgt, cmdcfg, *names) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/inprovise/control.rb', line 163

def run_provisioning_command(command, cmdtgt, cmdcfg, *names)
  # get intended infrastructure targets/config tuples
  targets = get_targets(*names)
  # create runner/config for each target/config
  runners = targets.map do |tgt, tgtcfg|
    @targets << tgt
    [
      if command == :trigger
        Inprovise::TriggerRunner.new(tgt, cmdtgt, Inprovise.skip_dependencies)
      else
        Inprovise::ScriptRunner.new(tgt, Inprovise::ScriptIndex.default.get(cmdtgt), Inprovise.skip_dependencies)
      end,
      tgtcfg
    ]
  end
  # execute runners
  if Inprovise.sequential
    runners.each {|runner, tgtcfg| exec(runner, command, tgtcfg.merge(cmdcfg)) }
  else
    @threads = runners.map {|runner, tgtcfg| Thread.new { exec(runner, command, tgtcfg.merge(cmdcfg)) } }
  end
end

#update_group(options, grpcfg, *names) ⇒ Object



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/inprovise/control.rb', line 250

def update_group(options, grpcfg, *names)
  groups = names.collect do |name|
    tgt = Inprovise::Infrastructure.find(name)
    raise ArgumentError, "Invalid group #{name}" unless tgt && tgt.is_a?(Inprovise::Infrastructure::Group)
    tgt
  end
  grp_tgts = options[:target].collect do |tnm|
    tgt = Inprovise::Infrastructure.find(tnm)
    raise ArgumentError, "Unknown target #{tnm}" unless tgt
    tgt
  end
  groups.each do |grp|
    Inprovise.log.local("Updating #{grp}")

    grp.config.clear if options[:reset]
    grp.config.merge!(grpcfg)
    grp_tgts.each {|gt| gt.add_to(grp) }
  end
end

#update_node(options, nodecfg, *names) ⇒ Object



212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/inprovise/control.rb', line 212

def update_node(options, nodecfg, *names)
  @targets = names.collect do |name|
    tgt = Inprovise::Infrastructure.find(name)
    raise ArgumentError, "Unknown target [#{name}]" unless tgt
    tgt.targets
  end.flatten.uniq
  if Inprovise.sequential || (!options[:sniff]) || @targets.size == 1
    @targets.each {|tgt| run_node_update(tgt, nodecfg.dup, options) }
  else
    threads = @targets.map {|tgt| Thread.new { run_node_update(tgt, nodecfg.dup, options) } }
    threads.each {|t| t.join }
  end
end

#waitObject



150
151
152
153
154
# File 'lib/inprovise/control.rb', line 150

def wait
  return if @threads.empty?
  Inprovise.log.local('Waiting for controller threads...') if Inprovise.verbosity > 0
  @threads.each { |t| t.join }
end