├── .gitignore
├── package
├── __init__.py
└── scripts
│ ├── __init__.py
│ ├── download.ini
│ ├── common.py
│ ├── params.py
│ ├── azkaban_executor.py
│ └── azkaban_web.py
├── bin
├── start-web.sh
├── start-exec.sh
├── shutdown-web.sh
├── shutdown-exec.sh
└── internal
│ ├── internal-start-web.sh
│ ├── internal-start-executor.sh
│ ├── util.sh
│ ├── stop-executor.sh
│ └── stop-web.sh
├── README.md
├── quicklinks
└── quicklinks.json
├── configuration
├── global.properties.xml
├── log4j.properties.xml
├── azkaban-db.xml
├── azkaban-users.xml
├── azkaban-web.properties.xml
└── azkaban-executor.properties.xml
└── metainfo.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 |
--------------------------------------------------------------------------------
/package/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package/scripts/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/bin/start-web.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | script_dir=$(dirname $0)
4 |
5 | ${script_dir}/internal/internal-start-web.sh >webServerLog_`date +%F+%T`.out 2>&1 &
6 |
--------------------------------------------------------------------------------
/bin/start-exec.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | script_dir=$(dirname $0)
4 |
5 | # pass along command line arguments to the internal launch script.
6 | ${script_dir}/internal/internal-start-executor.sh "$@" >executorServerLog__`date +%F+%T`.out 2>&1 &
7 |
8 |
--------------------------------------------------------------------------------
/bin/shutdown-web.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Shutdown script for azkaban web server
3 | set -o nounset
4 |
5 | script_dir=$(dirname $0)
6 | base_dir="${script_dir}/.."
7 | source "${script_dir}/internal/stop-web.sh"
8 | common_shutdown "web-server" ${base_dir}
9 |
--------------------------------------------------------------------------------
/package/scripts/download.ini:
--------------------------------------------------------------------------------
1 | [download]
2 | azkaban_web_url = http://fp-bd6/azkaban/azkaban-web-server-3.38.0.tar.gz
3 | azkaban_executor_url = http://fp-bd6/azkaban/azkaban-exec-server-3.38.0.tar.gz
4 | azkaban_db_url = http://fp-bd6/azkaban/create-all-sql-3.38.0.sql
5 |
--------------------------------------------------------------------------------
/bin/shutdown-exec.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Shutdown script for azkaban executor server
3 | set -o nounset
4 |
5 | script_dir=$(dirname $0)
6 | base_dir="${script_dir}/.."
7 | source "${script_dir}/internal/stop-executor.sh"
8 | common_shutdown "executor" ${base_dir}
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Intro
2 | Ambari 集成 Azkaban
3 |
4 | 使用前,先clone.代码到本地,选择合适你的分支版本。
5 |
6 | # Major Project Structure
7 | - configuration : azkaban 配置文件
8 | - bin : Azkaban脚本修改(单机部署web、exec需要更换)
9 | - package :
10 | - scripts : ambari 管理逻辑脚本
11 | - azkaban_executor.py
12 | - azkaban_web.py
13 | - common.py
14 | - download.ini
15 | - params.py
16 |
17 | # Deploy
18 |
19 | - 1台服务器同时安装web、executor(需要修改azkaban的脚本,同时启动有冲突)
20 | - web、executor分别部署在多台服务器(无需关心脚本)
21 |
22 | # Usage
23 |
24 | https://cwiki.apache.org/confluence/display/AMBARI/Overview
25 |
--------------------------------------------------------------------------------
/quicklinks/quicklinks.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "default",
3 | "description": "default quick links configuration",
4 | "configuration": {
5 | "protocol": {
6 | "type": "HTTP_ONLY"
7 | },
8 | "links": [
9 | {
10 | "name": "azkaban_web",
11 | "label": "Azkaban Web",
12 | "component_name": "AZKABAN_WEB",
13 | "requires_user_name": "false",
14 | "url": "%@://%@:%@",
15 | "port": {
16 | "http_property": "jetty.port",
17 | "regex": "^(\\d+)$",
18 | "site": "azkaban-web.properties"
19 | }
20 | }
21 | ]
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/package/scripts/common.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | import os
16 |
17 | import ConfigParser
18 |
19 | script_dir = os.path.dirname(os.path.realpath(__file__))
20 | config = ConfigParser.ConfigParser()
21 | config.readfp(open(os.path.join(script_dir, 'download.ini')))
22 |
23 | AZKABAN_HOME = '/usr/hdp/current/azkaban'
24 | AZKABAN_NAME = 'azkaban'
25 | AZKABAN_SQL = 'azkaban.sql'
26 | AZKABAN_WEB_URL = config.get('download', 'azkaban_web_url')
27 | AZKABAN_EXECUTOR_URL = config.get('download', 'azkaban_executor_url')
28 | AZKABAN_DB_URL = config.get('download', 'azkaban_db_url')
29 | AZKABAN_CONF = AZKABAN_HOME + '/conf'
30 |
--------------------------------------------------------------------------------
/configuration/global.properties.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | content
21 | global.properties template
22 | Custom global.properties
23 | #
24 |
25 | content
26 | false
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/package/scripts/params.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 | from resource_management.libraries.script.script import Script
17 |
18 | # config object that holds the configurations declared in the config xml file
19 | config = Script.get_config()
20 |
21 | azkaban_web_properties = config['configurations']['azkaban-web.properties']
22 | azkaban_executor_properties = config['configurations']['azkaban-executor.properties']
23 | azkaban_users = config['configurations']['azkaban-users']
24 | azkaban_db = config['configurations']['azkaban-db']
25 | global_properties = config['configurations']['global.properties']
26 | log4j_properties = config['configurations']['log4j.properties']
27 |
28 | host_info = config['clusterHostInfo']
29 | host_level_params = config['hostLevelParams']
30 | java_home = host_level_params['java_home']
31 |
--------------------------------------------------------------------------------
/configuration/log4j.properties.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | content
21 | log4j.properties template
22 | Custom log4j.properties
23 |
24 | log4j.rootLogger=INFO, Console
25 | log4j.appender.Console=org.apache.log4j.ConsoleAppender
26 | log4j.appender.Console.layout=org.apache.log4j.PatternLayout
27 | log4j.appender.Console.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss.SSS Z} %p [%c{1}] %m%n
28 | log4j.category.velocity=INFO
29 |
30 |
31 | content
32 | false
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/configuration/azkaban-db.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 | database.type
22 | mysql
23 |
24 |
25 | mysql.host
26 | fp-bd5
27 |
28 |
29 | mysql.port
30 | 3306
31 |
32 |
33 | mysql.database
34 | azkaban
35 |
36 |
37 | mysql.user
38 | azkaban
39 |
40 |
41 | mysql.password
42 | azkaban
43 |
44 |
45 | mysql.numconnections
46 | 100
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/configuration/azkaban-users.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 | content
21 | azkaban-users.xml template
22 | Custom azkaban-users.xml
23 |
24 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | ]]>
43 |
44 |
45 | content
46 | false
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/bin/internal/internal-start-web.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | azkaban_dir=$(dirname $0)/../..
4 |
5 | # Specifies location of azkaban.properties, log4j.properties files
6 | # Change if necessary
7 | conf=$azkaban_dir/conf
8 | filtr="exec"
9 | if [[ -z "$tmpdir" ]]; then
10 | tmpdir=/tmp
11 | fi
12 |
13 | for file in $azkaban_dir/lib/*.jar;
14 | do
15 | if [[ $file =~ $filtr ]];
16 | then
17 | echo ""
18 | else
19 | CLASSPATH=$CLASSPATH:$file
20 | fi
21 | done
22 |
23 | for file in $azkaban_dir/extlib/*.jar;
24 | do
25 | CLASSPATH=$CLASSPATH:$file
26 | done
27 |
28 | for file in $azkaban_dir/plugins/*/*.jar;
29 | do
30 | CLASSPATH=$CLASSPATH:$file
31 | done
32 |
33 | if [ "$HADOOP_HOME" != "" ]; then
34 | echo "Using Hadoop from $HADOOP_HOME"
35 | CLASSPATH=$CLASSPATH:$HADOOP_HOME/conf:$HADOOP_HOME/*
36 | JAVA_LIB_PATH="-Djava.library.path=$HADOOP_HOME/lib/native/Linux-amd64-64"
37 | else
38 | echo "Error: HADOOP_HOME is not set. Hadoop job types will not run properly."
39 | fi
40 |
41 | if [ "$HIVE_HOME" != "" ]; then
42 | echo "Using Hive from $HIVE_HOME"
43 | CLASSPATH=$CLASSPATH:$HIVE_HOME/conf:$HIVE_HOME/lib/*
44 | fi
45 |
46 | echo $azkaban_dir;
47 | echo $CLASSPATH;
48 |
49 | executorport=`cat $conf/azkaban.properties | grep executor.port | cut -d = -f 2`
50 | serverpath=`pwd`
51 |
52 | if [[ -z "$AZKABAN_OPTS" ]]; then
53 | AZKABAN_OPTS="-Xmx4G"
54 | fi
55 | # Set the log4j configuration file
56 | if [ -f $conf/log4j.properties ]; then
57 | AZKABAN_OPTS="$AZKABAN_OPTS -Dlog4j.configuration=file:$conf/log4j.properties -Dlog4j.log.dir=$azkaban_dir/logs"
58 | else
59 | echo "Exit with error: $conf/log4j.properties file doesn't exist."
60 | exit 1;
61 | fi
62 | AZKABAN_OPTS="$AZKABAN_OPTS -server -Dcom.sun.management.jmxremote -Djava.io.tmpdir=$tmpdir -Dexecutorport=$executorport -Dserverpath=$serverpath"
63 |
64 | java $AZKABAN_OPTS $JAVA_LIB_PATH -cp $CLASSPATH azkaban.webapp.AzkabanWebServer -conf $conf $@ &
65 |
66 | echo $! > $azkaban_dir/web_currentpid
67 |
68 |
--------------------------------------------------------------------------------
/bin/internal/internal-start-executor.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | azkaban_dir=$(dirname $0)/../..
4 |
5 | # Specifies location of azkaban.properties, log4j.properties files
6 | # Change if necessary
7 | conf=$azkaban_dir/conf
8 | filtr="web"
9 | if [[ -z "$tmpdir" ]]; then
10 | tmpdir=/tmp
11 | fi
12 |
13 | for file in $azkaban_dir/lib/*.jar;
14 | do
15 | if [[ $file =~ $filtr ]];
16 | then
17 | echo ""
18 | else
19 | CLASSPATH=$CLASSPATH:$file
20 | fi
21 | done
22 |
23 | for file in $azkaban_dir/extlib/*.jar;
24 | do
25 | CLASSPATH=$CLASSPATH:$file
26 | done
27 |
28 | for file in $azkaban_dir/plugins/*/*.jar;
29 | do
30 | CLASSPATH=$CLASSPATH:$file
31 | done
32 |
33 | if [ "$HADOOP_HOME" != "" ]; then
34 | echo "Using Hadoop from $HADOOP_HOME"
35 | CLASSPATH=$CLASSPATH:$HADOOP_HOME/conf:$HADOOP_HOME/*
36 | JAVA_LIB_PATH="-Djava.library.path=$HADOOP_HOME/lib/native/Linux-amd64-64"
37 | else
38 | echo "Error: HADOOP_HOME is not set. Hadoop job types will not run properly."
39 | fi
40 |
41 | if [ "$HIVE_HOME" != "" ]; then
42 | echo "Using Hive from $HIVE_HOME"
43 | CLASSPATH=$CLASSPATH:$HIVE_HOME/conf:$HIVE_HOME/lib/*
44 | fi
45 |
46 | echo $azkaban_dir;
47 | echo $CLASSPATH;
48 |
49 | executorport=`cat $conf/azkaban.properties | grep executor.port | cut -d = -f 2`
50 | echo "Starting AzkabanExecutorServer on port $executorport ..."
51 | serverpath=`pwd`
52 |
53 | if [[ -z "$AZKABAN_OPTS" ]]; then
54 | AZKABAN_OPTS="-Xmx3G"
55 | fi
56 | # Set the log4j configuration file
57 | if [ -f $conf/log4j.properties ]; then
58 | AZKABAN_OPTS="$AZKABAN_OPTS -Dlog4j.configuration=file:$conf/log4j.properties -Dlog4j.log.dir=$azkaban_dir/logs"
59 | else
60 | echo "Exit with error: $conf/log4j.properties file doesn't exist."
61 | exit 1;
62 | fi
63 | AZKABAN_OPTS="$AZKABAN_OPTS -server -Dcom.sun.management.jmxremote -Djava.io.tmpdir=$tmpdir -Dexecutorport=$executorport -Dserverpath=$serverpath"
64 |
65 | java $AZKABAN_OPTS $JAVA_LIB_PATH -cp $CLASSPATH azkaban.execapp.AzkabanExecutorServer -conf $conf $@ &
66 |
67 | echo $! > $azkaban_dir/currentpid
68 |
69 |
--------------------------------------------------------------------------------
/bin/internal/util.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Common utils
3 | set -o nounset # exit the script if you try to use an uninitialised variable
4 | set -o errexit # exit the script if any statement returns a non-true return value
5 |
6 | #---
7 | # is_process_running: Checks if a process is running
8 | # args: Process ID of running proccess
9 | # returns: returns 0 if process is running, 1 if not found
10 | #---
11 | function is_process_running {
12 | local pid=$1
13 | kill -0 $pid > /dev/null 2>&1 #exit code ($?) is 0 if pid is running, 1 if not running
14 | local status=$? #because we are returning exit code, can use with if & no [ bracket
15 | return $status
16 | }
17 |
18 | #---
19 | # args: Process name of a running process to shutdown, install directory
20 | # returns: returns 0 if success, 1 otherwise
21 | #---
22 | function common_shutdown {
23 | process_name="$1"
24 | install_dir="$2"
25 | max_attempt=3
26 | pid=`cat ${install_dir}/currentpid`
27 |
28 | kill_process_with_retry "${pid}" "${process_name}" "${max_attempt}"
29 |
30 | if [[ $? == 0 ]]; then
31 | rm -f ${install_dir}/currentpid
32 | return 0
33 | else
34 | return 1
35 | fi
36 | }
37 |
38 | #---
39 | # kill_process_with_retry: Checks and attempts to kill the running process
40 | # args: PID, process name, number of kill attempts
41 | # returns: returns 0 if kill succeds or nothing to kill, 1 if kill fails
42 | # exception: If passed a non-existant pid, function will forcefully exit
43 | #---
44 | function kill_process_with_retry {
45 | local pid="$1"
46 | local pname="$2"
47 | local maxattempt="$3"
48 | local sleeptime=5
49 |
50 | if ! is_process_running $pid ; then
51 | echo "ERROR: process name ${pname} with pid: ${pid} not found"
52 | exit 1
53 | fi
54 |
55 | for try in $(seq 1 $maxattempt); do
56 | echo "Killing $pname. [pid: $pid], attempt: $try"
57 | kill ${pid}
58 | sleep 5
59 | if is_process_running $pid; then
60 | echo "$pname is not dead [pid: $pid]"
61 | echo "sleeping for $sleeptime seconds before retry"
62 | sleep $sleeptime
63 | else
64 | echo "shutdown succeeded"
65 | return 0
66 | fi
67 | done
68 |
69 | echo "Error: unable to kill process for $maxattempt attempt(s), killing the process with -9"
70 | kill -9 $pid
71 | sleep $sleeptime
72 |
73 | if is_process_running $pid; then
74 | echo "$pname is not dead even after kill -9 [pid: $pid]"
75 | return 1
76 | else
77 | echo "shutdown succeeded"
78 | return 0
79 | fi
80 | }
81 |
82 |
--------------------------------------------------------------------------------
/bin/internal/stop-executor.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Common utils
3 | set -o nounset # exit the script if you try to use an uninitialised variable
4 | set -o errexit # exit the script if any statement returns a non-true return value
5 |
6 | #---
7 | # is_process_running: Checks if a process is running
8 | # args: Process ID of running proccess
9 | # returns: returns 0 if process is running, 1 if not found
10 | #---
11 | function is_process_running {
12 | local pid=$1
13 | kill -0 $pid > /dev/null 2>&1 #exit code ($?) is 0 if pid is running, 1 if not running
14 | local status=$? #because we are returning exit code, can use with if & no [ bracket
15 | return $status
16 | }
17 |
18 | #---
19 | # args: Process name of a running process to shutdown, install directory
20 | # returns: returns 0 if success, 1 otherwise
21 | #---
22 | function common_shutdown {
23 | process_name="$1"
24 | install_dir="$2"
25 | max_attempt=3
26 | if [ ! -f "${install_dir}/currentpid" ]; then
27 | return 0
28 | fi
29 | pid=`cat ${install_dir}/currentpid`
30 | kill_process_with_retry "${pid}" "${process_name}" "${max_attempt}"
31 |
32 | if [[ $? == 0 ]]; then
33 | rm -f ${install_dir}/currentpid
34 | return 0
35 | else
36 | return 1
37 | fi
38 | }
39 |
40 | #---
41 | # kill_process_with_retry: Checks and attempts to kill the running process
42 | # args: PID, process name, number of kill attempts
43 | # returns: returns 0 if kill succeds or nothing to kill, 1 if kill fails
44 | # exception: If passed a non-existant pid, function will forcefully exit
45 | #---
46 | function kill_process_with_retry {
47 | local pid="$1"
48 | local pname="$2"
49 | local maxattempt="$3"
50 | local sleeptime=5
51 |
52 | if ! is_process_running $pid ; then
53 | echo "ERROR: process name ${pname} with pid: ${pid} not found"
54 | exit 1
55 | fi
56 |
57 | for try in $(seq 1 $maxattempt); do
58 | echo "Killing $pname. [pid: $pid], attempt: $try"
59 | kill ${pid}
60 | sleep 5
61 | if is_process_running $pid; then
62 | echo "$pname is not dead [pid: $pid]"
63 | echo "sleeping for $sleeptime seconds before retry"
64 | sleep $sleeptime
65 | else
66 | echo "shutdown succeeded"
67 | return 0
68 | fi
69 | done
70 |
71 | echo "Error: unable to kill process for $maxattempt attempt(s), killing the process with -9"
72 | kill -9 $pid
73 | sleep $sleeptime
74 |
75 | if is_process_running $pid; then
76 | echo "$pname is not dead even after kill -9 [pid: $pid]"
77 | return 1
78 | else
79 | echo "shutdown succeeded"
80 | return 0
81 | fi
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/bin/internal/stop-web.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Common utils
3 | set -o nounset # exit the script if you try to use an uninitialised variable
4 | set -o errexit # exit the script if any statement returns a non-true return value
5 |
6 | #---
7 | # is_process_running: Checks if a process is running
8 | # args: Process ID of running proccess
9 | # returns: returns 0 if process is running, 1 if not found
10 | #---
11 | function is_process_running {
12 | local pid=$1
13 | kill -0 $pid > /dev/null 2>&1 #exit code ($?) is 0 if pid is running, 1 if not running
14 | local status=$? #because we are returning exit code, can use with if & no [ bracket
15 | return $status
16 | }
17 |
18 | #---
19 | # args: Process name of a running process to shutdown, install directory
20 | # returns: returns 0 if success, 1 otherwise
21 | #---
22 | function common_shutdown {
23 | process_name="$1"
24 | install_dir="$2"
25 | max_attempt=3
26 | if [ ! -f "${install_dir}/web_currentpid" ]; then
27 | return 0
28 | fi
29 | pid=`cat ${install_dir}/web_currentpid`
30 | kill_process_with_retry "${pid}" "${process_name}" "${max_attempt}"
31 |
32 | if [[ $? == 0 ]]; then
33 | rm -f ${install_dir}/web_currentpid
34 | return 0
35 | else
36 | return 1
37 | fi
38 | }
39 |
40 | #---
41 | # kill_process_with_retry: Checks and attempts to kill the running process
42 | # args: PID, process name, number of kill attempts
43 | # returns: returns 0 if kill succeds or nothing to kill, 1 if kill fails
44 | # exception: If passed a non-existant pid, function will forcefully exit
45 | #---
46 | function kill_process_with_retry {
47 | local pid="$1"
48 | local pname="$2"
49 | local maxattempt="$3"
50 | local sleeptime=5
51 |
52 | if ! is_process_running $pid ; then
53 | echo "ERROR: process name ${pname} with pid: ${pid} not found"
54 | exit 1
55 | fi
56 |
57 | for try in $(seq 1 $maxattempt); do
58 | echo "Killing $pname. [pid: $pid], attempt: $try"
59 | kill ${pid}
60 | sleep 5
61 | if is_process_running $pid; then
62 | echo "$pname is not dead [pid: $pid]"
63 | echo "sleeping for $sleeptime seconds before retry"
64 | sleep $sleeptime
65 | else
66 | echo "shutdown succeeded"
67 | return 0
68 | fi
69 | done
70 |
71 | echo "Error: unable to kill process for $maxattempt attempt(s), killing the process with -9"
72 | kill -9 $pid
73 | sleep $sleeptime
74 |
75 | if is_process_running $pid; then
76 | echo "$pname is not dead even after kill -9 [pid: $pid]"
77 | return 1
78 | else
79 | echo "shutdown succeeded"
80 | return 0
81 | fi
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/metainfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 2.0
19 |
20 |
21 | AZKABAN
22 | Azkaban
23 | Azkaban is a batch workflow job scheduler created at LinkedIn to run Hadoop jobs. Azkaban resolves
24 | the ordering through job dependencies and provides an easy to use web user interface to maintain and
25 | track your workflows.
26 |
27 | 3.81.4
28 |
29 |
30 | quicklinks.json
31 | true
32 |
33 |
34 |
35 |
36 | AZKABAN_WEB
37 | Azkaban Web Server
38 | MASTER
39 | 1
40 | true
41 |
42 |
43 | PYTHON
44 | 1200
45 |
46 |
47 |
48 |
49 | AZKABAN_EXECUTOR
50 | Azkaban Executor Server
51 | SLAVE
52 | 0+
53 | true
54 |
55 |
56 | PYTHON
57 |
58 |
59 |
60 |
61 |
62 |
63 | azkaban-executor.properties.xml
64 | azkaban-users.xml
65 | azkaban-web.properties.xml
66 | log4j.properties.xml
67 |
68 |
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/package/scripts/azkaban_executor.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | import os.path as path
16 | import time
17 | import socket
18 | from common import AZKABAN_EXECUTOR_URL, AZKABAN_NAME, AZKABAN_HOME, AZKABAN_CONF
19 | from resource_management.core.exceptions import ExecutionFailed, ComponentIsNotRunning
20 | from resource_management.core.resources.system import Execute
21 | from resource_management.libraries.script.script import Script
22 |
23 |
24 | class ExecutorServer(Script):
25 | def install(self, env):
26 | #from params import java_home
27 | java_home='/usr/local/jdk1.8.0_171'
28 | Execute('wget --no-check-certificate {0} -O /tmp/{1}'.format(AZKABAN_EXECUTOR_URL, AZKABAN_NAME))
29 | Execute(
30 | 'mkdir -p {0} {1} {2} || echo "whatever"'.format(
31 | AZKABAN_HOME + '/conf',
32 | AZKABAN_HOME + '/extlib',
33 | AZKABAN_HOME + '/plugins/jobtypes',
34 | )
35 | )
36 | Execute('echo execute.as.user=false > {0} '.format(AZKABAN_HOME + '/plugins/jobtypes/commonprivate.properties'))
37 | Execute(
38 | 'export JAVA_HOME={0} && tar -xf /tmp/{1} -C {2} --strip-components 1'.format(
39 | java_home,
40 | AZKABAN_NAME,
41 | AZKABAN_HOME
42 | )
43 | )
44 | self.configure(env)
45 |
46 | def stop(self, env):
47 | self.configure(env)
48 | Execute('cd {0} && bin/shutdown-exec.sh'.format(AZKABAN_HOME))
49 |
50 | def start(self, env):
51 | from params import azkaban_executor_properties
52 | self.configure(env)
53 | executor_port = int(azkaban_executor_properties['executor.port'])
54 | Execute('cd {0} && bin/start-exec.sh'.format(AZKABAN_HOME))
55 | while 1:
56 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
57 | result = sock.connect_ex(('127.0.0.1',executor_port))
58 | sock.close()
59 | if result == 0:
60 | Execute('curl http://localhost:{0}/executor?action=activate'.format(executor_port))
61 | break
62 | else:
63 | time.sleep(5)
64 |
65 | def status(self, env):
66 | try:
67 | self.configure(env)
68 | Execute(
69 | 'export AZ_CNT=`ps -ef |grep -v grep |grep azkaban-exec-server | wc -l` && `if [ $AZ_CNT -ne 0 ];then exit 0;else exit 3;fi `'
70 | )
71 | except ExecutionFailed as ef:
72 | if ef.code == 3:
73 | raise ComponentIsNotRunning("ComponentIsNotRunning")
74 | else:
75 | raise ef
76 |
77 | def configure(self, env):
78 | from params import azkaban_executor_properties, log4j_properties, azkaban_db
79 | key_val_template = '{0}={1}\n'
80 |
81 | with open(path.join(AZKABAN_CONF, 'azkaban.properties'), 'w') as f:
82 | for key, value in azkaban_db.iteritems():
83 | f.write(key_val_template.format(key, value))
84 | for key, value in azkaban_executor_properties.iteritems():
85 | if key != 'content':
86 | f.write(key_val_template.format(key, value))
87 | #f.write(azkaban_executor_properties['content'])
88 | if azkaban_executor_properties.has_key('content'):
89 | f.write(str(azkaban_executor_properties['content']))
90 |
91 | with open(path.join(AZKABAN_CONF, 'log4j.properties'), 'w') as f:
92 | #f.write(log4j_properties['content'])
93 | if log4j_properties.has_key('content'):
94 | f.write(str(log4j_properties['content']))
95 |
96 |
97 | if __name__ == '__main__':
98 | ExecutorServer().execute()
99 |
--------------------------------------------------------------------------------
/package/scripts/azkaban_web.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | import os.path as path
16 |
17 | from common import AZKABAN_DB_URL, AZKABAN_WEB_URL, AZKABAN_NAME, AZKABAN_HOME, AZKABAN_CONF, AZKABAN_SQL
18 | from resource_management.core.exceptions import ExecutionFailed, ComponentIsNotRunning
19 | from resource_management.core.resources.system import Execute
20 | from resource_management.libraries.script.script import Script
21 |
22 |
23 | class WebServer(Script):
24 | def install(self, env):
25 | #from params import java_home, azkaban_db
26 | from params import azkaban_db
27 | java_home='/usr/local/jdk1.8.0_171'
28 | Execute('wget --no-check-certificate {0} -O /tmp/{1}'.format(AZKABAN_WEB_URL, AZKABAN_NAME))
29 | Execute('wget --no-check-certificate {0} -O /tmp/{1}'.format(AZKABAN_DB_URL, AZKABAN_SQL))
30 | Execute(
31 | 'mysql -h{0} -P{1} -D{2} -u{3} -p{4} < {5}'.format(
32 | azkaban_db['mysql.host'],
33 | azkaban_db['mysql.port'],
34 | azkaban_db['mysql.database'],
35 | azkaban_db['mysql.user'],
36 | azkaban_db['mysql.password'],
37 | '/tmp/{0}'.format(AZKABAN_SQL),
38 | )
39 | )
40 | Execute(
41 | 'mkdir -p {0} {1} {2} || echo "whatever"'.format(
42 | AZKABAN_HOME + '/conf',
43 | AZKABAN_HOME + '/extlib',
44 | AZKABAN_HOME + '/plugins/jobtypes',
45 | )
46 | )
47 | Execute('echo execute.as.user=false > {0} '.format(AZKABAN_HOME + '/plugins/jobtypes/commonprivate.properties'))
48 | Execute(
49 | 'export JAVA_HOME={0} && tar -xf /tmp/{1} -C {2} --strip-components 1'.format(
50 | java_home,
51 | AZKABAN_NAME,
52 | AZKABAN_HOME
53 | )
54 | )
55 | self.configure(env)
56 |
57 | def stop(self, env):
58 | self.configure(env)
59 | Execute('cd {0} && bin/shutdown-web.sh'.format(AZKABAN_HOME))
60 |
61 | def start(self, env):
62 | self.configure(env)
63 | Execute('cd {0} && bin/start-web.sh'.format(AZKABAN_HOME))
64 |
65 | def status(self, env):
66 | try:
67 | self.configure(env)
68 | Execute(
69 | 'export AZ_CNT=`ps -ef |grep -v grep |grep azkaban-web-server | wc -l` && `if [ $AZ_CNT -ne 0 ];then exit 0;else exit 3;fi `'
70 | )
71 | except ExecutionFailed as ef:
72 | if ef.code == 3:
73 | raise ComponentIsNotRunning("ComponentIsNotRunning")
74 | else:
75 | raise ef
76 |
77 | def configure(self, env):
78 | from params import azkaban_db, azkaban_web_properties, azkaban_users, global_properties, log4j_properties
79 | key_val_template = '{0}={1}\n'
80 |
81 | with open(path.join(AZKABAN_CONF, 'azkaban.properties'), 'w') as f:
82 | for key, value in azkaban_db.iteritems():
83 | f.write(key_val_template.format(key, value))
84 | for key, value in azkaban_web_properties.iteritems():
85 | if key != 'content':
86 | f.write(key_val_template.format(key, value))
87 | #f.write(azkaban_web_properties['content'])
88 | if azkaban_web_properties.has_key('content'):
89 | f.write(str(azkaban_web_properties['content']))
90 |
91 | with open(path.join(AZKABAN_CONF, 'azkaban-users.xml'), 'w') as f:
92 | if azkaban_users.has_key('content'):
93 | f.write(str(azkaban_users['content']))
94 |
95 | with open(path.join(AZKABAN_CONF, 'global.properties'), 'w') as f:
96 | #f.write(global_properties['content'])
97 | if global_properties.has_key('content'):
98 | f.write(str(global_properties['content']))
99 |
100 | with open(path.join(AZKABAN_CONF, 'log4j.properties'), 'w') as f:
101 | #f.write(log4j_properties['content'])
102 | if log4j_properties.has_key('content'):
103 | f.write(str(log4j_properties['content']))
104 |
105 |
106 | if __name__ == '__main__':
107 | WebServer().execute()
108 |
--------------------------------------------------------------------------------
/configuration/azkaban-web.properties.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 | java_home
23 | /usr/local/jdk1.8.0_171
24 |
25 |
26 | azkaban.name
27 | azkaban
28 |
29 |
30 | azkaban.label
31 | test
32 |
33 |
34 | azkaban.color
35 | #FF3601
36 |
37 |
38 | azkaban.default.servlet.path
39 | /index
40 |
41 |
42 | web.resource.dir
43 | web/
44 |
45 |
46 | default.timezone.id
47 | Asia/Shanghai
48 |
49 |
50 |
51 | user.manager.class
52 | azkaban.user.XmlUserManager
53 |
54 |
55 | user.manager.xml.file
56 | conf/azkaban-users.xml
57 |
58 |
59 |
60 | executor.global.properties
61 | conf/global.properties
62 |
63 |
64 | azkaban.project.dir
65 | projects
66 |
67 |
68 |
69 | velocity.dev.mode
70 | false
71 |
72 |
73 |
74 | jetty.use.ssl
75 | false
76 |
77 |
78 | jetty.maxThreads
79 | 25
80 |
81 |
82 | jetty.port
83 | 10200
84 |
85 |
86 |
87 |
88 | mail.sender
89 | azkaban@email.com
90 |
91 |
92 | mail.host
93 | azkaban@email.com
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | job.failure.email
104 | azkaban@email.com
105 |
106 |
107 | job.success.email
108 | azkaban@email.com
109 |
110 |
111 | lockdown.create.projects
112 | false
113 |
114 |
115 | cache.directory
116 | cache
117 |
118 |
119 |
120 | jetty.connector.stats
121 | true
122 |
123 |
124 | executor.connector.stats
125 | true
126 |
127 |
128 |
129 | database.type
130 | mysql
131 |
132 |
133 | mysql.port
134 | 3306
135 |
136 |
137 | mysql.host
138 | localhost
139 |
140 |
141 | mysql.database
142 | azkaban
143 |
144 |
145 | mysql.user
146 | azkaban
147 |
148 |
149 | mysql.password
150 | azkaban
151 |
152 |
153 | mysql.numconnections
154 | 100
155 |
156 |
157 | executor.port
158 | 12321
159 |
160 |
161 |
162 | azkaban.use.multiple.executors
163 | true
164 |
165 |
166 | azkaban.executorselector.filters
167 | StaticRemainingFlowSize,MinimumFreeMemory,CpuStatus
168 |
169 |
170 | azkaban.executorselector.comparator.NumberOfAssignedFlowComparator
171 | 1
172 |
173 |
174 | azkaban.executorselector.comparator.Memory
175 | 1
176 |
177 |
178 | azkaban.executorselector.comparator.LastDispatched
179 | 1
180 |
181 |
182 | azkaban.executorselector.comparator.CpuUsage
183 | 1
184 |
185 |
186 |
187 |
--------------------------------------------------------------------------------
/configuration/azkaban-executor.properties.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
19 |
20 |
21 |
22 | java_home
23 | /usr/local/jdk1.8.0_171
24 |
25 |
26 | azkaban.name
27 | azkaban
28 |
29 |
30 | azkaban.label
31 | test
32 |
33 |
34 | azkaban.color
35 | #FF3601
36 |
37 |
38 | azkaban.default.servlet.path
39 | /index
40 |
41 |
42 | web.resource.dir
43 | web/
44 |
45 |
46 | default.timezone.id
47 | Asia/Shanghai
48 |
49 |
50 |
51 | user.manager.class
52 | azkaban.user.XmlUserManager
53 |
54 |
55 | user.manager.xml.file
56 | conf/azkaban-users.xml
57 |
58 |
59 |
60 | executor.global.properties
61 | conf/global.properties
62 |
63 |
64 | azkaban.project.dir
65 | projects
66 |
67 |
68 |
69 | velocity.dev.mode
70 | false
71 |
72 |
73 |
74 | jetty.use.ssl
75 | false
76 |
77 |
78 | jetty.maxThreads
79 | 25
80 |
81 |
82 | jetty.port
83 | 10200
84 |
85 |
86 |
87 |
88 | azkaban.webserver.url
89 | http://localhost:10200
90 |
91 |
92 |
93 | mail.sender
94 | azkaban@email.com
95 |
96 |
97 | mail.host
98 | azkaban@email.com
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | job.failure.email
109 | azkaban@email.com
110 |
111 |
112 | job.success.email
113 | azkaban@email.com
114 |
115 |
116 | lockdown.create.projects
117 | false
118 |
119 |
120 | cache.directory
121 | cache
122 |
123 |
124 |
125 | jetty.connector.stats
126 | true
127 |
128 |
129 | executor.connector.stats
130 | true
131 |
132 |
133 |
134 | azkaban.jobtype.plugin.dir
135 | plugins/jobtypes
136 |
137 |
138 |
139 | database.type
140 | mysql
141 |
142 |
143 | mysql.port
144 | 3306
145 |
146 |
147 | mysql.host
148 | localhost
149 |
150 |
151 | mysql.database
152 | azkaban
153 |
154 |
155 | mysql.user
156 | azkaban
157 |
158 |
159 | mysql.password
160 | azkaban
161 |
162 |
163 | mysql.numconnections
164 | 100
165 |
166 |
167 |
168 | executor.maxThreads
169 | 50
170 |
171 |
172 | executor.flow.threads
173 | 30
174 |
175 |
176 | executor.port
177 | 12321
178 |
179 |
180 |
181 | azkaban.use.multiple.executors
182 | true
183 |
184 |
185 | azkaban.executorselector.filters
186 | StaticRemainingFlowSize,MinimumFreeMemory,CpuStatus
187 |
188 |
189 | azkaban.executorselector.comparator.NumberOfAssignedFlowComparator
190 | 1
191 |
192 |
193 | azkaban.executorselector.comparator.Memory
194 | 1
195 |
196 |
197 | azkaban.executorselector.comparator.LastDispatched
198 | 1
199 |
200 |
201 | azkaban.executorselector.comparator.CpuUsage
202 | 1
203 |
204 |
205 |
--------------------------------------------------------------------------------