cookbooks/aws-parallelcluster-slurm/libraries/storage.rb (47 lines of code) (raw):
# frozen_string_literal: true
# Copyright:: 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "LICENSE.txt" file accompanying this file.
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied.
# See the License for the specific language governing permissions and limitations under the License.
# rubocop:disable Style/SingleArgumentDig
STORAGE_TYPES_SUPPORTING_LIVE_UPDATES = %w(Efs FsxLustre FsxOntap FsxOpenZfs FileCache).freeze
EXTERNAL_STORAGE_KEYS = %w(VolumeId FileSystemId FileCacheId).freeze
class SharedStorageChangeInfo
attr_reader :is_mount, :is_unmount, :storage_type, :storage_settings, :is_external
# Creates a new instance of SharedStorageChangeInfo capturing the relevant information out of the given
# shared storage change of a change-set.
#
# @param [any] change a change provided by a change-set. Example of a change:
# {
# "parameter": "SharedStorage",
# "requestedValue": {
# "MountDir": "/opt/shared/efs/managed/1",
# "Name": "shared-efs-managed-1",
# "StorageType": "Efs",
# "EfsSettings": {
# "FileSystemId": "fs-123456789"
# },
# "currentValue": nil
# }
def initialize(change)
old_value = change["currentValue"]
new_value = change["requestedValue"]
storage_item = new_value.nil? ? old_value : new_value
# Storage Action
@is_mount = (old_value.nil? and !new_value.nil?)
@is_unmount = (!old_value.nil? and new_value.nil?)
@storage_type = storage_item["StorageType"]
@storage_settings = storage_item["#{@storage_type}Settings"] || {}
# Storage Ownership
@is_external = @storage_settings.keys.any? { |k| EXTERNAL_STORAGE_KEYS.include?(k) }
end
# Checks if a given shared storage change within a changeset supports live updates.
# With live updates we refer to in-place updates that do not required node replacement.
# Currently, a live update is supported only in the following cases:
# 1. mount/unmount of external EFS
# 1. mount/unmount of external FSx
#
# @return [Boolean] true if the change supports live updates; false, otherwise.
def support_live_updates?
@is_external and STORAGE_TYPES_SUPPORTING_LIVE_UPDATES.include?(@storage_type)
end
# Returns the string representation of the object.
#
# @return [String] the string representation of the object.
def to_s
attributes = instance_variables.reduce [] do |list, attribute|
list.append "#{attribute}=#{instance_variable_get(attribute).inspect}"
end
"{#{attributes.join(', ')}}"
end
end
# Checks if all the shared storage changes in the change-set (if any) support live updates.
# With live updates we refer to in-place updates that do not required node replacement.
# The decision on the support is demanded to SharedStorageChangeInfo.
# If the changes are nil, empty or they do not contain any shared storage change,
# we assume that a live update is supported.
#
# @return [Boolean] true if the change supports live updates; false, otherwise.
def storage_change_supports_live_update?
change_set = JSON.load_file("#{node['cluster']['change_set_path']}")
changes = change_set["changeSet"]
if changes.nil? || changes.empty?
Chef::Log.info("Changeset is empty: live update is supported")
return true
end
storage_changes = changes.select { |change| change["parameter"] == "SharedStorage" }
if storage_changes.empty?
Chef::Log.info("Changeset does not contain shared storage changes: live update is supported")
return true
end
storage_changes.each do |change|
Chef::Log.info("Analyzing shared storage change: #{change}")
change_info = SharedStorageChangeInfo.new(change)
Chef::Log.info("Generated shared storage change info: #{change_info}")
supported = change_info.support_live_updates?
Chef::Log.info("Change #{change} #{'does not ' unless supported}support live update")
return false unless supported
end
Chef::Log.info("All shared storage changes support live update.")
true
end