From Fedora Project Wiki
Warning.png
This page is a draft only
It is still under construction and content may change. Do not rely on the information on this page.

Systemd is the new Fedora init system. We need to document the following areas for packagers and system administrators:

  • Scriptlets for systemd -- these go in the spec files so we need them
  • How to write unit files -- packagers often get stuck writing init scripts for starting services. Since systemd is new, it'll be even more so.

Also need to make some decisions:

Documentation on how to do equivalent things in systemd as in SysVinit/Upstart in SysVinit compatibility are also necessary but probably should go to the documentation team and live in the general Fedora wiki instead of in the Packaging Guidelines. SysVinit to Systemd Cheatsheet started for this purpose.

Pages needing updates

https://fedoraproject.org/wiki/Packaging/Guidelines#Initscripts

https://fedoraproject.org/wiki/Packaging:ScriptletSnippets#Initscripts_Conventions

Need something comparable to this for systemd: https://fedoraproject.org/wiki/Packaging:SysVInitScript

Foundational decisions

SysVinit requirement

I justify the current guidelines requirement for a SysVinit script to be that there is an init script for the default initsystem. With this idea in mind, I'd change the requirement to be "There must be a init configuration for the default Fedora init system. In Fedora < 14, that's upstart (which understands sysVinit scripts and event files). In Fedora 14 or greater, that's systemd which understands sysvinit scripts or unit files.

There's another argument for SysVinit scripts -- they're often a lowest common denominator among people wanting to switch between init systems. (At least, upstart, SysVinit, and systemd in Fedora). If that's the reason then we should probably include that rationale in the guideline. We also should consider how the sysvinit script is to be tested. Does the sysvinit script override a systemd unit file? Do we have QA test booting Fedora with upstart? If we don't test that the init scripts work, I think that the argument that the init scripts are there for compatibility becomes much weaker.

Service start

Currently the Guidelines tell packagers not to start services when they install. The system administrator must do that themselves. There are a few updates that need to be done here:

  1. Do we want this at all? -- I think the answer is yes.
  2. Are there some exceptions? -- I think the answer is yes even now. Certain services are so core to how Linux works so we enable them when we install them. We need to come up with two things:
    1. a list of programs that we knowingly want this to be the case for.
    2. pick out the characteristics of those programs so we can write a Guidelines that people can use to judge if their service should start by itself or not.
  3. Most D-Bus services were enabled by default in F14 (i.e. udisks needed no manual enabling, always has been started whenever used). In F-14 we run more D-Bus services by default than SysV services. Hence one could say the majority of services were actually enabled by default. It might make sense to allow disabling some D-Bus services that so far could not be disabled.

Current Guidelines have the following required properties:

  • Don't turn on a service on upgrade if it was explicitly disabled:
  • Default for most network-listening services is off
  • Do not start the service after installation as they may be in changeroots, in an installer context, or in other situations where you don't want the services started.

Note that "systemctl install" is smart enough to detect a chroot() environment and will not start a service after making a configuration change.

Some bugs about bus/socket activation causing services to start

Scriptlets

This seems to be the common case where we install something but want the system administrator to explicitly enable it:

Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units

%post
if [ $1 -eq 1 ]; then
        # Package install, not upgrade
        /bin/systemctl daemon-reload >/dev/null 2>&1 || :
fi

%preun
if [ $1 -eq 0 ] ; then
        # Package removal, not upgrade
        /bin/systemctl disable httpd.service > /dev/null 2>&1 || :
        /bin/systemctl stop httpd.service > /dev/null 2>&1 || :
fi

%postun
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ] ; then
        # Package upgrade, not uninstall
        /bin/systemctl try-restart httpd.service >/dev/null 2>&1 || :
fi

This is probably what we want for "Core" systems that are enabled for the next reboot:

Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units

%post
if [ $1 -eq 1 ]; then
        # Package install, not upgrade
	/bin/systemctl enable httpd.service >/dev/null 2>&1 || :
fi

%preun
if [ $1 -eq 0 ] ; then
        # Package removal, not upgrade
        /bin/systemctl disable httpd.service >/dev/null 2>&1 || :
        /bin/systemctl stop httpd.service > /dev/null 2>&1 || :
fi

%postun  
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ] ; then
        # Package upgrade, not uninstall
        /bin/systemctl try-restart httpd.service >/dev/null 2>&1 || :
fi

There's no special handling for socket, hardware or bus activated services necessary. All that matters is that the unit files needing installation are listed on the systemctl command lines.

Writing unit files

I'm not very informed in this area. We need to know:

  • which options are necessary and which are optional
  • Which optional ones make sense to have in most unit files
  • Which ones to avoid Added one option -- needs a lot more work
  • Where to place unit files on the filessytem Review, add macro to a package
  • How to name unit files
    • Is there something special about the filename like /etc/init.d/httpd => service httpd [ACTION]
    • How do we determine which suffix to use with the file?

Filesystem placement

Unit files belong in /lib/systemd/system/. They are architecture independent (hence, not %{_lib}) and needed early in the boot process.

SystemVinit has a macro for this: %{_initddir}. I believe that rpmlint will issue a warning on spec files that use "/lib/" directly so having a macro for this would be a good idea.

Options to avoid

For most services, we do not want to use Require. Instead we want to use After. The difference is that Require will bring the service up and down when the Required service goes up and down. After will make the service startup after the required service but won't bring it up and down if the other service is restarted.

Here's an example of this common case:

  1. A web application needs postgres to store its data.
  2. It is set to start After postgres. On startup, the web application does not start until postgres does.
  3. Once running, the system administrator needs to restart postgres due to a config tweak.
  4. Since After was used, the web application may be temporarily unable to serve some requests but it does not need to restart in order to serve pages after the database comes back up.

Need an example of when Require is wanted.

Comments, Discussion

For the 'Start service' question, I think the packaging guidelines should be clarified to discriminate between services that are in the default install, and things that an admin explicitly installs. Services in the default install should almost always be on by default (because they are needed for a working system, which is why they are in the default install). Optional services that are installed explicitly should be off by default after installation. --mclasen 19:30, 9 September 2010 (UTC)

For 'Writing unit files', we probably need a good, simple example of a typical service unit file. There is pretty exhaustive information about the file formats and different kind of service files available in the various man pages shipped with systemd, and we should refer to those:

[systemd.unit(7)] [systemd.service(7)] [systemd.socket(7)] etc --mclasen 19:58, 9 September 2010 (UTC)