프로젝트 가장 상위에 script 디렉토리를 만들고 그 아래에 4개의 파일을 생성한다.
script 디렉토리를 src 디렉토리의 바깥에 둔 이유는 소스에 포함시키지 않기 위해서이다.
diary.service
[Unit]
Description=Diary Web Program
After=syslog.target network.target
[Service]
#Type=simple
User=root
Group=root
ExecStart=/usr/bin/java -Xms128m -Xmx256m -jar /var/webapp/diary/study.diary.jar
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Alias=diary.service
install.sh
#!/bin/bash
SERVICE_NAME="diary.service"
# 현재 유닛의 활성화 상태 확인
is_enabled=$(systemctl is-enabled "$SERVICE_NAME" 2>/dev/null)
cp /var/webapp/diary/diary.service /etc/systemd/system/diary.service
systemctl daemon-reload
if [[ $is_enabled == "enabled" ]]; then
echo "Service is already enabled."
else
# 유닛을 활성화
systemctl enable "$SERVICE_NAME"
echo "Service has been enabled"
fi
start.sh
#!/bin/bash
# check if process exist
PID=$(ps -ef | grep -v grep | grep 'diary.jar')
echo current PID = ${PID}
get_pid=$(echo ${PID} | cut -d " " -f2)
# stop service if current process exist
if [ -n "${get_pid}" ]; then # -n : Checks if the length of a string is nonzero
# stop service
systemctl stop diary.service
echo service stopped: ${get_pid}
fi
# start service
systemctl start diary.service
# check executed process
NEWPID=$(ps -ef | grep -v grep | grep 'diary.jar')
echo NEWPID = ${NEWPID}
# check service status
systemctl status diary.service
if [[ "$PID" = "$NEWPID" ]]; then # PID is not changed
exit 1; # return error
fi
exit 0 # success
stop.sh
#!/bin/bash
# check if process exist
PID=$(ps -ef | grep -v grep | grep 'diary.jar')
echo current PID = ${PID}
get_pid=$(echo ${PID} | cut -d " " -f2)
# stop service if current process exist
if [ -n "${get_pid}" ]; then # -n : Checks if the length of a string is nonzero
# stop service
systemctl stop diary.service
echo service stopped: ${get_pid}
fi
# check executed process
NEWPID=$(ps -ef | grep -v grep | grep 'diary.jar')
echo NEWPID = ${NEWPID}
# check service status
systemctl status diary.service
if [ -n "${NEWPID}" ]; then # -n : Checks if the length of a string is nonzero
exit 1; # return error
fi
exit 0 # success
서버에 동작하고 있는 프로그램의 프로세스를 종료시킨다.
$ ps -ef | grep -v grep | grep diary
위 명령어로 동작중인 프로세스의 PID 를 확인하고
$ sudo kill -9 <PID>
위 명령어로 프로세스를 종료시킨다.
jenkins 에 아래 스크립트를 등록한다.
Pipeline Item name: install as service
pipeline {
agent any
stages {
stage('install as service') {
steps {
echo 'installing as service...'
sh '''
cd /var/lib/jenkins/workspace/diary/clonesource/script
scp * webapp@10.10.1.2:/var/webapp/diary/
ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 "sed -i 's/\r//g' /var/webapp/diary/*.sh"
ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 "chmod +x /var/webapp/diary/*.sh"
ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 "sudo /var/webapp/diary/install.sh"
'''
}
}
}
}
10.10.1.2 서버에 ssh 로 접속하여 관리자권한으로 명령어를 실행시키기 위해서 sudo 를 사용하고 있는데, sudo 는 사용자의 비밀번호 입력을 필요로 하므로 사용자 비밀번호 입력이 불필요하게 설정하기 위해서 다음과 같이 수행한다.
ssh 로 10.10.1.2 에 접속하여
$ sudo visudo
# User privilege specification 영역에 webapp 계정에 대한 설정을 추가한다.
webapp ALL=(ALL) NOPASSWD:ALL
위 처리를 하지 않으면 다음과 같은 에러가 발생한다.
+ ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 sudo /var/webapp/diary/install.sh
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required
deploy Pipeline item script 를 다음과 같이 수정한다.
pipeline {
agent any
stages {
stage('deploy') {
steps {
echo 'deploying output'
sh '''
ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 "mkdir -p /var/webapp/diary"
cd /var/lib/jenkins/workspace/diary/clonesource/build/libs
ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 "cp /var/webapp/diary/study.diary.jar /var/webapp/diary/study.diary.jar.bak"
scp study.diary-0.0.1-SNAPSHOT.jar webapp@10.10.1.2:/var/webapp/diary/study.diary.jar
'''
}
}
stage('execute') {
steps {
echo 'executing program'
sh '''
#ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 /usr/bin/java -jar /var/webapp/diary/study.diary-0.0.1-SNAPSHOT.jar > /dev/null 2>&1 &
ssh -o StrictHostKeyChecking=no webapp@10.10.1.2 "sudo /var/webapp/diary/start.sh"
'''
}
}
}
}