Bereitstellung normaler Funktionen für die Initialisierung und das Herunterfahren von normalen Benutzern (ohne Rootberechtigung)

7

Ich hoste eine experimentelle / testende Linux-Box, auf der die Debian Wheezy 7.4.0-Distribution ausgeführt wird. Verschiedene Benutzer melden sich über ssh bei ihren Konten am Computer an und können die Entwicklungstools ausführen und ihre Programme als Dienste im Hintergrund ausführen, wenn sie dies wünschen.

Da es sich um eine Testmaschine für alle Arten von Zwecken handelt, muss häufig die gesamte Maschine neu gestartet werden. Anschließend müssen sich die Benutzer erneut anmelden und ihre ausgeführten User-Space-Inhalte neu starten. Das möchte ich automatisieren. Grundsätzlich möchte ich den Benutzern ein Mittel zum Starten von Dingen direkt nach dem Start des Computers (nachdem alles andere initialisiert wurde) und ein Mittel zum Starten von Dingen beim Herunterfahren des Systems (ohne zeitliche Einschränkungen, das das Herunterfahren bis zu all diesen Herunterfahren zum Stillstand bringt) bereitstellen Benutzerprozesse abgeschlossen).

Was ich bisher versucht habe:
Ich habe ein Init-Bash-Skript erstellt, indem ich den Prinzipien in der 'Skeleton'-Vorlagendatei unter /etc/init.d/ (Quellcode der Skeleton-Vorlage: https: //gist.github) gefolgt bin. com / ivankovacevic / 9917139 )

Mein Code ist hier: https://github.com/ivankovacevic/userspaceServices

Grundsätzlich durchsucht das Skript die Home-Verzeichnisse der Benutzer und sucht nach ausführbaren Dateien in den entsprechenden Unterverzeichnissen mit den Namen .startUp, .shutDown oder .status. Abhängig von dem Ereignis, das gerade ausgeführt wird, werden die Skripte mit su ausgeführt, als hätten die Benutzer sie selbst gestartet.

Das Problem, mit dem ich derzeit bei diesem Ansatz konfrontiert bin, besteht darin, dass nach dem Systemstart ein seltsamer Prozess hängen bleibt und das Skript alle Prozesse anderer Benutzer startet. So sieht es in der Prozessliste aus:

UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
root      3053     1  0  1024   620   1 17:42 ?        00:00:00 startpar -f -- userspaceServices

Ich weiß nicht, was dieser Prozess ist, und in der Manpage wird das Argument -f nicht erwähnt. Ich bin also ahnungslos, aber ich muss etwas falsch machen, da kein anderes Skript / Dienst von init.d einen solchen Prozess nach dem Booten hängen lässt.

Ich suche jemanden, der mir beim Debuggen meiner Lösung hilft (was meiner Meinung nach auch etwas komplex erscheint). Oder geben Sie mir eine Vorstellung davon, wie dies auf ganz andere Weise umgesetzt werden könnte.

UPDATE
Ich habe eine separate Frage für das Startpar- Problem gestartet : Der Startpar-Prozess blieb hängen, wenn Prozesse von rc.local oder init.d gestartet wurden

UPDATE 2
Problem für meine ursprüngliche Lösung gelöst. Überprüfen Sie die zuvor erwähnte Frage auf startpar . Der Code auf GitHub wird ebenfalls korrigiert, um dies widerzuspiegeln.

UPDATE 3 - Verwendung von crontab
Wie Jenny vorgeschlagen hat, können normale Benutzer Aufgaben planen, die beim Booten mit crontab einmal ausgeführt werden sollen. Ich finde, dass dies die einfachste Methode ist, wenn Sie nur Benutzeraufgaben beim Booten starten und nicht herunterfahren müssen. Es gibt jedoch einen Nachteil, dass Benutzer den Cron-Prozess als übergeordnetes Element "hängen lassen" können, wenn sie laufende, serviceähnliche Aufgaben starten. Lassen Sie mich zunächst erklären, wie es funktioniert:

Stammbenutzer selbst sollten anrufen:

crontab -e

(-e wie beim Bearbeiten ) Öffnet einen Standard-Konsolentexteditor mit der Benutzer-Crontab-Datei. Um eine Aufgabe hinzuzufügen, die beim Booten ausgeführt werden soll, muss ein Benutzer eine Zeile am Ende der Datei hinzufügen:

@reboot /path/to/the/executable/file

Wenn der Benutzer genau das tun würde und diese Datei nicht nur ein einfaches Skript ist, das etwas linear abschließt und endet, sondern eine Art Watchdog, würden Sie beispielsweise nach einem Neustart mit etwas Ähnlichem in Ihrer Prozessliste enden:

    1  2661 root       20   0 20380   860   660 S  0.0  0.0  0:00.00 ├─ /usr/sbin/cron
 2661  2701 root       20   0 33072  1152   868 S  0.0  0.0  0:00.00   └─ /USR/SBIN/CRON
 2701  2944 someuser   20   0  4180   580   484 S  0.0  0.0  0:00.00      └─ /bin/sh -c ./watchdog
 2944  2945 someuser   20   0 10752  1204  1016 S  0.0  0.0  0:00.00         └─ /bin/bash ./watchdog
 2945  2946 someuser   20   0 23696  4460  2064 S  0.0  0.1  0:00.01            └─ /usr/bin/python ./some_program.py

Um zu vermeiden, dass der Benutzer seinen Crontab-Eintrag so ändern muss, dass er folgendermaßen aussieht:

@reboot /path/to/the/executable/file >/dev/null 2>&1 &

Die Umleitungen von Dateideskriptoren sind optional, werden jedoch empfohlen, um sie sauber zu halten. Wenn Sie untersuchen möchten, warum, schauen Sie sie sich an:

ls -l /proc/pid_of_started_process/fd
Ivan Kovacevic
quelle
Sie sollten Ihre "Lösungen" als Antworten und nicht als Änderungen an Ihrer Frage veröffentlichen.
Gerald Schneider
Nun, ich habe immer Zweifel, ob das fair gegenüber anderen Menschen ist, die antworten möchten.
Ivan Kovacevic

Antworten:

8

Ich bin damit einverstanden, dass Ihre Lösung etwas komplex erscheint, daher gehe ich zu "Geben Sie mir eine Vorstellung davon, wie dies auf eine ganz andere Art und Weise implementiert werden könnte" :-)

  1. Die Standardlösung hierfür besteht darin, ein Konfigurationsverwaltungssystem wie Puppet zu verwenden und Benutzern das Hinzufügen ihrer Inhalte zur Puppet-Konfiguration für den Server zu ermöglichen. Puppet wird dann das Startskript herausschieben und sie den relevanten Runlevels hinzufügen.

  2. Ein schnellerer Weg wäre, ihnen Sudoedit-Zugang zu gewähren /etc/rc.d/rc.localund ihre Sachen dort hinzuzufügen.

  3. Oder geben Sie jedem ein Verzeichnis, in das die zu startenden Startskripte eingefügt werden sollen, und lassen Sie diese Skripte von einem Cron-Job kopieren /etc/init.d, su $USER -can geeigneten Stellen einfügen und chkconfig darauf ausführen.

  4. Oder geben Sie jedem ein Verzeichnis, in das die Startskripte eingefügt werden sollen, und fügen Sie am Ende einige Zeilen hinzu, um diese Verzeichnisse zu durchsuchen /etc/rc.d/rc.localund für jedes Skript in ihnen bearbeitet su $USER -c 'script start' zu arbeiten.

Bearbeitet, um Folgendes hinzuzufügen: 5. Lassen Sie sie crontab verwenden, um die auszuführenden Jobs zu planen@reboot

Jenny D.
quelle
Das Problem mit Ihren Vorschlägen ist, dass Benutzer Skripte bearbeiten können, die beim Booten oder Herunterfahren als Root ausgeführt werden. Ohne dass ich diese Skripte jedes Mal überprüfe, wenn der Computer neu gestartet werden muss, kann ich nicht sicher sein, dass ein von Benutzern bereitgestellter Code das System nicht auf unerwünschte Weise verändert (beschädigt).
Ivan Kovacevic
Diese Einschränkung war nicht in der Spezifikation enthalten ... Sie können dies immer noch mit Puppet tun, indem Sie entweder die Skripte überprüfen, bevor Sie sie bereitstellen, oder indem Sie die Puppet-Konfiguration ändern, um diese Skripte für die Ausführung als Benutzer bereitzustellen. Aber ich habe auch Punkt 3 und 4 geändert und als Antwort darauf Punkt 5 hinzugefügt.
Jenny D
:) Danke für deine Änderungen, nimm es nicht zu persönlich :). Puppe scheint nur eine weitere Schicht des Teints zum Thema. Die Idee Nummer 4 steht. Das teste ich gerade. ABER ich sehe immer noch dieses Problem mit startpar -f, wenn ich das mache. Jetzt sehe ich es in der Prozessliste als: startpar -f - rc.local und alles, was ich in rc.local hinzugefügt habe, ist eine Zeile, um ein einfaches Watchdog-Bash-Skript in einem der Benutzerverzeichnisse genau gemäß Ihrer Nummer 4 zu starten. Vorschlag. Ich möchte jetzt wirklich herausfinden, was zum Teufel dieser Prozess ist. Vielleicht sollte ich eine andere separate Frage dafür stellen ...
Ivan Kovacevic
1
Was Crontab beim Herunterfahren betrifft - nein, das hat es nicht. Sie können jedoch ein K99-Skript hinzufügen, das die Crontab jedes Benutzers überprüft, nach @reboot sucht und dasselbe Skript mit ausführt su -c $USER 'crontabentry stop'- ein wenig erfunden, aber machbar.
Jenny D
1
Danke für den Link, es war interessant die Ursache zu kennen! (Ich habe Ihre Antwort positiv bewertet. Es ist nicht ungewöhnlich, dass eine nicht umgeleitete Ausgabe dazu führt, dass ein Prozess nicht erfolgreich dämonisiert wird, aber ich wusste nicht genug über startpar, um dies sofort zu erfassen. Die nächste Person, die diese Frage findet, wird es definitiv sein geholfen durch Ihre Antwort.) ¨
Jenny D