- MySQL sample document content
-
###===============================================================================###
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
###===============================================================================###
schemaVersion: '2.2'
description: Amazon Data Lifecycle Manager Pre/Post script for MySQL databases
parameters:
executionId:
type: String
default: None
description: (Required) Specifies the unique identifier associated with a pre and/or post execution
allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
command:
# Data Lifecycle Manager will trigger the pre-script and post-script actions during policy execution.
# 'dry-run' option is intended for validating the document execution without triggering any commands
# on the instance. The following allowedValues will allow Data Lifecycle Manager to successfully
# trigger pre and post script actions.
type: String
default: 'dry-run'
description: (Required) Specifies whether pre-script and/or post-script should be executed.
allowedValues:
- pre-script
- post-script
- dry-run
mainSteps:
- action: aws:runShellScript
description: Run MySQL Database freeze/thaw commands
name: run_pre_post_scripts
precondition:
StringEquals:
- platformType
- Linux
inputs:
runCommand:
- |
#!/bin/bash
###===============================================================================###
### Error Codes
###===============================================================================###
# The following Error codes will inform Data Lifecycle Manager of the type of error
# and help guide handling of the error.
# The Error code will also be emitted via AWS Eventbridge events in the 'cause' field.
# 1 Pre-script failed during execution - 201
# 2 Post-script failed during execution - 202
# 3 Auto thaw occurred before post-script was initiated - 203
# 4 Pre-script initiated while post-script was expected - 204
# 5 Post-script initiated while pre-script was expected - 205
# 6 Application not ready for pre or post-script initiation - 206
###=================================================================###
### Global variables
###=================================================================###
START=$(date +%s)
# For testing this script locally, replace the below with OPERATION=$1.
OPERATION={{ command }}
FS_ALREADY_FROZEN_ERROR='freeze failed: Device or resource busy'
FS_ALREADY_THAWED_ERROR='unfreeze failed: Invalid argument'
FS_BUSY_ERROR='mount point is busy'
# Auto thaw is a fail safe mechanism to automatically unfreeze the application after the
# duration specified in the global variable below. Choose the duration based on your
# database application's tolerance to freeze.
export AUTO_THAW_DURATION_SECS="60"
# Add all pre-script actions to be performed within the function below
execute_pre_script() {
echo "INFO: Start execution of pre-script"
# Check if filesystem is already frozen. No error code indicates that filesystem
# is not currently frozen and that the pre-script can proceed with freezing the filesystem.
check_fs_freeze
# Execute the DB commands to flush the DB in preparation for snapshot
snap_db
# Freeze the filesystem. No error code indicates that filesystem was succefully frozen
freeze_fs
echo "INFO: Schedule Auto Thaw to execute in ${AUTO_THAW_DURATION_SECS} seconds."
$(nohup bash -c execute_schedule_auto_thaw >/dev/null 2>&1 &)
}
# Add all post-script actions to be performed within the function below
execute_post_script() {
echo "INFO: Start execution of post-script"
# Unfreeze the filesystem. No error code indicates that filesystem was successfully unfrozen.
unfreeze_fs
thaw_db
}
# Execute Auto Thaw to automatically unfreeze the application after the duration configured
# in the AUTO_THAW_DURATION_SECS global variable.
execute_schedule_auto_thaw() {
sleep ${AUTO_THAW_DURATION_SECS}
execute_post_script
}
# Disable Auto Thaw if it is still enabled
execute_disable_auto_thaw() {
echo "INFO: Attempting to disable auto thaw if enabled"
auto_thaw_pgid=$(pgrep -f execute_schedule_auto_thaw | xargs -i ps -hp {} -o pgid)
if [ -n "${auto_thaw_pgid}" ]; then
echo "INFO: execute_schedule_auto_thaw process found with pgid ${auto_thaw_pgid}"
sudo pkill -g ${auto_thaw_pgid}
rc=$?
if [ ${rc} != 0 ]; then
echo "ERROR: Unable to kill execute_schedule_auto_thaw process. retval=${rc}"
else
echo "INFO: Auto Thaw has been disabled"
fi
fi
}
# Iterate over all the mountpoints and check if filesystem is already in freeze state.
# Return error code 204 if any of the mount points are already frozen.
check_fs_freeze() {
for target in $(lsblk -nlo MOUNTPOINTS)
do
# Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
# Hence, we will skip the root and boot mountpoints while checking if filesystem is in freeze state.
if [ $target == '/' ]; then continue; fi
if [[ "$target" == *"/boot"* ]]; then continue; fi
error_message=$(sudo mount -o remount,noatime $target 2>&1)
# Remount will be a no-op without a error message if the filesystem is unfrozen.
# However, if filesystem is already frozen, remount will fail with busy error message.
if [ $? -ne 0 ];then
# If the filesystem is already in frozen, return error code 204
if [[ "$error_message" == *"$FS_BUSY_ERROR"* ]];then
echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
exit 204
fi
# If the check filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
echo "ERROR: Failed to check_fs_freeze on mountpoint $target due to error - $errormessage"
exit 201
fi
done
}
# Iterate over all the mountpoints and freeze the filesystem.
freeze_fs() {
for target in $(lsblk -nlo MOUNTPOINTS)
do
# Freeze of the root and boot filesystems is dangerous. Hence, skip filesystem freeze
# operations for root and boot mountpoints.
if [ $target == '/' ]; then continue; fi
if [[ "$target" == *"/boot"* ]]; then continue; fi
echo "INFO: Freezing $target"
error_message=$(sudo fsfreeze -f $target 2>&1)
if [ $? -ne 0 ];then
# If the filesystem is already in frozen, return error code 204
if [[ "$error_message" == *"$FS_ALREADY_FROZEN_ERROR"* ]]; then
echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
sudo mysql -e 'UNLOCK TABLES;'
exit 204
fi
# If the filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
echo "ERROR: Failed to freeze mountpoint $targetdue due to error - $errormessage"
thaw_db
exit 201
fi
echo "INFO: Freezing complete on $target"
done
}
# Iterate over all the mountpoints and unfreeze the filesystem.
unfreeze_fs() {
for target in $(lsblk -nlo MOUNTPOINTS)
do
# Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
# Hence, will skip the root and boot mountpoints during unfreeze as well.
if [ $target == '/' ]; then continue; fi
if [[ "$target" == *"/boot"* ]]; then continue; fi
echo "INFO: Thawing $target"
error_message=$(sudo fsfreeze -u $target 2>&1)
# Check if filesystem is already unfrozen (thawed). Return error code 204 if filesystem is already unfrozen.
if [ $? -ne 0 ]; then
if [[ "$error_message" == *"$FS_ALREADY_THAWED_ERROR"* ]]; then
echo "ERROR: Filesystem ${target} is already in thaw state. Return Error Code: 205"
exit 205
fi
# If the filesystem unfreeze failed due to any reason other than the filesystem already unfrozen, return 202
echo "ERROR: Failed to unfreeze mountpoint $targetdue due to error - $errormessage"
exit 202
fi
echo "INFO: Thaw complete on $target"
done
}
snap_db() {
# Run the flush command only when MySQL DB service is up and running
sudo systemctl is-active --quiet mysqld.service
if [ $? -eq 0 ]; then
echo "INFO: Execute MySQL Flush and Lock command."
sudo mysql -e 'FLUSH TABLES WITH READ LOCK;'
# If the MySQL Flush and Lock command did not succeed, return error code 201 to indicate pre-script failure
if [ $? -ne 0 ]; then
echo "ERROR: MySQL FLUSH TABLES WITH READ LOCK command failed."
exit 201
fi
sync
else
echo "INFO: MySQL service is inactive. Skipping execution of MySQL Flush and Lock command."
fi
}
thaw_db() {
# Run the unlock command only when MySQL DB service is up and running
sudo systemctl is-active --quiet mysqld.service
if [ $? -eq 0 ]; then
echo "INFO: Execute MySQL Unlock"
sudo mysql -e 'UNLOCK TABLES;'
else
echo "INFO: MySQL service is inactive. Skipping execution of MySQL Unlock command."
fi
}
export -f execute_schedule_auto_thaw
export -f execute_post_script
export -f unfreeze_fs
export -f thaw_db
# Debug logging for parameters passed to the SSM document
echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"
# Based on the command parameter value execute the function that supports
# pre-script/post-script operation
case ${OPERATION} in
pre-script)
execute_pre_script
;;
post-script)
execute_post_script
execute_disable_auto_thaw
;;
dry-run)
echo "INFO: dry-run option invoked - taking no action"
;;
*)
echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
exit 1 # return failure
;;
esac
END=$(date +%s)
# Debug Log for profiling the script time
echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."
- PostgreSQL sample document content
-
###===============================================================================###
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
###===============================================================================###
schemaVersion: '2.2'
description: Amazon Data Lifecycle Manager Pre/Post script for PostgreSQL databases
parameters:
executionId:
type: String
default: None
description: (Required) Specifies the unique identifier associated with a pre and/or post execution
allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
command:
# Data Lifecycle Manager will trigger the pre-script and post-script actions during policy execution.
# 'dry-run' option is intended for validating the document execution without triggering any commands
# on the instance. The following allowedValues will allow Data Lifecycle Manager to successfully
# trigger pre and post script actions.
type: String
default: 'dry-run'
description: (Required) Specifies whether pre-script and/or post-script should be executed.
allowedValues:
- pre-script
- post-script
- dry-run
mainSteps:
- action: aws:runShellScript
description: Run PostgreSQL Database freeze/thaw commands
name: run_pre_post_scripts
precondition:
StringEquals:
- platformType
- Linux
inputs:
runCommand:
- |
#!/bin/bash
###===============================================================================###
### Error Codes
###===============================================================================###
# The following Error codes will inform Data Lifecycle Manager of the type of error
# and help guide handling of the error.
# The Error code will also be emitted via AWS Eventbridge events in the 'cause' field.
# 1 Pre-script failed during execution - 201
# 2 Post-script failed during execution - 202
# 3 Auto thaw occurred before post-script was initiated - 203
# 4 Pre-script initiated while post-script was expected - 204
# 5 Post-script initiated while pre-script was expected - 205
# 6 Application not ready for pre or post-script initiation - 206
###===============================================================================###
### Global variables
###===============================================================================###
START=$(date +%s)
OPERATION={{ command }}
FS_ALREADY_FROZEN_ERROR='freeze failed: Device or resource busy'
FS_ALREADY_THAWED_ERROR='unfreeze failed: Invalid argument'
FS_BUSY_ERROR='mount point is busy'
# Auto thaw is a fail safe mechanism to automatically unfreeze the application after the
# duration specified in the global variable below. Choose the duration based on your
# database application's tolerance to freeze.
export AUTO_THAW_DURATION_SECS="60"
# Add all pre-script actions to be performed within the function below
execute_pre_script() {
echo "INFO: Start execution of pre-script"
# Check if filesystem is already frozen. No error code indicates that filesystem
# is not currently frozen and that the pre-script can proceed with freezing the filesystem.
check_fs_freeze
# Execute the DB commands to flush the DB in preparation for snapshot
snap_db
# Freeze the filesystem. No error code indicates that filesystem was succefully frozen
freeze_fs
echo "INFO: Schedule Auto Thaw to execute in ${AUTO_THAW_DURATION_SECS} seconds."
$(nohup bash -c execute_schedule_auto_thaw >/dev/null 2>&1 &)
}
# Add all post-script actions to be performed within the function below
execute_post_script() {
echo "INFO: Start execution of post-script"
# Unfreeze the filesystem. No error code indicates that filesystem was successfully unfrozen
unfreeze_fs
}
# Execute Auto Thaw to automatically unfreeze the application after the duration configured
# in the AUTO_THAW_DURATION_SECS global variable.
execute_schedule_auto_thaw() {
sleep ${AUTO_THAW_DURATION_SECS}
execute_post_script
}
# Disable Auto Thaw if it is still enabled
execute_disable_auto_thaw() {
echo "INFO: Attempting to disable auto thaw if enabled"
auto_thaw_pgid=$(pgrep -f execute_schedule_auto_thaw | xargs -i ps -hp {} -o pgid)
if [ -n "${auto_thaw_pgid}" ]; then
echo "INFO: execute_schedule_auto_thaw process found with pgid ${auto_thaw_pgid}"
sudo pkill -g ${auto_thaw_pgid}
rc=$?
if [ ${rc} != 0 ]; then
echo "ERROR: Unable to kill execute_schedule_auto_thaw process. retval=${rc}"
else
echo "INFO: Auto Thaw has been disabled"
fi
fi
}
# Iterate over all the mountpoints and check if filesystem is already in freeze state.
# Return error code 204 if any of the mount points are already frozen.
check_fs_freeze() {
for target in $(lsblk -nlo MOUNTPOINTS)
do
# Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
# Hence, we will skip the root and boot mountpoints while checking if filesystem is in freeze state.
if [ $target == '/' ]; then continue; fi
if [[ "$target" == *"/boot"* ]]; then continue; fi
error_message=$(sudo mount -o remount,noatime $target 2>&1)
# Remount will be a no-op without a error message if the filesystem is unfrozen.
# However, if filesystem is already frozen, remount will fail with busy error message.
if [ $? -ne 0 ];then
# If the filesystem is already in frozen, return error code 204
if [[ "$error_message" == *"$FS_BUSY_ERROR"* ]];then
echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
exit 204
fi
# If the check filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
echo "ERROR: Failed to check_fs_freeze on mountpoint $target due to error - $errormessage"
exit 201
fi
done
}
# Iterate over all the mountpoints and freeze the filesystem.
freeze_fs() {
for target in $(lsblk -nlo MOUNTPOINTS)
do
# Freeze of the root and boot filesystems is dangerous. Hence, skip filesystem freeze
# operations for root and boot mountpoints.
if [ $target == '/' ]; then continue; fi
if [[ "$target" == *"/boot"* ]]; then continue; fi
echo "INFO: Freezing $target"
error_message=$(sudo fsfreeze -f $target 2>&1)
if [ $? -ne 0 ];then
# If the filesystem is already in frozen, return error code 204
if [[ "$error_message" == *"$FS_ALREADY_FROZEN_ERROR"* ]]; then
echo "ERROR: Filesystem ${target} already frozen. Return Error Code: 204"
exit 204
fi
# If the filesystem freeze failed due to any reason other than the filesystem already frozen, return 201
echo "ERROR: Failed to freeze mountpoint $targetdue due to error - $errormessage"
exit 201
fi
echo "INFO: Freezing complete on $target"
done
}
# Iterate over all the mountpoints and unfreeze the filesystem.
unfreeze_fs() {
for target in $(lsblk -nlo MOUNTPOINTS)
do
# Freeze of the root and boot filesystems is dangerous and pre-script does not freeze these filesystems.
# Hence, will skip the root and boot mountpoints during unfreeze as well.
if [ $target == '/' ]; then continue; fi
if [[ "$target" == *"/boot"* ]]; then continue; fi
echo "INFO: Thawing $target"
error_message=$(sudo fsfreeze -u $target 2>&1)
# Check if filesystem is already unfrozen (thawed). Return error code 204 if filesystem is already unfrozen.
if [ $? -ne 0 ]; then
if [[ "$error_message" == *"$FS_ALREADY_THAWED_ERROR"* ]]; then
echo "ERROR: Filesystem ${target} is already in thaw state. Return Error Code: 205"
exit 205
fi
# If the filesystem unfreeze failed due to any reason other than the filesystem already unfrozen, return 202
echo "ERROR: Failed to unfreeze mountpoint $targetdue due to error - $errormessage"
exit 202
fi
echo "INFO: Thaw complete on $target"
done
}
snap_db() {
# Run the flush command only when PostgreSQL DB service is up and running
sudo systemctl is-active --quiet postgresql
if [ $? -eq 0 ]; then
echo "INFO: Execute Postgres CHECKPOINT"
# PostgreSQL command to flush the transactions in memory to disk
sudo -u postgres psql -c 'CHECKPOINT;'
# If the PostgreSQL Command did not succeed, return error code 201 to indicate pre-script failure
if [ $? -ne 0 ]; then
echo "ERROR: Postgres CHECKPOINT command failed."
exit 201
fi
sync
else
echo "INFO: PostgreSQL service is inactive. Skipping execution of CHECKPOINT command."
fi
}
export -f execute_schedule_auto_thaw
export -f execute_post_script
export -f unfreeze_fs
# Debug logging for parameters passed to the SSM document
echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"
# Based on the command parameter value execute the function that supports
# pre-script/post-script operation
case ${OPERATION} in
pre-script)
execute_pre_script
;;
post-script)
execute_post_script
execute_disable_auto_thaw
;;
dry-run)
echo "INFO: dry-run option invoked - taking no action"
;;
*)
echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
exit 1 # return failure
;;
esac
END=$(date +%s)
# Debug Log for profiling the script time
echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."
- InterSystems IRIS sample document content
-
###===============================================================================###
# MIT License
#
# Copyright (c) 2024 InterSystems
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
###===============================================================================###
schemaVersion: '2.2'
description: SSM Document Template for Amazon Data Lifecycle Manager Pre/Post script feature for InterSystems IRIS.
parameters:
executionId:
type: String
default: None
description: Specifies the unique identifier associated with a pre and/or post execution
allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
command:
type: String
# Data Lifecycle Manager will trigger the pre-script and post-script actions. You can also use this SSM document with 'dry-run' for manual testing purposes.
default: 'dry-run'
description: (Required) Specifies whether pre-script and/or post-script should be executed.
#The following allowedValues will allow Data Lifecycle Manager to successfully trigger pre and post script actions.
allowedValues:
- pre-script
- post-script
- dry-run
mainSteps:
- action: aws:runShellScript
description: Run InterSystems IRIS Database freeze/thaw commands
name: run_pre_post_scripts
precondition:
StringEquals:
- platformType
- Linux
inputs:
runCommand:
- |
#!/bin/bash
###===============================================================================###
### Global variables
###===============================================================================###
DOCKER_NAME=iris
LOGDIR=./
EXIT_CODE=0
OPERATION={{ command }}
START=$(date +%s)
# Check if Docker is installed
# By default if Docker is present, script assumes that InterSystems IRIS is running in Docker
# Leave only the else block DOCKER_EXEC line, if you run InterSystems IRIS non-containerised (and Docker is present).
# Script assumes irissys user has OS auth enabled, change the OS user or supply login/password depending on your configuration.
if command -v docker &> /dev/null
then
DOCKER_EXEC="docker exec $DOCKER_NAME"
else
DOCKER_EXEC="sudo -i -u irissys"
fi
# Add all pre-script actions to be performed within the function below
execute_pre_script() {
echo "INFO: Start execution of pre-script"
# find all iris running instances
iris_instances=$($DOCKER_EXEC iris qall 2>/dev/null | tail -n +3 | grep '^up' | cut -c5- | awk '{print $1}')
echo "`date`: Running iris instances $iris_instances"
# Only for running instances
for INST in $iris_instances; do
echo "`date`: Attempting to freeze $INST"
# Detailed instances specific log
LOGFILE=$LOGDIR/$INST-pre_post.log
#check Freeze status before starting
$DOCKER_EXEC irissession $INST -U '%SYS' "##Class(Backup.General).IsWDSuspendedExt()"
freeze_status=$?
if [ $freeze_status -eq 5 ]; then
echo "`date`: ERROR: $INST IS already FROZEN"
EXIT_CODE=204
else
echo "`date`: $INST is not frozen"
# Freeze
# Docs: https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=Backup.General#ExternalFreeze
$DOCKER_EXEC irissession $INST -U '%SYS' "##Class(Backup.General).ExternalFreeze(\"$LOGFILE\",,,,,,600,,,300)"
status=$?
case $status in
5) echo "`date`: $INST IS FROZEN"
;;
3) echo "`date`: $INST FREEZE FAILED"
EXIT_CODE=201
;;
*) echo "`date`: ERROR: Unknown status code: $status"
EXIT_CODE=201
;;
esac
echo "`date`: Completed freeze of $INST"
fi
done
echo "`date`: Pre freeze script finished"
}
# Add all post-script actions to be performed within the function below
execute_post_script() {
echo "INFO: Start execution of post-script"
# find all iris running instances
iris_instances=$($DOCKER_EXEC iris qall 2>/dev/null | tail -n +3 | grep '^up' | cut -c5- | awk '{print $1}')
echo "`date`: Running iris instances $iris_instances"
# Only for running instances
for INST in $iris_instances; do
echo "`date`: Attempting to thaw $INST"
# Detailed instances specific log
LOGFILE=$LOGDIR/$INST-pre_post.log
#check Freeze status befor starting
$DOCKER_EXEC irissession $INST -U '%SYS' "##Class(Backup.General).IsWDSuspendedExt()"
freeze_status=$?
if [ $freeze_status -eq 5 ]; then
echo "`date`: $INST is in frozen state"
# Thaw
# Docs: https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=Backup.General#ExternalFreeze
$DOCKER_EXEC irissession $INST -U%SYS "##Class(Backup.General).ExternalThaw(\"$LOGFILE\")"
status=$?
case $status in
5) echo "`date`: $INST IS THAWED"
$DOCKER_EXEC irissession $INST -U%SYS "##Class(Backup.General).ExternalSetHistory(\"$LOGFILE\")"
;;
3) echo "`date`: $INST THAW FAILED"
EXIT_CODE=202
;;
*) echo "`date`: ERROR: Unknown status code: $status"
EXIT_CODE=202
;;
esac
echo "`date`: Completed thaw of $INST"
else
echo "`date`: ERROR: $INST IS already THAWED"
EXIT_CODE=205
fi
done
echo "`date`: Post thaw script finished"
}
# Debug logging for parameters passed to the SSM document
echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"
# Based on the command parameter value execute the function that supports
# pre-script/post-script operation
case ${OPERATION} in
pre-script)
execute_pre_script
;;
post-script)
execute_post_script
;;
dry-run)
echo "INFO: dry-run option invoked - taking no action"
;;
*)
echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
# return failure
EXIT_CODE=1
;;
esac
END=$(date +%s)
# Debug Log for profiling the script time
echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."
exit $EXIT_CODE
For more information, see the
GitHub repository.
- Empty document template
-
###===============================================================================###
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
# software and associated documentation files (the "Software"), to deal in the Software
# without restriction, including without limitation the rights to use, copy, modify,
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
###===============================================================================###
schemaVersion: '2.2'
description: SSM Document Template for Amazon Data Lifecycle Manager Pre/Post script feature
parameters:
executionId:
type: String
default: None
description: (Required) Specifies the unique identifier associated with a pre and/or post execution
allowedPattern: ^(None|[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$
command:
# Data Lifecycle Manager will trigger the pre-script and post-script actions during policy execution.
# 'dry-run' option is intended for validating the document execution without triggering any commands
# on the instance. The following allowedValues will allow Data Lifecycle Manager to successfully
# trigger pre and post script actions.
type: String
default: 'dry-run'
description: (Required) Specifies whether pre-script and/or post-script should be executed.
allowedValues:
- pre-script
- post-script
- dry-run
mainSteps:
- action: aws:runShellScript
description: Run Database freeze/thaw commands
name: run_pre_post_scripts
precondition:
StringEquals:
- platformType
- Linux
inputs:
runCommand:
- |
#!/bin/bash
###===============================================================================###
### Error Codes
###===============================================================================###
# The following Error codes will inform Data Lifecycle Manager of the type of error
# and help guide handling of the error.
# The Error code will also be emitted via AWS Eventbridge events in the 'cause' field.
# 1 Pre-script failed during execution - 201
# 2 Post-script failed during execution - 202
# 3 Auto thaw occurred before post-script was initiated - 203
# 4 Pre-script initiated while post-script was expected - 204
# 5 Post-script initiated while pre-script was expected - 205
# 6 Application not ready for pre or post-script initiation - 206
###===============================================================================###
### Global variables
###===============================================================================###
START=$(date +%s)
# For testing this script locally, replace the below with OPERATION=$1.
OPERATION={{ command }}
# Add all pre-script actions to be performed within the function below
execute_pre_script() {
echo "INFO: Start execution of pre-script"
}
# Add all post-script actions to be performed within the function below
execute_post_script() {
echo "INFO: Start execution of post-script"
}
# Debug logging for parameters passed to the SSM document
echo "INFO: ${OPERATION} starting at $(date) with executionId: ${EXECUTION_ID}"
# Based on the command parameter value execute the function that supports
# pre-script/post-script operation
case ${OPERATION} in
pre-script)
execute_pre_script
;;
post-script)
execute_post_script
;;
dry-run)
echo "INFO: dry-run option invoked - taking no action"
;;
*)
echo "ERROR: Invalid command parameter passed. Please use either pre-script, post-script, dry-run."
exit 1 # return failure
;;
esac
END=$(date +%s)
# Debug Log for profiling the script time
echo "INFO: ${OPERATION} completed at $(date). Total runtime: $((${END} - ${START})) seconds."