diff mbox

[1/1] skeleton: add systemd network.service unit

Message ID 1388713112-4686-1-git-send-email-vsergeev@kumunetworks.com
State Superseded
Headers show

Commit Message

Ivan Sergeev Jan. 3, 2014, 1:38 a.m. UTC
Add and enable a systemd unit file to bring up / down network with ifup /
ifdown, analogous to the skeleton/etc/init.d/S40network init script.

Signed-off-by: Ivan Sergeev <vsergeev@kumunetworks.com>
---
 .../system/multi-user.target.wants/network.service  |  1 +
 system/skeleton/etc/systemd/system/network.service  | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+)
 create mode 120000 system/skeleton/etc/systemd/system/multi-user.target.wants/network.service
 create mode 100644 system/skeleton/etc/systemd/system/network.service

Comments

Thomas Petazzoni Jan. 3, 2014, 7:13 p.m. UTC | #1
Dear Ivan Sergeev,

On Thu,  2 Jan 2014 17:38:32 -0800, Ivan Sergeev wrote:
> Add and enable a systemd unit file to bring up / down network with ifup /
> ifdown, analogous to the skeleton/etc/init.d/S40network init script.
> 
> Signed-off-by: Ivan Sergeev <vsergeev@kumunetworks.com>
> ---
>  .../system/multi-user.target.wants/network.service  |  1 +
>  system/skeleton/etc/systemd/system/network.service  | 21 +++++++++++++++++++++
>  2 files changed, 22 insertions(+)
>  create mode 120000 system/skeleton/etc/systemd/system/multi-user.target.wants/network.service
>  create mode 100644 system/skeleton/etc/systemd/system/network.service

We probably want to make that conditional on the type of init system
that is used, no?

Thomas
Ivan Sergeev Jan. 3, 2014, 7:41 p.m. UTC | #2
Hah, sorry. I forgot the reply all. This was supposed to be my follow up
discussion email:

Hello buildroot,

I'm submitting this in hopes of catching up network init in systemd with
that of busybox init, which is currently served by /etc/init.d/S40network.
This patch adds and enables network.service (which assumes ifup / ifdown
exists and uses them like /etc/init.d/S40network does).

I also wanted to bring up a more general issue:

Currently, it seems that the /etc/init.d scripts are copied over blindly
from the target skeleton to the target even if systemd (and not busybox) is
the chosen init system. Moving forward, having both busybox and systemd
init files in the skeleton, like this patch would have, will always clutter
/etc/ with some unused init files in the target system, since only one init
system will be active.

Should such init files be conditional targets in system/system.mk?  Or
should S40network be owned and copied over by package/busybox, and
network.service be owned and copied over by package/systemd, instead of
having them included statically in the target skeleton?

Thanks,
~vsergeev
Ivan Sergeev


On Fri, Jan 3, 2014 at 11:13 AM, Thomas Petazzoni <
thomas.petazzoni@free-electrons.com> wrote:

> Dear Ivan Sergeev,
>
> On Thu,  2 Jan 2014 17:38:32 -0800, Ivan Sergeev wrote:
> > Add and enable a systemd unit file to bring up / down network with ifup /
> > ifdown, analogous to the skeleton/etc/init.d/S40network init script.
> >
> > Signed-off-by: Ivan Sergeev <vsergeev@kumunetworks.com>
> > ---
> >  .../system/multi-user.target.wants/network.service  |  1 +
> >  system/skeleton/etc/systemd/system/network.service  | 21
> +++++++++++++++++++++
> >  2 files changed, 22 insertions(+)
> >  create mode 120000
> system/skeleton/etc/systemd/system/multi-user.target.wants/network.service
> >  create mode 100644 system/skeleton/etc/systemd/system/network.service
>
> We probably want to make that conditional on the type of init system
> that is used, no?
>
> Thomas
> --
> Thomas Petazzoni, CTO, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
>
Arnout Vandecappelle Jan. 28, 2014, 7:13 a.m. UTC | #3
On 03/01/14 20:41, Ivan Sergeev wrote:
> Currently, it seems that the /etc/init.d scripts are copied over blindly
> from the target skeleton to the target even if systemd (and not busybox)
> is the chosen init system. Moving forward, having both busybox and
> systemd init files in the skeleton, like this patch would have, will
> always clutter /etc/ with some unused init files in the target system,
> since only one init system will be active.
>
> Should such init files be conditional targets in system/system.mk
> ?  Or should S40network be owned and copied over by
> package/busybox, and network.service be owned and copied over by
> package/systemd, instead of having them included statically in the target
> skeleton?

  I completely agree that the way it is done now is far from ideal.

  I think the best way to work with this would be to:

- remove the contents of the init.d directory from the skeleton;

- create a new skeleton fragment system/skeleton-init-sysv that contains 
etc/init.d;

- create a new skeleton fragment system/skeleton-init-systemd that 
contains whatever support files are needed by systemd (currently nothing, 
but your patch would add the networking unit file);

- copy the correct skeleton fragment as part of the .root target, but 
only if the default skeleton was selected - with a custom skeleton, it's 
up to the user to provide the right systemd/init.d;



  Regards,
  Arnout
Maxime Hadjinlian Jan. 28, 2014, 8:25 a.m. UTC | #4
Hi all

On Tue, Jan 28, 2014 at 8:13 AM, Arnout Vandecappelle <arnout@mind.be> wrote:
> On 03/01/14 20:41, Ivan Sergeev wrote:
>>
>> Currently, it seems that the /etc/init.d scripts are copied over blindly
>> from the target skeleton to the target even if systemd (and not busybox)
>> is the chosen init system. Moving forward, having both busybox and
>> systemd init files in the skeleton, like this patch would have, will
>> always clutter /etc/ with some unused init files in the target system,
>> since only one init system will be active.
>>
>> Should such init files be conditional targets in system/system.mk
>> ?  Or should S40network be owned and copied over by
>> package/busybox, and network.service be owned and copied over by
>> package/systemd, instead of having them included statically in the target
>> skeleton?
>
>
>  I completely agree that the way it is done now is far from ideal.
>
>  I think the best way to work with this would be to:
>
> - remove the contents of the init.d directory from the skeleton;
>
> - create a new skeleton fragment system/skeleton-init-sysv that contains
> etc/init.d;
>
> - create a new skeleton fragment system/skeleton-init-systemd that contains
> whatever support files are needed by systemd (currently nothing, but your
> patch would add the networking unit file);
>
> - copy the correct skeleton fragment as part of the .root target, but only
> if the default skeleton was selected - with a custom skeleton, it's up to
> the user to provide the right systemd/init.d;
I  agree with you and as a matter of fact, I had already started
working on a patch that implement exactly this.

I would even like to go even further, as I have noticed that a lot of
the defined LIBFOO_INSTALL_INIT_SYSTEMD and LIBFOO_INSTALL_INIT_SYSV
almost always do the exact same stuff.
I would like for the infrastructure to take care of this, if no
function is defined, and a .service or S\d{0,2}*, then we should take
it and install it.

In that case, any particular requirements, the package define a
function, other than that, it's taken care of and we avoid duplicate
code in all the packages.

>
>
>
>  Regards,
>  Arnout
>
> --
> Arnout Vandecappelle                          arnout at mind be
> Senior Embedded Software Architect            +32-16-286500
> Essensium/Mind                                http://www.mind.be
> G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
> LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
> GPG fingerprint:  7CB5 E4CC 6C2E EFD4 6E3D A754 F963 ECAB 2450 2F1F
>
> _______________________________________________
> buildroot mailing list
> buildroot@busybox.net
> http://lists.busybox.net/mailman/listinfo/buildroot
Arnout Vandecappelle Jan. 28, 2014, 8:38 a.m. UTC | #5
On 28/01/14 09:25, Maxime Hadjinlian wrote:
> Hi all
>
> On Tue, Jan 28, 2014 at 8:13 AM, Arnout Vandecappelle <arnout@mind.be> 
> wrote:
> > On 03/01/14 20:41, Ivan Sergeev wrote:
> >>
> >> Currently, it seems that the /etc/init.d scripts are copied over blindly
> >> from the target skeleton to the target even if systemd (and not busybox)
> >> is the chosen init system. Moving forward, having both busybox and
> >> systemd init files in the skeleton, like this patch would have, will
> >> always clutter /etc/ with some unused init files in the target system,
> >> since only one init system will be active.
> >>
> >> Should such init files be conditional targets in system/system.mk
> >> ?  Or should S40network be owned and copied over by
> >> package/busybox, and network.service be owned and copied over by
> >> package/systemd, instead of having them included statically in the 
> target
> >> skeleton?
> >
> >
> >   I completely agree that the way it is done now is far from ideal.
> >
> >   I think the best way to work with this would be to:
> >
> > - remove the contents of the init.d directory from the skeleton;
> >
> > - create a new skeleton fragment system/skeleton-init-sysv that contains
> > etc/init.d;
> >
> > - create a new skeleton fragment system/skeleton-init-systemd that 
> contains
> > whatever support files are needed by systemd (currently nothing, but your
> > patch would add the networking unit file);
> >
> > - copy the correct skeleton fragment as part of the .root target, but 
> only
> > if the default skeleton was selected - with a custom skeleton, it's up to
> > the user to provide the right systemd/init.d;
> I  agree with you and as a matter of fact, I had already started
> working on a patch that implement exactly this.
>
> I would even like to go even further, as I have noticed that a lot of
> the defined LIBFOO_INSTALL_INIT_SYSTEMD and LIBFOO_INSTALL_INIT_SYSV
> almost always do the exact same stuff.
> I would like for the infrastructure to take care of this, if no
> function is defined, and a .service or S\d{0,2}*, then we should take
> it and install it.

  Sounds like a great idea!

>
> In that case, any particular requirements, the package define a
> function, other than that, it's taken care of and we avoid duplicate
> code in all the packages.

  Probably the whole INSTALL_INIT_* stuff can even be removed - the 
number of packages that require special-casing is currently zero and may 
not ever be larger than zero. And if they do, it's not that difficult to 
make conditional post-install hooks.

  If you make a patch, don't forget to update the documentation!


  Regards,
  Arnout


>
> >
> >
> >
> >   Regards,
> >   Arnout
> >
> > --
> > Arnout Vandecappelle                          arnout at mind be
> > Senior Embedded Software Architect            +32-16-286500
> > Essensium/Mind                                http://www.mind.be
> > G.Geenslaan 9, 3001 Leuven, Belgium           BE 872 984 063 RPR Leuven
> > LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle
> > GPG fingerprint:  7CB5 E4CC 6C2E EFD4 6E3D A754 F963 ECAB 2450 2F1F
> >
> > _______________________________________________
> > buildroot mailing list
> > buildroot@busybox.net
> > http://lists.busybox.net/mailman/listinfo/buildroot
Maxime Ripard Jan. 28, 2014, 1:20 p.m. UTC | #6
On Tue, Jan 28, 2014 at 09:25:20AM +0100, Maxime Hadjinlian wrote:
> I would even like to go even further, as I have noticed that a lot of
> the defined LIBFOO_INSTALL_INIT_SYSTEMD and LIBFOO_INSTALL_INIT_SYSV
> almost always do the exact same stuff.
> I would like for the infrastructure to take care of this, if no
> function is defined, and a .service or S\d{0,2}*, then we should take
> it and install it.
> 
> In that case, any particular requirements, the package define a
> function, other than that, it's taken care of and we avoid duplicate
> code in all the packages.

Actually, there's two main issues that prevents this in the systemd
case, and are why we did it that way:
  - the multi-user-wants thing is actually comparable to the sysvinit
    runlevels. Some packages might want to set their units to other
    targets than multi-user (for example, graphical applications are
    likely to go in the graphical target, not the multi-user one)
  - Some units also takes "variables" from the created link names. For
    example, when you want to run getty, you just have a single getty
    unit, and the device to run getty on is set in the link name to
    that unit (so you'd end up with a link in multi-user.target.wants
    that will be getty.ttyS0.service, linking to
    /etc/systemd/system/getty.service).

At the time, we thought that in the systemd case, the easiest would be
to simply write down the 2-3 commands we need to setup the unit,
instead of having to give a whole bunch of variables. And we did the
same for sysvinit scripts, for consistency.

Maxime
Arnout Vandecappelle Jan. 28, 2014, 5:20 p.m. UTC | #7
On 28/01/14 14:20, Maxime Ripard wrote:
> On Tue, Jan 28, 2014 at 09:25:20AM +0100, Maxime Hadjinlian wrote:
>> I would even like to go even further, as I have noticed that a lot of
>> the defined LIBFOO_INSTALL_INIT_SYSTEMD and LIBFOO_INSTALL_INIT_SYSV
>> almost always do the exact same stuff.
>> I would like for the infrastructure to take care of this, if no
>> function is defined, and a .service or S\d{0,2}*, then we should take
>> it and install it.
>>
>> In that case, any particular requirements, the package define a
>> function, other than that, it's taken care of and we avoid duplicate
>> code in all the packages.
>
> Actually, there's two main issues that prevents this in the systemd
> case, and are why we did it that way:
>    - the multi-user-wants thing is actually comparable to the sysvinit
>      runlevels. Some packages might want to set their units to other
>      targets than multi-user (for example, graphical applications are
>      likely to go in the graphical target, not the multi-user one)

  I disagree with this one. Buildroot's defaults should support only a 
single runlevel/target. That's how it's done for sysv init, and I'm very 
happy with it: it's dead easy to see which scripts will be executed at 
startup, you don't have to find out the runlevel etc. With systemd, 
things can become even more complex (because there can be several 
"targets" active at the same time IIRC), and I'd prefer to exclude this 
complexity by default.

  If a user requires several runlevels/targets, than most likely any 
default that buildroot provide will not fit anyway, so the user will have 
to manipulate things in their rootfs overlay or post-build script anyway. 
Therefore, I think it is better for the user if the defaults are simple 
and predictable.


>    - Some units also takes "variables" from the created link names. For
>      example, when you want to run getty, you just have a single getty
>      unit, and the device to run getty on is set in the link name to
>      that unit (so you'd end up with a link in multi-user.target.wants
>      that will be getty.ttyS0.service, linking to
>      /etc/systemd/system/getty.service).

  That is one of the special cases that would be handled in a 
post-install hook. But specifically for the getty case, it's not even 
necessary because we start only a single getty in the default setup, so 
we can directly install it to getty@ttyS0.service .


> At the time, we thought that in the systemd case, the easiest would be
> to simply write down the 2-3 commands we need to setup the unit,
> instead of having to give a whole bunch of variables. And we did the
> same for sysvinit scripts, for consistency.

  I think at the time, we mainly thought that we didn't know yet if the 
installation could be generalized. Now that we have a few packages that 
install unit files, it's more clear that they always to the same.

  Also, as far as I understand, the idea is not to add variables, but 
rather to check for the existence of package/foo/*.service and install that.


  Regards,
  Arnout

>
> Maxime
>
Maxime Ripard Jan. 29, 2014, 8:26 a.m. UTC | #8
On Tue, Jan 28, 2014 at 06:20:20PM +0100, Arnout Vandecappelle wrote:
> On 28/01/14 14:20, Maxime Ripard wrote:
> >On Tue, Jan 28, 2014 at 09:25:20AM +0100, Maxime Hadjinlian wrote:
> >>I would even like to go even further, as I have noticed that a lot of
> >>the defined LIBFOO_INSTALL_INIT_SYSTEMD and LIBFOO_INSTALL_INIT_SYSV
> >>almost always do the exact same stuff.
> >>I would like for the infrastructure to take care of this, if no
> >>function is defined, and a .service or S\d{0,2}*, then we should take
> >>it and install it.
> >>
> >>In that case, any particular requirements, the package define a
> >>function, other than that, it's taken care of and we avoid duplicate
> >>code in all the packages.
> >
> >Actually, there's two main issues that prevents this in the systemd
> >case, and are why we did it that way:
> >   - the multi-user-wants thing is actually comparable to the sysvinit
> >     runlevels. Some packages might want to set their units to other
> >     targets than multi-user (for example, graphical applications are
> >     likely to go in the graphical target, not the multi-user one)
> 
>  I disagree with this one. Buildroot's defaults should support only
> a single runlevel/target. That's how it's done for sysv init, and

Hmm, afaik, it's not done at all in the sysvinit case, because the
default sysvinit we use most of the time (busybox's) doesn't handle
the runlevel at all. It's not really the same story there.

> I'm very happy with it: it's dead easy to see which scripts will be
> executed at startup, you don't have to find out the runlevel etc.
> With systemd, things can become even more complex (because there can
> be several "targets" active at the same time IIRC), and I'd prefer
> to exclude this complexity by default.
> 
>  If a user requires several runlevels/targets, than most likely any
> default that buildroot provide will not fit anyway, so the user will
> have to manipulate things in their rootfs overlay or post-build
> script anyway. Therefore, I think it is better for the user if the
> defaults are simple and predictable.
> 
> 
> >   - Some units also takes "variables" from the created link names. For
> >     example, when you want to run getty, you just have a single getty
> >     unit, and the device to run getty on is set in the link name to
> >     that unit (so you'd end up with a link in multi-user.target.wants
> >     that will be getty.ttyS0.service, linking to
> >     /etc/systemd/system/getty.service).
> 
>  That is one of the special cases that would be handled in a
> post-install hook. But specifically for the getty case, it's not
> even necessary because we start only a single getty in the default
> setup, so we can directly install it to getty@ttyS0.service .

Which won't work if you don't have a different tty to export a shell
on, but yes, I get your point.

> >At the time, we thought that in the systemd case, the easiest would be
> >to simply write down the 2-3 commands we need to setup the unit,
> >instead of having to give a whole bunch of variables. And we did the
> >same for sysvinit scripts, for consistency.
> 
>  I think at the time, we mainly thought that we didn't know yet if
> the installation could be generalized. Now that we have a few
> packages that install unit files, it's more clear that they always
> to the same.

We have *three* packages with systemd units in current master. I
hardly see how you can generalize something out of 3 (similar)
samples.

>  Also, as far as I understand, the idea is not to add variables, but
> rather to check for the existence of package/foo/*.service and
> install that.

This also doesn't cover the case anymore where a package would ship
together with the source code a systemd unit file. I expect it to be
more and more common, and it's something that we will want to use most
of the time, and not duplicate the unit file in the buildroot package
itself.

Maxime
Maxime Hadjinlian Jan. 29, 2014, 9:07 a.m. UTC | #9
On Wed, Jan 29, 2014 at 9:26 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
>
>
> On Tue, Jan 28, 2014 at 06:20:20PM +0100, Arnout Vandecappelle wrote:
>> On 28/01/14 14:20, Maxime Ripard wrote:
>> >On Tue, Jan 28, 2014 at 09:25:20AM +0100, Maxime Hadjinlian wrote:
>> >>I would even like to go even further, as I have noticed that a lot of
>> >>the defined LIBFOO_INSTALL_INIT_SYSTEMD and LIBFOO_INSTALL_INIT_SYSV
>> >>almost always do the exact same stuff.
>> >>I would like for the infrastructure to take care of this, if no
>> >>function is defined, and a .service or S\d{0,2}*, then we should take
>> >>it and install it.
>> >>
>> >>In that case, any particular requirements, the package define a
>> >>function, other than that, it's taken care of and we avoid duplicate
>> >>code in all the packages.
>> >
>> >Actually, there's two main issues that prevents this in the systemd
>> >case, and are why we did it that way:
>> >   - the multi-user-wants thing is actually comparable to the sysvinit
>> >     runlevels. Some packages might want to set their units to other
>> >     targets than multi-user (for example, graphical applications are
>> >     likely to go in the graphical target, not the multi-user one)
>>
>>  I disagree with this one. Buildroot's defaults should support only
>> a single runlevel/target. That's how it's done for sysv init, and
>
> Hmm, afaik, it's not done at all in the sysvinit case, because the
> default sysvinit we use most of the time (busybox's) doesn't handle
> the runlevel at all. It's not really the same story there.
>
>> I'm very happy with it: it's dead easy to see which scripts will be
>> executed at startup, you don't have to find out the runlevel etc.
>> With systemd, things can become even more complex (because there can
>> be several "targets" active at the same time IIRC), and I'd prefer
>> to exclude this complexity by default.
>>
>>  If a user requires several runlevels/targets, than most likely any
>> default that buildroot provide will not fit anyway, so the user will
>> have to manipulate things in their rootfs overlay or post-build
>> script anyway. Therefore, I think it is better for the user if the
>> defaults are simple and predictable.
>>
>>
>> >   - Some units also takes "variables" from the created link names. For
>> >     example, when you want to run getty, you just have a single getty
>> >     unit, and the device to run getty on is set in the link name to
>> >     that unit (so you'd end up with a link in multi-user.target.wants
>> >     that will be getty.ttyS0.service, linking to
>> >     /etc/systemd/system/getty.service).
>>
>>  That is one of the special cases that would be handled in a
>> post-install hook. But specifically for the getty case, it's not
>> even necessary because we start only a single getty in the default
>> setup, so we can directly install it to getty@ttyS0.service .
>
> Which won't work if you don't have a different tty to export a shell
> on, but yes, I get your point.
>
>> >At the time, we thought that in the systemd case, the easiest would be
>> >to simply write down the 2-3 commands we need to setup the unit,
>> >instead of having to give a whole bunch of variables. And we did the
>> >same for sysvinit scripts, for consistency.
>>
>>  I think at the time, we mainly thought that we didn't know yet if
>> the installation could be generalized. Now that we have a few
>> packages that install unit files, it's more clear that they always
>> to the same.
>
> We have *three* packages with systemd units in current master. I
> hardly see how you can generalize something out of 3 (similar)
> samples.
Well to be fair, a *lot* of startup script (Whatever if it's SysV,
systemd, or another one), it is usually a single file starting a
binary with command line arguments. Nothing really fancy.
>
>>  Also, as far as I understand, the idea is not to add variables, but
>> rather to check for the existence of package/foo/*.service and
>> install that.
>
> This also doesn't cover the case anymore where a package would ship
> together with the source code a systemd unit file. I expect it to be
> more and more common, and it's something that we will want to use most
> of the time, and not duplicate the unit file in the buildroot package
> itself.
If a package ship with the unit file in its source code, there should
be a way to install it using the package configure/make or whatever is
provided for that. So you won't even copy the file, we won't need a
copy. Or if it's not possible, we would define the helper function,
and it will install it, which would avoid the copy again.
>
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux, Kernel and Android engineering
> http://free-electrons.com
Peter Korsgaard Jan. 29, 2014, 9:09 a.m. UTC | #10
>>>>> "Maxime" == Maxime Ripard <maxime.ripard@free-electrons.com> writes:

Hi,

 >> Also, as far as I understand, the idea is not to add variables, but
 >> rather to check for the existence of package/foo/*.service and
 >> install that.

 > This also doesn't cover the case anymore where a package would ship
 > together with the source code a systemd unit file. I expect it to be
 > more and more common, and it's something that we will want to use most
 > of the time, and not duplicate the unit file in the buildroot package
 > itself.

Good point. I would certainly not want us to write our own service files
if upstream provides a workable one.
diff mbox

Patch

diff --git a/system/skeleton/etc/systemd/system/multi-user.target.wants/network.service b/system/skeleton/etc/systemd/system/multi-user.target.wants/network.service
new file mode 120000
index 0000000..d3558f9
--- /dev/null
+++ b/system/skeleton/etc/systemd/system/multi-user.target.wants/network.service
@@ -0,0 +1 @@ 
+../network.service
\ No newline at end of file
diff --git a/system/skeleton/etc/systemd/system/network.service b/system/skeleton/etc/systemd/system/network.service
new file mode 100644
index 0000000..0d77bb8
--- /dev/null
+++ b/system/skeleton/etc/systemd/system/network.service
@@ -0,0 +1,21 @@ 
+[Unit]
+Description=Network Connectivity
+Wants=network.target
+Before=network.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+
+# lo is brought up earlier, which will cause the upcoming "ifup -a" to fail
+# with exit code 1, due to an "ip: RTNETLINK answers: File exists" error during
+# its "ip addr add ..." command, subsequently causing this unit to fail even
+# though it is a benign error. Flushing the lo address with the command below
+# before ifup prevents this failure.
+ExecStart=/sbin/ip addr flush dev lo
+
+ExecStart=/sbin/ifup -a
+ExecStop=/sbin/ifdown -a
+
+[Install]
+WantedBy=multi-user.target