8.5.2. Example Gear Placement Algorithms
Prerequisites:
Gem_Location/lib/openshift/ directory, with any related example initializers and configuration files located in the Gem_Location/config/initializers/ and /etc/openshift/plugins.d/ directories, respectively. See Section 8.5.1, “Developing and Implementing a Custom Gear Placement Algorithm” for information on implementing custom algorithms in your environment.
The following are administrator constraint example algorithms for the gear placement plug-in.
Example 8.8. Return the First Node in the List
def self.select_best_fit_node_impl(server_infos, app_props, current_gears, comp_list, user_props, request_time) return server_infos.first end
Example 8.9. Place PHP Applications on Specific Nodes
def self.select_best_fit_node_impl(server_infos, app_props, current_gears, comp_list, user_props, request_time)
unless %w[php-5.3 php-5.4].include? app_props.web_cartridge
Rails.logger.debug("'#{app_props.web_cartridge}' is not a PHP app; selecting a node normally.")
return OpenShift::MCollectiveApplicationContainerProxy.select_best_fit_node_impl(server_infos)
end
php_hosts = Broker::Application.config.gear_placement[:php_hosts]
Rails.logger.debug("selecting a php node from: #{php_hosts.join ', '}")
# figure out which of the nodes given is allowed for php carts
matched_server_infos = server_infos.select {|x| php_hosts.include?(x.name) }
matched_server_infos.empty? and
raise "The gear-placement PHP_HOSTS setting doesn't match any of the NodeProfile names"
return matched_server_infos.sample #chooses randomly from the matched hosts
endGem_Location/lib/openshift/gear_placement_plugin.rb.pin-php-to-host-example file. However, to prevent scalable or highly-available applications from behaving unpredictably as a result of the server_infos filters mentioned in Section 8.5.1, “Developing and Implementing a Custom Gear Placement Algorithm”, use the VALID_GEAR_SIZES_FOR_CARTRIDGE parameter in the /etc/openshift/broker.conf file in conjunction with profiles.
Example 8.10. Restrict a User's Applications to Slow Hosts
def self.select_best_fit_node_impl(server_infos, app_props, current_gears, comp_list, user_props, request_time)
config = Broker::Application.config.gear_placement
pinned_user = config[:pinned_user]
if pinned_user == user_props.login
slow_hosts = config[:slow_hosts]
Rails.logger.debug("user '#{pinned_user}' needs a gear; restrict to '#{slow_hosts.join ', '}'")
matched_server_infos = server_infos.select {|x| slow_hosts.include?(x.name)}
matched_server_infos.empty? and
raise "The gear-placement SLOW_HOSTS setting does not match any available NodeProfile names"
return matched_server_infos.first
else
Rails.logger.debug("user '#{user_props.login}' is not pinned; choose a node normally")
return OpenShift::MCollectiveApplicationContainerProxy.select_best_fit_node_impl(server_infos)
end
endGem_Location/lib/openshift/gear_placement_plugin.rb.pin-user-to-host-example file. However, this could prevent the user from scaling applications in some situations as a result of the server_infos filters mentioned in Section 8.5.1, “Developing and Implementing a Custom Gear Placement Algorithm”.
Example 8.11. Ban a Specific Vendor's Cartridges
def self.select_best_fit_node_impl(server_infos, app_props, current_gears, comp_list, user_props, request_time)
Rails.logger.debug("Using blacklist gear placement plugin to choose node.")
Rails.logger.debug("selecting from nodes: #{server_infos.map(:name).join ', '}")
blacklisted_vendor = Broker::Application.config.gear_placement[:blacklisted_vendor]
unless blacklisted_vendor.nil?
comp_list.each do |comp|
if blacklisted_vendor == comp.cartridge_vendor
raise "Applications containing cartridges from #{blacklisted_vendor} are blacklisted"
end
end
end
Rails.logger.debug("no contraband found, choosing node as usual")
return OpenShift::MCollectiveApplicationContainerProxy.select_best_fit_node_impl(server_infos)
endGem_Location/lib/openshift/gear_placement_plugin.rb.blacklisted-vendor-example file.
The following are resource usage example algorithms for the gear placement plug-in.
Example 8.12. Place a Gear on the Node with the Most Free Memory
def self.select_best_fit_node_impl(server_infos, app_props, current_gears, comp_list, user_props, request_time)
# collect memory statistic from all nodes
memhash = Hash.new(0)
OpenShift::MCollectiveApplicationContainerProxy.rpc_get_fact('memoryfree') {|name,mem| memhash[name] = to_bytes(mem)}
Rails.logger.debug("node memory hash: #{memhash.inspect}")
# choose the one from our list with the largest value
return server_infos.max_by {|server| memhash[server.name]}
end
def self.to_bytes(mem)
mem.to_f * case mem
when /TB/; 1024 ** 4
when /GB/; 1024 ** 3
when /MB/; 1024 ** 2
when /KB/; 1024
else ; 1
end
endGem_Location/lib/openshift/gear_placement_plugin.rb.free-memory-example file.
Example 8.13. Sort Nodes by Gear Usage (Round Robin)
def self.select_best_fit_node_impl(server_infos, app_props, current_gears, comp_list, user_props, request_time)
return server_infos.sort_by {|x| x.node_consumed_capacity.to_f}.first
endGem_Location/lib/openshift/gear_placement_plugin.rb.round-robin-example file. The nodes in each profile fill evenly, unless complications arise, for example due to scaled applications, gears being deleted unevenly, or MCollective fact updates trailing behind. Implementing true round robin requires writing out a state file owned by this algorithm and using that for scheduling the placement rotation.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.