Python Skripte remote überwachen und steuern [Linux]
-
- User
- Beiträge: 30
- Registriert: Montag 19. September 2022, 22:48
Moin,
ich suche eine Software, welche Serverseitig läuft und mit der es ermöglicht wird, Python Scripte/Programme, welche im Hintergrund laufen sollen, zu starten oder stoppen. Auch um zu prüfen, ob das Programm ausgeführt wird oder nicht, quasi remote, weil auf der Konsole wäre das ja mehr oder weniger trivial. Der Hintergrund dazu ist einfach, dass die meisten Programme, die ich schreibe, im Hintergrund laufen und irgendwas machen, ich aber in der Lage sein möchte, die Programme zu stoppen/starten oder zu resetten, falls sich am Code etwas ändert, ohne gleich wieder per SSH auf den Host zu gehen.
Ich bin zwar gerade dabei, mir so etwas in der Art selber zu schreiben, mittels HTML/PHP/JS/Shell, weil ich trotz ausgiebiger Suche nichts Vernünftiges gefunden habe, dennoch möchte ich hier die Frage in den Raum stellen, ob so etwas jemand kennt oder sogar benutzt.
Würde mich über Tipps freuen!
Grüße
ich suche eine Software, welche Serverseitig läuft und mit der es ermöglicht wird, Python Scripte/Programme, welche im Hintergrund laufen sollen, zu starten oder stoppen. Auch um zu prüfen, ob das Programm ausgeführt wird oder nicht, quasi remote, weil auf der Konsole wäre das ja mehr oder weniger trivial. Der Hintergrund dazu ist einfach, dass die meisten Programme, die ich schreibe, im Hintergrund laufen und irgendwas machen, ich aber in der Lage sein möchte, die Programme zu stoppen/starten oder zu resetten, falls sich am Code etwas ändert, ohne gleich wieder per SSH auf den Host zu gehen.
Ich bin zwar gerade dabei, mir so etwas in der Art selber zu schreiben, mittels HTML/PHP/JS/Shell, weil ich trotz ausgiebiger Suche nichts Vernünftiges gefunden habe, dennoch möchte ich hier die Frage in den Raum stellen, ob so etwas jemand kennt oder sogar benutzt.
Würde mich über Tipps freuen!
Grüße
Also einen Webserver der die Python-Hintergrundprozesse managt? Was selbst gebautes auf Basis von Django oder Flask (mittels HTML und Python)?
Ich meine ich müsste da noch irgendwelche Namen von fertigen Geschichten wissen, aktuell aber gähnende Leere im Hirn. Eine Suche hat mich dafür eben zu "Cockpit" geführt: https://cockpit-project.org/
Jetzt zum ersten Mal gesehen, kann also nicht sagen ob das was 'vernünftiges' ist.
Eine andere Idee: nichts auf dem Server machen, sondern mittels "Fabric" (https://www.fabfile.org/) vom Client-Rechner auf den Server zugreifen? Gut, das ist im Prinzip nicht anderes als 'per SSH auf den Host zu gehen', aber wenigstens in hübsch und in Python...
Ich meine ich müsste da noch irgendwelche Namen von fertigen Geschichten wissen, aktuell aber gähnende Leere im Hirn. Eine Suche hat mich dafür eben zu "Cockpit" geführt: https://cockpit-project.org/
Jetzt zum ersten Mal gesehen, kann also nicht sagen ob das was 'vernünftiges' ist.
Eine andere Idee: nichts auf dem Server machen, sondern mittels "Fabric" (https://www.fabfile.org/) vom Client-Rechner auf den Server zugreifen? Gut, das ist im Prinzip nicht anderes als 'per SSH auf den Host zu gehen', aber wenigstens in hübsch und in Python...
Klingt für mich nach einem systemd Service, ist zwar nicht Python spezifisch, dafür aber gut dokumentiert und millionenfach im Einsatz.Xbash_Zero hat geschrieben: ↑Donnerstag 22. Juni 2023, 21:16 ich suche eine Software, welche Serverseitig läuft und mit der es ermöglicht wird, Python Scripte/Programme, welche im Hintergrund laufen sollen, zu starten oder stoppen. Auch um zu prüfen, ob das Programm ausgeführt wird oder nicht...
Wahlweise tut es auch jedes andere Init-System, was immer gerade auf deinen Server verfügbar ist.
Na er will die ja managen via Webseite oder so. Das bringt systemd nicht mit sich. sparrow hat da schon recht - das ist klassisch deployment (und Monitoring), und zb sowas wie Terraform etc könnte da helfen. Ist aber natürlich auch gleich die ganz dicke Kanone für den Spatz.
Erstmal will der das Programme, im Hintergrund laufen und bei Bedarf neu starten, das Pattern heißt, Dämonprozess oder eben (Systemd) Service.
Dass der TO dafür eine Webseite schreibt, hat nichts damit zu tun, dass es eigentlich Prozesse im Hintergrund laufen lassen will. Abgesehen davon wird es wahrscheinlich für den TO immer noch einfacher, wenn er die Prozesse in systemd Unit erzeugt und ggf. eine GUI zusammenbaut, die ein wrapper für systemctl ist.
Dass der TO dafür eine Webseite schreibt, hat nichts damit zu tun, dass es eigentlich Prozesse im Hintergrund laufen lassen will. Abgesehen davon wird es wahrscheinlich für den TO immer noch einfacher, wenn er die Prozesse in systemd Unit erzeugt und ggf. eine GUI zusammenbaut, die ein wrapper für systemctl ist.
Es wird nit-picky, aber er redet ja nun davon, dass die schon im Hintergrund laufen. Nicht, dass er dazu einen Weg sucht. Du hast natuerlich trotzdem Recht, dass man dazu systemd benutzen sollte, wenn das die einzige Aufgabe waere. Ausser eben man benutzt stattdessen Docker & Co, weil die einem die remote Orchestrierung ermoeglichen.
-
- User
- Beiträge: 30
- Registriert: Montag 19. September 2022, 22:48
Hi Deets & Danke!__deets__ hat geschrieben: ↑Freitag 23. Juni 2023, 11:23 Es wird nit-picky, aber er redet ja nun davon, dass die schon im Hintergrund laufen. Nicht, dass er dazu einen Weg sucht. Du hast natuerlich trotzdem Recht, dass man dazu systemd benutzen sollte, wenn das die einzige Aufgabe waere. Ausser eben man benutzt stattdessen Docker & Co, weil die einem die remote Orchestrierung ermoeglichen.
Über systemd werde ich mal nachdenken ... Docker ist, denke ich für mein Szenario etwas too much ... da müsste ich glaube ich zumindest, für jedes Programm einen eigenen Container bereitstellen? Wie würdest du bei einem Docker Szenario vorgehen?
Hi grubenfox & Danke!grubenfox hat geschrieben: ↑Donnerstag 22. Juni 2023, 23:17 Also einen Webserver der die Python-Hintergrundprozesse managt? Was selbst gebautes auf Basis von Django oder Flask (mittels HTML und Python)?
Ich meine ich müsste da noch irgendwelche Namen von fertigen Geschichten wissen, aktuell aber gähnende Leere im Hirn. Eine Suche hat mich dafür eben zu "Cockpit" geführt: https://cockpit-project.org/
Jetzt zum ersten Mal gesehen, kann also nicht sagen ob das was 'vernünftiges' ist.
Eine andere Idee: nichts auf dem Server machen, sondern mittels "Fabric" (https://www.fabfile.org/) vom Client-Rechner auf den Server zugreifen? Gut, das ist im Prinzip nicht anderes als 'per SSH auf den Host zu gehen', aber wenigstens in hübsch und in Python...
Das Cockpit schaue ich mal näher an, an so etwas in der Art habe ich gedacht.
Ihr wisst ja, ein Python Script lässt sich auf dem Linux Terminal zB. so starten, damit dieses im Hintergrund läuft und auch die prints & loggings in ein log-file laufen -> "python3 my_script.py &> $LOG_FILE_1 &"
Auf einer zweiten virtuellen Maschine, habe ich ein sh Script, das sieht so aus:
Code: Alles auswählen
#!/bin/bash
# Search for running python processes
ssh user@192.168.1.24 'ps aux | grep python'
Bei meiner eigen Entwicklung habe ich mir überlegt, ich schreibe ein frontend mittels hmtl und javascript und ein backend mittels python statt php ... php ist viel zu unflexibel finde ich. Jetzt könnte man via longpoling oder socket bzw. websocket auf das backend zugreifen um dort shell scripte auszuführen oder auszulesen ...
HTML
Hier hänge ich gerne mal an was ich schon hab:
Code: Alles auswählen
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<link href="favicon.png" rel="icon" type="image/png" />
<title>Server Control</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="left-bar"></div>
<div class="top-bar"></div>
<div class="tabs-container">
<div class="green-bar">
<div class="tabs">
<button class="tablink" onclick="openTab(event, 'Tab1')">Tab 1</button>
<button class="tablink" onclick="openTab(event, 'Tab2')">Tab 2</button>
<button class="tablink" onclick="openTab(event, 'Tab2')">Tab 3</button>
</div>
</div>
</div>
<div id="Tab1" class="tabcontent">
<iframe src="tab1_content.html" frameborder="10" scrolling="no" width="600" height="400"></iframe>
</div>
<div id="Tab2" class="tabcontent">
<iframe src="tab2_content.html" frameborder="10" scrolling="no" width="600" height="400"></iframe>
</div>
<div id="Tab3" class="tabcontent">
<iframe src="tab2_content.html" frameborder="10" scrolling="no" width="600" height="400"></iframe>
</div>
<div id="output1"></div>
<div id="output2"></div>
<script src="worker.js"></script>
<script src="websocket.js"></script>
</body>
</html>
CSS
Code: Alles auswählen
.left-bar {
background-color: orange;
width: 120px;
position: fixed;
top: 0;
left: 0;
height: 100%;
z-index: 9999;
border-top-left-radius: 20px;
border-bottom-left-radius: 40px;
}
.top-bar {
background-color: orange;
height: 30px;
position: fixed;
top: 0;
left: 120px;
width: calc(100% - 120px);
z-index: 9999;
border-top-right-radius: 20px;
}
.green-bar {
background-color: green;
left: 120px;
height: 50px;
position: fixed;
width: calc(100% - 120px);
display: flex;
align-items: center;
}
/* Tabs */
.tabs-container {
margin-top: 50px;
}
.tabs {
display: flex;
justify-content: flex-start;
/* justify-content: center; */
/* text-align: center; */
padding: 5px;
margin-left: 25px;
}
.tablink {
background-color: #808080; /* #4CAF50; */
color: white;
border: none;
outline: none;
cursor: pointer;
padding: 5px 30px;
font-size: 15px;
margin-right: 10px;
margin-left: 25;
}
.tablink:hover {
background-color: red;
}
.tabcontent {
position: fixed;
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
margin-top: 100px;
margin-left: 150px;
margin-right: 250px;
width: 900px;
height: 500px;
}
.tabcontent h3 {
margin-top: 50;
}
.tabcontent.show {
display: block;
}
JS - Tabs
Code: Alles auswählen
function openTab(evt, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " active";
}
JS
Code: Alles auswählen
var socket = new WebSocket("ws://192.168.0.7:8080"); // WebSocket-Verbindung herstellen
socket.onmessage = function(event) {
var data = JSON.parse(event.data);
var scriptId = data.scriptId;
var output = data.output;
if (scriptId === 1) {
document.getElementById("output1").innerHTML = output;
} else if (scriptId === 2) {
document.getElementById("output2").innerHTML = output;
}
};
// Funktion zum Senden einer Befehlsanfrage an das Shell-Skript
function sendCommand(scriptId, command) {
var data = {
scriptId: scriptId,
command: command
};
socket.send(JSON.stringify(data));
}
Tab1-Content
Code: Alles auswählen
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tab 1 Inhalt</title>
<style>
#text-container {
position: absolute;
margin-top: 150px;
top: 20px;
font-size: 18px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="frame-container">
<form method="post" action="control.php">
<input type="submit" name="button1" value="Button 1">
<input type="submit" name="button2" value="Button 2">
<input type="submit" name="check_script" value="Skript ausführen">
</form>
<iframe class="frame-content" src="control.php" frameborder="0"></iframe>
</div>
<div id="text-container">
Python Server Script -_TEXT_-
</div>
</body>
</html>
Also was du da mit "im Hintergrund laufen lassen" machst, ist natuerlich so erstmal nicht gut. Denn die sollten dann AfAIK noch nicht mal den logout ueberleben. Dafuer ist in erster Naeherung mindestens mal das von imonbln vorgeschlagenen systemd zu benutzen. Damit koennen die Services sauber gestarted, ueberwacht, und gestoppt werden.
Oder eben tatsaechlich Docker, ja. Wie genau sich das dann aufteilt, haengt von deinen konkreten Programmen ab. Wenn da mehrere sowieso immer zusammen gestartet werden, koennen die auch in einen container. Aber allgemein wird man eher einen Container pro Skript einsetzen.
Oder eben tatsaechlich Docker, ja. Wie genau sich das dann aufteilt, haengt von deinen konkreten Programmen ab. Wenn da mehrere sowieso immer zusammen gestartet werden, koennen die auch in einen container. Aber allgemein wird man eher einen Container pro Skript einsetzen.
-
- User
- Beiträge: 30
- Registriert: Montag 19. September 2022, 22:48
Ok, danke dir!
Ich werde es versuchen und mich wieder melden.
Ich werde es versuchen und mich wieder melden.
-
- User
- Beiträge: 30
- Registriert: Montag 19. September 2022, 22:48
Gut, ich habe es zumindest eingerichtet bekommen, allerdings schaffe ich es nicht, dass zB. "~$ systemctl start server.service" nicht ohne Passwort-Abfrage ausgeführt wird. Ok, logisch, man benötigt sudo bzw. root Rechte ... aber für mein Vorhaben ist es notwendig, dass einige meiner Skripte mit meinem normalen User ausgeführt werden können, da müsste es doch evtl. einen Workaround geben?
Hat jemand eine Idee, wie ich das machen kann? Ich werde ebenfalls noch mal eine Recherche starten ...
Edit:
so habe ich es eingerichtet:
Hat jemand eine Idee, wie ich das machen kann? Ich werde ebenfalls noch mal eine Recherche starten ...
Edit:
so habe ich es eingerichtet:
Code: Alles auswählen
sudo nano /etc/systemd/system/
Code: Alles auswählen
[Unit]
Description=Beschreibung des Services
After=network.target
[Service]
User=user
WorkingDirectory=/pfad/zum/programm
ExecStart=/pfad/zu/python /pfad/zum/programm/programm.py
Restart=always
[Install]
WantedBy=multi-user.target
Code: Alles auswählen
sudo systemctl enable programm.service
- noisefloor
- User
- Beiträge: 3857
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
es gibt zwei Wege: zum einem kannst du in einer systemd Service Unit eine Direktive anlegen, unter welchem User diese laufen soll. Default ist ist `root`, `User=otto` würde die Unit als User `otto` starten. Zum anderen gibt es systemd User Service Units. Diese werden (erst) gestartet, wenn der Nutzer, für den die Unit gelegt ist, sich einloggt.
Welcher Weg der besser für dich ist musst du entscheiden.
Gruß, noisefloor
es gibt zwei Wege: zum einem kannst du in einer systemd Service Unit eine Direktive anlegen, unter welchem User diese laufen soll. Default ist ist `root`, `User=otto` würde die Unit als User `otto` starten. Zum anderen gibt es systemd User Service Units. Diese werden (erst) gestartet, wenn der Nutzer, für den die Unit gelegt ist, sich einloggt.
Welcher Weg der besser für dich ist musst du entscheiden.
Gruß, noisefloor
Grundsätzlich gilt unter Linux, dass Prozesse mit dem minimal-notwendigen Set an Berechtigungen laufen sollen. Jeder Daemon – danach klingen deine "Skripte" jedenfalls – läuft zudem unter einem eigenen Systemuser. Dass nur Root und User mit Sudo diese Dienste starten und stoppen können, ist Best Practice; dass du dein Passwort eingeben musst "gehört" so und das sollte man auch nicht umgehen (auch wenn das geht). Für mich klingen deine Beschreibungen jedenfalls teilweise noch etwas unsortiert. Was sind das für Skripte, die da laufen sollen? Welche Rechte brauchen die? Warum soll ein User, der nicht Root ist und dem der Prozess nicht läuft diesen starten/stoppen können? Wäre evtl. ein Userspace Prozessmanager wie supervisord hier eine Lösung für dich?Xbash_Zero hat geschrieben: ↑Samstag 24. Juni 2023, 00:09 Gut, ich habe es zumindest eingerichtet bekommen, allerdings schaffe ich es nicht, dass zB. "~$ systemctl start server.service" nicht ohne Passwort-Abfrage ausgeführt wird.
-
- User
- Beiträge: 30
- Registriert: Montag 19. September 2022, 22:48
Hallo noisefloor & Danke!noisefloor hat geschrieben: ↑Samstag 24. Juni 2023, 14:47 Hallo,
es gibt zwei Wege: zum einem kannst du in einer systemd Service Unit eine Direktive anlegen, unter welchem User diese laufen soll. Default ist ist `root`, `User=otto` würde die Unit als User `otto` starten. Zum anderen gibt es systemd User Service Units. Diese werden (erst) gestartet, wenn der Nutzer, für den die Unit gelegt ist, sich einloggt.
Welcher Weg der besser für dich ist musst du entscheiden.
Gruß, noisefloor
Das mit dem User "user" habe ich schon getestet,
Code: Alles auswählen
~$ systemctl --user start server.service
Ich habe es jetzt erstmal so gelöst, dass ich in
Code: Alles auswählen
visudo
Code: Alles auswählen
user ALL=(ALL) NOPASSWD: /usr/bin/systemctl start server.service, /user/bin/systemctl stop server.service
Hallo nezzcarth & Danke!nezzcarth hat geschrieben: ↑Samstag 24. Juni 2023, 16:42Grundsätzlich gilt unter Linux, dass Prozesse mit dem minimal-notwendigen Set an Berechtigungen laufen sollen. Jeder Daemon – danach klingen deine "Skripte" jedenfalls – läuft zudem unter einem eigenen Systemuser. Dass nur Root und User mit Sudo diese Dienste starten und stoppen können, ist Best Practice; dass du dein Passwort eingeben musst "gehört" so und das sollte man auch nicht umgehen (auch wenn das geht). Für mich klingen deine Beschreibungen jedenfalls teilweise noch etwas unsortiert. Was sind das für Skripte, die da laufen sollen? Welche Rechte brauchen die? Warum soll ein User, der nicht Root ist und dem der Prozess nicht läuft diesen starten/stoppen können? Wäre evtl. ein Userspace Prozessmanager wie supervisord hier eine Lösung für dich?Xbash_Zero hat geschrieben: ↑Samstag 24. Juni 2023, 00:09 Gut, ich habe es zumindest eingerichtet bekommen, allerdings schaffe ich es nicht, dass zB. "~$ systemctl start server.service" nicht ohne Passwort-Abfrage ausgeführt wird.
Weiter oben habe ich das doch bereits spezifiziert, ich möchte gerne, dass einige meiner Server-Programme, die in Python geschrieben sind, auf einem Web-Interface angezeigt und gesteuert werden können, ob das Sinn macht oder nicht, spielt erstmal keine Rolle, weil vielleicht noch weitere Features hinzukommen sollen, mal schauen.
Einer der Gründe ist auch, dass manche von den Programmen, von denen die meisten im Entwicklungs- und Teststadium sind, nicht permanent laufen müssen oder wenn ich ein paar Zeilen Code zwischendurch ändere, ich mich nicht für einen Restart auf der Konsole einloggen müsste, usw...
Und was das Thema Sicherheit betrifft, so läuft das Szenario in einem abgesicherten Netzwerk, auf welches kein Zugriff von Außen möglich ist. Auch die internen Sicherheitskonzepte für dieses Netzwerk haben einen hohen Standard. Und solche Spielereien wie ich es hier beschrieben habe und umsetzen möchte, laufen auf keinen Systemkritischen oder Produktiv-System.
Code: Alles auswählen
Warum soll ein User, der nicht Root ist und dem der Prozess nicht läuft diesen starten/stoppen können?
Code: Alles auswählen
python3 programm_server.py &
Den "Userspace Prozessmanager" schaue ich mir auch noch an, Danke vielmals für den Input!
Und noch eine weitere Frage, welche Python Websocket Bibliothek könnt ihr mir empfehlen? Habe mir websockets angeschaut, ist aber mit asyncio nicht so mein Fall, ich bin mehr so der threading Typ
-
- User
- Beiträge: 30
- Registriert: Montag 19. September 2022, 22:48
Um mir meine Frage selbst zu beantworten: Seit der Version 10.0 gibt es bei der Python Bibliothek "Websockets", die synchrone Implementierung und dabei können auch asynchrone Techniken wie Threading oder Multiprocessing genutzt werden.Xbash_Zero hat geschrieben: ↑Samstag 24. Juni 2023, 18:29 Und noch eine weitere Frage, welche Python Websocket Bibliothek könnt ihr mir empfehlen? Habe mir websockets angeschaut, ist aber mit asyncio nicht so mein Fall, ich bin mehr so der threading Typ
Zur Vollständigkeit, hier meine Implementierung zu diesem Projekt.
index.html
Code: Alles auswählen
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<link href="favicon.png" rel="icon" type="image/png" />
<title>Server Control</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="left-bar"></div>
<div class="top-bar"></div>
<div class="tabs-container">
<div class="green-bar">
<div class="tabs">
<button class="tablink" onclick="openTab(event, 'Tab1')">Tab 1</button>
<button class="tablink" onclick="openTab(event, 'Tab2')">Tab 2</button>
<button class="tablink" onclick="openTab(event, 'Tab2')">Tab 3</button>
</div>
</div>
</div>
<div id="Tab1" class="tabcontent">
<div id="service-status">
<div id="service-status-text">Service Status keep_alive</div>
<div class="image-wrapper">
<img id="myImage1" src="off.png" alt="state_led">
</div>
</div>
<div id="service-control">
<button class="toggel-button" onclick="start_keep_alive()">start</button>
<button class="toggel-button" onclick="stop_keep_alive()">stop</button>
<button class="toggel-button" onclick="restart_keep_alive()">restart</button>
</div>
<div id="service-status">
<div id="service-status-text">Service Status Websocket</div>
<div class="image-wrapper">
<img id="myImage2" src="off.png" alt="state_led">
</div>
</div>
<div id="service-control">
<button class="toggel-button" onclick="start_websocket()">start</button>
<button class="toggel-button" onclick="stop_websocket()">stop</button>
<button class="toggel-button" onclick="restart_websocket()">restart</button>
</div>
<div id="service-status">
<div id="service-status-text">Service Status ClickBot</div>
<div class="image-wrapper">
<img id="myImage3" src="off.png" alt="state_led">
</div>
</div>
<div id="service-control">
<button class="toggel-button" onclick="start_clickbot()">start</button>
<button class="toggel-button" onclick="stop_clickbot()">stop</button>
<button class="toggel-button" onclick="restart_clickbot()">restart</button>
</div>
</div>
<div id="Tab2" class="tabcontent">
<iframe src="tab2_content.html" frameborder="10" scrolling="no" width="600" height="400"></iframe>
</div>
<div id="Tab3" class="tabcontent">
<iframe src="tab2_content.html" frameborder="10" scrolling="no" width="600" height="400"></iframe>
</div>
<script src="worker.js"></script>
<script src="websocket.js"></script>
</body>
</html>
tab2_content.html (Optional bei verschiedenen Inhalten)
Code: Alles auswählen
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tab 2 Inhalt</title>
</head>
<body>
<div class="frame-container">
<form method="post" action="control.php">
<input type="submit" name="button1" value="Button 1">
<input type="submit" name="button2" value="Button 2">
<input type="submit" name="check_script" value="Skript ausführen">
</form>
<iframe class="frame-content" src="control.php" frameborder="0" scrolling="no"></iframe>
</div>
</body>
</html>
style.css
Code: Alles auswählen
/* CSS für die Leisten */
.left-bar {
background-color: orange;
width: 120px;
position: fixed;
top: 0;
left: 0;
height: 100%;
z-index: 9999;
border-top-left-radius: 20px;
border-bottom-left-radius: 40px;
}
.top-bar {
background-color: orange;
height: 30px;
position: fixed;
top: 0;
left: 120px;
width: calc(100% - 120px);
z-index: 9999;
border-top-right-radius: 20px;
}
.green-bar {
background-color: green;
left: 120px;
height: 50px;
position: fixed;
width: calc(100% - 120px);
display: flex;
align-items: center;
}
/* Tabs */
.tabs-container {
margin-top: 50px;
}
.tabs {
display: flex;
justify-content: flex-start;
/* justify-content: center; */
/* text-align: center; */
padding: 5px;
margin-left: 25px;
}
.tablink {
background-color: #808080; /* #4CAF50; */
color: white;
border: none;
outline: none;
cursor: pointer;
padding: 5px 30px;
font-size: 15px;
margin-right: 10px;
margin-left: 25;
}
.tablink:hover {
background-color: red; /* #45a049; */
}
.tabcontent {
position: fixed;
display: none;
padding: 6px 12px;
border: 2px solid #ccc;
margin-top: 100px;
margin-left: 150px;
margin-right: 250px;
width: 900px;
height: 700px;
}
.tabcontent h3 {
margin-top: 50;
}
.tabcontent.show {
display: block;
}
#output1 {
position: absolute;
top: 250px;
left: 200px;
width: 300px;
height: 400px;
margin-left: 150px;
}
#output2 {
position: absolute;
top: 250px;
left: 600px;
width: 300px;
height: 400px;
margin-left: 150px;
}
.output-container {
width: 600px;
height: 400px;
overflow: auto;
border: 1px solid #000;
white-space: pre-wrap;
}
#service-status {
margin-top: 50px;
text-align: center;
}
#service-status img {
width: 30px;
height: 30px;
/* box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5); */
border-radius: 25px;
}
#service-status-text {
font-size: 18px;
color: #555;
margin-top: 10px;
}
#service-control {
margin-top: 50px;
text-align: center;
}
#service-control button {
padding: 10px 20px;
margin: 5px;
border: none;
background-color: #808080;
color: white;
font-size: 15px;
cursor: pointer;
border-radius: 5px;
transition: background-color 0.3s ease;
}
#service-control button:hover {
background-color: #555;
}
worker.js
Code: Alles auswählen
function openTab(evt, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(tabName).style.display = "block";
evt.currentTarget.className += " active";
}
websocket.js
Code: Alles auswählen
var socket = new WebSocket("ws://192.168.0.7:8080"); // WebSocket-Verbindung herstellen
var outputText1 = "";
var outputText2 = "";
socket.onerror = function(event) {
console.error("WebSocket error observed:", event);
};
// Nach dem Öffnen der WebSocket-Verbindung
socket.onopen = function(event) {
console.log("Connected to server");
sendCommand(0, 'get');
setInterval(function() {
sendCommand(0, 'get');
}, 15000);
};
// Funktion zum Senden einer Befehlsanfrage an das Shell-Skript
function sendCommand(scriptId, command) {
var data = {
scriptId: scriptId,
command: command
};
socket.send(JSON.stringify(data));
}
socket.onmessage = function(event) {
console.log("Received message:", event.data);
try {
var data = JSON.parse(event.data);
if (data.scriptId === 0 && data.output) {
var service = data.output.service;
var state = data.output.state;
if (service === "keep_alive_server.service") {
updateState("myImage1", state);
} else if (service === "websocket_server.service") {
updateState("myImage2", state);
} else if (service === "clickbot_server.service") {
updateState("myImage3", state);
}
}
} catch (e) {
console.error("Error handling message:", e);
}
};
async function start_keep_alive() {
await socket.send(JSON.stringify({"service": "keep_alive", "command": "start"}));
}
async function stop_keep_alive() {
await socket.send(JSON.stringify({"service": "keep_alive", "command": "stop"}));
}
async function restart_keep_alive() {
await socket.send(JSON.stringify({"service": "keep_alive", "command": "restart"}));
}
async function start_websocket() {
await socket.send(JSON.stringify({"service": "websocket", "command": "start"}));
}
async function stop_websocket() {
await socket.send(JSON.stringify({"service": "websocket", "command": "stop"}));
}
async function restart_websocket() {
await socket.send(JSON.stringify({"service": "websocket", "command": "restart"}));
}
async function start_clickbot() {
await socket.send(JSON.stringify({"service": "clickbot", "command": "start"}));
}
async function stop_clickbot() {
await socket.send(JSON.stringify({"service": "clickbot", "command": "stop"}));
}
async function restart_clickbot() {
await socket.send(JSON.stringify({"service": "clickbot", "command": "restart"}));
}
function updateState(imageId, state) {
var image = document.getElementById(imageId);
if (state === "active") {
image.src = "on.png";
} else {
image.src = "off.png";
}
}
websockets_server.py (Synchrone Version)
Code: Alles auswählen
import websockets.sync.server
import subprocess
import json
import os
import signal
import multiprocessing
import threading
import time
import logging
logging.basicConfig(level=logging.INFO)
queue_to_process = multiprocessing.Queue()
queue_from_process = multiprocessing.Queue()
# Mapping from script-IDs to processes
processes = {}
def send_output(websocket, process, script_id):
while True:
logging.info(f"send_output called for script {script_id}")
output = process.stdout.readline().decode('utf-8').strip()
if not output:
break
try:
output_json = json.loads(output)
logging.info(f"Script {script_id} output: {output_json}")
message = {'scriptId': script_id, 'output': output_json}
logging.info("websocket.send")
logging.info(f"Sending message: {message}")
websocket.send(json.dumps(message))
logging.info(f"Message sent successfully")
time.sleep(0.1)
except json.JSONDecodeError:
logging.warning(f"Ignoring invalid JSON output: {output}")
except Exception as e:
logging.error(f"Error sending message: {e}", exc_info=True)
pass
def handle_message(websocket):
logging.info("Client connected") # Log when a client connects
for message in websocket:
data = json.loads(message)
script_id = data.get('scriptId')
command = data.get('command')
if command == 'get':
logging.info(f"Received get command for script {script_id}")
# Start the script
process = subprocess.Popen(['python3', 'execute_script5.py'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
processes[script_id] = process
# Create a background task to send the output
threading.Thread(target=send_output, args=(websocket, process, script_id)).start()
elif command == 'start':
logging.info(f"Received start command for service {script_id}")
service = data.get('service')
if service == 'keep_alive':
os.system(f"ssh user@192.168.0.24 sudo systemctl start keep_alive_server.service")
elif service == 'websocket':
os.system(f"ssh user@192.168.0.24 sudo systemctl start websocket_server.service")
elif service == 'clickbot':
os.system(f"ssh user@192.168.0.24 sudo systemctl start clickbot.service")
else:
logging.warning(f"Invalid service: {service}")
elif command == 'stop':
logging.info(f"Received stop command for service {script_id}")
service = data.get('service')
if service == 'keep_alive':
os.system(f"ssh user@192.168.0.24 sudo systemctl stop keep_alive_server.service")
elif service == 'websocket':
os.system(f"ssh user@192.168.0.24 sudo systemctl stop websocket_server.service")
elif service == 'clickbot':
os.system(f"ssh user@192.168.0.24 sudo systemctl stop clickbot.service")
else:
logging.warning(f"Invalid service: {service}")
elif command == 'restart':
logging.info(f"Received restart command for service {script_id}")
service = data.get('service')
if service == 'keep_alive':
os.system(f"ssh user@192.168.0.24 sudo systemctl restart keep_alive_server.service")
elif service == 'websocket':
os.system(f"ssh user@192.168.0.24 sudo systemctl restart websocket_server.service")
elif service == 'clickbot':
os.system(f"ssh user@192.168.0.24 sudo systemctl restart clickbot.service")
else:
logging.warning(f"Invalid service: {service}")
#def process_interface(queue_in, queue_out):
# while True:
#
# do not block
# if not queue_in.empty():
# message = queue_in.get()
# print(f"Process received message: {message}")
# queue_out.put("Response from process")
# time.sleep(10)
with websockets.sync.server.serve(handle_message, '192.168.0.7', 8080) as server:
server.serve_forever()
execute_script5.py
Code: Alles auswählen
import subprocess
import re
import json
import time
def execute_shell_script():
process = subprocess.Popen(['/bin/sh', '/var/www/html/control/script3.sh'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE) # Capture stderr separately
stdout, stderr = process.communicate() # Get stdout and stderr
if process.returncode != 0:
print(f"Script execution failed with error: {stderr.decode('utf-8')}")
return process.returncode
return stdout.decode('utf-8')
def parse_service_status(output):
service_sections = re.split(r'● |○ ', output)
for section in service_sections[1:]:
match = re.search(r'(.*?\.service)', section)
if match:
name = match.group(1)
status = "active" if "Active: active" in section else "inactive"
print(json.dumps({"service": name, "state": status}))
def print_service_status(service_status):
for service in service_status:
print(json.dumps(service))
def execute_and_parse():
output = execute_shell_script()
time.sleep(1)
if isinstance(output, str):
parse_service_status(output)
else:
print("No valid output to parse")
if __name__ == "__main__":
execute_and_parse()
script3.sh
Code: Alles auswählen
#!/bin/bash
# Script for remote access
#output=$(ssh user@192.168.0.24 'ps aux | grep python')
#echo "$output"
output=$(ssh user@192.168.0.24 sudo systemctl status keepalive_server.service)
echo "$output"
output=$(ssh user@192.168.0.24 systemctl status websocket_server.service)
echo "$output"
keepalive_status=$(ssh user@192.168.0.24 sudo systemctl is-active keepalive_server.service)
if [ "$keepalive_status" = "active" ]; then
echo "keepalive_server.service is active"
else
echo "keepalive_server.service is inactive"
fi
websocket_status=$(ssh user@192.168.0.24 sudo systemctl is-active websocket_server.service)
if [ "$websocket_status" = "active" ]; then
echo "websocket_server.service is active"
else
echo "websocket_server.service is inactive"
fi