Compare commits

..

No commits in common. "master" and "0.7" have entirely different histories.
master ... 0.7

13 changed files with 338 additions and 503 deletions

View File

@ -1,5 +1,6 @@
NAME = netoik-cicd
VERSION = $(shell [ -d ".git" ] && git describe | sed "s/-/./g")
BRANCH = $(shell [ -d ".git" ] && git branch --show-current)
TEMP_DIR = "${PWD}/.temp"
RPM_SOURCEDIR = $(shell rpm --eval "%{_sourcedir}")
@ -40,7 +41,7 @@ $(RPM_SOURCEDIR)/$(NAME)-%.tar.gz: *
--prefix="$(NAME)-$(VERSION)/" \
--worktree-attributes \
--verbose \
HEAD
"$(BRANCH)"
.PHONY: tarball
tarball: $(RPM_SOURCEDIR)/$(NAME)-$(VERSION).tar.gz
@ -81,18 +82,16 @@ install: conf/*.sample systemd/*.service bin/*
install --directory "$(DESTDIR)$(RUNDIR)/$(NAME)/deployer"
install --directory "$(DESTDIR)$(RUNDIR)/$(NAME)/runner"
install --directory "$(DESTDIR)$(RUNDIR)/$(NAME)/pipeline"
install --directory "$(DESTDIR)$(RUNDIR)/$(NAME)/pids"
install --directory "$(DESTDIR)$(TMPDIR)/$(NAME)/repositories"
.PHONY: check_format
check_format:
shfmt --diff ./src ./tests
shfmt --diff ./src
.PHONY: check_linting
check_linting:
shfmt --find ./src ./tests | while read f; do bash -o noexec $$f; done
shfmt --find ./src ./tests | while read f; do \
shellcheck --external-sources $$f; done
shfmt --find ./src | xargs bash -o noexec
shfmt --find ./src | xargs shellcheck --external-sources
.PHONY: unit_test
unit_test:

View File

@ -1,81 +1,61 @@
# Deployer config parsing errors.
err_deployer_sock_empty=11
err_deployer_sock_dir_not_directory=12
err_deployer_sock_dir_not_writable=13
err_deployer_sock_dir_not_accessible=14
err_deployer_sock_already_in_use=15
err_deployer_sock_not_exist=16
err_deployer_pid_empty=17
err_deployer_pid_dir_not_directory=18
err_deployer_pid_dir_not_writable=19
err_deployer_timeout_empty=20
err_deployer_timeout_not_valid=21
err_deployer_username_empty=22
err_deployer_user_not_exist=23
# Config parsing errors.
i=11 && err_deployer_sock_empty=$i
((i++)) && err_deployer_sock_dir_not_directory=$i
((i++)) && err_deployer_sock_dir_not_writable=$i
((i++)) && err_deployer_sock_already_in_use=$i
((i++)) && err_deployer_sock_not_exist=$i
((i++)) && err_repos_dir_empty=$i
((i++)) && err_repos_dir_not_directory=$i
((i++)) && err_repos_dir_not_accessible=$i
((i++)) && err_rpms_dir_empty=$i
((i++)) && err_rpms_dir_not_directory=$i
((i++)) && err_rpms_dir_not_accessible=$i
((i++)) && err_runner_username_empty=$i
((i++)) && err_runner_user_not_exist=$i
((i++)) && err_deployer_timeout_empty=$i
((i++)) && err_deployer_timeout_not_valid=$i
((i++)) && err_runner_sock_empty=$i
((i++)) && err_runner_sock_dir_not_directory=$i
((i++)) && err_runner_sock_dir_not_writable=$i
((i++)) && err_runner_sock_already_in_use=$i
((i++)) && err_runner_sock_not_exist=$i
((i++)) && err_deployer_username_empty=$i
((i++)) && err_deployer_user_not_exist=$i
((i++)) && err_runner_cloning_dir_empty=$i
((i++)) && err_runner_cloning_dir_not_directory=$i
((i++)) && err_runner_cloning_dir_not_writable=$i
((i++)) && err_runner_timeout_empty=$i
((i++)) && err_runner_timeout_not_valid=$i
((i++)) && err_git_runner_groupname_empty=$i
((i++)) && err_git_runner_group_not_exist=$i
((i++)) && err_runner_deployer_groupname_empty=$i
((i++)) && err_runner_deployer_group_not_exist=$i
((i++)) && err_pipeline_sock_dir_empty=$i
((i++)) && err_pipeline_sock_dir_not_directory=$i
((i++)) && err_pipeline_sock_dir_not_writable=$i
# Runner config parsing errors.
err_runner_username_empty=41
err_runner_user_not_exist=42
err_runner_sock_empty=43
err_runner_sock_dir_not_directory=44
err_runner_sock_dir_not_writable=45
err_runner_sock_already_in_use=46
err_runner_sock_not_exist=47
err_runner_pid_empty=48
err_runner_pid_dir_not_directory=49
err_runner_pid_dir_not_writable=50
err_runner_pid_not_exist=51
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
# JSON parsing errors
i=51 && err_json_bad_format=$i
((i++)) && err_pkg_name_missing=$i
((i++)) && err_pkg_name_empty=$i
((i++)) && err_repo_dir_not_exist=$i
((i++)) && err_pkg_version_missing=$i
((i++)) && err_pkg_version_empty=$i
((i++)) && err_rpm_path_not_exist=$i
((i++)) && err_repo_name_missing=$i
((i++)) && err_repo_name_empty=$i
((i++)) && err_repo_hash_missing=$i
((i++)) && err_repo_hash_empty=$i
((i++)) && err_repo_tag_empty=$i
# Operationnal errors.
err_clone_repo=131
err_checkout_hash=132
err_check_format=133
err_check_linting=134
err_unit_test=135
err_add_tag=136
err_make_tarball=137
err_rpm_build=138
err_rpm_upgrade=139
err_rpm_install=140
err_deployer_pid_not_exist=141
err_deployer_pid_not_readable=142
err_deployer_process_not_running=143
err_deployer_process_not_running=144
err_deployer_process_not_killed=145
i=101 && err_clone_repo=$i
((i++)) && err_checkout_hash=$i
((i++)) && err_check_format=$i
((i++)) && err_check_linting=$i
((i++)) && err_unit_test=$i
((i++)) && err_add_tag=$i
((i++)) && err_make_tarball=$i
((i++)) && err_rpm_build=$i
((i++)) && err_rpm_upgrade=$i
((i++)) && err_rpm_install=$i

View File

@ -10,9 +10,6 @@ deployer_username="netoik-cicd-deployer"
# Location of unixsock file used to send requests to the deployer server.
deployer_sock="/run/netoik-cicd/deployer/deployer.sock"
# Location of deployer pid.
deployer_pid="/run/netoik-cicd/pids/deployer.pid"
# Maximum number of seconds to wait for deployer response.
# Set to 0 to disable timeout.
deployer_timeout=30
@ -23,9 +20,6 @@ runner_username="netoik-cicd-runner"
# Location of unixsock file used to send requests to the runner server.
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.
runner_cloning_dir="/var/tmp/netoik-cicd/repositories"
@ -40,4 +34,4 @@ pipeline_sock_dir="/run/netoik-cicd/pipeline"
repos_dir="/var/gogs/repositories/samuel"
# Directory containing rpm packages.
rpms_dir="/home/netoik-cicd-runner/rpmbuild/RPMS"
rpms_dir="/home/netoik-cicd/rpmbuild/RPMS"

View File

@ -10,7 +10,7 @@ Source0: %{name}-%{version}.tar.gz
BuildArch: x86_64
BuildRequires: make
Requires: bash,go-toolset,inotify-tools,jq,nmap-ncat,rpm-build,rpmdevtools,ShellCheck,shfmt
Requires: bash,inotify-tools,jq,nmap-ncat,rpm-build,rpmdevtools,ShellCheck,shfmt
%description
Netoik Continuous Deployment tool
@ -38,14 +38,9 @@ if ! id %{name}-runner; then
--home-dir /home/%{name}-runner \
--shell=%{_bindir}/rpmdev-setuptree \
--groups %{name}-git-runner,%{name}-runner-deployer \
--gid %{name}-runner-deployer \
--user-group \
%{name}-runner
chmod 710 /home/%{name}-runner
runuser --login %{name}-runner
runuser --user %{name}-runner -- git config \
--global user.email %{name}-runner@netoik.io
runuser --user %{name}-runner -- git config \
--global user.name %{name}-runner
fi
if ! id %{name}-deployer; then
useradd --no-create-home \
@ -60,17 +55,23 @@ fi
# Reload systemctl daemon.
systemctl daemon-reload
# Restart deployer service.
systemctl restart %{name}-deployer.service
systemctl stop %{name}-deployer.service
rm --force %{_rundir}/%{name}/deployer/deployer.sock
systemctl start %{name}-deployer.service
systemctl enable %{name}-deployer.service
# Restart runner service.
systemctl restart %{name}-runner.service
systemctl stop %{name}-runner.service
rm --force %{_rundir}/%{name}/runner/runner.sock
systemctl start %{name}-runner.service
systemctl enable %{name}-runner.service
%preun
# Stop service only if uninstalling.
if [ $1 -eq 0 ]; then
systemctl disable --now %{name}-deployer.service
rm --force %{_rundir}/%{name}/deployer/deployer.sock
systemctl disable --now %{name}-runner.service
rm --force %{_rundir}/%{name}/runner/runner.sock
fi
%postun
@ -98,6 +99,5 @@ fi
%attr(755, %{name}-deployer, %{name}-deployer) %dir %{_rundir}/%{name}/deployer
%attr(755, git, git) %dir %{_rundir}/%{name}/pipeline
%attr(755, %{name}-runner, %{name}-runner) %dir %{_rundir}/%{name}/runner
%attr(775, %{name}-deployer, %{name}-runner-deployer) %dir %{_rundir}/%{name}/pids
%attr(755, root, root) %dir %{_tmppath}/%{name}
%attr(755, %{name}-runner, root) %dir %{_tmppath}/%{name}/repositories
%attr(755, %{name}-runner, %{name}-runner) %dir %{_tmppath}/%{name}/repositories

View File

@ -77,7 +77,7 @@ fail() (
)
usage() (
echo "Usage: ${PROGRAM_NAME} [OPTION]... ACTION
echo "Usage: ${PROGRAM_NAME} [OPTION]...
Start deployer server, wait for unixsock requests to deploy rpm packages.
Mandatory argumentes for long options are mandatory for short options too.
@ -89,14 +89,10 @@ Mandatory argumentes for long options are mandatory for short options too.
${DEFAULT_ERRORS_FILE}
-o, --once stop listening after first request process
-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
-h, --help display this help message and exit
Positional argument ACTION
start start deployer server
stop stop deployer server
test test configuration and exit
"
)
@ -198,9 +194,9 @@ process_request() (
fi
log_debug "RPM path found at '${rpm_path}'."
# Upgrade package if already installed.
log_debug "Check if pkg '${pkg_name}' is already installed."
if rpm --query "${pkg_name}" 1>/dev/null 2>/dev/null; then
# Upgrade package if already installed.
log_debug "Package '${pkg_name}' already installed, so upgrade to v
${pkg_version}"
if ! output="$(sudo rpm --upgrade \
@ -210,15 +206,15 @@ process_request() (
return
fi
log_debug "RPM package '${pkg_name}' upgraded to v${pkg_version}."
else
# Install package if not already installed.
log_debug "Package '${pkg_name}' is not already installed, so install
v${pkg_version}."
if ! output="$(sudo rpm --install --verbose --hash "${rpm_path}")"; then
reply "${err_rpm_install}" \
"Cannot install package '${pkg_name}' v${pkg_version}: ${output}."
return
fi
fi
# Install package if not already installed.
log_debug "Package '${pkg_name}' is not already installed, so install
v${pkg_version}."
if ! output="$(sudo rpm --install --verbose --hash "${rpm_path}")"; then
reply "${err_rpm_install}" \
"Cannot install package '${pkg_name}' v${pkg_version}: ${output}."
return
fi
# Package deployed.
@ -231,30 +227,41 @@ process_loop() (
log_info "Start listening unixsock with keep-open at '${deployer_sock}'."
while read -r request; do
log_info "Process new request '${request}'."
process_request &
process_request
done < <(ncat --listen --keep-open --unixsock "${deployer_sock}")
log_critical "Unexpected end of listening at '${deployer_sock}'."
else
log_info "Start listening unixsock without keep-open at '${deployer_sock}'."
while read -r request; do
log_info "Process new request '${request}'."
process_request
done < <(ncat --listen --unixsock "${deployer_sock}")
log_info "End of listening at '${deployer_sock}'."
fi
# Kill all remaining subprocesses only if daemon.
log_info "End of loop."
if "${daemon}"; then
log_debug "Kill child jobs."
jobs -p | xargs kill 2>/dev/null || true
fi
# Remove sock file
log_debug "Remove deployer unixsock file."
rm --force "${deployer_sock}"
log_info "End of process."
)
main() (
# Parse arguments.
daemonize="false"
daemon="false"
testing="false"
keep_open="true"
config_file="${DEFAULT_CONFIG_FILE}"
errors_file="${DEFAULT_ERRORS_FILE}"
verbosity_option=""
verbosity_level="${DEFAULT_VERBOSITY_LEVEL}"
if ! args="$(getopt --name "${PROGRAM_NAME}" \
--options c:de:hoqv \
--longoptions conf:,daemon,errs:,help,once,quiet,verbose \
--options c:de:hoqtv \
--longoptions conf:,daemon,errs:,help,once,quiet,test,verbose \
-- "$@")"; then
usage
fail "Bad arguments."
@ -268,7 +275,7 @@ main() (
shift 2
;;
-d | --daemon)
daemonize="true"
daemon="true"
shift
;;
-e | --errs)
@ -292,6 +299,10 @@ main() (
((verbosity_level -= 10))
shift
;;
-t | --test)
testing="true"
shift
;;
-v | --verbose)
if [ "${verbosity_option}" ]; then
usage
@ -311,19 +322,10 @@ main() (
;;
esac
done
if [ $# -ne 1 ]; then
if [ "$@" ]; then
usage
fail "Missing positional argument ACTION"
fail "Unexpected extra arguments '$*'."
fi
case "$1" in
start | stop | test)
action="$1"
;;
*)
usage
fail "Bad positional argument ACTION '$1'."
;;
esac
# Load config file.
if [ ! -r "${config_file}" ]; then
@ -353,6 +355,10 @@ main() (
fail "Directory of deployer_sock='${deployer_sock}' is not writable." \
"${err_deployer_sock_dir_not_writable}"
fi
if [ -e "${deployer_sock}" ]; then
fail "Sock deployer_sock='${deployer_sock}' is already in use." \
"${err_deployer_sock_already_in_use}"
fi
if [ -z "${repos_dir}" ]; then
fail "Variable repos_dir is empty." "${err_repos_dir_empty}"
@ -375,84 +381,35 @@ main() (
fi
if [ -z "${runner_deployer_groupname}" ]; then
fail "Variable runner_deployer_username is empty." \
"${err_runner_deployer_groupname_empty}"
fail "Variable runner_deployer_username is empty." "${err_runner_deployer_groupname_empty}"
fi
if ! getent group "${runner_deployer_groupname}" >/dev/null; then
if ! getent group "${runner_deployer_groupname}"; then
fail "Runner-deployer group '${runner_deployer_groupname}' does not exist." \
"${err_runner_deployer_group_not_exist}"
fi
if [ -z "${deployer_pid}" ]; then
fail "Variable deployer_pid is empty." "${err_deployer_pid_empty}"
fi
if [ ! -d "$(dirname "${deployer_pid}")" ]; then
fail "Dirname of deployer_pid='${deployer_pid}' is not a directory." \
"${err_deployer_pid_dir_not_directory}"
fi
if [ ! -w "$(dirname "${deployer_pid}")" ]; then
fail "Dirname of deployer_pid='${deployer_pid}' is not writable." \
"${err_deployer_pid_dir_not_writable}"
fi
case "${action}" in
test)
# Stop now if we are only testing config.
# Stop now if we are only testing config.
if "${testing}"; then
exit 0
;;
start)
if [ -e "${deployer_sock}" ]; then
fail "Sock deployer_sock='${deployer_sock}' is already in use." \
"${err_deployer_sock_already_in_use}"
fi
fi
# Set right access in background after nc listen.
(
inotifywait --timeout 1 --quiet --quiet \
--event create "$(dirname "${deployer_sock}")" || true
chmod 775 "${deployer_sock}"
chgrp "${runner_deployer_groupname}" "${deployer_sock}"
) &
# Set right access in background after nc listen.
(
inotifywait --timeout 1 --quiet --quiet \
--event create "$(dirname "${deployer_sock}")" || true
chmod 775 "${deployer_sock}"
chgrp "${runner_deployer_groupname}" "${deployer_sock}"
) &
# Run process loop in background or foreground.
if "${daemonize}"; then
log_info "Run process loop in background."
process_loop &
echo "$!" >"${deployer_pid}"
else
log_info "Run process loop in foreground."
echo "$$" >"${deployer_pid}"
process_loop
fi
;;
stop)
if [ ! -f "${deployer_pid}" ]; then
fail "File deployer_pid='${deployer_pid}' does not exist." \
"${err_deployer_pid_not_exist}"
fi
if [ ! -r "${deployer_pid}" ]; then
fail "File deployer_pid='${deployer_pid}' is not readable." \
"${err_deployer_pid_not_readable}"
fi
pid="$(cat "${deployer_pid}")"
rm --force "${deployer_pid}"
# Kill deployer process.
log_info "Kill deployer process with pid '${pid}'."
if ! ps -p "${pid}" >/dev/null; then
fail "Deployer process with pid='${pid}' is not running." \
"${err_deployer_process_not_running}"
fi
if ! output="$(kill "${pid}" 2>&1 || kill -KILL "${pid}" 2>&1)"; then
fail "Cannot kill deployer process: ${output}." \
"${err_deployer_process_not_killed}"
fi
# Remove deployer sock file.
log_info "Remove deployer sock at '${deployer_sock}'."
rm --force "${deployer_sock}"
;;
esac
# Run process loop in background or foreground.
if "${daemon}"; 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 "$@"

View File

@ -198,7 +198,7 @@ main() (
if [ -z "${git_runner_groupname}" ]; then
fail "Variable git_runner_groupname is empty." "${err_git_runner_groupname_empty}"
fi
if ! getent group "${git_runner_groupname}" >/dev/null; then
if ! getent group "${git_runner_groupname}"; then
fail "Git-runner group '${git_runner_groupname}' does not exist." \
"${err_git_runner_group_not_exist}"
fi
@ -215,24 +215,24 @@ main() (
"${err_pipeline_sock_dir_not_writable}"
fi
# Generate random string.
random="$(echo "${RANDOM}" | md5sum | head --bytes 7)"
# Generate pipeline tmp sock.
tsp="$(date +%s)"
random="$(echo "${RANDOM}" | md5sum | head --bytes 32)"
rd_pipeline_sock_dir="${pipeline_sock_dir}/${pipeline}-${tsp}-${random}"
rd_pipeline_sock="${rd_pipeline_sock_dir}/pipeline.sock"
# Build runner request.
case "${pipeline}" in
newcommit)
repo_id="$(echo "${repo_hash}" | head -c 7)"
rd_pipeline_sock_dir="${pipeline_sock_dir}/${pipeline}-${repo_id}-${random}"
runner_request="$(jq --null-input --compact-output \
--arg s "${rd_pipeline_sock_dir}/pipeline.sock" \
--arg s "${rd_pipeline_sock}" \
--arg n "${repo_name}" \
--arg h "${repo_hash}" \
'{"response_sock":$s,"repo_name":$n,"repo_hash":$h}')"
;;
newtag)
rd_pipeline_sock_dir="${pipeline_sock_dir}/${pipeline}-${repo_tag}-${random}"
runner_request="$(jq --null-input --compact-output \
--arg s "${rd_pipeline_sock_dir}/pipeline.sock" \
--arg s "${rd_pipeline_sock}" \
--arg n "${repo_name}" \
--arg h "${repo_hash}" \
--arg t "${repo_tag}" \
@ -254,30 +254,25 @@ main() (
(
inotifywait --timeout 1 --quiet --quiet \
--event create "${rd_pipeline_sock_dir}" || true
chmod 775 "${rd_pipeline_sock_dir}/pipeline.sock"
chgrp "${git_runner_groupname}" "${rd_pipeline_sock_dir}/pipeline.sock"
chmod 775 "${rd_pipeline_sock}"
chgrp "${git_runner_groupname}" "${rd_pipeline_sock}"
echo "${runner_request}" | ncat --unixsock "${runner_sock}"
) &
# Start CI runner.
echo -e "Starting CI runner..."
cd "${rd_pipeline_sock_dir}"
ncat_cmd="ncat --listen --unixsock --keep-open pipeline.sock"
# Wait for runner response.
if [ "${runner_timeout}" -gt 0 ]; then
ncat_cmd="timeout ${runner_timeout} ${ncat_cmd}"
response="$(timeout "${runner_timeout}" ncat --listen \
--unixsock "${rd_pipeline_sock}")"
else
response="$(ncat --listen --unixsock "${rd_pipeline_sock}")"
fi
while read -r response; do
echo -e "$(echo "${response}" | jq --raw-output .msg)"
code="$(echo "${response}" | jq .code)"
[ "${code}" = "null" ] || break
done < <($ncat_cmd)
pkill --full --exact --parent "$$" "${ncat_cmd}" || true
# Remove random directory.
rm --recursive "${rd_pipeline_sock_dir}"
# Display response.
exit "${code}"
echo -e "$(echo "${response}" | jq .msg)"
exit "$(echo "${response}" | jq .code)"
)
main "$@"

View File

@ -70,7 +70,7 @@ fail() (
)
usage() (
echo "Usage: ${PROGRAM_NAME} [OPTION]... ACTION
echo "Usage: ${PROGRAM_NAME} [OPTION]...
Start runner server, wait for unixsock requests to clone git repo, run tests
and build rpm package.
@ -83,41 +83,29 @@ Mandatory argumentes for long options are mandatory for short options too.
${DEFAULT_ERRORS_FILE}
-o, --once stop listening after first request process
-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
-h, --help display this help message and exit
Positional argument ACTION
start start runner server
stop stop runner server
test tests configuration and exit
"
)
reply() (
msg="$1"
code="$2"
code="$1"
msg="$2"
if [ -z "${code}" ]; then
log_info "${msg}"
json="$(jq --null-input \
--compact-output \
--arg m "${msg}" \
'{"msg":$m}')"
if [ "${code}" -gt 0 ]; then
log_error "${msg}"
else
if [ "${code}" -eq 0 ]; then
log_info "${msg}"
else
log_error "${msg}"
fi
json="$(jq --null-input \
--compact-output \
--arg m "${msg}" \
--arg c "${code}" \
'{"msg":$m,"code":$c|tonumber}')"
log_info "${msg}"
fi
if ! output="$(echo "${json}" | ncat --unixsock "${response_sock}" 2>&1)"; then
if ! output="$(jq --null-input \
--compact-output \
--arg c "${code}" \
--arg m "${msg}" \
'{"code":$c|tonumber,"msg":$m}' |
ncat --unixsock "${response_sock}" 2>&1)"; then
log_error "Cannot write to sock '${response_sock}': ${output}."
fi
)
@ -125,7 +113,7 @@ reply() (
fwd_reply() (
read -r json
if ! output="$(echo "${json}" | ncat --unixsock "${response_sock}" 2>&1)"; then
if ! output="$(echo "${json}" | ncat --unixsock 2>&1)"; then
log_error "Cannot write to sock '${response_sock}': ${output}."
fi
)
@ -157,18 +145,17 @@ process_request() (
log_debug "Get repo_name from json."
if ! repo_name="$(echo "${request}" |
jq --raw-output ".repo_name" 2>&1)"; then
reply "Cannot parse json '${request}': ${repo_name}." \
"${err_json_bad_format}"
reply "${err_json_bad_format}" \
"Cannot parse json '${request}': ${repo_name}."
return
fi
if [ "${repo_name}" = "null" ]; then
reply "Missing key repo_name in '${request}'." \
"${err_repo_name_missing}"
reply "${err_repo_name_missing}" "Missing key repo_name in '${request}'."
return
fi
if [ -z "${repo_name}" ]; then
reply "Empty value for key repo_name in '${request}'." \
"${err_repo_name_empty}"
reply "${err_repo_name_empty}" \
"Empty value for key repo_name in '${request}'."
return
fi
log_debug "Got pkg name: '${repo_name}'."
@ -176,8 +163,7 @@ process_request() (
# Get repository folder.
repo_dir="${repos_dir}/${repo_name}.git"
if [ ! -d "${repo_dir}" ]; then
reply "Repository '${repo_dir}' does not exist." \
"${err_repo_dir_not_exist}"
reply "${err_repo_dir_not_exist}" "Repository '${repo_dir}' does not exist."
return
fi
log_debug "Repository is present at '${repo_dir}'."
@ -185,105 +171,96 @@ process_request() (
# Get repo_hash from json.
log_debug "Get repo_hash from json."
if ! repo_hash=$(echo "${request}" | jq --raw-output ".repo_hash" 2>&1); then
reply "Cannot parse json '${request}': ${repo_hash}." \
"${err_json_bad_format}"
reply "${err_json_bad_format}" \
"Cannot parse json '${request}': ${repo_hash}."
return
fi
if [ "${repo_hash}" = "null" ]; then
reply "Missing key repo_hash in '${request}'." \
"${err_repo_hash_missing}"
reply "${err_repo_hash_missing}" "Missing key repo_hash in '${request}'."
return
fi
if [ -z "${repo_hash}" ]; then
reply "Empty value for key repo_hash in '${request}'." \
"${err_repo_hash_empty}"
reply "${err_repo_hash_empty}" \
"Empty value for key repo_hash in '${request}'." 1>&2
return
fi
# Get repo_tag from json.
log_debug "Get repo_tag from json."
if ! repo_tag=$(echo "${request}" | jq --raw-output ".repo_tag"); then
reply "Cannot parse json '${request}': ${repo_tag}." \
"${err_json_bad_format}"
reply "${err_json_bad_format}" \
"Cannot parse json '${request}': ${repo_tag}."
return
fi
if [ -z "${repo_tag}" ]; then
reply "Empty value for key repo_tag in '${request}'." \
"${err_repo_tag_empty}"
reply "${err_repo_tag_empty}" \
"Empty value for key repo_tag in '${request}'."
return
fi
# Clone repo and move into it.
repo_id="$(echo "${repo_hash}" | head --bytes 7)"
[ "${repo_tag}" != "null" ] && repo_id="${repo_tag}"
rand="$(echo "${RANDOM}" | md5sum | head --bytes 7)"
repo_clone="${runner_cloning_dir}/${repo_name}-${repo_id}-${rand}"
reply "Cloning repo '${repo_name}'..."
if ! output="$(git clone "${repo_dir}" "${repo_clone}" 2>&1)"; then
reply "Cannot clone repo '${repo_name}': ${output}." \
"${err_clone_repo}"
rand="$(echo "${RANDOM}" | md5sum | head --bytes 32)"
repo_clone="${runner_cloning_dir}/${repo_name}-${repo_hash}-${rand}"
log_info "Clone '$repo_name'."
if ! output="$(git clone "$repo_dir" "$repo_clone" 2>&1)"; then
reply "${err_clone_repo}" "Cannot clone repo '${repo_name}': ${output}."
return
fi
cd "$repo_clone"
# Checkout git hash.
reply "Checkouting hash '${repo_hash}..."
log_info "Checkout hash $repo_hash."
if ! output="$(git checkout "$repo_hash" 2>&1)"; then
reply "Cannot checkout hash '${repo_hash}': ${output}." \
"${err_checkout_hash}"
reply "${err_checkout_hash}" \
"Cannot checkout hash '${repo_hash}': ${output}."
return
fi
# Check code validity.
reply "Checking code format..."
log_info "Check code validity."
if ! output="$(make check_format 2>&1)"; then
reply "Check format error: ${output}." "${err_check_format}"
reply "${err_check_format}" "Check format error: ${output}."
return
fi
reply "Checking code linting..."
if ! output="$(make check_linting 2>&1)"; then
reply "Check linting error: ${output}." "${err_check_linting}"
reply "${err_check_linting}" "Check linting error: ${output}."
return
fi
reply "Running unit tests..."
if ! output="$(make unit_test 2>&1)"; then
reply "Unit test error: ${output}." "${err_unit_test}"
reply "${err_unit_test}" "Unit test error: ${output}."
return
fi
# Stop now if no tag specified.
if [ "$repo_tag" = "null" ]; then
reply "Hash '${repo_hash}' OK for repo '${repo_name}'." 0
reply 0 "Hash '${repo_hash}' OK for repo '${repo_name}'."
return
fi
# Build rpm package.
reply "Adding tag '${repo_tag}'..."
echo "Build RPM package."
if ! output="$(git tag --message="$repo_tag" "$repo_tag" 2>&1)"; then
reply "Cannot add git tag '${repo_tag}': ${output}." "${err_add_tag}"
reply "${err_add_tag}" "Cannot add git tag '${repo_tag}': ${output}."
return
fi
reply "Making source tarball..."
if ! output="$(make tarball 2>&1)"; then
reply "Cannot make tarball for tag '${repo_tag}': ${output}." \
"${err_make_tarball}"
reply "${err_make_tarball}" \
"Cannot make tarball for tag '${repo_tag}': ${output}."
return
fi
repo_version="$(make version)"
reply "Building RPM package '${repo_name}' v${repo_version}..."
if ! output="$(rpmbuild -bb "$repo_name.spec" 2>&1)"; then
reply "Cannot build rpm for tag '${repo_tag}': ${output}." \
"${err_rpm_build}"
reply "${err_rpm_build}" \
"Cannot build rpm for tag '${repo_tag}': ${output}."
return
fi
# Deploy rpm package.
reply "Deploying RPM package '${repo_name}' v${repo_version}..."
log_info "Deploy RPM package."
deployer_request="$(jq --null-input \
--compact-output \
--arg s "${repo_clone}/runner.sock" \
--arg n "${repo_name}" \
--arg v "${repo_version}" \
--arg v "$(make version)" \
'{"response_sock":$s,"pkg_name":$n,"pkg_version":$v}')"
(
inotifywait --timeout 1 --quiet --quiet \
@ -308,30 +285,41 @@ process_loop() (
log_info "Start listening unixsock with keep-open at '${runner_sock}'."
while read -r request; do
log_info "Process new request '${request}'."
process_request &
process_request
done < <(ncat --listen --keep-open --unixsock "${runner_sock}")
log_critical "Unexpected end of listening at '${deployer_sock}'."
else
log_info "Start listening unixsock without keep-open at '${runner_sock}'."
while read -r request; do
log_info "Process new request '${request}'."
process_request
done < <(ncat --listen --unixsock "${runner_sock}")
log_info "End of listening at '${deployer_sock}'."
fi
# Kill all remaining subprocesses only if daemon.
log_info "End of loop."
if "${daemonize}"; then
log_debug "Kill child jobs."
jobs -p | xargs kill 2>/dev/null || true
fi
# Remove sock file.
log_debug "Remove deployer unixsock file."
rm --force "${runner_sock}"
log_info "End of process."
)
main() (
# Parse arguments.
daemonize="false"
testing="false"
keep_open="true"
config_file="${DEFAULT_CONFIG_FILE}"
errors_file="${DEFAULT_ERRORS_FILE}"
verbosity_option=""
verbosity_level="${DEFAULT_VERBOSITY_LEVEL}"
if ! args="$(getopt --name "${PROGRAM_NAME}" \
--options c:de:hoqv \
--longoptions conf:,daemon,errs:,help,once,quiet,verbose \
--options c:de:hoqtv \
--longoptions conf:,daemon,errs:,help,once,quiet,test,verbose \
-- "$@")"; then
usage
fail "Bad arguments."
@ -369,6 +357,10 @@ main() (
((verbosity_level -= 10))
shift
;;
-t | --test)
testing="true"
shift
;;
-v | --verbose)
if [ "${verbosity_option}" ]; then
usage
@ -388,19 +380,10 @@ main() (
;;
esac
done
if [ $# -ne 1 ]; then
if [ "$@" ]; then
usage
fail "Missing positional argument ACTION."
fail "Unexpected extra arguments '$*'."
fi
case "$1" in
start | stop | test)
action="$1"
;;
*)
usage
fail "Bad postional argument ACTION '$1'."
;;
esac
# Load config file.
if [ ! -r "${config_file}" ]; then
@ -422,13 +405,9 @@ main() (
if [ -z "${deployer_sock}" ]; then
fail "Variable deployer_sock is empty." "${err_deployer_sock_empty}"
fi
if [ ! -d "$(dirname "${deployer_sock}")" ]; then
fail "Dirname of deployer_sock='${deployer_sock}' is not a directory." \
"${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}"
if [ ! -S "${deployer_sock}" ]; then
fail "Sock deployer_sock='${deployer_sock}' does not exist." \
"${err_deployer_sock_not_exist}"
fi
if [ -z "${deployer_timeout}" ]; then
@ -450,6 +429,10 @@ main() (
fail "Directory of runner_sock='${runner_sock}' is not writable." \
"${err_runner_sock_dir_not_writable}"
fi
if [ -e "${runner_sock}" ]; then
fail "Sock deployer_sock='${runner_sock}' is already in use." \
"${err_runner_sock_already_in_use}"
fi
if [ -z "${runner_cloning_dir}" ]; then
fail "Variable runner_cloning_dir is empty." \
@ -487,7 +470,7 @@ main() (
if [ -z "${runner_deployer_groupname}" ]; then
fail "Variable runner_deployer_groupname is empty." "${err_runner_deployer_groupname_empty}"
fi
if ! getent group "${runner_deployer_groupname}" >/dev/null; then
if ! getent group "${runner_deployer_groupname}"; then
fail "Runner-deployer group '${runner_deployer_groupname}' does not exist." \
"${err_runner_deployer_group_not_exist}"
fi
@ -495,87 +478,33 @@ main() (
if [ -z "${git_runner_groupname}" ]; then
fail "Variable git_runner_groupname is empty." "${err_git_runner_groupname_empty}"
fi
if ! getent group "${git_runner_groupname}" >/dev/null; then
if ! getent group "${git_runner_groupname}"; then
fail "Git-runner group '${git_runner_groupname}' does not exist." \
"${err_git_runner_group_not_exist}"
fi
if [ -z "${runner_pid}" ]; 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
test)
# Stop now if we are only testing.
log_info "Configuration OK."
# Stop now if we are only testing config.
if "${testing}"; then
exit 0
;;
start)
if [ ! -S "${deployer_sock}" ]; then
fail "Sock deployer_sock='${deployer_sock}' does not exist." \
"${err_deployer_sock_not_exist}"
fi
if [ -e "${runner_sock}" ]; then
fail "Sock deployer_sock='${runner_sock}' is already in use." \
"${err_runner_sock_already_in_use}"
fi
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}"
) &
# 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
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}"
# Kill runner process.
log_info "Kill runner process with pid '${pid}'."
if ! ps -p "${pid}" >/dev/null; then
fail "Runner process with pid='${pid}' is not running." \
"${err_runner_process_not_running}"
fi
if ! output="$(kill "${pid}" || kill -KILL "${pid}")"; then
fail "Cannot kill runner process: ${output}." \
"${err_runner_process_not_killed}"
fi
# Remove runner sock file.
log_info "Remove runner sock at '${runner_sock}'."
rm --force "${runner_sock}"
;;
esac
# 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 "$@"

View File

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

View File

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

View File

@ -1,11 +1,10 @@
#
#
# Deployer unit tests using BATS framework.
#
bats_require_minimum_version 1.5.0
setup() {
# shellcheck source=./tests/tests.conf
source "${PWD}/tests/tests.conf"
make build >/dev/null
DESTDIR="${temp}" make install >/dev/null
@ -14,7 +13,6 @@ setup() {
"${temp}${sysconf_dir}/${name}/${name}.conf"
install --directory "${temp}${var_dir}/${name}/repositories/test.git"
install --directory "${temp}${var_dir}/${name}/RPMS"
# shellcheck source=./conf/errors.conf.sample
source "${errs_file}"
}
@ -23,89 +21,87 @@ teardown() {
make clean >/dev/null
}
run_with_bad_arguments() { #@test
run -1 "${deployer_bin}" -z test
run -1 "${deployer_bin}" --zzz test
@test "run with bad arguments" {
run -1 "${deployer_bin}" -z
run -1 "${deployer_bin}" --zzz
run -1 "${deployer_bin}" zzz
run -1 "${deployer_bin}" --conf
run -1 "${deployer_bin}" --conf=/path/to/nowhere test
run -1 "${deployer_bin}" --conf=/path/to/nowhere
run -1 "${deployer_bin}" --errs
run -1 "${deployer_bin}" --errs=/path/to/nowhere test
run -1 "${deployer_bin}" --verbose --quiet test
run -1 "${deployer_bin}" --errs=/path/to/nowhere
run -1 "${deployer_bin}" --verbose --quiet
}
run_without_loop() { #@test
"${deployer_bin}" --conf="${conf_file}" --errs="${errs_file}" --verbose test
@test "run without loop" {
"${deployer_bin}" --conf="${conf_file}" --errs="${errs_file}" --test --verbose
}
send_request() (
request="$1"
"${deployer_bin}" --conf="${conf_file}" --errs="${errs_file}" \
--once --daemon --verbose start || return $?
--daemon --once --verbose || return $?
(
inotifywait --timeout 1 --quiet --quiet \
--event create "${response_sock_dir}" || true
echo "${request}" | ncat --unixsock "${deployer_sock}"
echo "${request}" | ncat --unixsock "${deployer_sock}"
) &
code="$(ncat --listen --unixsock "${response_sock}" | jq .code)"
"${deployer_bin}" --conf="${conf_file}" --errs="${errs_file}" stop
return "${code}"
return "$(ncat --listen --unixsock "${response_sock}" | jq .code)"
)
run_with_err_pkg_name_missing() { #@test
@test "run with err_pkg_name_missing" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_pkg_name_missing}"
echo "status: got ${status}, expected ${err_pkg_name_missing}"
[ "${status}" -eq "${err_pkg_name_missing}" ]
}
run_with_err_pkg_name_empty() { #@test
@test "run with err_pkg_name_empty" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"pkg_name":""}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_pkg_name_empty}"
echo "status: got ${status}, expected ${err_pkg_name_empty}"
[ "${status}" -eq "${err_pkg_name_empty}" ]
}
run_with_err_repo_dir_not_exist() { #@test
@test "run with err_repo_dir_not_exist" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"pkg_name":"not_exist"}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_repo_dir_not_exist}"
echo "status: got ${status}, expected ${err_repo_dir_not_existyy}"
[ "${status}" -eq "${err_repo_dir_not_exist}" ]
}
run_with_err_pkg_version_missing() { #@test
@test "run with err_pkg_version_missing" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"pkg_name":"test"}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_pkg_version_missing}"
echo "status: got ${status}, expected ${err_pkg_version_missing}"
[ "${status}" -eq "${err_pkg_version_missing}" ]
}
run_with_err_pkg_version_empty() { #@test
@test "run with err_pkg_version_empty" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"pkg_name":"test","pkg_version":""}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_pkg_version_empty}"
echo "status: got ${status}, expected ${err_pkg_version_empty}"
[ "${status}" -eq "${err_pkg_version_empty}" ]
}
run_with_err_rpm_path_not_exist() { #@test
@test "run with err_rpm_path_not_exist" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"pkg_name":"test","pkg_version":"0.1"}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_rpm_path_not_exist}"
echo "status: got ${status}, expected ${err_rpm_path_not_exist}"
[ "${status}" -eq "${err_rpm_path_not_exist}" ]
}

View File

@ -5,14 +5,12 @@
bats_require_minimum_version 1.5.0
setup() {
# shellcheck source=./tests/tests.conf
source "${PWD}/tests/tests.conf"
make build >/dev/null
DESTDIR="${temp}" make install >/dev/null
install --no-target-directory \
"${PWD}/tests/tests.conf" \
"${temp}${sysconf_dir}/${name}/${name}.conf"
# shellcheck source=./conf/errors.conf.sample
source "${errs_file}"
}
@ -21,7 +19,7 @@ teardown() {
make clean >/dev/null
}
run_with_bad_arguments() { #@test
@test "run with bad arguments" {
run -1 "${pipeline_bin}"
run -1 "${pipeline_bin}" bad_pipeline
@ -41,21 +39,21 @@ run_with_bad_arguments() { #@test
run -1 "${pipeline_bin}" -e /path/to/nowhere -H hash -n name newcommit
}
run_without_runner_sock() { #@test
@test "run without runner sock" {
run "${pipeline_bin}" --conf="${conf_file}" --errs="${errs_file}" \
--test --hash hash --name name newcommit
echo "status: got ${status:?}, expected ${err_runner_sock_not_exist}"
echo "status: got ${status}, expected ${err_runner_sock_not_exist}"
[ "${status}" -eq "${err_runner_sock_not_exist}" ]
}
run_newcommit_ok() { #@test
@test "run newcommit ok" {
ncat --listen --unixsock "${runner_sock}" &
"${pipeline_bin}" --conf="${conf_file}" --errs="${errs_file}" \
--test --hash hash --name name newcommit
echo "done" | ncat --unixsock "${runner_sock}"
}
run_newtag_ok() { #@test
@test "run newtag ok" {
ncat --listen --unixsock "${runner_sock}" &
"${pipeline_bin}" --conf="${conf_file}" --errs="${errs_file}" \
--test --hash hash --name name --tag tag newtag

View File

@ -1,11 +1,10 @@
#
#
# Deployer unit tests using BATS framework.
#
bats_require_minimum_version 1.5.0
setup() {
# shellcheck source=./tests/tests.conf
source "${PWD}/tests/tests.conf"
make build >/dev/null
DESTDIR="${temp}" make install >/dev/null
@ -14,7 +13,6 @@ setup() {
"${temp}${sysconf_dir}/${name}/${name}.conf"
install --directory "${temp}${var_dir}/${name}/repositories/test.git"
install --directory "${temp}${var_dir}/${name}/RPMS"
# shellcheck source=./conf/errors.conf.sample
source "${errs_file}"
}
@ -23,99 +21,96 @@ teardown() {
make clean >/dev/null
}
run_with_bad_arguments() { #@test
@test "run with bad arguments" {
run -1 "${runner_bin}" -z
run -1 "${runner_bin}" --zzz
run -1 "${runner_bin}" zzz
run -1 "${runner_bin}" --conf
run -1 "${runner_bin}" --conf=/path/to/nowhere
run -1 "${runner_bin}" --errs
run -1 "${runner_bin}" --errs=/path/to/nowhere
run -1 "${runner_bin}" --verbose --quiet
}
run_without_loop() { #@test
@test "run without loop" {
ncat --listen --unixsock "${deployer_sock}" &
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" --verbose test
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" --test --verbose
echo "done" | ncat --unixsock "${deployer_sock}"
}
send_request() (
request="$1"
request="$1"
ncat --listen --unixsock "${deployer_sock}" &
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" \
--daemon --once --verbose start
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" \
--daemon --once --verbose
code=$?
if [ "${code}" -ne 0 ]; then
echo "fail" | ncat --unixsock "${deployer_sock}"
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" stop
return "${code}"
fi
(
(
inotifywait --timeout 1 --quiet --quiet \
--event create "${response_sock_dir}" >&3
echo "${request}" | ncat --unixsock "${runner_sock}"
) &
echo "${request}" | ncat --unixsock "${runner_sock}"
) &
echo "done" | ncat --unixsock "${deployer_sock}"
code="$(ncat --listen --unixsock "${response_sock}" | jq .code)"
"${runner_bin}" --conf="${conf_file}" --errs="${errs_file}" stop
return "${code}"
return "$(ncat --listen --unixsock "${response_sock}" | jq .code)"
)
run_with_err_repo_name_missing() { #@test
request="$(jq --null-input --compact-output \
@test "run with err_repo_name_missing" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_repo_name_missing}"
[ "${status}" -eq "${err_repo_name_missing}" ]
'{"response_sock":$s}')"
run send_request "${request}"
echo "status: got ${status}, expected ${err_repo_name_missing}"
[ "${status}" -eq "${err_repo_name_missing}" ]
}
run_with_err_repo_name_empty() { #@test
request="$(jq --null-input --compact-output \
@test "run with err_repo_name_empty" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"repo_name":""}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_repo_name_empty}"
[ "${status}" -eq "${err_repo_name_empty}" ]
'{"response_sock":$s,"repo_name":""}')"
run send_request "${request}"
echo "status: got ${status}, expected ${err_repo_name_empty}"
[ "${status}" -eq "${err_repo_name_empty}" ]
}
run_with_err_repo_dir_not_exist() { #@test
request="$(jq --null-input --compact-output \
@test "run with err_repo_dir_not_exist" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"repo_name":"not_exist"}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_repo_dir_not_exist}"
[ "${status}" -eq "${err_repo_dir_not_exist}" ]
'{"response_sock":$s,"repo_name":"not_exist"}')"
run send_request "${request}"
echo "status: got ${status}, expected ${err_repo_dir_not_exist}"
[ "${status}" -eq "${err_repo_dir_not_exist}" ]
}
run_with_err_repo_hash_missing() { #@test
request="$(jq --null-input --compact-output \
@test "run with err_repo_hash_missing" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"repo_name":"test"}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_repo_hash_missing}"
[ "${status}" -eq "${err_repo_hash_missing}" ]
'{"response_sock":$s,"repo_name":"test"}')"
run send_request "${request}"
echo "status: got ${status}, expected ${err_repo_hash_missing}"
[ "${status}" -eq "${err_repo_hash_missing}" ]
}
run_with_err_repo_hash_empty() { #@test
request="$(jq --null-input --compact-output \
@test "run with err_repo_hash_empty" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"repo_name":"test","repo_hash":""}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_repo_hash_empty}"
[ "${status}" -eq "${err_repo_hash_empty}" ]
'{"response_sock":$s,"repo_name":"test","repo_hash":""}')"
run send_request "${request}"
echo "status: got ${status}, expected ${err_repo_hash_empty}"
[ "${status}" -eq "${err_repo_hash_empty}" ]
}
run_with_err_repo_tag_empty() { #@test
request="$(jq --null-input --compact-output \
@test "run with err_repo_tag_empty" {
request="$(jq --null-input --compact-output \
--arg s "${response_sock}" \
'{"response_sock":$s,"repo_name":"test","repo_hash":"hash","repo_tag":""}')"
run send_request "${request}"
echo "status: got ${status:?}, expected ${err_repo_tag_empty}"
[ "${status}" -eq "${err_repo_tag_empty}" ]
'{"response_sock":$s,"repo_name":"test","repo_hash":"hash","repo_tag":""}')"
run send_request "${request}"
echo "status: got ${status}, expected ${err_repo_tag_empty}"
[ "${status}" -eq "${err_repo_tag_empty}" ]
}

View File

@ -14,10 +14,10 @@ conf_file="${temp}${sysconf_dir}/${name}/${name}.conf"
errs_file="${temp}${sysconf_dir}/${name}/errors.conf"
# Name of group unifying git and runner.
git_runner_groupname="$(id --group --name)"
git_runner_groupname="$(id --user --name)"
# Name of group unifying runner and deployer.
runner_deployer_groupname="$(id --group --name)"
runner_deployer_groupname="$(id --user --name)"
# Name of the user responsible of the deployer server.
deployer_username="$(id --user --name)"
@ -25,9 +25,6 @@ deployer_username="$(id --user --name)"
# Location of unixsock file used to send requests to the deployer server.
deployer_sock="${temp}${run_dir}/${name}/deployer/deployer.sock"
# Location of deployer pid.
deployer_pid="${temp}${run_dir}/${name}/pids/deployer.pid"
# Maximum number of seconds to wait for deployer response.
# Set to 0 to disable timeout.
deployer_timeout=30
@ -38,9 +35,6 @@ runner_username="$(id --user --name)"
# Location of unixsock file used to send requests to the runner server.
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.
runner_cloning_dir="${temp}${tmp_dir}/${name}/repositories"