cookbooks/aws-parallelcluster-shared/libraries/helpers.rb (68 lines of code) (raw):
class NilClass
def blank?
true
end
end
class String
def blank?
strip.empty?
end
end
#
# Check if a service is installed in the instance and in the specific platform
#
def is_service_installed?(service, platform_families = node['platform_family'])
if platform_family?(platform_families)
# Add chkconfig for alinux2 and centos platform, because they do not generate systemd unit file automatically from init script
# Ubuntu platform generate systemd unit file from init script automatically, if the service is not found by systemd the check will fail because chkconfig does not exist
shell_out("systemctl daemon-reload; systemctl list-unit-files --all | grep #{service} || chkconfig --list #{service}").exitstatus.to_i.zero?
else
# in case of different platform return false
false
end
end
#
# Check if Nvidia driver is installed
# TODO: verify if it can be moved to platform cookbook later.
#
def nvidia_installed?
nvidia_installed = ::File.exist?('/usr/bin/nvidia-smi')
Chef::Log.warn("Nvidia driver is not installed") unless nvidia_installed
nvidia_installed
end
#
# Retrieve token to use to retrieve metadata
#
def get_metadata_token
# generate the token for retrieving IMDSv2 metadata
token_uri = URI("http://169.254.169.254/latest/api/token")
token_request = Net::HTTP::Put.new(token_uri)
token_request["X-aws-ec2-metadata-token-ttl-seconds"] = "300"
res = Net::HTTP.new("169.254.169.254").request(token_request)
res.body
end
#
# Retrieve metadata using a given token
#
def get_metadata_with_token(token, uri)
# get IMDSv2 metadata with token
request = Net::HTTP::Get.new(uri)
request["X-aws-ec2-metadata-token"] = token
res = Net::HTTP.new("169.254.169.254").request(request)
metadata = res.body if res.code == '200'
metadata
end
#
# load cluster configuration file into node object
#
def load_cluster_config(config_path)
ruby_block "load cluster configuration" do
block do
require 'yaml'
Chef::Log.info("Reading Config from #{config_path}")
config = YAML.safe_load(File.read(config_path))
Chef::Log.debug("Config read #{config}")
node.override['cluster']['config'].merge! config
end
only_if { node['cluster']['config'].nil? }
end
end
#
# Check if custom node is specified in the config
#
def is_custom_node?
custom_node_package = node['cluster']['custom_node_package']
!custom_node_package.nil? && !custom_node_package.empty?
end
def write_sync_file(path)
# Write a synchronization file containing the current cluster config version.
# Synchronization files are used as a synchronization point between cluster nodes
# to signal that a group of actions have been completed.
file path do
content node["cluster"]["cluster_config_version"]
mode "0644"
owner "root"
group "root"
end
end
def wait_sync_file(path)
# Wait for a synchronization file to exist.
# Synchronization files are used as a synchronization point between cluster nodes
# to signal that a group of actions have been completed.
# Wait for the config version file to contain the current cluster config version.
bash "Wait for synchronization file at #{path} to exist" do
code "[[ -e #{path} ]] || exit 1"
retries 30
retry_delay 10
timeout 5
end
end