20 Jahre Axels Cron-wrapper

Donnerstag, 10. März, 2022

Ich habe grad in die History geschaut: 20 Jahre (!!!) nutze ich schon den meinigen Cronwrapper auf Linux/ Unix-Systemen.

Und ich bin noch immer am Aktualisieren und Verfeinern von dessen Skripten oder Dokumentation. Auch weil ich dessen Idee so mag. Alles ist OpenSource - GNU GPL 3.0.

Das Repository [1] enthält

  • cronwrapper.sh - ein Wrapper - wenn man Cronjobs hat, dann stellt man den einfach mal vorn dran
  • cronstatus.sh - das Skript zeigt den Status aller auf dem System befindlichen Cronjobs
  • inc_cronfunctions.sh - ein Script, dass in Bash geschriebene Cronjobs gesourct werden kann, um div. nützliche Funktionen zu nutzen.
  • Dokumentation im Markdown Format zur Installation und allen Features.

Der einfachste Einstieg ist, den Wrapper cronwrapper.sh zu verwenden: mit allen bestehenden Cronjobs, egal welcher Programmiersprache jene sind, lässt sich dieser ergänzen. Und man erhält out-of-the-box kleine nette Features.

  • STDOUT und STDERR werden eingefangen und in ein normiertes Logfile geschrieben (ohne jenes explizit angeben zu müssen)
  • Das Logfile wird normiert und ist mit grep nach Output oder Metadaten durchsuchbar

Alle Cronjobs, die den Wrapper verwenden, werden mit dem Skript cronstatus.sh aufgelistet und bewertet:

  • weisen sie exitcode 0 auf?
  • sind sie in der vorgegebenen Frist gestartet worden?

Diese Ausgabe kann man auch in einem Monitoring Script für die Überwachng aller Cronjobs auf seinen Systemen einbinden.

Und als Goodie gibt es ein Include file inc_cronfunctions.sh,welches hilfreich sein kann, sofern die Cronjobs in Bash geschrieben sind: eine Reihe nützlicher Funktionen werden darin bereitgestellt, um das Schreiben von “sicheren” und lesbaren Conjobs zu erleichtern.

weiterführende Links: (en)

  1. Github: cronwrapper
  2. Docs auf axel-hahn.de

Manjaro update - pacman (6.0.0-1) breaks dependency ‘pacman<5.3′ required by package-query

Mittwoch, 14. Juli, 2021

Der grafische Software-Manager wollte pacman nicht aktualisieren … und wegen jenes Konflikts alle möglichen Pakete auch nicht.

Dann aktualisere ich halt “pamac upgrade pacman” von Hand und schaue, was passiert.

axel@mypc~> pamac upgrade pacman
(...)
   vulkan-intel                      21.1.4-1 
(21.1.2-1)                  extra      2.3 MB
   vulkan-radeon                     21.1.4-1 
(21.1.2-1)                  extra      1.7 MB
   wireless-regdb                    2021.04.21-1 
(2020.11.20-1)              core       10.3 kB
Wird installiert (10):
   syndication 5.84.0-1                                              
extra 1.0 MB
   electron12 12.0.14-1                                             
community 50.7 MB
   layer-shell-qt 5.22.3-1                                              
extra 23.1 kB
   ksystemstats 5.22.3-1                                              
extra 162.9 kB
   pahole 1.21-1                                                extra 
262.9 kB
   nodejs-nopt 5.0.0-2                                               
community 13.4 kB
   libpamac                          11.0.1-3 (Ersetzt: 
pamac-common)     extra      818.4 kB
   kio-fuse 5.0.1-1                                               extra 
70.3 kB
   fakeroot 1.25.3-2                                              core
   bison 3.7.6-1                                               core
Zu erstellen (2):
   package-query                     1.12-1 (1.10-1)                    AUR
   zoom                              5.7.1-1 (5.6.7-1)                   AUR
Wird entfernt (1):
   pamac-common                      10.0.6-2 (Konflikt mit: libpamac)

Download-Größe gesamt: 2.3 GB
Gesamtgröße installiert: 269.3 MB
Gesamtgröße entfernt: 9.5 MB

Build-Dateien bearbeiten : [e]
Transaktion durchführen ? [e/j/N] j

Warning: installing pacman (6.0.0-1) breaks dependency 'pacman<5.3' 
required by package-query
Add package-query to remove
Fehler: Failed to prepare transaction:
could not satisfy dependencies:
- removing package-query breaks dependency 'package-query>=1.9' required 
by yaourt,
- if possible, remove yaourt and retry

Leider nein.

Beim Lesen von “installing pacman (6.0.0-1) breaks dependency ‘pacman<5.3' " dachte ich schon fast: oh, ein Henne-Ei-Problem?

Die Lösung:

Ich bin einfach dem letzten Rat in der Ausgabe gefolgt und habe yaourt entfernt.

axel@mypc~ [1]> pamac remove yaourt
Vorbereitung...
Abhängigkeiten werden überprüft...

Wird entfernt (1):
   yaourt  1.9-2

Gesamtgröße entfernt: 849.9 kB

Transaktion durchführen ? [j/N] j
Removing yaourt (1.9-2)... [1/1]
Vorgang erfolgreich abgeschlossen.

Und nun nochmal der Versuch eines Updates …

axel@mypc~> pamac upgrade pacman
...

… hurra, nun klappt es!

weiterführende Links:

  1. manjaro.org (en)

Linux: Kommando unter einem anderen User starten

Donnerstag, 8. Juli, 2021

Um die Frage des Titels zu beantworten, kommt man schnell auf ein … als root startet man

su - [USERNAME] -c [KOMMANDO]

Und wenn der User, unter dem ich das Kommando starten will, keine Shell hat? Tja, dann kommt eine Fehlermeldung der Art

This account is currently not available.

Wirklich sehr lange habe ich mir beholfen, dass ich dem User in der /etc/passwd eine Shell gegeben habe - das /usr/bin/nologin oder /bin/false wurde durch ein /bin/bash o.ä. ersetzt. Jaja, ganz generell fördern man [Kommando] oder [Kommando] –help hilfreiche Dinge zutage. Aber das ist völlig unnötig. Der “Trick” ist, dass man bei su mit dem Parameter -s eine Shell vorgibt, z.B. die /bin/sh.

su - [USERNAME] -c [KOMMANDO] -s /bin/bash

Um die Parameter wegzulassen und optisch zu vereinfachen, kann man auch eine kleine Funktion in sein Skript setzen:

# run a command as another posix user (even if it does not have a shell)
#
# example:
# runas www-data "/some/where/mysript.sh"
#
# param  string  username
# param  string  command to execute. Needs to be quoted.
# param  string  optional: shell (default: /bin/sh)
function runas(){
    local _user=$1
    local _cmd=$2
    local _shell=$3
    test -z "$_shell" && _shell=/bin/sh

    su $_user -s $_shell -c "$_cmd"
}

Dann kann man im Skript etwas kürzer schreiben:

runas [USERNAME] [KOMMANDO]

weiterführende Links:

  1. man7.org: Manpage für su

Mysql Replikation neu aufsetzen als Bash Skript

Donnerstag, 24. Juni, 2021

Wenn eine bestehende Mysql Replikation nicht mehr funktioniert, so half mir etliche Male im Laufe der Berufszeit als Webmaster beim Schweizer Radio DRS / Sysadmin Daseins an der Uni Bern ein top-down-Skript weiter. Wenn gerade Stress ist und man in der Situation nicht erst alle Kommandos zur Wiederinbetriebnahme des Slave nachschlagen mag, dann ist ist man froh, wenn man ein Skript dafür parat liegen hat.

reinit_mysql_replication.sh

Es gibt keine Parameter.

Installation:

Man benötigt einen Mysql Client. Ich hatte daher die Skripte am Mysql-Slave unterhalb /root zu liegen. Daher ist die Verbindung zum Slave ohne Passwort (wird aus der /root/.my.cnf gelesen).
Es wird auch vom eigenen Rechner aus funktionieren, der die Mysql-Ports von Master und Slave erreichen kann. Es ist nur “einen Tick” langsamer (sprich: bei vielen und/ oder grossen Datenbanken > 1 GB Gesamtgrösse nicht zu empfehlen).

Konfiguration:

Die *dist Datei ist umzukopieren und die Hostnamen und Root-Passwörter für Master + Slave sind zu setzen.

Start:

Das Skript reinit_mysql_replication.sh führt der Reihe nach folgende Aktionen aus: es …

  • zeigt aktuellen Slave Status
  • wartet dann auf ein RETURN, bevor die Replikation neu aufgesetzt wird

Aktionen zum Neuaufsetzen der Replikation: das Skript …

  • liest die Position des Binlog am Master (per SQL “SHOW MASTER STATUS G;”)
  • sperrt den Master für Schreibaktionen (”FLUSH TABLES WITH READ LOCK;”)
  • holt aktuelle Datenbank-Dumps vom Master (mysqldump –all-databases –lock-all-tables …)
  • hebt Schreibsperre am Master auf (”UNLOCK TABLES;”)
  • stoppt den Slave (”STOP SLAVE G;”)
  • importiert Dumps des Master auf dem Slave (cat $dumpMaster | mysql $paramdbSlave)
  • setzt am Slave binfile und Position (”CHANGE MASTER TO MASTER_LOG_FILE = …” ; “CHANGE MASTER TO MASTER_LOG_POS = …”)
  • startet den Slave (”START SLAVE G;”)

weiterführende Links:

  1. git-repo.iml.unibe.ch: iml-open-source/mysql-slave-scripts

Manjaro: ttyrec installieren

Freitag, 30. April, 2021

Ttyrec ist ein Open Source Werkzeug, mit dem man auf der Konsole alle Eingaben “mitschneiden” kann. Damit lassen sich Demos zur Handhabe von Installationen anfertigen oder ASCII Animationen aufzeichnen. Zur Wiedergabe gibt es ein ttyplay - oder für Webseiten auch einen Video Player, um eigene Online Dokumentationen zu ergänzen.

BTW: von ttyrec gibt es noch Portierungen in anderen Programmiersprachen, wie Python, Go, …

Aber zurück zu Manjaro. Es gibt mehrere AUR Pakete, um ttyrec auf Manjaro Linux builden zu lassen. Der Compilervorgang schlug bei mir aber jeweils fehl, weil ein man Verzeichnis bereits existiert:

Fehler: Vorgang konnte nicht abgeschlossen werden:
In Konflikt stehende Dateien:
- ovh-ttyrec-git: /usr/local/share/man existiert bereits im Dateisystem (gehört zu filesystem)

Die Lösung klingt etwas zu einfach … aber immerhin funktioniert es: man schaut einmal, was in diesem Verzeichnis ist und benennt es temporär um, um es dann anschliessend nach der Complilierung wiederherzustellen.

Gesagt - getan … und mit einem Underscore umbenannt:

axel@tux > sudo -i
root@tux# ls -l /usr/local/share/man
lrwxrwxrwx 1 root root 6 20. Jan 17:33 /usr/local/share/man -> ../man
root@tux# mv /usr/local/share/man /usr/local/share/man_

Ja, dann installieren / compilieren wir das nochmal … und starten pamac install ovh-ttyrec-git

root@tux# pamac install ovh-ttyrec-git
Warnung: ovh-ttyrec-git ist nur im AUR verfügbar
Vorbereitung...
Klone ovh-ttyrec-git Build-Dateien...
Running as unit: run-u161595.service
Finished with result: success
Main processes terminated with: code=exited/status=0
Service runtime: 309ms
Running as unit: run-u161597.service
Finished with result: success
Main processes terminated with: code=exited/status=0
Service runtime: 9ms
Überprüfe ovh-ttyrec-git Abhängigkeiten...
Abhängigkeiten werden aufgelöst...
Interne Konflikte werden überprüft...

Zu erstellen (1):
   ovh-ttyrec-git  v1.1.6.3.r0.gb8bdaab-1    AUR

Build-Dateien bearbeiten : [e]
Transaktion durchführen ? [e/j/N] j

Erstelle ovh-ttyrec-git...
Running as unit: run-u161604.service
Press ^] three times within 1s to disconnect TTY.
==> Making package: ovh-ttyrec-git v1.1.6.7.r1.ga13ca74-1 (Di 13 Apr 2021 17:24:30)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
   -> Updating ovh-ttyrec git repo...
Fetching origin
==> Validating source files with sha256sums...
     ovh-ttyrec ... Skipped
==> Removing existing $srcdir/ directory...
==> Extracting sources...
   -> Creating working copy of ovh-ttyrec git repo...
Cloning into 'ovh-ttyrec'...
done.
Switched to a new branch 'makepkg'
==> Starting prepare()...
Looking for compiler... gcc
Checking if compiler can create executables... yes
Checking how to get pthread support... -pthread
Looking for libzstd... yes
Checking whether we can link zstd statically... no
Looking for isastream()... no
Looking for cfmakeraw()... yes
Looking for getpt()... yes
Looking for posix_openpt()... yes
Looking for grantpt()... yes
Looking for openpty()... yes (pty.h, libutil)
Checking for supported compiler options...
... OK -Wall
... OK -Wextra
... OK -pedantic
... OK -Wno-unused-result
... OK -Wbad-function-cast
... OK -Wmissing-declarations
... OK -Wmissing-prototypes
... OK -Wnested-externs
... OK -Wold-style-definition
... OK -Wstrict-prototypes
... OK -Wpointer-sign
... OK -Wmissing-parameter-type
... OK -Wold-style-declaration
... OK -Wl,--as-needed
... OK -Wno-unused-command-line-argument

You may run make now
==> Starting pkgver()...
==> Starting build()...

(...)

Vorgang erfolgreich abgeschlossen.

Das “erfolgreich abgeschlossen” klingt ja schonmal gut.

Jetzt muss ich nur noch das man Verzeichnis wiederherstellen. Durch das Complilieren entstand:

root@tux# ls -l /usr/local/share/man/man1/
insgesamt 12
-rw-r--r-- 1 root root  641 13. Apr 17:24 ttyplay.1.gz
-rw-r--r-- 1 root root 1751 13. Apr 17:24 ttyrec.1.gz
-rw-r--r-- 1 root root  308 13. Apr 17:24 ttytime.1.gz

In /usr/local/share/ sieht es nun so aus:

root@tux# ls -l
insgesamt 4
lrwxrwxrwx 1 root root    6 20. Jan 17:33 man -> ../man
drwxr-xr-x 3 root root 4096 13. Apr 17:24 man_ttyrec

Hier muss man nur das man_ttyrec/man1 in das man hineinschieben.

root@tux# mv man_ttyrec/man1/ ../man

Und das war’s dann.
Hurra, das Paket ist erfolgreich installiert… und ttyrec lässt sich starten.

weiterführende Links:

  1. Wikipedia: ttyrec (en)
  2. Arch-Linux AUR: Suche nach ttyrec (en)