Method: Beaker::Shared::HostManager#run_block_on

Defined in:
lib/beaker/shared/host_manager.rb

#run_block_on(hosts = [], filter = nil, opts = {}, &block) ⇒ Array<Result>, ...

TODO:

(beaker3.0:BKR-571): simplify return types to Array<Result> only

Execute a block selecting the hosts that match with the provided criteria

Parameters:

  • hosts (Array<Host>, Host) (defaults to: [])

    The host or hosts to run the provided block against

  • filter (String, Symbol) (defaults to: nil)

    Optional filter to apply to provided hosts - limits by name or role

  • opts (Hash{Symbol=>String}) (defaults to: {})
  • block (Block)

    This method will yield to a block of code passed by the caller

Options Hash (opts):

  • :run_in_parallel (Boolean)

    Whether to run on each host in parallel.

Returns:

  • (Array<Result>, Result, nil)

    If an array of hosts has been passed (after filtering), then either an array of results is returned (if the array is non-empty), or nil is returned (if the array is empty). Else, a result object is returned. If filtering makes it such that only one host is left, then it’s passed as a host object (not in an array), and thus a result object is returned.



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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/beaker/shared/host_manager.rb', line 87

def run_block_on hosts = [], filter = nil, opts = {}, &block
  result = nil
  block_hosts = hosts #the hosts to apply the block to after any filtering
  if filter
    if not hosts.empty?
      block_hosts = hosts_with_role(hosts, filter) #check by role
      if block_hosts.empty?
        block_hosts = hosts_with_name(hosts, filter) #check by name
      end
      if block_hosts.length == 1  #we only found one matching host, don't need it wrapped in an array
        block_hosts = block_hosts.pop
      end
    else
      raise ArgumentError, "Unable to sort for #{filter} type hosts when provided with [] as Hosts"
    end
  end
  if block_hosts.is_a? Array
    if block_hosts.length > 0
      if run_in_parallel? opts
        # Pass caller[1] - the line that called block_on - for logging purposes.
        result = block_hosts.map.each_in_parallel(caller[1]) do |h|
          run_block_on h, &block
        end
        hosts.each{|host| host.close}# For some reason, I have to close the SSH connection
        # after spawning a process and running commands on a host,
        # or else it gets into a broken state for the next call.
      else
        result = block_hosts.map do |h|
          run_block_on h, &block
        end
      end
    else
      # there are no matching hosts to execute against
      # should warn here
      # check if logger is defined in this context
      if ( cur_logger = (logger || @logger ) )
        cur_logger.info "Attempting to execute against an empty array of hosts (#{hosts}, filtered to #{block_hosts}), no execution will occur"
      end
    end
  else
    result = yield block_hosts
  end
  result
end