Para realizar el apagado automático de un Spacename de JupiterLab (Shutdown) definiendo un tiempo de inactividad, se deberá configurar un LifeCycle de Dominio, para ello dentro de la consola de AWS se deberá ir a la siguiente opción:
Amazon SageMaker > Admin configurations > Lifecycle configurations > Create configuration
Aquí se deberá pegar el siguiente código, que lo que hará es de manera continua revisar el estado del kernel, y contabilizar conforme los segundos que se confifguren, si se está realizando alguna tarea dentro de Jupiter, si no hay nada en ejecución una vez transcurrido el tiempo, el entorno se apagará:
#!/bin/bash
set -eux
ASI_VERSION=0.3.1
# User variables [update as needed]
####################
### Ajustar el tiempo, tener en cuenta esto!!! https://github.com/aws-samples/sagemaker-studio-lifecycle-config-examples/issues/17#issuecomment-2364659767
####################
IDLE_TIME_IN_SECONDS=1200 # The max time (in seconds) the JupyterLab app can stay idle before being terminated.
# User variables - advanced [update only if needed]
IGNORE_CONNECTIONS=True # Set to False if you want to consider idle JL sessions with active connections as not idle.
SKIP_TERMINALS=False # Set to True if you want to skip any idleness check on Jupyter terminals.
# System variables [do not change if not needed]
JL_HOSTNAME=0.0.0.0
JL_PORT=8888
JL_BASE_URL=/jupyterlab/default/
CONDA_HOME=/opt/conda/bin
LOG_FILE=/var/log/apps/app_container.log # Writing to app_container.log delivers logs to CW logs.
SOLUTION_DIR=/var/tmp/auto-stop-idle # Do not use /home/sagemaker-user
STATE_FILE=$SOLUTION_DIR/auto_stop_idle.st
PYTHON_PACKAGE=sagemaker_studio_jlab_auto_stop_idle-$ASI_VERSION.tar.gz
PYTHON_SCRIPT_PATH=$SOLUTION_DIR/sagemaker_studio_jlab_auto_stop_idle/auto_stop_idle.py
CHECK_KERNEL_ACTIVITY_SCRIPT=/var/tmp/check_kernel_activity.sh
# Check if cron needs to be installed
status="$(dpkg-query -W --showformat='${db:Status-Status}' "cron" 2>&1)" || true
if [ ! $? = 0 ] || [ ! "$status" = installed ]; then
# Fixing invoke-rc.d: policy-rc.d denied execution of restart.
sudo /bin/bash -c "echo '#!/bin/sh
exit 0' > /usr/sbin/policy-rc.d"
# Installing cron.
echo "Installing cron..."
sudo apt install cron
else
echo "Package cron is already installed."
# start/restart the service.
sudo service cron restart
fi
# Creating solution directory.
sudo mkdir -p $SOLUTION_DIR
# Downloading autostop idle Python package.
echo "Downloading autostop idle Python package..."
curl -LO --output-dir /var/tmp/ https://github.com/aws-samples/sagemaker-studio-apps-lifecycle-config-examples/releases/download/v$ASI_VERSION/$PYTHON_PACKAGE
sudo $CONDA_HOME/pip install -U -t $SOLUTION_DIR /var/tmp/$PYTHON_PACKAGE
# Setting container credential URI variable to /etc/environment to make it available to cron
sudo /bin/bash -c "echo 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' >> /etc/environment"
# Create a script to check for kernel activity
sudo tee $CHECK_KERNEL_ACTIVITY_SCRIPT > /dev/null <<EOF
#!/bin/bash
# Set the notebook server hostname and port
JL_HOSTNAME=0.0.0.0
JL_PORT=8888
JL_TOKEN_FILE="/var/tmp/jupyter.token"
# Get the Jupyter token
TOKEN=\$(jupyter server list | grep -oP 'token=\K[^ ]+')
# Fetch list of kernels using Jupyter REST API
KERNELS=\$(curl -s -H "Authorization: Token \$TOKEN" "http://\$JL_HOSTNAME:\$JL_PORT/api/kernels " | jq -r '.[] | .execution_state')
# Check if any kernel is in a busy or executing state
for KERNEL_STATUS in \$KERNELS; do
if [[ "\$KERNEL_STATUS" == "busy" || "\$KERNEL_STATUS" == "executing" ]]; then
echo "Kernel is active. Autostop will not proceed."
exit 1
fi
done
echo "No active kernels found."
exit 0
EOF
# Make the kernel activity script executable
sudo chmod +x $CHECK_KERNEL_ACTIVITY_SCRIPT
# Add script to crontab for root.
echo "Adding autostop idle script with kernel monitoring to crontab..."
echo "*/2 * * * * /bin/bash -c '$CHECK_KERNEL_ACTIVITY_SCRIPT && $CONDA_HOME/python $PYTHON_SCRIPT_PATH --idle-time $IDLE_TIME_IN_SECONDS --hostname $JL_HOSTNAME \
--port $JL_PORT --base-url $JL_BASE_URL --ignore-connections $IGNORE_CONNECTIONS \
--skip-terminals $SKIP_TERMINALS --state-file-path $STATE_FILE >> $LOG_FILE'" | sudo crontab -
El código anterior está corregido, ya que el código fuente, apaga el entorno desde el tiempo que se inicia el entorno, y no es lo que se necesita en este caso.
Una vez guardado el LifeCycle, se deberá atachar este al entorno de trabajo, esto se realiza en la opción:
Amazon SageMaker > Admin configurations > Domains > Nombre Dominio > Enviroment > Lifecycle configurations for personal Studio apps > Attach
Allí se deberá seleccionar el LifeCycle configurado y seleccionar “Attach to domain” una vez guardado, se deberá seleccionar este por defecto para el entorno configurado, para ello en la lista se deberá seleccioanr el LifeCycle configurado y posteriormente seleccioanr “Set as default”
Ya se podrá iniciar el entorno de trabajo y este se detendrá automáticamente una vez se complete el proceso de ejecución con el tiempo definido. Tener en cuent aque si hay trabajos de Glue en curso, estos continuarán procesando la información en segundo plano, así el entorno de SageMaker se encuentre detenido, ya que este opera como un servicio independiente.