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

Debian: Add a systemd service file for LMS #18

Merged
merged 3 commits into from Feb 7, 2021

Conversation

mw9
Copy link
Contributor

@mw9 mw9 commented Feb 3, 2021

Summary

As discussed in the forum thread "systemd service file for LMS":
https://forums.slimdevices.com/showthread.php?113114-systemd-service-file-for-LMS

This proposed change adds a systemd unit file to the Debian installation package, and will stand in place of the "auto-generated" unit file that systemd currently creates. The "auto-generated" unit file simply calls the existing SysV init script.

Main features:

  • squeezeboxserver_safe goes, and LMS is started directly by systemd. No "supervisor", if it fails it stops.

  • Supports setting start up options by using /etc/default/logitechmediaserver, similar to the existing SysV init script. But LMS user is hardcoded to 'squeezeboxserver'.

  • Checks that /var/log/squeezeboxserver exists and is writeable, and creates it if not.
    (Good for systems with /var/log mounted as temporary file system).
    (But only on modern versions of systemd).

  • Addresses issue whereby LMS may start "too early", before network connections are configured.
    In systemd-speak, by including an After=network-online.target stanza in the unit file.
    It is left to the user to configure his system in a manner that gives appropriate meaning to the network-online.target.

I have removed a "Service reload" ('HUP' to LMS) action from the draft unit file that I posted in the forum thread. I am not sure that the function that it supplies is useful. It can be added at a later date if it is, indeed, useful.

I have left a complete set of comments in the unit file itself, which should help to explain why each option is set the way it is, so I won't repeat them here. I'd propose leaving them in there to assist knowledgeable users, but perhaps it is too wordy.

I have successfully built a Debian package on both Debian 9 and Debian 10, and I have installed the resulting package successfully on Debian 7 through 9. It should work equally well on any Debian derived system, with or without systemd, including Ubuntu and Devuan (a non-systemd port of Debian).

So I think it will prove itself in the real world of LMS users, but I shall not be surprised if the real world of LMS users does generate a surprise or two.

Commits

There are three commits:

Debian: Add systemd service unit

Adds boiler plate changes to Debian rules, config file, and the unit file itself. These are as described in the Debian wiki: https://wiki.debian.org/Teams/pkg-systemd/Packaging

Debian: Add systemd service unit - support older systems without 'init-system-helpers'

The boiler plate rules may or may not generate a dependency on a relatively new package, init-system-helpers.
This will break older Debian systems if the dependency is not removed, and there still appear to be plenty of users whose systems fall into this category. Installation will proceed successfully without it, although a "deb-systemd-helper: not found" message will be logged. Such users need to upgrade to a more modern system to remove it.

Debian: Add systemd service unit - add explanatory comments to LMS default file

This is not essential, but, I think helpful. It just adds additional explanatory comments in the existing LMS default file /etc/default/logitechmediaserver.

However, we should be aware that anyone who has edited his LMS default file away from the previously installed version will get the usual Debian "Configuration file has been modified" interactive prompt during installation. And that may trigger requests for help in the forum. I would hope not, but it might.

This change adds a systemd service unit file to the Debian installation
package.

On a systemd enabled system, this service file will be used in place of
the SysV init scripts that have traditionally used to start LMS. It
offers better logging at LMS start up by eliminating use of the
'squeezeboxserver_safe' script. Other behavioural differences are noted
by way of comments in the unit file.

On a "non-systemd" system, the existing SysV init scripts will be used.

The method used is that published in the Debian systemd packaging wiki:
https://wiki.debian.org/Teams/pkg-systemd/Packaging

The present packaging uses debhelper compatibility level 9, and that
remains unchanged. The required amendments are described in the wiki.

debian/control:
+ Added Build-Depends on dh-systemd (>= 1.5)
+ Also added '${misc:Depends}' and '${misc:Pre-Depends}'. This is not
  referenced in the wiki, but the "systemd helper" may populate these
  fields.

debian/rules:
+ 'dh' is now invoked '--with systemd'

debian/logitechmediaserver.service
+ This is the systemd unit file.
…t-system-helpers'

The debhelper systemd tools may automatically add a dependency on
package 'init-system-helpers' to the LMS package. (debhelper <= 11 will
do this).

This dependency cannot/may not be met on older Debian based systems
(Debian version <= 7), and in consequence the package would fail to
install on these systems. These systems will not be using 'systemd'.

There continues to be a significant element of the user base that runs
these older systems, and they need to be accommodated.

This change does that by simply removing the dependency from the
generated debian control file, should it be there.

The LMS package will be successfully installed and started regardless of
whether the 'init-system-helpers' package is available. The user of a
'deficient' system will see the following message, or similar, during
installation:

/var/lib/dpkg/info/logitechmediaserver.postinst: 61:
   /var/lib/dpkg/info/logitechmediaserver.postinst: deb-systemd-helper: not found

Nevertheless, LMS will have been installed, and the traditional SysV
init script will be in place.

Package 'init-system-helpers' has been an 'essential' package since
Debian version 9, so modern systems will not be impacted by removing the
dependency.
…fault file

This change adds some explanatory comments to the LMS defaults file
'/etc/defaults/logitechmediaserver'.

In particular, to highlight that the 'SLIMUSER' option is not effective
on a systemd based system.
@sciurius
Copy link

sciurius commented Feb 4, 2021

LMS user is hardcoded to 'squeezeboxserver'

For access purposes I run my LMS as an 'ordinary' user. It would be nice if the LMS user can be set in the /etc/default/logitechmediaserver .

@mw9
Copy link
Contributor Author

mw9 commented Feb 4, 2021

For access purposes I run my LMS as an 'ordinary' user. It would be nice if the LMS user can be set in the /etc/default/logitechmediaserver .

With the proposed unit file, a knowledgeable user can override the user setting (or any others), using systemctl edit. Or just by copying the unit file into /etc/systemd/system and editing to suit.

The existing Init script reads and executes the default file, and then uses start-stop-daemon to set the user. As far as I can see, the Debian package has used this method "for ever".

A systemd unit file does not offer that kind of flexibility. In an attempt to maintain some kind of compatibility with the use of the existing default file, the proposed unit file reads it and sets environment variables to achieve a similar effect. But this approach cannot work with systemd's USER setting in the unit file.

The unit file could choose to honour the SLIMUSER setting in the default file by passing that as an argument to LMS, with LMS launched as root. LMS would then take on the obligation to change the effective user/group after it has launched. I don't think that this code path has been used for many years (on Debian), and I don't have the competence to judge its effectiveness. So I took the cowardly approach and avoided it.

Perhaps there is a better way of launching LMS from a systemd unit file. For example, by using a "pre-launch" script/program to do the job. But that would add additional complexity.

@sciurius
Copy link

sciurius commented Feb 4, 2021

With the proposed unit file, a knowledgeable user can override the user setting (or any others),

Which is what I did a long time ago ;).

If there is no need for a more generic solution let's leave it as is. No problem.

@tomscytale
Copy link
Contributor

Nice!

Copy link
Contributor

@tomscytale tomscytale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good to see slimserver_safe finally going away.

I'll try make time to test this on a few debian and ubuntu systems over the weekend.

Does this support non-systemd versions of debian or ubuntu?
Systemd has been the default for both since April 2015.

@mherger do we have a list of debian and ubuntu versions that are officially supported?

# User to run Logitech Media Server as.
# Only applicable to platforms that do not use systemd.
# Running the server as a user other than the default squeezeboxserver
# is not recommended.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about a brief note explaining how to change the user with systemd

On platforms running systemd this will be ignored. 
If you want to change the user LMS runs as you need to use a 
systemd override file. 
With recent versions of systemd you can simply do this:
- sudo systemctl edit logitechmediaserver
- in that file add the line 
User=<new username>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly.

Bear in mind that the Debian installer sets everything up to run under user squeezeboxserver.

I would not personally be inclined to encourage users to depart from that. Knowledgeable users can figure it out for themselves.

That's my take, anyway. But I'm more than happy to change if that's what's wanted.

@@ -12,7 +12,16 @@ source=$(CURDIR)/../server

# main packaging script based on dh7 syntax
%:
dh $@
dh $@ --with=systemd
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does adding this arg do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It triggers debhelper into adding the necessary boiler plate to the install scripts to install the systemd unit file, and enable the unit. Explained here:

The method used is that published in the Debian systemd packaging wiki:
https://wiki.debian.org/Teams/pkg-systemd/Packaging

# 'network-online.target' is active and, even then, it is only effective
# if the user's system has been, or can be, configured to wait
# appropriately for network connections to be established before
# reaching this target.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the very detailed comments


# Note one consequence of this approach: LMS can now see environment
# variables that correspond to the defined run time variables, should it
# choose to look (it doesn't at present). This behaviour is an artefact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "defined run time variables" ?
I'd have thought that systemd mean less leakeage of environment between invoking environment and runtime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean the shell variables that are defined in the init script and defaults file. These are used to build the LMS command line. Perhaps I might have said "defined run time parameters". Or something else. I'll try to find some better words.

A systemd unit file does not provide for parameter substitution (no "local variables"), so I am using environment variables to achieve the same trick, i.e. read the defaults file to set environment variables, which we can then use. But that, of necessity, leads to a rather full environment. I believe that some other projects may have adopted the same approach.

This is all predicated on the notion that we really do wish to support use of the existing defaults file. I suspect that its main role is in defining SLIMOPTIONS.

Another way of doing it would be to abandon the defaults file altogether and teach users how to edit their unit files, possibly after explaining to them why the upgrade didn't "just work"... :(

@mw9
Copy link
Contributor Author

mw9 commented Feb 4, 2021

Does this support non-systemd versions of debian or ubuntu?

Yes.

Devuan: I don't have a Devuan system, but it is based on Debian, which supports both sysvinit and systemd, so it should just work.

Pre 2015: Tested on Debian 7 & Debian 6. There's a bit of chatter during installation, but installation succeeds. See comment in second commit.

But needs testing in the Real World to confirm that practice matches theory.

# User to run Logitech Media Server as
# User to run Logitech Media Server as.
# Only applicable to platforms that do not use systemd.
# Running the server as a user other than the default squeezeboxserver
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why you'd stick with squeezeboxserver for the user but use logitechmediaserver in most other cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've chosen to stick with what the existing installer does, this proposed change only adds a systemd unit file to the existing installation.

The existing installation is somewhat "conflicted". It creates the user squeezeboxserver, and sets up directories under a squeezeboxserver hierarchy. (/var/lib/squeezeboxserver, /var/log/squeezeboxserver).

logitechmediaserver is used only (I think) as the service name (i.e. the init script is named /etc/init.d/logitechmediaserver) and some items in the /etc hierarchy use that name. (So we have /etc/default/logitechmediaserver, /etc/logrotate.d/logitechmediaserver, but /etc/squeezeboxserver).

The systemd unit file that this change installs is named logitechmediaserver.service. Keeping the service name consistent between SysV and systemd is important, otherwise systemd will launch two instances - once from the unit file and one from the SysV init script.

A tidying up exercise might be nice to do, but I wouldn't wish to incorporate it into this change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd agree that keeping things as similar as possible to the current set up is the way to go. At the expense of maintaining the current inconsistency in naming.

Standards-Version: 3.9.5

Package: logitechmediaserver
Architecture: all
Conflicts: slimp3,slimserver,squeezecenter,squeezeboxserver
Replaces: slimp3,slimserver,squeezecenter,squeezeboxserver
Depends: perl (>= 5.8.8), adduser, libc6, libgcc1, libstdc++6, zlib1g, libio-socket-ssl-perl, ca-certificates
Depends: ${misc:Depends}, perl (>= 5.8.8), adduser, libc6, libgcc1, libstdc++6, zlib1g, libio-socket-ssl-perl, ca-certificates
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW: Perl 5.10 is now the minimum supported :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that's Debian 4 (Etch) out of the running !
I'll put in another PR.

@michaelherger
Copy link
Member

@mw9 - thanks for this PR. I'm a bit puzzled by how this would become active, used. You say

squeezeboxserver_safe goes..

But I don't see any related change. How would I tell debpkg to use this init script instead of the old one?

@tomscytale
Copy link
Contributor

do you have a copy of the .deb available somewhere I could download? would save me a few minutes building it.

@tomscytale
Copy link
Contributor

@mherger is there a list of supported versions of debian, ubuntu, red hat, centos?

Or is it more that a valiant attempt is made to support running on any reasonably sane system with perl >= 5.10 ?

@mw9
Copy link
Contributor Author

mw9 commented Feb 6, 2021

@mw9 - thanks for this PR. I'm a bit puzzled by how this would become active, used. You say

squeezeboxserver_safe goes..

But I don't see any related change. How would I tell debpkg to use this init script instead of the old one?

You need tell it nothing.

The secret sauce is in how systemd operates:

  • If systemd finds an enabled SysV init script but does not find a unit file for the service, it will generate a unit file on the fly that executes the SysV init script. That generated unit file is then used to launch the service. This is why the existing installation continues to work under systemd.

  • If, however, systemd does find an installed unit file (which will have the same name as the SysV init script), it will ignore the init script altogether, and simply use the installed unit file.

This change installs a unit file for systemd to use.

A no systemd here system will not concern itself with the installed unit file, and will run the init script in the usual way.

I hope that helps.

@mw9
Copy link
Contributor Author

mw9 commented Feb 6, 2021

do you have a copy of the .deb available somewhere I could download? would save me a few minutes building it.

Not that would be useful to you. (A somewhat patched armel version of LMS that is not fit for public viewing).
Testing the build on systems other than my own would be valuable in proving correct operation.

@michaelherger
Copy link
Member

You need tell it nothing.

The secret sauce is in how systemd operates:

So you're saying that if I merged this PR (and it was not broken), things should "just work"? 8.2 is in dev, I could give it a try and let the brave people using 8.2 report issues 😁.

@tomscytale
Copy link
Contributor

I've tested this on a Devuan 3 (Beowulf) x64 system (equivelant to Debian 10 Buster).

Everything works fine.

It's running on a tiny Linode instance. I'll leave it up for another few days (at a total cost of less than a dollar).

If any of you want to check it out pm me your ssh pubkey.

I think we can now be pretty confident that this will now work on the bulk of debian based systems.

So what testing is still necessary?

  • Definately Ubuntu 20.10
  • Maybe 20.04 and 19.10.
  • Debian 7? (last version to use sysvinit)
  • Ubuntu 15.04 ? (last version to use sysvinit)

This of course is all x86_64.

x86_32 is close enough that it should be covered.

ARM... harder to find cloud-based ARM systems to test on.
Plenty of RPi's about tho.

I'd suggest

  • doing the testing above on x86_64
  • releasing deb's for 8.2 for x86_64 and x86_32
  • wait for feedback, plus build and test on ARM
  • release ARM

Test matrix

Distro init manager version status
Debian systemd 10 tested OK
9 tested OK
8 tested OK
sysvinit 7
6
5
4 not supported
Devuan sysvinit 3 tested OK
2
Ubuntu systemd 20.10
20.04LTS
19.10
...
upstart/sysv 15.04
...

@mw9
Copy link
Contributor Author

mw9 commented Feb 7, 2021

You need tell it nothing.
The secret sauce is in how systemd operates:

So you're saying that if I merged this PR (and it was not broken), things should "just work"? 8.2 is in dev, I could give it a try and let the brave people using 8.2 report issues 😁.

That is the "design intent". People for whom it won't just work are those who have set SLIMUSER.

It might be worth waiting on @tomscytale, he was planning to set up a few test rigs.

@mw9
Copy link
Contributor Author

mw9 commented Feb 7, 2021

It might be worth waiting on @tomscytale, he was planning to set up a few test rigs.

Ah, I see that he has.

I can report that it works on armel based Debian 6 through 10. I don't plan to make a Debian 5 for testing.
I am not aware of any architectural dependencies/nuances that would get in the way.

@mherger
Copy link
Contributor

mherger commented Feb 7, 2021

Thank you very much guys! Let's give this a try.

@mherger mherger merged commit 14334b3 into LMS-Community:public/8.2 Feb 7, 2021
@tomscytale
Copy link
Contributor

ubuntu 20.10 looking good

there's a very high probability that this will just work everywhere now.

I will try to test on a few other systems over the coming days - in particular my RPi running aarch64 Ubuntu 20.10

@mw9
Copy link
Contributor Author

mw9 commented Feb 7, 2021

Thank you very much guys! Let's give this a try.

The new nightly arm deb looks good. Doubtless the other debs will be good as well.

@clivem
Copy link

clivem commented Feb 9, 2021

Tested on:
RPiOS (Buster 10) armhf
Ubuntu 20.04LTS aarch64

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

Successfully merging this pull request may close these issues.

None yet

6 participants