systemd: FIFO socket jako stdin bez socket activation

systemd: FIFO socket jako stdin bez socket activation
« kdy: 26. 07. 2016, 09:58:02 »
systemd umí socket activation a umí předat socket jako stdin daného procesu.

sluzba.service:

Kód: [Vybrat]
[Service]
ExecStart=...
StandardInput=socket

sluzba.socket:
Kód: [Vybrat]
[Socket]
ListenFIFO=/path-to-socket

Tohle funguje a lze předávat data danému procesu na stdin přes daný socket.

Lze (a tady začíná můj dotaz) předat socket na stdin BEZ socket activation?

Jedná se mi o to, že existují programy, které se dají řídit jen přes sekvence v terminálu. Dosud se to řeší přes screen / tmux a send-keys funkce těchto terminal multiplexorů. Což se zase dost špatně řídí jako služba (to by ani tak nevadilo), ale hlavně výstup z daného procesu (stdout a stderr) končí v nenávratnu (zatímco při spuštění systemd se výstupy logují).

Výše uvedené řešení funguje, funguje dobře, ale není příliš vtipné, když se do socketu pošle echo "stop" > sluzba.socket, ona se nastartuje (socket activation) a v momentě, kdy si proces přečte stdin, tak se opět ukončí.
 
Je tedy nějaká možnost, jak tomu předat fifo socket jako stdin bez aktivace?


Sten

Re:systemd: FIFO socket jako stdin bez socket activation
« Odpověď #1 kdy: 26. 07. 2016, 11:32:56 »
Do služba.socket:
Kód: [Vybrat]
ExecStartPost=/bin/systemctl start služba.service
Nevidím ale moc rozdíl v tom, když se služba spustí, protože na socket přijde stop, a když se spustí hned a nic nedělá, až dostane první zprávu, která je stop.

Re:systemd: FIFO socket jako stdin bez socket activation
« Odpověď #2 kdy: 26. 07. 2016, 11:47:29 »
Do služba.socket:
Kód: [Vybrat]
ExecStartPost=/bin/systemctl start služba.service
Nevidím ale moc rozdíl v tom, když se služba spustí, protože na socket přijde stop, a když se spustí hned a nic nedělá, až dostane první zprávu, která je stop.

Možná jsem to nenapsal srozumitelně. Cílem je mít možnost předat procesu zprávy (textové příkazy) na stdin.

Ta služba běží sama o sobě a většinou s ní není potřeba nijak (po stdin) komunikovat. Je aktivní na síti. Ale občas je třeba tomu nějaký příkaz poslat. Umí se ukončit i na příkaz stop (poslaný na stdin). Korektně se ukončí. Tohle všechno funguje.

Funguje i systemctl start sluzba, systemctl stop sluzba, i když je to spuštěné tímto způsobem (což chci), tak funguje propojení fifo socket na stdin - skvělé.

Ten socket na stdin chci zachovat (k vůli tomu to dělám), ale rád bych vypnul socket activation.

Tedy, pokud danou službu zapnu systemctl start sluzba, aby šlo komunikovat pomocí socketu (to teď jde), ale v momentě, kdy se služba ukončí (ať již sama - proces služby se ukončí, nebo systemctl stop sluzba), tak nechci, aby se opět spustila přes socket.

Teoreticky by šlo dát do sluzba.service:
Kód: [Vybrat]
ExecStopPost=systemctl stop sluzba.socket
Otázka: spustí se ExecStopPost i v případě, kdy se proces korektně sám ukončí? Nebo je v případě, kdy je zavoláno systemctl stop?

Sten

Re:systemd: FIFO socket jako stdin bez socket activation
« Odpověď #3 kdy: 26. 07. 2016, 12:03:57 »
Fungovat to tak bude, ExecStopPost se spouští, pokud se hlavní proces služby z libovolného důvodu ukončil či pokud se službu nepodařilo spustit. (Ale vyžaduje plnou cestu k tomu, co spustit.)

Re:systemd: FIFO socket jako stdin bez socket activation
« Odpověď #4 kdy: 26. 07. 2016, 14:14:43 »
Fungovat to tak bude, ExecStopPost se spouští, pokud se hlavní proces služby z libovolného důvodu ukončil či pokud se službu nepodařilo spustit. (Ale vyžaduje plnou cestu k tomu, co spustit.)

S tou poznámkou, že ExecStopPost se spouští pod uživatelem User/Group  :(

Takže uživatel pro danou službu by musel mít právo na systemctl ...

No, asi to nechám tak jak to je. Je to lepší řešení než přes tmux, stejně ta služba bude běžet neustále, takže se socket activation neuplatní. Data se předávají.

Je ale nějaký technický důvod, proč lze fifo socket předat jen v souvislosti se socket activation? Bylo by fajn, kdyby to uměl i pro normální service.


Sten

Re:systemd: FIFO socket jako stdin bez socket activation
« Odpověď #5 kdy: 26. 07. 2016, 14:29:37 »
S tou poznámkou, že ExecStopPost se spouští pod uživatelem User/Group  :(

Takže uživatel pro danou službu by musel mít právo na systemctl ...

To by šlo vyřešit další službou, která bude na téhle záviset.

Je ale nějaký technický důvod, proč lze fifo socket předat jen v souvislosti se socket activation? Bylo by fajn, kdyby to uměl i pro normální service.

Pravděpodobně to nikdo zatím nepožadoval (nic podobného jsem v issue trackeru systemd nenašel). Osobně ani neznám službu, která by se ovládala přes stdin, ale poskytovala další služby někde jinde, takže by měla mít socket a běžet bez socket activation.

Re:systemd: FIFO socket jako stdin bez socket activation
« Odpověď #6 kdy: 26. 07. 2016, 14:47:46 »
Pravděpodobně to nikdo zatím nepožadoval (nic podobného jsem v issue trackeru systemd nenašel). Osobně ani neznám službu, která by se ovládala přes stdin, ale poskytovala další služby někde jinde, takže by měla mít socket a běžet bez socket activation.

Tak nepožadoval. Já to také nepožaduju, jen hledám vhodnější řešení spouštění těchto divných procesů. FIFO na STDIN je přesně to co hledám. Kdyby to systemd neuměl, tak se hold pojede dál postaru. Jsem rád, že to tam je. Jen bych to chtěl bez té aktivační části.

Implementované to evidentně je, funguje to a funguje i složitější část (spouštění service a předávání socketu), tak proč by neměla být přístupná i ta část bez aktivace? Navíc na ten standard input umí napojit i TTY.

Díky za čas, nechám to takto, pokud na něco přijdu, tak sem napíšu řešení.


Re:systemd: FIFO socket jako stdin bez socket activation
« Odpověď #7 kdy: 27. 07. 2016, 10:57:18 »
Tak zdá se, že problém s právy u Exec* bude vyřešen v systemd 231:

CHANGES WITH 231:

        * In service units the various ExecXYZ= settings have been extended
          with an additional special character as first argument of the
          assigned value: if the character '+' is used the specified command
          line it will be run with full privileges, regardless of User=,
          Group=, CapabilityBoundingSet= and similar options. The effect is
          similar to the existing PermissionsStartOnly= option, but allows
          configuration of this concept for each executed command line
          independently.