Fórum Root.cz
Hlavní témata => Desktop => Téma založeno: barevnej 01. 06. 2022, 12:26:47
-
Je možné v gnome shell 42 nějak indikovat spuštěný program rslsync který otevírá na localhost port 8888?
Po spuštění se na localhost otevře port 8888 kde přes webový prohlížeč jde pozorovat a konfigurovat. Občas se stane že to spadne, a já bych to potřeboval nějak vědět bez toho abych to musel mít stále otevřené v prohlížeči.
Při spuštěném rslsync:
$ nmap -p 8888 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-01 12:12 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00013s latency).
PORT STATE SERVICE
8888/tcp open sun-answerbook
Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds
Při vypnutém:
$ nmap -p 8888 127.0.0.1
Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-01 12:13 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00012s latency).
PORT STATE SERVICE
8888/tcp closed sun-answerbook
Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds
Napadlo mě zda nepoužít nějaký extensions
https://extensions.gnome.org/extension/4687/server-status-indicator/
https://extensions.gnome.org/extension/4989/home-server/
Jenže tak snadné to není. Ale bylo by fajn mít nahoře ikonku která "zčervená" pokud http://127.0.0.1:8888/ není dostupná.
Nějaké nápady?
-
Spustil bych v tmuxu/screenu cyklus
while [ 1 ]; do
nc -zv 127.0.0.1 8888 2>/dev/null
if [ "$?" -ne "0" ]; then
zenity --info --text="$(date) nedostupny port";
fi
sleep 30s
done
pripadne doplnit o zaslani emailu
-
Co tak urobit z toho systemd user service a potom v ramci definicie unitu bud sluzbu restartovat (Restart=on-failure?), alebo urobit nejaku akciu pri chybe (OnFailure=...?).
-
systemd user service
ano, myslím si, že tohle je řešení, které pokryje i logování.
-
Já bych spíš opravdu "vizuální" kontrolu.
Nšel by tento extension upravit aby kontoloval ne jen IP ale i port?
https://extensions.gnome.org/extension/4989/home-server/
const { GObject, St, Clutter, GLib, Gio } = imports.gi;
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const ByteArray = imports.byteArray;
const Util = imports.misc.util;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext;
const Domain = Gettext.domain(Me.metadata.uuid);
const _ = Domain.gettext;
const Status = {
ONLINE: 1,
OFFLINE: 2,
ERROR: 3,
UNDEFINED: 4,
};
const Icon = {
ONLINE: 'online.svg',
OFFLINE: 'offline.svg',
ERROR: 'error.svg',
UNDEFINED: 'undefined.svg',
};
const Settings = {
SERVER_MAC: 'servermac',
SERVER_IP: 'serverip',
SERVER_POLL: 'serverpoll',
};
const HomeServer = GObject.registerClass(
class HomeServerIndicator extends PanelMenu.Button {
_init() {
super._init(0.0, _('Server'));
this._indicatorStatus = {
lastResponse: null,
status: Status.UNDEFINED,
};
this._settings = ExtensionUtils.getSettings();
this._isConnected = false;
this._setupWidgets();
this._mainLoop();
this._startMainLoop();
}
_setupWidgets() {
this._menuLayout = new St.BoxLayout();
this._ServerIcon = new St.Icon({ style_class: 'system-status-icon' });
this._setIndicatorIcon(Icon.UNDEFINED);
this._menuLayout.add_actor(this._ServerIcon);
this.add_actor(this._menuLayout);
this._setupPopupMenu();
}
_setupPopupMenu() {
this._settingsMenuItem = new PopupMenu.PopupMenuItem(_('Settings'));
this._settingsMenuItem.connect('activate', () => {
const extensionManager = imports.ui.main.extensionManager;
extensionManager.openExtensionPrefs(Me.uuid, '', {});
});
this.menu.addMenuItem(this._settingsMenuItem);
}
_setIndicatorIcon(iconFileName) {
const iconPath = Me.dir
.get_child('icons')
.get_child(iconFileName)
.get_path();
this._ServerIcon.set_gicon(Gio.Icon.new_for_string(iconPath));
}
_setIndicator(status) {
if (status == Status.ONLINE) {
if ( this._indicatorStatus.status !== Status.ONLINE ) {
this._setIndicatorIcon(Icon.ONLINE);
this._log('Set status ONLINE');
this._indicatorStatus.status = Status.ONLINE;
if (this._wakeonlanMenuItem) {
this._log('Remove WOL menu item');
this._wakeonlanMenuItem.disconnect();
this._wakeonlanMenuItem.destroy();
}
}
return;
}
if (status == Status.OFFLINE) {
if ( this._indicatorStatus.status !== Status.OFFLINE ) {
this._setIndicatorIcon(Icon.OFFLINE);
this._log('Set status OFFLINE');
this._indicatorStatus.status = Status.OFFLINE;
if (!this._wakeonlanMenuItem) {
this._log('Add WOL menu item');
this._wakeonlanMenuItem = new PopupMenu.PopupMenuItem(_('Start Server'));
this._wakeonlanMenuItem.connect('activate', () => {
this._wakeup();
});
this.menu.addMenuItem(this._wakeonlanMenuItem);
}
}
return;
}
if (status == Status.ERROR) {
if ( this._indicatorStatus.status !== Status.ERROR ) {
this._setIndicatorIcon(Icon.ERROR);
this._log('Set status ERROR');
this._indicatorStatus.status = Status.ERROR;
if (this._wakeonlanMenuItem) {
this._log('Remove WOL menu item');
this._wakeonlanMenuItem.disconnect();
this._wakeonlanMenuItem.destroy();
}
}
return;
}
if (status == Status.UNDEFINED) {
if ( this._indicatorStatus.status !== Status.UNDEFINED ) {
this._setIndicatorIcon(Icon.UNDEFINED);
this._log('Set status UNDEFINED');
this._indicatorStatus.status = Status.UNDEFINED;
if (this._wakeonlanMenuItem) {
this._log('Remove WOL menu item');
this._wakeonlanMenuItem.disconnect();
this._wakeonlanMenuItem.destroy();
}
}
return;
}
}
_wakeup() {
try {
let proc = Gio.Subprocess.new(
['wakeonlan', this._settings.get_string('servermac')],
Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE);
proc.communicate_utf8_async(null, null, (proc, res) => {
try {
Main.notify(Me.metadata.name, _('Start Server now. Please wait...'))
let [, stdout, stderr] = proc.communicate_utf8_finish(res);
} catch (e) {
Main.notify(Me.metadata.name, _('Start Server failed'))
this._log('Executing Wake On LAN failed. ' + e);
}
});
} catch (e) {
Main.notify(Me.metadata.name, _('Start Server failed. Already installed wakeonlan?'))
this._log('Wake On LAN failed. Already installed wakeonlan? ' + e);
}
}
_startMainLoop() {
this._mainLoopTimeout = GLib.timeout_add_seconds(
GLib.PRIORITY_DEFAULT,
this._settings.get_int(Settings.SERVER_POLL),
() => {
this._mainLoop();
return true;
}
);
}
_stopMainLoop() {
if (this._mainLoopTimeout) {
GLib.source_remove(this._mainLoopTimeout);
this._mainLoopTimeout = null;
}
this._connection = null;
}
async _mainLoop() {
let ip = this._settings.get_string('serverip')
let cmd = [];
if ( this._isConnected == true ) {
this._log('Connection established');
cmd = ['sh', '-c', `ping -q -c1 -w5 ${ip} >/dev/null 2>&1`];
} else {
this._log('Awaiting established connection');
cmd = ['sh', '-c', 'ping -q -c1 -w1 `ip r | grep default | cut -d " " -f 3` >/dev/null 2>&1 && exit 0 || exit 1'];
}
try {
let proc = Gio.Subprocess.new(cmd, Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE);
proc.communicate_utf8_async(null, null, (proc, res) => {
try {
if (proc.get_successful()) {
if ( this._isConnected == true ) {
this._log('Ping success');
this._setIndicator(Status.ONLINE);
} else {
this._isConnected = true;
this._setIndicator(Status.UNDEFINED);
}
} else {
if ( this._isConnected == true ) {
this._log('Ping failed');
this._setIndicator(Status.OFFLINE);
} else {
this._setIndicator(Status.UNDEFINED);
}
}
} catch (e) {
this._setIndicator(Status.UNDEFINED);
if ( this._isConnected == true ) {
this._log('Ping failed. ' + e);
} else {
this._log('Awaiting connection failed. ' + e);
}
}
});
} catch (e) {
this._setIndicator(Status.ERROR);
if ( this._isConnected == true ) {
this._log('Ping failed. ' + e);
} else {
this._log('Awaiting connection failed. ' + e);
}
}
}
_log(msg) {
if (this._settings.get_boolean('serverdebug')) {
log(`${Me.metadata.name}: ${msg}`);
}
}
_onDestroy() {
this._log('Indicator._onDestroy()');
this._stopMainLoop();
this._menuLayout = null;
this._indicatorStatus = null;
this._settings = null;
super._onDestroy();
}
}
);
class Extension {
constructor(uuid) {
this._uuid = uuid;
}
enable() {
this._homeServerIndicator = new HomeServer();
Main.panel.addToStatusArea(this._uuid, this._homeServerIndicator);
}
disable() {
this._homeServerIndicator.destroy();
this._homeServerIndicator = null;
}
}
function init(meta) {
ExtensionUtils.initTranslations(Me.metadata.uuid);
return new Extension(meta.uuid);
}