Por: @jonasc Publicado em: 2022-04-12

Objetivo

Ter uma chamada de serviço no PCS, que execute por último de todos os serviços, para executar ações necessárias da aplicação.

Método 1 - Serviço start/stop no systemd

Unit do tipo oneshot em /usr/lib/systemd/system/itflex-actions.service (sem processo rodando, somente para execução de scripts):

[Unit]
Description=iTFLEX Cluster Actions

[Service]
Type=oneshot
ExecStart=/usr/bin/itflex-actions start
ExecStop=/usr/bin/itflex-actions stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Exemplo de script:

#!/bin/bash

LOG=/var/log/itflex/itflex-actions.log

case "$1" in
    'start')
        echo "Executando itflex-actions start..."
        echo "`date "+%Y-%m-%d %H:%M:%S"` - Executando itflex-actions start" >> $LOG
        /bin/itflex-reload-routes >> $LOG
        RETVAL=$?
        ;;
    'stop')
        echo "Executando itflex-actions stop..."
        echo "`date "+%Y-%m-%d %H:%M:%S"` - Executando itflex-actions stop" >> $LOG
	/bin/itflex-reload-routes >> $LOG
	RETVAL=$?
        ;;
    *)
        echo "Usage: $0 { start | stop }"
        RETVAL=1
        ;;
esac
exit $RETVAL

OBS: Foi usado um exemplo simples em bash, pode ser melhorado algo em python, com melhor recursos de log e debug.

Para adicionar o resource:

itflex-cluster resource add service --name itflex-actions

O comando da iTFLEX usa o type systemd.

Método 2 - Serviço do tipo OCF Heartbeat

Para este formato é necessário criar um script customizado em /usr/lib/ocf/resource.d/heartbeat/itflex-actions:

#!/bin/bash

#######################################################################
# Initialization:

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs

LOG=/var/log/itflex/itflex-actions.log

metadata() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="itflex-actions">
<version>1.0</version>
<longdesc lang="en">
Execute itflex-actions after cluster takeover
</longdesc>
<shortdesc lang="en">itflex-actions</shortdesc>

<parameters>
</parameters>

<actions>
<action name="start" timeout="180s" />
<action name="stop" timeout="180s" />
<action name="monitor" depth="0" timeout="180s" interval="300s" />
<action name="meta-data" timeout="5s" />
</actions>
</resource-agent>
END
}


itflex-actions_start() {
	echo "Executando itflex-actions start..."
	echo "`date "+%Y-%m-%d %H:%M:%S"` - Executando itflex-actions start" >> $LOG
	/bin/itflex-reload-routes >> $LOG
        if [ $? != $OCF_SUCCESS ]; then
                ocf_log info "Could not start itflex-actions"
                return $OCF_ERR_GENERIC
        fi
        return $OCF_SUCCESS
}

itflex-actions_stop() {
        echo "Executando itflex-actions stop..."
        echo "`date "+%Y-%m-%d %H:%M:%S"` - Executando itflex-actions stop" >> $LOG
        /bin/itflex-reload-routes >> $LOG
        if [ $? != $OCF_SUCCESS ]; then
                ocf_log info "Could not stop itflex-actions"
                return $OCF_ERR_GENERIC
        fi
        return $OCF_SUCCESS
}

itflex-actions_monitor() {
	return $OCF_SUCCESS
}

case $__OCF_ACTION in
        meta-data)
		metadata
                exit $OCF_SUCCESS
                ;;
	start)
                itflex-actions_start
                ;;
        stop)
                itflex-actions_stop
                ;;
        monitor)
		itflex-actions_monitor
                ;;
	*)
		echo "Usage: $0 { start | stop }"
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac

exit $?

O script precisa ser no formato acima, para que o PCS consiga interpretar os status das ações. É necessário a ação de metadata com um XML de parametros e ações do serviço. Também é necessário uma ação de monitor, que executa a checagem do serviço. Neste caso, o monitor simplesmente retorna sucesso, porque se trata da execução de scripts que não ficam em execução.

Para adicionar o resource:

pcs resource create itflex-actions ocf:heartbeat:itflex-actions

O comando itflex-cluster não possui o tipo ocf:heartbeat.

Resultados

Ambos funcionam e atendem a necessidade. O formato do systemd é mais simples e fácil de entender. O formato OCF heartbeat é mais complexo, mas permite construir formas mais refinadas de checagem do status do serviço.