理解头文件

理解头文件#

前面章节中创建一个 Shell 脚本类型 (ShellScriptTask) 的 task。

每个 ShellScriptTask 都有对应的 takler 脚本 (takler script),定义需要执行哪些操作,脚本类似于 UNIX shell 脚本。

但 takler 脚本使用 Jinja2 提供的模板指令和预定义变量。

工作流定义中的变量 (Parameter) 可以在 takler 脚本中使用,提供一种配置机制。

变量指令是 {{ some_var }}

{{ TAKLER_HOST }}

头文件引用指令是 {% include "some file" %}

{% include "head.takler" %}

head.takler#

head.takler 头文件放在 takler 脚本的开头,用于:

  • 提供与 Takler 服务通讯的环境

  • 定义脚本错误处理,当脚本出错捕获 trap 信号时,通知服务该任务 abort

  • 使用 child 命令 (child command) init 通知服务该任务已经开始

应用在 CMA-PI 上的示例 head.takler

 1#!/bin/bash
 2
 3set -e          # stop the shell on first error
 4set -u          # fail when using an undefined variable
 5set -x          # echo script lines as they are executed
 6# set -o pipefail # fail if last(rightmost) command exits with a non-zero status
 7
 8date
 9
10# Defines the three variables that are needed for any
11# communication with SMS
12
13export TAKLER_HOST={{ TAKLER_HOST }}
14export TAKLER_PORT={{ TAKLER_PORT }}
15export TAKLER_NAME={{ TAKLER_NAME }}
16
17# for ksh
18. /etc/profile.d/modules.sh
19
20RID=$( echo ${SLURM_JOB_ID:-0} )
21if [ $RID -eq 0 ] ; then
22  RID=$$
23fi
24export TAKLER_RID=$RID
25
26export PATH=~/bin:$PATH
27
28takler_client init --host ${TAKLER_HOST} --port ${TAKLER_PORT} \
29  --task-id ${TAKLER_RID} --node-path ${TAKLER_NAME}
30
31# Define a error handler
32ERROR() {
33   set +e                      # Clear -e flag, so we don't fail
34   wait                        # wait for background process to stop
35   takler_client abort --host ${TAKLER_HOST} --port ${TAKLER_PORT} \
36      --node-path ${TAKLER_NAME}
37   trap 0                      # Remove the trap
38   exit 0                      # End the script
39}
40# Trap any calls to exit and errors caught by the -e flag
41
42trap ERROR 0
43
44# Trap any signal that may cause the script to fail
45
46trap '{ echo "Killed by a signal";trap 0;ERROR; }' 1 2 3 4 5 6 7 8 10 12 13 15
47echo "exec on hostname:" "$(hostname)"

tail.takler#

tail.takler 放在 takler 脚本文件的结尾,通知服务该任务已经完成。 使用 child command 中的 complete 命令。

date
wait                      # wait for background process to stop
takler_client complete --host ${TAKLER_HOST} --port ${TAKLER_PORT} \
      --node-path ${TAKLER_NAME}
trap 0                    # Remove all traps
exit 0                    # End the shell

这两个头文件主要用于与 takler 服务通讯:

  • 建立通讯环境

  • 在任务开始时通知服务任务已经开始

  • 在任务结束时通知服务任务已经完成

  • 在任务出错时通知服务任务发生错误

练习#

  1. ${TAKLER_HOME}/test 目录中创建头文件 head.taklertail.takler