Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request - better support for running under systemd #53

Closed
peterhoeg opened this issue Sep 11, 2019 · 12 comments
Closed

Feature Request - better support for running under systemd #53

peterhoeg opened this issue Sep 11, 2019 · 12 comments

Comments

@peterhoeg
Copy link

With the upcoming split between backend and frontend, it's likely that a user would want to run the backend under systemd. If that is the case, there are a few things maestral can do to make things nicer:

  1. When running in the foreground, send a notification that it's up and running
  2. Continuously update its status (using the same sd_notify mechanism), so that systemctl --user status maestral will return the current status in the status field ("Syncing X out of Y", "Up to date" etc)
  3. Log to the journal instead of just stdout

Regd item 1, this means that systemd will only continue starting other services when maestral actively informs it that it is up and running. A use case would be the GUI running as a separate service under systemd that is dependent on the backup actually being up and running.

Regd item 2, we could avoid spamming the logs with "maestral.monitor INFO: Up to date" as it would simply just show the status in the status field.

Regd item 3, we currently get duplicated timestamps as journald captures the timestamp when the message was output to stdout and maestral also writes the time. Example:

Sep 08 21:55:59 mildred maestral[3444]: 2019-09-08 21:55:59 maestral.monitor INFO: Up to date

There are some python modules that can help with this:

@peterhoeg
Copy link
Author

An example of the improved status (item 2):

emperor.uwsgi.service - uWSGI Emperor
 Loaded: loaded (/etc/systemd/system/emperor.uwsgi.service)
       Active: active (running) since Tue, 17 May 2011 08:51:31 +0200; 5s ago
Main PID: 30567 (uwsgi)
       Status: "The Emperor is governing 1 vassals"
       CGroup: name=systemd:/system/emperor.uwsgi.service
               ├ 30567 /root/uwsgi/uwsgi --ini /etc/uwsgi/emperor.ini
               ├ 30568 /root/uwsgi/uwsgi --ini werkzeug.ini
               └ 30569 /root/uwsgi/uwsgi --ini werkzeug.ini

@samschott
Copy link
Owner

Those are all good suggestions. Two possible issues that I see:

  • Is there a way to detect if Maestral is started under systemd? If not, could there be any issues with always emitting such notifications, or logging to the journal? The "start-on-login" option of the GUI for instance creates a Desktop Entry "~/.config/autostart/maestral.desktop" and does not use systemd.

  • It looks like python-systemd cannot directly be installed with pip without installing systemd-devel and other packages first. This would complicate the installation process for many people.

If the former is not an issue, and the latter can be circumvented, I am happy to review pull requests!

Regarding spamming the log with "Up to date" messages: You can raise the log level with for instance maestral log level WARNING. This will dramatically reduce the size of log files and will be the default in the next release. Or one can write a custom handler which ignores duplicate messages.

@peterhoeg
Copy link
Author

Is there a way to detect if Maestral is started under systemd?

systemd v232 and above sets an $INVOCATION_ID environment variable

The "start-on-login" option of the GUI for instance creates a Desktop Entry "~/.config/autostart/maestral.desktop" and does not use systemd.

The user could always just delete that file (and disable autostart) if they want systemd to run it. Alternatively, the maestral.desktop could execute systemctl --user maestral.target and we then have a target that depends on 2 services: the backend and the GUI.

Regarding spamming the log with "Up to date" messages

That specific message is more of a status message rather than a log message imho. Again, that could be solved at least when running under systemd.

It looks like python-systemd cannot directly be installed with pip without installing systemd-devel and other packages first

According to https://github.com/systemd/python-systemd#installation :

This module should be packaged for almost all Linux distributions.

@samschott
Copy link
Owner

systemd v232 and above sets an $INVOCATION_ID environment variable

Perfect, that simplifies things. I see no direct conflict with the GUI's autostart function, it could either continue as is or use systemd on Linux.

That specific message is more of a status message rather than a log message imho.

It is. But the way Maestral is set up at the moment, it uses log messages to communicate its status. Anything of level INFO and higher is used to populate the status and will affect the appearance of the GUI. WARNING is typically used for sync issues. ERROR and higher indicates problems which prevent Maestral from continuing to function, such as a deleted Dropbox folder or revoked access. They will raise a blocking error dialog which the user must act upon.

In that system, "Up to date" is indeed a logging message of level INFO.

According to https://github.com/systemd/python-systemd#installation...

True. But it needs to be installed with the system's package manager instead of pip. Installation with pip requires the installation of systemd headers first. This means that a simple pip install maestral will no longer be possible.

@peterhoeg
Copy link
Author

peterhoeg commented Sep 13, 2019 via email

@peterhoeg
Copy link
Author

peterhoeg commented Sep 13, 2019 via email

@samschott
Copy link
Owner

Turns out there are a few of the python modules that require compilation

There is. I take back what I said, python-systemd seems to compile just fine when during a pip-install. It seems that most Linux distributions already come with the required packages for a compilation. In this case, I am happy to use it.

I might be going off on a tangent here, but one thing that could be interesting to explore is dbus activation

The current implementation (develop branch) does something very similar but uses Pyro4. On startup, the daemon will write a file with its pid and socket. This is used by the GUI or CLI to find the process and, in case of the GUI, to attach to a running daemon or otherwise create a new one. When the daemon is shut-down or crashes, the pid-file will be deleted again.

I am reluctant to use dbus because it is not installed on macOS by default (but can be installed via homebrew).

@samschott
Copy link
Owner

Small side-note: Maestral already uses launchd on macOS to auto-start on login, which is the equivalent to systemd. But it has the advantage that login-items registered with launchd will show up in the user's "System Preferences". Whereas GNOME does not seem to list systemd login-items under "Startup Applications" in the GUI, only ".desktop" entries in "~/.config/autostart".

@peterhoeg
Copy link
Author

peterhoeg commented Sep 13, 2019 via email

@peterhoeg
Copy link
Author

peterhoeg commented Sep 13, 2019 via email

@samschott
Copy link
Owner

Right, I have implemented using the journal when started from systemd, and sending status updates when running as a service with "Type=notify". You can try it out from the develop branch if you like.

For now, I will not rely on systemd/launchd to launch the daemon for the gui. While macOS is guaranteed to have launchd available, too many Linux systems which have Maestral installed do not use systemd (for instance CentOS 6).

@peterhoeg
Copy link
Author

0.4.0 is very nice. I suggest we close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants