[Dev] Add postional arg action in runner

This commit is contained in:
samuel 2023-05-04 02:20:00 +02:00
parent d98f5f993b
commit 6a2617a688
7 changed files with 181 additions and 106 deletions

View File

@ -1,69 +1,81 @@
# Config parsing errors. # Deployer config parsing errors.
err_deployer_sock_empty=11 err_deployer_sock_empty=11
err_deployer_sock_dir_not_directory=12 err_deployer_sock_dir_not_directory=12
err_deployer_sock_dir_not_writable=13 err_deployer_sock_dir_not_writable=13
err_deployer_sock_already_in_use=14 err_deployer_sock_dir_not_accessible=14
err_deployer_sock_not_exist=15 err_deployer_sock_already_in_use=15
err_deployer_pid_empty=16 err_deployer_sock_not_exist=16
err_deployer_pid_dir_not_directory=17 err_deployer_pid_empty=17
err_deployer_pid_dir_not_writable=18 err_deployer_pid_dir_not_directory=18
err_repos_dir_empty=19 err_deployer_pid_dir_not_writable=19
err_repos_dir_not_directory=20 err_deployer_timeout_empty=20
err_repos_dir_not_accessible=21 err_deployer_timeout_not_valid=21
err_rpms_dir_empty=22 err_deployer_username_empty=22
err_rpms_dir_not_directory=23 err_deployer_user_not_exist=23
err_rpms_dir_not_accessible=24
err_runner_username_empty=25
err_runner_user_not_exist=26
err_deployer_timeout_empty=27
err_deployer_timeout_not_valid=28
err_runner_sock_empty=29
err_runner_sock_dir_not_directory=30
err_runner_sock_dir_not_writable=31
err_runner_sock_already_in_use=32
err_runner_sock_not_exist=33
err_deployer_username_empty=34
err_deployer_user_not_exist=35
err_runner_cloning_dir_empty=36
err_runner_cloning_dir_not_directory=37
err_runner_cloning_dir_not_writable=38
err_runner_timeout_empty=39
err_runner_timeout_not_valid=40
err_git_runner_groupname_empty=41
err_git_runner_group_not_exist=42
err_runner_deployer_groupname_empty=43
err_runner_deployer_group_not_exist=44
err_pipeline_sock_dir_empty=45
err_pipeline_sock_dir_not_directory=46
err_pipeline_sock_dir_not_writable=47
# JSON parsing errors # Runner config parsing errors.
err_json_bad_format=51 err_runner_username_empty=41
err_pkg_name_missing=52 err_runner_user_not_exist=42
err_pkg_name_empty=53 err_runner_sock_empty=43
err_repo_dir_not_exist=54 err_runner_sock_dir_not_directory=44
err_pkg_version_missing=55 err_runner_sock_dir_not_writable=45
err_pkg_version_empty=56 err_runner_sock_already_in_use=46
err_rpm_path_not_exist=57 err_runner_sock_not_exist=47
err_repo_name_missing=58 err_runner_pid_empty=48
err_repo_name_empty=59 err_runner_pid_dir_not_directory=49
err_repo_hash_missing=60 err_runner_pid_dir_not_writable=50
err_repo_hash_empty=61 err_runner_pid_not_exist=51
err_repo_tag_empty=62 err_runner_pid_not_readable=52
err_runner_process_not_running=53
err_runner_process_not_killed=54
err_runner_cloning_dir_empty=55
err_runner_cloning_dir_not_directory=56
err_runner_cloning_dir_not_writable=57
err_runner_timeout_empty=58
err_runner_timeout_not_valid=59
err_runner_deployer_groupname_empty=60
err_runner_deployer_group_not_exist=61
err_repos_dir_empty=62
err_repos_dir_not_directory=63
err_repos_dir_not_accessible=64
err_rpms_dir_empty=65
err_rpms_dir_not_directory=66
err_rpms_dir_not_accessible=67
# Pipeline config parsing errors.
err_git_runner_groupname_empty=81
err_git_runner_group_not_exist=82
err_pipeline_sock_dir_empty=83
err_pipeline_sock_dir_not_directory=84
err_pipeline_sock_dir_not_writable=85
# JSON parsing errors.
err_json_bad_format=101
err_pkg_name_missing=102
err_pkg_name_empty=103
err_repo_dir_not_exist=104
err_pkg_version_missing=105
err_pkg_version_empty=106
err_rpm_path_not_exist=107
err_repo_name_missing=108
err_repo_name_empty=109
err_repo_hash_missing=110
err_repo_hash_empty=111
err_repo_tag_empty=112
# Operationnal errors. # Operationnal errors.
err_clone_repo=101 err_clone_repo=131
err_checkout_hash=102 err_checkout_hash=132
err_check_format=103 err_check_format=133
err_check_linting=104 err_check_linting=134
err_unit_test=105 err_unit_test=135
err_add_tag=106 err_add_tag=136
err_make_tarball=107 err_make_tarball=137
err_rpm_build=108 err_rpm_build=138
err_rpm_upgrade=109 err_rpm_upgrade=139
err_rpm_install=110 err_rpm_install=140
err_deployer_pid_not_exist=111 err_deployer_pid_not_exist=141
err_deployer_pid_not_readable=112 err_deployer_pid_not_readable=142
err_deployer_process_not_running=113 err_deployer_process_not_running=143
err_deployer_process_not_running=114 err_deployer_process_not_running=144
err_deployer_process_not_killed=115 err_deployer_process_not_killed=145

View File

@ -23,6 +23,9 @@ runner_username="netoik-cicd-runner"
# Location of unixsock file used to send requests to the runner server. # Location of unixsock file used to send requests to the runner server.
runner_sock="/run/netoik-cicd/runner/runner.sock" runner_sock="/run/netoik-cicd/runner/runner.sock"
# Location of runner pid.
runner_pid="/run/netoik-cicd/pids/runner.pid"
# Directory in which to clone git repositories. # Directory in which to clone git repositories.
runner_cloning_dir="/var/tmp/netoik-cicd/repositories" runner_cloning_dir="/var/tmp/netoik-cicd/repositories"

View File

@ -63,9 +63,7 @@ systemctl daemon-reload
systemctl restart %{name}-deployer.service systemctl restart %{name}-deployer.service
systemctl enable %{name}-deployer.service systemctl enable %{name}-deployer.service
# Restart runner service. # Restart runner service.
systemctl stop %{name}-runner.service systemctl restart %{name}-runner.service
rm --force %{_rundir}/%{name}/runner/runner.sock
systemctl start %{name}-runner.service
systemctl enable %{name}-runner.service systemctl enable %{name}-runner.service
%preun %preun
@ -73,7 +71,6 @@ systemctl enable %{name}-runner.service
if [ $1 -eq 0 ]; then if [ $1 -eq 0 ]; then
systemctl disable --now %{name}-deployer.service systemctl disable --now %{name}-deployer.service
systemctl disable --now %{name}-runner.service systemctl disable --now %{name}-runner.service
rm --force %{_rundir}/%{name}/runner/runner.sock
fi fi
%postun %postun

View File

@ -70,7 +70,7 @@ fail() (
) )
usage() ( usage() (
echo "Usage: ${PROGRAM_NAME} [OPTION]... echo "Usage: ${PROGRAM_NAME} [OPTION]... ACTION
Start runner server, wait for unixsock requests to clone git repo, run tests Start runner server, wait for unixsock requests to clone git repo, run tests
and build rpm package. and build rpm package.
@ -83,10 +83,14 @@ Mandatory argumentes for long options are mandatory for short options too.
${DEFAULT_ERRORS_FILE} ${DEFAULT_ERRORS_FILE}
-o, --once stop listening after first request process -o, --once stop listening after first request process
-q, --quiet set level verbosity to WARN, default to INFO -q, --quiet set level verbosity to WARN, default to INFO
-t, --test just test config file and do not run start loop
-v, --verbose set level verbosity to DEBUG, default to INFO -v, --verbose set level verbosity to DEBUG, default to INFO
-h, --help display this help message and exit -h, --help display this help message and exit
Positional argument ACTION
start start runner server
stop stop runner server
test tests configuration and exit
" "
) )
@ -313,15 +317,14 @@ process_loop() (
main() ( main() (
# Parse arguments. # Parse arguments.
daemonize="false" daemonize="false"
testing="false"
keep_open="true" keep_open="true"
config_file="${DEFAULT_CONFIG_FILE}" config_file="${DEFAULT_CONFIG_FILE}"
errors_file="${DEFAULT_ERRORS_FILE}" errors_file="${DEFAULT_ERRORS_FILE}"
verbosity_option="" verbosity_option=""
verbosity_level="${DEFAULT_VERBOSITY_LEVEL}" verbosity_level="${DEFAULT_VERBOSITY_LEVEL}"
if ! args="$(getopt --name "${PROGRAM_NAME}" \ if ! args="$(getopt --name "${PROGRAM_NAME}" \
--options c:de:hoqtv \ --options c:de:hoqv \
--longoptions conf:,daemon,errs:,help,once,quiet,test,verbose \ --longoptions conf:,daemon,errs:,help,once,quiet,verbose \
-- "$@")"; then -- "$@")"; then
usage usage
fail "Bad arguments." fail "Bad arguments."
@ -359,10 +362,6 @@ main() (
((verbosity_level -= 10)) ((verbosity_level -= 10))
shift shift
;; ;;
-t | --test)
testing="true"
shift
;;
-v | --verbose) -v | --verbose)
if [ "${verbosity_option}" ]; then if [ "${verbosity_option}" ]; then
usage usage
@ -382,10 +381,19 @@ main() (
;; ;;
esac esac
done done
if [ "$@" ]; then if [ $# -ne 1 ]; then
usage usage
fail "Unexpected extra arguments '$*'." fail "Missing positional argument ACTION."
fi fi
case "$1" in
start | stop | test)
action="$1"
;;
*)
usage
fail "Bad postional argument ACTION '$1'."
;;
esac
# Load config file. # Load config file.
if [ ! -r "${config_file}" ]; then if [ ! -r "${config_file}" ]; then
@ -407,9 +415,13 @@ main() (
if [ -z "${deployer_sock}" ]; then if [ -z "${deployer_sock}" ]; then
fail "Variable deployer_sock is empty." "${err_deployer_sock_empty}" fail "Variable deployer_sock is empty." "${err_deployer_sock_empty}"
fi fi
if [ ! -S "${deployer_sock}" ]; then if [ ! -d "$(dirname "${deployer_sock}")" ]; then
fail "Sock deployer_sock='${deployer_sock}' does not exist." \ fail "Dirname of deployer_sock='${deployer_sock}' is not a directory." \
"${err_deployer_sock_not_exist}" "${err_deployer_sock_dir_not_directory}"
fi
if [ ! -x "$(dirname "${deployer_sock}")" ]; then
fail "Dirname of deployer_sock='${deployer_sock}' is not accessible." \
"${err_deployer_sock_dir_not_accessible}"
fi fi
if [ -z "${deployer_timeout}" ]; then if [ -z "${deployer_timeout}" ]; then
@ -485,28 +497,72 @@ main() (
"${err_git_runner_group_not_exist}" "${err_git_runner_group_not_exist}"
fi fi
# Stop now if we are only testing config. if [ -z "${runner_pid}" ]; then
if "${testing}"; then fail "Variable runner_pid is empty." "${err_runner_pid_empty}"
fi
if [ ! -d "$(dirname "${runner_pid}")" ]; then
fail "Dirname of runner_pid='${runner_pid}' is not a directory." \
"${err_runner_pid_dir_not_directory}"
fi
if [ ! -w "$(dirname "${runner_pid}")" ]; then
fail "Dirname of runner_pid='${runner_pid}' is not writable." \
"${err_runner_pid_dir_not_writable}"
fi
# Run chosen action.
case "${action}" in
start)
if [ ! -S "${deployer_sock}" ]; then
fail "Sock deployer_sock='${deployer_sock}' does not exist." \
"${err_deployer_sock_not_exist}"
fi
# Set right access in background after nc listen.
(
inotifywait --timeout 1 --quiet --quiet \
--event create "$(dirname "${runner_sock}")" || true
chmod 775 "${runner_sock}"
chgrp "${git_runner_groupname}" "${runner_sock}"
) &
# Run process loop in background or foreground.
if "${daemonize}"; then
log_info "Run process loop in background."
process_loop &
echo "$!" >"${runner_pid}"
else
log_info "Run process loop in foreground."
echo "$$" >"${runner_pid}"
process_loop
jobs -p | xargs kill 2>/dev/null || true
fi
;;
stop)
if [ ! -f "${runner_pid}" ]; then
fail "File runner_pid='${runner_pid}' does not exist." \
"${err_runner_pid_not_exist}"
fi
if [ ! -r "${runner_pid}" ]; then
fail "File runner_pid='${runner_pid}' is not readable." \
"${err_runner_pid_not_readable}"
fi
pid="$(cat "${runner_pid}")"
rm --force "${runner_pid}"
if ! ps -p "${pid}"; then
fail "Runner process with pid='${pid}' is not running." \
"${err_runner_process_not_running}"
fi
if ! kill "${pid}" || kill --signal KILL "${pid}"; then
fail "Cannot kill runner process." "${err_runner_process_not_killed}"
fi
rm --force "${runner_sock}"
;;
test)
# Stop now if we are only testing.
log_info "Configuration OK."
exit 0 exit 0
fi ;;
esac
# Set right access in background after nc listen.
(
inotifywait --timeout 1 --quiet --quiet \
--event create "$(dirname "${runner_sock}")" || true
chmod 775 "${runner_sock}"
chgrp "${git_runner_groupname}" "${runner_sock}"
) &
# Run process loop in background or foreground.
if "${daemonize}"; then
log_info "Run process loop in background."
process_loop &
else
log_info "Run process loop in foreground."
process_loop
jobs -p | xargs kill 2>/dev/null || true
fi
) )
main "$@" main "$@"

View File

@ -5,7 +5,8 @@ After=network.target netoik-cicd-deployer.service
[Service] [Service]
User=netoik-cicd-runner User=netoik-cicd-runner
Group=netoik-cicd-runner-deployer Group=netoik-cicd-runner-deployer
ExecStart=/usr/bin/netoik-cicd-runner ExecStart=/usr/bin/netoik-cicd-runner start
ExecStop=/usr/bin/netoik-cicd-runner stop
Restart=always Restart=always
[Install] [Install]

View File

@ -37,7 +37,7 @@ teardown() {
@test "run without loop" { @test "run without loop" {
ncat --listen --unixsock "${deployer_sock}" & ncat --listen --unixsock "${deployer_sock}" &
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" --test --verbose "${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" --verbose test
echo "done" | ncat --unixsock "${deployer_sock}" echo "done" | ncat --unixsock "${deployer_sock}"
} }
@ -46,10 +46,11 @@ send_request() (
ncat --listen --unixsock "${deployer_sock}" & ncat --listen --unixsock "${deployer_sock}" &
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" \ "${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" \
--daemon --once --verbose --daemon --once --verbose start
code=$? code=$?
if [ "${code}" -ne 0 ]; then if [ "${code}" -ne 0 ]; then
echo "fail" | ncat --unixsock "${deployer_sock}" echo "fail" | ncat --unixsock "${deployer_sock}"
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" stop
return "${code}" return "${code}"
fi fi
( (
@ -58,7 +59,9 @@ send_request() (
echo "${request}" | ncat --unixsock "${runner_sock}" echo "${request}" | ncat --unixsock "${runner_sock}"
) & ) &
echo "done" | ncat --unixsock "${deployer_sock}" echo "done" | ncat --unixsock "${deployer_sock}"
return "$(ncat --listen --unixsock "${response_sock}" | jq .code)" code="$(ncat --listen --unixsock "${response_sock}" | jq .code)"
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" stop
return "${code}"
) )
@test "run with err_repo_name_missing" { @test "run with err_repo_name_missing" {

View File

@ -38,6 +38,9 @@ runner_username="$(id --user --name)"
# Location of unixsock file used to send requests to the runner server. # Location of unixsock file used to send requests to the runner server.
runner_sock="${temp}${run_dir}/${name}/runner/runner.sock" runner_sock="${temp}${run_dir}/${name}/runner/runner.sock"
# Location of deployer pid.
runner_pid="${temp}${run_dir}/${name}/pids/runner.pid"
# Directory in which to clone git repositories. # Directory in which to clone git repositories.
runner_cloning_dir="${temp}${tmp_dir}/${name}/repositories" runner_cloning_dir="${temp}${tmp_dir}/${name}/repositories"