updated install script with cron jobs
All checks were successful
Tests / Run Go Tests (push) Successful in 1m35s
All checks were successful
Tests / Run Go Tests (push) Successful in 1m35s
This commit is contained in:
6
Cron/autoBackup.sh
Executable file
6
Cron/autoBackup.sh
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
# cron-timing: 05 01 * * 1
|
||||||
|
container_name="arbeitszeitmessung-main-db-1"
|
||||||
|
filename=backup-$(date '+%d%m%Y').sql
|
||||||
|
database_name=__DATABASE__
|
||||||
|
docker exec $container_name pg_dump $database_name > /home/pi/arbeitszeitmessung-backup/$filename
|
||||||
|
echo "created backup file: "$filename
|
||||||
3
Cron/autoHolidays.sh
Executable file
3
Cron/autoHolidays.sh
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
# Calls endpoint to write all public Holidays for the current year inside a database.
|
||||||
|
port=__PORT__
|
||||||
|
curl localhost:$port/auto/feiertage
|
||||||
4
Cron/autoLogout.sh
Executable file
4
Cron/autoLogout.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
# cron-timing: 55 23 * * *
|
||||||
|
# Calls endpoint to log out all users, still logged in for today
|
||||||
|
port=__PORT__
|
||||||
|
curl localhost:$port/auto/logout
|
||||||
@@ -2,11 +2,10 @@ POSTGRES_USER=root # Postgres ADMIN Nutzername
|
|||||||
POSTGRES_PASSWORD=very_secure # Postgres ADMIN Passwort
|
POSTGRES_PASSWORD=very_secure # Postgres ADMIN Passwort
|
||||||
POSTGRES_API_USER=api_nutzer # Postgres API Nutzername (für Arbeitszeitmessung)
|
POSTGRES_API_USER=api_nutzer # Postgres API Nutzername (für Arbeitszeitmessung)
|
||||||
POSTGRES_API_PASS=password # Postgres API Passwort (für Arbeitszeitmessung)
|
POSTGRES_API_PASS=password # Postgres API Passwort (für Arbeitszeitmessung)
|
||||||
POSTGRES_PATH=../DB # Datebank Pfad (relativ zu Docker Ordner oder absoluter pfad mit /...)
|
POSTGRES_PATH=__ROOT__/DB # Datebank Pfad (relativ zu Docker Ordner oder absoluter pfad mit /...)
|
||||||
LOG_PATH=../logs # Pfad für Logdatein
|
LOG_PATH=__ROOT__/logs # Pfad für Audit Logs
|
||||||
POSTGRES_DB=arbeitszeitmessung # Postgres Datenbank Name
|
POSTGRES_DB=arbeitszeitmessung # Postgres Datenbank Name
|
||||||
POSTGRES_PORT=127.0.0.1:5432 # Postgres Port will not be exposed by default. regex:^[0-9]{1,5}$
|
POSTGRES_PORT=127.0.0.1:5432 # Postgres Port will not be exposed by default. regex:^[0-9]{1,5}$
|
||||||
TZ=Europe/Berlin # Zeitzone
|
TZ=Europe/Berlin # Zeitzone
|
||||||
API_TOKEN=dont_access # API Token für ESP Endpoints
|
API_TOKEN=dont_access # API Token für ESP Endpoints
|
||||||
WEB_PORT=8000 # Port from which Arbeitszeitmessung should be accessable regex:^[0-9]{1,5}$
|
WEB_PORT=8000 # Port from which Arbeitszeitmessung should be accessable regex:^[0-9]{1,5}$
|
||||||
TYPST_CONTAINER=arbeitszeitmessung-doc-creator # Name of the pdf compiler container
|
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
FROM ghcr.io/typst/typst:0.14.0
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
COPY ./templates /app/templates
|
|
||||||
COPY ./static /app/static
|
|
||||||
|
|
||||||
ENTRYPOINT ["sh", "-c", "while true; do sleep 3600; done"]
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 17 KiB |
@@ -1,97 +0,0 @@
|
|||||||
#let table-header(..headers) = {
|
|
||||||
table.header(
|
|
||||||
..headers.pos().map(h => strong(h))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#let abrechnung(meta, days) = {
|
|
||||||
set page(paper: "a4", margin: (x:1.5cm, y:2.25cm),
|
|
||||||
footer:[#grid(
|
|
||||||
columns: (3fr, .65fr),
|
|
||||||
align: left + horizon,
|
|
||||||
inset: .5em,
|
|
||||||
[#meta.EmployeeName -- #meta.TimeRange], grid.cell(rowspan: 2)[#image("/static/logo.png")],
|
|
||||||
[Arbeitszeitrechnung maschinell erstellt am #meta.CurrentTimestamp],
|
|
||||||
)
|
|
||||||
])
|
|
||||||
set text(font: "Noto Sans", size:10pt, fill: luma(10%))
|
|
||||||
set table(
|
|
||||||
stroke: 0.5pt + luma(10%),
|
|
||||||
inset: .5em,
|
|
||||||
align: center + horizon,
|
|
||||||
)
|
|
||||||
show text: it => {
|
|
||||||
if it.text == "0min"{
|
|
||||||
text(oklch(70.8%, 0, 0deg))[#it]
|
|
||||||
}else if it.text.starts-with("-"){
|
|
||||||
text(red)[#it]
|
|
||||||
}else{
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[= Abrechnung Arbeitszeit -- #meta.EmployeeName]
|
|
||||||
|
|
||||||
[Zeitraum: #meta.TimeRange]
|
|
||||||
|
|
||||||
table(
|
|
||||||
columns: (1fr, 1fr, 1fr, 1fr, 1fr, 1fr, .875fr, 1.25fr),
|
|
||||||
fill: (x, y) =>
|
|
||||||
if y == 0 { oklch(87%, 0, 0deg) },
|
|
||||||
table-header(
|
|
||||||
[Datum], [Kommen], [Gehen], [Arbeitsart], [Stunden], [Kurzarbeit], [Pause], [Überstunden]
|
|
||||||
),
|
|
||||||
.. for day in days {
|
|
||||||
(
|
|
||||||
[#day.Date],
|
|
||||||
if day.DayParts.len() == 0{
|
|
||||||
table.cell(colspan: 3)[Keine Buchungen]
|
|
||||||
}else if day.DayParts.len() == 1 and not day.DayParts.first().IsWorkDay{
|
|
||||||
table.cell(colspan: 3)[#day.DayParts.first().WorkType]
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
table.cell(colspan: 3, inset: 0em)[
|
|
||||||
#table(
|
|
||||||
columns: (1fr, 1fr, 1fr),
|
|
||||||
.. for Zeit in day.DayParts {
|
|
||||||
(
|
|
||||||
if Zeit.IsWorkDay{
|
|
||||||
(
|
|
||||||
table.cell()[#Zeit.BookingFrom],
|
|
||||||
table.cell()[#Zeit.BookingTo],
|
|
||||||
table.cell()[#Zeit.WorkType],
|
|
||||||
)
|
|
||||||
}else{
|
|
||||||
(table.cell(colspan: 3)[#Zeit.WorkType],)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
]
|
|
||||||
},
|
|
||||||
[#day.Worktime],
|
|
||||||
[#day.Kurzarbeit],
|
|
||||||
[#day.Pausetime],
|
|
||||||
[#day.Overtime],
|
|
||||||
)
|
|
||||||
if day.IsFriday {
|
|
||||||
( table.cell(colspan: 8, fill: oklch(87%, 0, 0deg))[Wochenende], ) // note the trailing comma
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
table(
|
|
||||||
columns: (3fr, 1fr),
|
|
||||||
align: right,
|
|
||||||
inset: (x: .25em, y:.75em),
|
|
||||||
stroke: none,
|
|
||||||
table.hline(start: 0, end: 2, stroke: stroke(dash:"dashed", thickness:.5pt)),
|
|
||||||
[Arbeitszeit :], table.cell(align: left)[#meta.WorkTime],
|
|
||||||
[Kurzarbeit :], table.cell(align: left)[#meta.Kurzarbeit],
|
|
||||||
[Überstunden :], table.cell(align: left)[#meta.Overtime],
|
|
||||||
[Überstunden lfd. :],table.cell(align: left)[#meta.OvertimeTotal],
|
|
||||||
table.hline(start: 0, end: 2),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
82
install.sh
82
install.sh
@@ -4,6 +4,10 @@ set -e
|
|||||||
envFile=Docker/.env
|
envFile=Docker/.env
|
||||||
envExample=Docker/env.example
|
envExample=Docker/env.example
|
||||||
|
|
||||||
|
autoBackupScript=Cron/autoBackup.sh
|
||||||
|
autoHolidaysScript=Cron/autoHolidays.sh
|
||||||
|
autoLogoutScript=Cron/autoLogout.sh
|
||||||
|
|
||||||
echo "Checking Docker installation..."
|
echo "Checking Docker installation..."
|
||||||
if ! command -v docker >/dev/null 2>&1; then
|
if ! command -v docker >/dev/null 2>&1; then
|
||||||
echo "Docker not found. Install Docker? [y/N]"
|
echo "Docker not found. Install Docker? [y/N]"
|
||||||
@@ -18,12 +22,16 @@ else
|
|||||||
echo "Docker is already installed."
|
echo "Docker is already installed."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
echo "Checking Docker Compose..."
|
echo "Checking Docker Compose..."
|
||||||
if ! docker compose version >/dev/null 2>&1; then
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
echo "Docker Compose plugin missing. You may need to update Docker."
|
echo "Docker Compose plugin missing. You may need to update Docker."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
echo "Preparing .env file..."
|
echo "Preparing .env file..."
|
||||||
if [ ! -f $envFile ]; then
|
if [ ! -f $envFile ]; then
|
||||||
if [ -f $envExample ]; then
|
if [ -f $envExample ]; then
|
||||||
@@ -44,6 +52,9 @@ if [ ! -f $envFile ]; then
|
|||||||
raw_val=$(printf "%s" "$rest" | sed 's/ *#.*//')
|
raw_val=$(printf "%s" "$rest" | sed 's/ *#.*//')
|
||||||
default_value=$(printf "%s" "$raw_val" | sed 's/"//g')
|
default_value=$(printf "%s" "$raw_val" | sed 's/"//g')
|
||||||
|
|
||||||
|
# Replace __ROOT__ with script pwd
|
||||||
|
default_value="${default_value/__ROOT__/$(pwd)}"
|
||||||
|
|
||||||
regex=""
|
regex=""
|
||||||
if [[ "$comment" =~ regex:(.*)$ ]]; then
|
if [[ "$comment" =~ regex:(.*)$ ]]; then
|
||||||
regex="${BASH_REMATCH[1]}"
|
regex="${BASH_REMATCH[1]}"
|
||||||
@@ -96,13 +107,80 @@ else
|
|||||||
echo "Using existing .env. (found at $envFile)"
|
echo "Using existing .env. (found at $envFile)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
LOG_PATH=$(grep -E '^LOG_PATH=' $envFile | cut -d= -f2)
|
||||||
|
if [ -z "$LOG_PATH" ]; then
|
||||||
|
echo "LOG_PATH not found in .env using default $(pwd)/logs"
|
||||||
|
LOG_PATH=$(pwd)/logs
|
||||||
|
else
|
||||||
|
LOG_PATH=Docker/$LOG_PATH
|
||||||
|
fi
|
||||||
|
mkdir -p $LOG_PATH
|
||||||
|
echo "Created logs folder at $LOG_PATH"
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
echo -e "\n\n"
|
||||||
echo "Start containers with docker compose up -d? [y/N]"
|
echo "Start containers with docker compose up -d? [y/N]"
|
||||||
read -r start_containers
|
read -r start_containersmkdi
|
||||||
if [[ "$start_containers" =~ ^[Yy]$ ]]; then
|
if [[ "$start_containers" =~ ^[Yy]$ ]]; then
|
||||||
|
|
||||||
cd Docker
|
cd Docker
|
||||||
mkdir ../logs
|
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
echo "Containers started."
|
echo "Containers started."
|
||||||
else
|
else
|
||||||
echo "You can start them manually with: docker compose up -d"
|
echo "You can start them manually with: docker compose up -d"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
echo -e "\n\n"
|
||||||
|
echo "Setup Crontab for automatic logout, backup and holiday creation? [y/N]"
|
||||||
|
read -r setup_cron
|
||||||
|
if [[ "$setup_cron" =~ ^[Yy]$ ]]; then
|
||||||
|
WEB_PORT=$(grep -E '^WEB_PORT=' $envFile | cut -d= -f2)
|
||||||
|
if [ -z "$WEB_PORT" ]; then
|
||||||
|
echo "WEB_PORT not found in .env using default 8000"
|
||||||
|
WEB_PORT=8000
|
||||||
|
fi
|
||||||
|
|
||||||
|
POSTGRES_DB=$(grep -E '^POSTGRES_DB=' $envFile | cut -d= -f2)
|
||||||
|
if [ -z "$POSTGRES_DB" ]; then
|
||||||
|
echo "arbeitszeitmessung not found in .env using default arbeitszeitmessung"
|
||||||
|
POSTGRES_DB="arbeitszeitmessung"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sed -i "s/__PORT__/$WEB_PORT/" $autoHolidaysScript
|
||||||
|
sed -i "s/__PORT__/$WEB_PORT/" $autoLogoutScript
|
||||||
|
sed -i "s/__DATABASE__/$POSTGRES_DB/" $autoBackupScript
|
||||||
|
|
||||||
|
chmod +x $autoBackupScript $autoHolidaysScript $autoLogoutScript
|
||||||
|
|
||||||
|
# echo "Scripts build with PORT=$WEB_PORT and DATABSE=$POSTGRES_DB!"
|
||||||
|
echo "Adding rules to crontab."
|
||||||
|
|
||||||
|
cron_commands=$(mktemp /tmp/arbeitszeitmessung-cron.XXX)
|
||||||
|
|
||||||
|
for file in Cron/*; do
|
||||||
|
cron_timing=$(grep -E '^# cron-timing:' "$file" | sed 's/^# cron-timing:[[:space:]]*//')
|
||||||
|
|
||||||
|
if [ -z "$cron_timing" ]; then
|
||||||
|
echo "No cron-timing found in $file, so it's not added to crontab."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
( crontab -l ; echo "$cron_timing $(pwd)/$file" )| awk '!x[$0]++' | crontab -
|
||||||
|
echo "Added entry to crontab: $cron_timing $(pwd)/$file."
|
||||||
|
done
|
||||||
|
|
||||||
|
if systemctl is-active --quiet cron.service ; then
|
||||||
|
echo "cron.service is running. Everything should be fine now."
|
||||||
|
else
|
||||||
|
echo "cron.service is not running. Please start and enable cron.service."
|
||||||
|
echo "For how to start a service, see: https://wiki.ubuntuusers.de/systemd/systemctl UNITNAME will be cron.service"
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "Please setup cron manually by executing crontab -e and adding all files from inside the Cron directory!"
|
||||||
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user