Website-Suche

Systemweite Vereinheitlichung von benutzerdefinierten Skripten mit rpm auf Red Hat/CentOS


Objektiv

Unser Ziel ist es, RPM-Pakete mit benutzerdefinierten Inhalten zu erstellen und Skripte über eine beliebige Anzahl von Systemen hinweg zu vereinheitlichen, einschließlich Versionierung, Bereitstellung und Dedeployment.

Betriebssystem- und Softwareversionen

  • Betriebssystem: Red Hat Enterprise Linux 7.5
  • Software: rpm-build 4.11.3+

Anforderungen

Privilegierter Zugriff auf das System für die Installation, normaler Zugriff für den Build.

Schwierigkeit

MITTEL

Konventionen

  • # – erfordert, dass bestimmte Linux-Befehle mit Root-Rechten ausgeführt werden, entweder direkt als Root-Benutzer oder mit dem Befehl sudo
  • $ – gegebene Linux-Befehle, die als normaler, nicht privilegierter Benutzer ausgeführt werden sollen

Einleitung

Eines der Kernmerkmale eines jeden Linux-Systems ist, dass es für die Automatisierung entwickelt wurde. Wenn eine Aufgabe mehr als einmal ausgeführt werden muss – auch wenn sich ein Teil davon beim nächsten Ausführen ändert – stehen einem Systemadministrator unzählige Tools zur Verfügung, um sie zu automatisieren, von einfachen Shell-Skripten, die bei Bedarf von Hand ausgeführt werden (wodurch Tippfehler vermieden oder nur einige Tastaturklicks gespeichert werden) bis hin zu komplexen Skriptsystemen, bei denen Aufgaben von cron ausgeführt werden Zu einem bestimmten Zeitpunkt, interagieren miteinander, arbeiten mit dem Ergebnis eines anderen Skripts, können möglicherweise von einem zentralen Managementsystem gesteuert werden usw.

Während diese Freiheit und dieses reichhaltige Toolset in der Tat zur Produktivität beitragen, gibt es einen Haken: Als Systemadministrator schreiben Sie ein nützliches Skript auf einem System, das sich auf einem anderen System als nützlich erweist, also kopieren Sie das Skript rüber. Auf einem dritten System ist das Skript auch nützlich, aber mit geringfügigen Änderungen – vielleicht eine neue Funktion, die nur in diesem System nützlich ist und mit einem neuen Parameter erreichbar ist. Unter Berücksichtigung der Generalisierung erweitern Sie das Skript, um die neue Funktion bereitzustellen und die Aufgabe zu erfüllen, für die es geschrieben wurde. Jetzt haben Sie zwei Versionen des Skripts, die erste befindet sich auf den ersten beiden Systemen, die zweite auf dem dritten System.

Sie haben 1024 Computer im Datencenter ausgeführt, und 256 von ihnen benötigen einige der Funktionen, die von diesem Skript bereitgestellt werden. Mit der Zeit werden Sie 64 Versionen des Skripts haben, wobei jede Version ihre Aufgabe erfüllt. Bei der nächsten Systembereitstellung benötigen Sie eine Funktion, an die Sie sich erinnern, dass Sie sie in einer bestimmten Version codiert haben, aber welche? Und auf welchen Systemen befinden sie sich?

Auf RPM-basierten Systemen, wie z. B. Red Hat-Varianten, kann ein Systemadministrator den Paketmanager nutzen, um Ordnung in den benutzerdefinierten Inhalt zu bringen, einschließlich einfacher Shell-Skripte, die möglicherweise nur die Tools bereitstellen, die der Administrator der Einfachheit halber geschrieben hat.

In diesem Tutorial erstellen wir ein benutzerdefiniertes RPM für Red Hat Enterprise Linux 7.5 mit zwei Bash-Skripten, parselogs.sh und pullnews.sh, um eine Möglichkeit zu bieten, dass alle Systeme die neueste Version dieser Skripte im Verzeichnis /usr/local/sbin und somit auf dem Pfad jedes Benutzers haben, der sich am System anmeldet.

Distributionen, Haupt- und Nebenversionen

Im Allgemeinen sollten die Neben- und Hauptversion des Buildcomputers mit den Systemen identisch sein, die das Paket bereitstellen soll, sowie mit der Distribution, um die Kompatibilität sicherzustellen. Wenn es verschiedene Versionen einer bestimmten Distribution oder sogar verschiedene Distributionen mit vielen Versionen in Ihrer Umgebung gibt (oh, Freude!), sollten Sie für jede Version Build-Maschinen einrichten. Um die Arbeit abzukürzen, können Sie einfach eine Build-Umgebung für jede Distribution und jede Hauptversion einrichten und sie in der niedrigsten Nebenversion verwenden, die in Ihrer Umgebung für die jeweilige Hauptversion vorhanden ist. Natürlich müssen es sich nicht um physische Computer handeln, sondern müssen nur zur Buildzeit ausgeführt werden, sodass Sie virtuelle Computer oder Container verwenden können.

In diesem Tutorial ist unsere Arbeit viel einfacher, wir stellen nur zwei Skripte bereit, die überhaupt keine Abhängigkeiten haben (außer bash), also werden wir noarch-Pakete erstellen, die für "not architecture dependent" stehen, wir werden auch nicht die Distribution angeben, für die das Paket erstellt wurde. Auf diese Weise können wir sie auf jeder Distribution, die rpm verwendet, und auf jede Version installieren und aktualisieren – wir müssen nur sicherstellen, dass das rpm-build-Paket der Build-Maschine auf der ältesten Version in der Umgebung ist.

Einrichten der Gebäudeumgebung

Um benutzerdefinierte RPM-Pakete zu erstellen, müssen wir das rpm-build-Paket installieren:

yum install rpm-build

Von nun an verwenden wir den Root-Benutzer nicht, und das aus gutem Grund. Das Erstellen von Paketen erfordert keine Root-Rechte, und Sie möchten Ihre Erstellungsmaschine nicht beschädigen.

Erstellen der ersten Version des Pakets

Lassen Sie uns die Verzeichnisstruktur erstellen, die für die Erstellung benötigt wird:

mkdir -p rpmbuild/SPECS

Unser Paket heißt admin-scripts, Version 1.0. Wir erstellen eine Spezifikationsdatei, die die Metadaten, Inhalte und Aufgaben angibt, die vom Paket ausgeführt werden. Dies ist eine einfache Textdatei, die wir mit unserem bevorzugten Texteditor erstellen können, z. B. vi. Das zuvor installierte rpmbuild-Paket füllt Ihre leere Spezifikationsdatei mit Vorlagendaten, wenn Sie vi verwenden, um eine leere Datei zu erstellen, aber für dieses Tutorial betrachten Sie die folgende Spezifikation namens admin-scripts-1.0.spec:

Name:           admin-scripts
Version:        1
Release:        0
Summary:        FooBar Inc. IT dept. admin scripts
Packager:       John Doe 
Group:          Application/Other
License:        GPL
URL:            www.foobar.com/admin-scripts
Source0:        %{name}-%{version}.tar.gz
BuildArch:      noarch

%description
Package installing latest version the admin scripts used by the IT dept.

%prep
%setup -q


%build

%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr/local/sbin
cp scripts/* $RPM_BUILD_ROOT/usr/local/sbin/

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%dir /usr/local/sbin
/usr/local/sbin/parselogs.sh
/usr/local/sbin/pullnews.sh

%doc

%changelog
* Wed Aug 1 2018 John Doe 
- release 1.0 - initial release

Platzieren Sie die Spezifikationsdatei in dem Verzeichnis rpmbuild/SPEC, das wir zuvor erstellt haben.

Wir benötigen die Quellen, auf die im Specfile verwiesen wird – in diesem Fall die beiden Shell-Skripte. Erstellen wir das Verzeichnis für die Quellen (aufgerufen als der Paketname, der an die Hauptversion angehängt wird):

mkdir -p rpmbuild/SOURCES/admin-scripts-1/scripts

Und kopieren/verschieben Sie die Skripte hinein:

ls rpmbuild/SOURCES/admin-scripts-1/scripts/
parselogs.sh  pullnews.sh

Da es in diesem Tutorial nicht um Shell-Scripting geht, ist der Inhalt dieser Skripte irrelevant. Da wir eine neue Version des Pakets erstellen werden und die pullnews.sh das Skript ist, mit dem wir demonstrieren werden, ist der Quellcode in der ersten Version wie folgt:

#!/bin/bash
echo "news pulled"
exit 0

Vergessen Sie nicht, den Dateien im Quellcode die entsprechenden Rechte hinzuzufügen – in unserem Fall das Ausführungsrecht:

chmod +x rpmbuild/SOURCES/admin-scripts-1/scripts/*.sh


Nun erstellen wir ein tar.gz Archiv aus der Quelle im selben Verzeichnis:

cd rpmbuild/SOURCES/ && tar -czf admin-scripts-1.tar.gz admin-scripts-1

Wir sind bereit, das Paket zusammenzustellen:

rpmbuild --bb rpmbuild/SPECS/admin-scripts-1.0.spec

Wir erhalten eine Ausgabe über den Build, und wenn etwas schief geht, werden Fehler angezeigt (z. B. fehlende Datei oder Pfad). Wenn alles gut geht, erscheint unser neues Paket im RPMS-Verzeichnis, das standardmäßig unter dem Verzeichnis rpmbuild generiert wird (sortiert in Unterverzeichnisse nach Architektur):

ls rpmbuild/RPMS/noarch/
admin-scripts-1-0.noarch.rpm

Wir haben ein einfaches, aber voll funktionsfähiges RPM-Paket erstellt. Wir können alle Metadaten abfragen, die wir zuvor bereitgestellt haben:

rpm -qpi rpmbuild/RPMS/noarch/admin-scripts-1-0.noarch.rpm 
Name        : admin-scripts
Version     : 1
Release     : 0
Architecture: noarch
Install Date: (not installed)
Group       : Application/Other
Size        : 78
License     : GPL
Signature   : (none)
Source RPM  : admin-scripts-1-0.src.rpm
Build Date  : 2018. aug.  1., Wed, 13.27.34 CEST
Build Host  : build01.foobar.com
Relocations : (not relocatable)
Packager    : John Doe 
URL         : www.foobar.com/admin-scripts
Summary     : FooBar Inc. IT dept. admin scripts
Description :
Package installing latest version the admin scripts used by the IT dept.


Und natürlich können wir es installieren (mit Root-Rechten):

Installieren von benutzerdefinierten Skripten mit rpm

Da wir die Skripte in einem Verzeichnis installiert haben, das sich auf dem ` PATH jedes Benutzers befindet, können Sie sie wie jeder Benutzer im System von jedem Verzeichnis aus ausführen:

pullnews.sh 
news pulled


Das Paket kann so verteilt werden, wie es ist, und kann in Repositories verschoben werden, die für eine beliebige Anzahl von Systemen verfügbar sind. Dies würde den Rahmen dieses Tutorials sprengen – das Erstellen einer anderen Version des Pakets ist es jedoch sicherlich nicht.

Erstellen einer weiteren Version des Pakets

Unser Paket und die äußerst nützlichen Skripte darin werden in kürzester Zeit populär, wenn man bedenkt, dass sie überall mit einer einfachen Installation von Admin-Skripten innerhalb der Umgebung erreichbar sind. Es wird bald viele Wünsche nach einigen Verbesserungen geben – in diesem Beispiel kommen viele Stimmen von zufriedenen Benutzern, dass der pullnews.sh bei der Ausführung eine weitere Zeile drucken sollte, diese Funktion würde das ganze Unternehmen retten. Wir müssen eine andere Version des Pakets erstellen, da wir kein weiteres Skript installieren wollen, sondern eine neue Version davon mit dem gleichen Namen und Pfad, da die Systemadministratoren in unserer Organisation bereits stark darauf angewiesen sind.

Zuerst ändern wir die Quelle der pullnews.sh in den QUELLEN in etwas noch Komplexeres:

#!/bin/bash
echo "news pulled"
echo "another line printed"
exit 0

Wir müssen die tar.gz mit dem neuen Quellinhalt neu erstellen – wir können den gleichen Dateinamen wie beim ersten Mal verwenden, da wir nicht die Version, sondern nur die Veröffentlichung ändern (und somit die Source0-Referenz weiterhin gültig ist). Beachten Sie, dass wir zuerst das vorherige Archiv löschen:

cd rpmbuild/SOURCES/ && rm -f admin-scripts-1.tar.gz && tar -czf admin-scripts-1.tar.gz admin-scripts-1

Nun erstellen wir ein weiteres Specfile mit einer höheren Release-Nummer:

cp rpmbuild/SPECS/admin-scripts-1.0.spec rpmbuild/SPECS/admin-scripts-1.1.spec

Wir ändern nicht viel am Paket selbst, daher verwalten wir einfach die neue Version, wie unten gezeigt:

Name:           admin-scripts
Version:        1
Release:        1
Summary:        FooBar Inc. IT dept. admin scripts
Packager:       John Doe 
Group:          Application/Other
License:        GPL
URL:            www.foobar.com/admin-scripts
Source0:        %{name}-%{version}.tar.gz
BuildArch:      noarch

%description
Package installing latest version the admin scripts used by the IT dept.

%prep
%setup -q


%build

%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr/local/sbin
cp scripts/* $RPM_BUILD_ROOT/usr/local/sbin/

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-,root,root,-)
%dir /usr/local/sbin
/usr/local/sbin/parselogs.sh
/usr/local/sbin/pullnews.sh

%doc

%changelog
* Wed Aug 22 2018 John Doe 
- release 1.1 - pullnews.sh v1.1 prints another line
* Wed Aug 1 2018 John Doe 
- release 1.0 - initial release

Alles erledigt, können wir eine weitere Version unseres Pakets erstellen, die das aktualisierte Skript enthält. Beachten Sie, dass wir das Specfile mit der höheren Version als Quelle des Builds referenzieren:

rpmbuild --bb rpmbuild/SPECS/admin-scripts-1.1.spec

Wenn der Build erfolgreich ist, haben wir jetzt zwei Versionen des Pakets in unserem RPMS-Verzeichnis:

ls rpmbuild/RPMS/noarch/
admin-scripts-1-0.noarch.rpm  admin-scripts-1-1.noarch.rpm

Und jetzt können wir das "erweiterte" Skript installieren oder ein Upgrade durchführen, wenn es bereits installiert ist.

Aktualisieren von benutzerdefinierten Skripten mit rpm

Und unsere Systemadministratoren können sehen, dass die Feature-Anfrage in dieser Version gelandet ist:

rpm -q --changelog admin-scripts
* Wed aug 22 2018 John Doe 
- release 1.1 - pullnews.sh v1.1 prints another line

* Wed aug 01 2018 John Doe 
- release 1.0 - initial release

Schlussfolgerung

Wir haben unsere benutzerdefinierten Inhalte in versionierte RPM-Pakete verpackt. Das bedeutet, dass keine älteren Versionen mehr auf den Systemen verstreut sind, sondern alles an seinem Platz ist, in der Version, die wir installiert oder auf die wir aktualisiert haben. RPM bietet die Möglichkeit, alte Dinge zu ersetzen, die nur in früheren Versionen benötigt wurden, kann benutzerdefinierte Abhängigkeiten hinzufügen oder einige Tools oder Dienste bereitstellen, auf die unsere anderen Pakete angewiesen sind. Mit Mühe können wir fast jeden unserer benutzerdefinierten Inhalte in RPM-Pakete packen und in unserer Umgebung verteilen, nicht nur mit Leichtigkeit, sondern auch mit Konsistenz.

Verwandte Artikel: