[dev] First commit

This commit is contained in:
samuel 2023-02-18 13:49:35 +01:00
parent 0204c48240
commit c2cac454b8
8 changed files with 272 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/*.conf

45
Makefile Normal file
View File

@ -0,0 +1,45 @@
NAME = netoik-cicd
VERSION = $(shell [ -d ".git" ] && git describe | sed "s/-/./g")
BRANCH = $(shell [ -d ".git" ] && git branch --show-current)
RPM_SOURCEDIR = $(shell rpm --eval "%{_sourcedir}")
SYSCONFDIR = $(shell rpm --eval "%{_sysconfdir}")
UNITDIR = $(shell rpm --eval "%{_unitdir}")
BINDIR = $(shell rpm --eval "%{_bindir}")
TMPDIR = $(shell rpm --eval "%{_tmppath}")
.PHONY: build
build: bin/$(NAME)-deployer bin/$(NAME)-newtag
bin/$(NAME)-deployer: src/deployer.sh
mkdir --parents bin
cp "$<" "$@"
bin/$(NAME)-newtag: src/newtag.sh
mkdir --parents bin
cp "$<" "$@"
.PHONY: name
name:
@echo "$(NAME)"
.PHONY: version
version:
@echo "$(VERSION)"
$(RPM_SOURCEDIR)/$(NAME)-%.tar.gz: *
git archive --format=tar.gz --output="$@" --prefix="$(NAME)-$(VERSION)/" --worktree-attributes --verbose "$(BRANCH)"
.PHONY: tarball
tarball: $(RPM_SOURCEDIR)/$(NAME)-$(VERSION).tar.gz
.PHONY: install
install:
install -D --no-target-directory deployer.conf.sample "$(DESTDIR)$(SYSCONFDIR)/$(NAME)/deployer.conf"
install -D --target-directory="$(DESTDIR)$(SYSCONFDIR)/$(NAME)" deployer.conf.sample
install -D --target-directory="$(DESTDIR)$(SYSCONFDIR)/profile.d" profile/$(NAME)-git.sh
install -D --target-directory="$(DESTDIR)$(UNITDIR)" systemd/$(NAME)-deployer.service
install -D --target-directory="$(DESTDIR)$(BINDIR)" bin/$(NAME)-*
install --directory "$(DESTDIR)$(TMPDIR)/$(NAME)/deployer/request"
install --directory "$(DESTDIR)$(TMPDIR)/$(NAME)/deployer/response"

7
deployer.conf.sample Normal file
View File

@ -0,0 +1,7 @@
REQUEST_DIR="/var/tmp/netoik-cicd/deployer/request"
RESPONSE_DIR="/var/tmp/netoik-cicd/deployer/response"
REPOS_DIR="/var/gogs/repositories/samuel"
RPMS_DIR="/home/git/rpmbuild/RPMS"
RPM_ARCH="x86_64"
RPM_RELEASE="1"
RPM_DIST="el8_5"

60
netoik-cicd.spec Normal file
View File

@ -0,0 +1,60 @@
%define debug_package %{nil}
Name: netoik-cicd
Version: %(make version)
Release: 1%{?dist}
Summary: Netoik Continuous Deployment tool
License: GPLv3
Source0: %{name}-%{version}.tar.gz
BuildArch: x86_64
BuildRequires: make
Requires: bash,rpm-build,rpmdevtools,inotify-tools
%description
Netoik Continuous Deployment tool
%prep
%autosetup -v
%build
%make_build
%install
%make_install
%pre
# Build rpm setuptree if not already done.
runuser --login git --command "rpmdev-setuptree"
%post
# Reload systemctl daemon and (re)start service.
systemctl daemon-reload
systemctl restart %{name}-deployer.service
systemctl enable %{name}-deployer.service
%preun
# Stop service only if uninstalling.
if [ $1 -eq 0 ]; then
systemctl disable --now %{name}-deployer.service
fi
%postun
# Reload systemctl daemon only if uninstalling.
if [ $1 -eq 0 ]; then
systemctl daemon-reload
fi
%files
%attr(755, root, root) %dir %{_sysconfdir}/%{name}
%attr(644, root, root) %config(noreplace) %{_sysconfdir}/%{name}/deployer.conf
%attr(644, root, root) %{_sysconfdir}/%{name}/deployer.conf.sample
%attr(644, root, root) %{_sysconfdir}/profile.d/%{name}-git.sh
%attr(644, root, root) %{_unitdir}/%{name}-deployer.service
%attr(755, root, root) %{_bindir}/%{name}-deployer
%attr(755, root, root) %{_bindir}/%{name}-newtag
%attr(755, root, root) %dir %{_tmppath}/%{name}
%attr(755, root, root) %dir %{_tmppath}/%{name}/deployer
%attr(775, root, git) %dir %{_tmppath}/%{name}/deployer/request
%attr(775, root, root) %dir %{_tmppath}/%{name}/deployer/response

View File

@ -0,0 +1,6 @@
source "/etc/netoik-cicd/deployer.conf"
if [ "$(id --user --name)" = "git" ]; then
NETOIK_CICD_DEPLOYER_RESPONSE_DIR="$REQUEST_DIR"
NETOIK_CICD_DEPLOYER_REQUEST_DIR="$RESPONSE_DIR"
fi

82
src/deployer.sh Executable file
View File

@ -0,0 +1,82 @@
#!/usr/bin/bash
#
# This binary is made to be run by root, it expects a request from git server, deploy (install or update)
# the related tpm package and send a response to git server.
# Exit immediately if any command fails.
set -e
# Exit with the last non-zero fail code.
set -o pipefail
log() {
echo -e "[DEPLOYER] $(date --rfc-3339=s) - $1"
}
fail () {
if [ $# -eq 1 ]; then
echo "$1" 1>&2
fi
exit 1
}
# Load config file.
[ $# -eq 1 ] || fail "Expecting 1 argument: config file."
source "$1"
# Check variables in config file.
[ -d "$REQUEST_DIR" ] || fail "Directory does not exist REQUEST_DIR=$REQUEST_DIR in config file $1."
[ -d "$RESPONSE_DIR" ] || fail "Directory does not exist RESPONSE_DIR=$RESPONSE_DIR in config file $1."
[ -d "$REPOS_DIR" ] || fail "Directory does not exist REPOS_DIR=$REPOS_DIR in config file $1."
[ -d "$RPMS_DIR" ] || fail "Directory does not exist RPMS_DIR=$RPMS_DIR in config file $1."
[ -z "$RPM_ARCH" ] && fail "Empty value RPM_ARCH in config file $1."
[ -z "$RPM_RELEASE" ] && fail "Empty value RPM_RELEASE in config file $1."
[ -z "$RPM_DIST" ] && fail "Empty value RPM_DIST in config file $1."
# First remove eventual old existing tmp files.
find "$REQUEST_DIR" -type f -delete
find "$RESPONSE_DIR" -type f -delete
# Loop on every created request.
while read _ _ repo_name; do
log "New request detected for repo $repo_name."
# Read request file and remove it immediately.
repo_version=$(cat "$REQUEST_DIR/$repo_name")
rm "$REQUEST_DIR/$repo_name"
# Check repo version not empty.
if [ -z "$repo_version" ]; then
echo -e "Content of $REQUEST_DIR/$repo_name must contain repo version but is empty\n1" > "$RESPONSE_DIR/$repo_name"
continue
fi
# Check if repo does exist.
if [ ! -d "$REPOS_DIR/$repo_name.git" ]; then
echo -e "Repository $REPOS_DIR/$repo_name.git does not exist!\n1" > "$RESPONSE_DIR/$repo_name"
continue
fi
# Check if repo package is already exisitng.
rpm_path="$RPMS_DIR/$RPM_ARCH/$repo_name-$repo_version-$RPM_RELEASE.$RPM_DIST.$RPM_ARCH.rpm"
log "Using rpm package at $rpm_path."
if [ ! -f "$rpm_path" ]; then
echo -e "RPM package $rpm_path does not exist!\n1" > "$RESPONSE_DIR/$repo_name"
continue
fi
# Upgrade package if already installed.
if rpm -q "$repo_name" 1>/dev/null 2>/dev/null; then
log "Upgrade package $repo_name to v$repo_version"
output=$(rpm --upgrade --verbose --hash "$rpm_path" 2>&1) || exit_code=$?
echo -e "$output\n$exit_code" > "$RESPONSE_DIR/$repo_name"
continue
fi
# Install package if not already installed.
log "Install package $repo_name v$repo_version."
output=$(rpm --install --verbose --hash "$rpm_path" 2>&1) || exit_code=$?
echo -e "$output\n$exit_code" > "$RESPONSE_DIR/$repo_name"
done < <(inotifywait --monitor --event create "$REQUEST_DIR")

59
src/newtag.sh Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/bash
#
# This binary is made to be run by git server, it builds a rpm package and send a request to root in order
# to deploy the package on the server.
# Exit immediately if any command fails.
set -e
# Exit with the last non-zero exit code.
set -o pipefail
# Name of current gitops pipeline.
pipeline="NEWTAG"
log () {
echo -e "[$pipeline] $(date --rfc-3339=s) - $1"
}
fail () {
if [ $# -eq 1 ]; then
echo "$1" 1>&2
fi
exit 1
}
# Retrieve necessary details about package.
pkg_name=$(make name)
[ -z $pkg_name ] && fail "Empty result for target 'make name'."
pkg_version=$(make version)
[ -z $pkg_version ] && fail "Empty result for target 'make version'."
# Make tarball with source code.
log "Make source tarball for $pkg_name v$pkg_version."
make tarball
# Build rpm package.
log "Build rpm package."
rpmbuild -bb "$pkg_name.spec"
# Cleanup last response.
[ -f "$NETOIK_CICD_DEPLOYER_RESPONSE_DIR/$pkg_name" ] || touch "$NETOIK_CICD_DEPLOYER_RESPONSE_DIR/$pkg_name"
sed -i "d" "$NETOIK_CICD_DEPLOYER_RESPONSE_DIR/$pkg_name"
# Send request to deployer with a little delay in background.
log "Install or update rpm package."
echo "$pkg_version" > "$NETOIK_CICD_DEPLOYER_REQUEST_DIR/$pkg_name"
# Wait for response from deployer.
inotifywait --timeout 600 --event modify "$NETOIK_CICD_DEPLOYER_RESPONSE_DIR/$pkg_name" >/dev/null
# Get content of the response.
while read line; do
[ -z "$previous" ] || echo "$previous"
previous="$line"
done < "$NETOIK_CICD_DEPLOYER_RESPONSE_DIR/$pkg_name"
# Exit now with exit code found in response.
exit_code=$(printf "%d\n" "$previous")
exit $exit_code

View File

@ -0,0 +1,12 @@
[Unit]
Description=Netoik automatic deployer
After=network.target
[Service]
User=root
Group=root
ExecStart=/usr/bin/netoik-cicd-deployer /etc/netoik-cicd/deployer.conf
Restart=always
[Install]
WantedBy=multi-user.target