目录
前言
背景:常常需要将 二进制文件打包成 rpm 包, 以便其他人安装使用或上传 yum 源。本文包含两部分内容,二进制包制作 rpm,以service方式运行。
文件说明:
/usr/bin/gocron-node:二进制文件
/opt/gocron-node/start.sh: service启动脚本
/opt/gocron-node/stop.sh: service停止脚本
/etc/gocron-node/gocron.conf:二进制执行配置文件
/etc/init.d/gocron:service脚本
spec 文件
首先,需要将二进制及需要的其他启动脚本放在一个目录下,目录的命名规则以"Name-Version-Release.arch"方式命名,arch为机器的架构,如本人是 X86_64。名字和spec里必须对应。撰写spec文件,由于是二进制打包,无源码也就没有build过程,本人的二进制没有安装依赖,也没写。源码打包可参看博客 制作rpm ,主要涉及 install 和 file
Summary: Go crontab package.
Name: gocronNode
Version: 1.0
Release: 1
License: GPL
Group:Development/Tools
%description
This is go crontab node service.
%prep
%build
%install # 安装阶段
mkdir -p $RPM_BUILD_ROOT/usr/bin
mkdir -p $RPM_BUILD_ROOT/etc/gocron-node
mkdir -p $RPM_BUILD_ROOT/opt/gocron-node
mkdir -p $RPM_BUILD_ROOT/etc/init.d
cd $RPM_BUILD_DIR
pwd
tar xzvf ../BUILD/gocronNode-1.0-1.x86_64.tar.gz
cp ../BUILD/gocronNode-1.0-1.x86_64/gocron-node $RPM_BUILD_ROOT/usr/bin
cp ../BUILD/gocronNode-1.0-1.x86_64/start.sh $RPM_BUILD_ROOT/opt/gocron-node
cp ../BUILD/gocronNode-1.0-1.x86_64/gocron.conf $RPM_BUILD_ROOT/etc/gocron-node
cp ../BUILD/gocronNode-1.0-1.x86_64/stop.sh $RPM_BUILD_ROOT/opt/gocron-node
cp ../BUILD/gocronNode-1.0-1.x86_64/gocron $RPM_BUILD_ROOT/etc/init.d
#rpm 包含文件
%files
/usr/bin/gocron-node
/opt/gocron-node/start.sh
/opt/gocron-node/stop.sh
/etc/gocron-node/gocron.conf
/etc/init.d/gocron
编写启动停止脚本(自行修改)
建议编写脚本,处理进程已存在和停止的一些逻辑
#!/bin/bash
# start.sh
conf=$1
PIDFILE=$2
if [[ $PIDFILE == "" ]];then
PIDFILE="/var/run/gocron-node.pid"
fi
oldPid=`pidof gocron-node`
if [[ $oldPid != "" ]];then
echo "[info] gocron-node is active, do nothing..."
exit 0
fi
while read line
do
if [[ `echo $line | grep -v "#"` ]];then
port=$line
break
fi
done < $conf
port=`echo $port | awk -F '=' '{print $2}'`
function isPositiveInt () {
if [[ ${1} =~ ^[0-9]*[1-9][0-9]*$ ]]; then
return 1
fi
return 0
}
isPositiveInt $port
returnValue=$?
if [[ $returnValue -eq 0 ]];then
port=5921
fi
echo "[info] Your custom port: $port"
gocron-node -allow-root true -s 0.0.0.0:$port &
exitCode=$?
pid=`pidof gocron-node`
echo $pid > "$PIDFILE"
exit $exitCode
#!/bin/bash
# stop.sh
info=`netstat -nlp | grep gocron`
gocronPid=`pidof gocron-node`
if [[ $gocronPid == "" ]];then
exit 0
else
echo "[info] Gocron pid:[$gocronPid]."
/bin/kill $gocronPid
exit $?
fi
编写service
为了兼容,使用 /etc/init.d下的方式来编写,也可以使用 systemd编写服务,可自行谷歌。此脚本需编写start,stop,restart等模块。本人参考 hadoop-yarn-manager 撰写。开头使用了service系统调用,详情可参考这篇 博客
. /lib/lsb/init-functions
CONF_PATH="/etc/gocron-node/gocron.conf"
EXEC_DIR="/opt/gocron-node"
SLEEP_TIME=3
RETVAL=0
DESC="Go crontab node"
STATUS_RUNNING=0
RETVAL_SUCCESS=0
PROC_NAME='gocron-node'
PIDFILE="/var/run/gocron-node.pid"
STATUS_RUNNING=0
STATUS_DEAD=1
STATUS_DEAD_AND_LOCK=2
STATUS_NOT_RUNNING=3
start() {
echo "[info] Default port: 5921, custom by changing $CONF_PATH"
/bin/bash $EXEC_DIR/start.sh $CONF_PATH $PIDFILE
# Some processes are slow to start
sleep $SLEEP_TIME
checkstatusofproc
RETVAL=$?
if [ $RETVAL -eq $STATUS_RUNNING ]; then
log_success_msg "[info] Started ${DESC}: "
else
log_failure_msg "[err ] Failed to start ${DESC}. Return value: $RETVAL"
fi
return $RETVAL
}
stop() {
/bin/bash $EXEC_DIR/stop.sh
RETVAL=$?
if [ $RETVAL -eq $RETVAL_SUCCESS ]; then
log_success_msg "[info] Stopped ${DESC}: "
else
log_failure_msg "[err ] Failed to stop ${DESC}. Return value: $RETVAL."
fi
}
restart() {
stop
start
}
checkstatusofproc(){
pidofproc -p $PIDFILE $PROC_NAME > /dev/null
}
checkstatus(){
checkstatusofproc
status=$?
case "$status" in
$STATUS_RUNNING)
log_success_msg "[info] ${DESC} is running"
;;
$STATUS_DEAD)
log_failure_msg "[info] ${DESC} is dead and pid file exists"
;;
$STATUS_DEAD_AND_LOCK)
log_failure_msg "[info] ${DESC} is dead and lock file exists"
;;
$STATUS_NOT_RUNNING)
log_failure_msg "[info] ${DESC} is not running"
;;
*)
log_failure_msg "[info] ${DESC} status is unknown"
;;
esac
return $status
}
check_for_root() {
if [ $(id -ur) -ne 0 ]; then
echo '[err ] Error: root user required'
echo
exit 1
fi
}
service() {
case "$1" in
start)
check_for_root
start
;;
stop)
check_for_root
stop
;;
status)
checkstatus
RETVAL=$?
;;
restart)
check_for_root
restart
;;
*)
echo $"[info] Usage: $0 {start|stop|status|restart}"
exit 1
esac
}
service "$@"
exit $RETVAL
编译执行
编译spec文件,启动服务
rpmbuild -bb gnode.spec #编译
rpm -ivh xxxx.rpm #安装
# rpm -e xxx #卸载
service gocron start #启动
看似简单几步,却过程相对复杂。
参考文献
shell 正则 https://blog.csdn.net/dlutbrucezhang/article/details/9255081
服务注册 https://blog.51cto.com/sf1314/2112860
Linux进程启动脚本编写https://blog.fudenglong.site/2017/03/24/Linux%E8%BF%9B%E7%A8%8B%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC%E7%BC%96%E5%86%99/