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

Don't override BLOCK_USER on service reload #335

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

JackNewman12
Copy link
Contributor

This might be more a personal choice, but at least how we are using finit if we stop a service manually (only done during debugging) we want it to stay stopped regardless of other things happening in the system.

I think this makes sense and follows systemd where reloading a config doesn't suddenly start the service (or other unrelated services).

Sorry for all the pull request spam, I just wanted to keep all the changes I've done isolated from each other. Feel free to reject any of these.

If the user has asked for the service to stop, keep it stopped.

This keeps it a little more inline with systemd where reloading a config
and enable/disable/restarting a service is separate.
@JackNewman12
Copy link
Contributor Author

Actually on my drive home I had a few more thoughts about this. It might be better if I first explain how we use finit and why I wanted it to behave like this.

Most of our services are in a ro filesystem /etc/finit.d, any services that need to be dynamically added/removed are thrown in /var/finit.d (which is symlinked to /etc/finit.d/enabled). This is all working perfectly for us, we can add/remove services as needed then sighup finit to do all the hard work.

However when debugging I'd like to disable a service. Unfortunately disabling a service in /var/finit.d causes it to get deleted, and it is not possible to disable a service in /etc/finit.d

Perhaps if services had a "disabled" flag that might be more appropriate. Thanks for your time. Let us know what you think.

@troglobit
Copy link
Owner

First of all, no need to apologize. I really appreciate getting PRs for my projects, in particular when they come with motivation and are split up in logical chunks like you've done! :-)

Now, Finit is not systemd and we don't strive to replace or replicate all behaviors of it. But I have to admit, this is one of the cases I've run into myself a few times. However, there are lots of users out there that expect the existing behavior. My former employer, for instance, switches between various system configurations and swaps in/out a lot of services, activating all changes with initctl reload should behave the same as rebooting the device, only quicker. Breaking those use-cases is a big no-no.

I didn't fully understand your setup, have you considered using an overlay over /etc? That's what we do in a few projects. It's quite handy to be able to use initctl enable|disable foo to manage symlinks from /etc/finit.d/availble/ -> /etc/finit.d/enabled/foo. We make sure to have all possible services pre-configured in /etc/finit.d/availble/ and control their behavior by their own respective configurations files in /etc/, and command line args infused from /etc/default/foo.

I need to give this one a think, and talk to my colleague again, to see what we can do. I'd very much like to support both existing and new use-cases, and breaking changes I try to do only with major version numbers. E.g., file format change is planned for 5.0 and maybe this could be postponed for that too.

@troglobit
Copy link
Owner

I've now discussed this too with my colleague. He agrees with me, and we will not accept this PR right now.

However, he reacted to the following paragraphs (my emphasis added) and suggested two things:

  1. I need to update and clarify the documentation on /etc/finit.d/{available,enabled}
  2. An alternate approach for you

Most of our services are in a ro filesystem /etc/finit.d, any services that
need to be dynamically added/removed are thrown in /var/finit.d (which is
symlinked to /etc/finit.d/enabled). This is all working perfectly for us,
we can add/remove services as needed then sighup finit to do all the hard work.

However when debugging I'd like to disable a service. Unfortunately disabling
a service in /var/finit.d causes it to get deleted
, and it is not possible to
disable a service in /etc/finit.d

The idea is to tweak your setup slightly, to this:

  1. Keep all your static services and finit configuration in /etc/finit.d/*.conf

  2. Set up the following symlinks for dynamic services in your rootfs:
    - /etc/finit.d/available -> /var/finit.d/available
    - /etc/finit.d/enabled -> /var/finit.d/enabled

  3. At boot, copy from a template directory (or generate, however you do it) all possible dynamic services to /var/finit.d/available/*.conf

  4. To enable services, either create the relative symlinks yourself from at boot (4) or use initctl enable foo when needed, e.g.

      cd /var/finit.d/enabled
      ln -s ../available/foo.conf .
    
  5. For your debugging purposes, disabling a service with initctl disable foo, would then only remove the symlink in
    /var/finit.d/enabled, so it would be possible to re-enable it again

@JackNewman12
Copy link
Contributor Author

Cheers. I got this working and here is some of my brain vomit:

  • I still like using init.d/ and init.d/enabled as two separate conf directories (Same idea as Feature request, Allow additional directories included in config with include /etc/finit.d/*.conf #184).

    • I feel like having service enable/disable support without having to convert all of our services to dynamic services makes sense in my head. Although I guess you would never want to disable a static service (except when debugging).
    • I wonder if something like '/tmp/forcestop' (name pending) could be a good workaround similar to '/tmp/norespawn' .
    • It can be little unclear which services are built-in, and which ones have been generated when they all exist in the same folder. Maybe this doesn't really matter in practice.
  • It would be nice if initctl could show disabled services. It can be hard to parse 'initctl enable' and compare it with the currently running services.

    • Note I have modified initctl status to color the state of all services. This makes it really easy to spot Green/Yellow/White services at a glance.

Thanks for all your time and effort, have a great weekend.

@troglobit troglobit added this to the 5.0 milestone Jan 7, 2023
@troglobit
Copy link
Owner

I've scheduled this PR for v5.0 now. It'll still require some extra logic to go in, i.e., something along the lines of initctl --reset reload to reset internal "states" like user block.

  • I still like using init.d/ and init.d/enabled as two separate conf directories (Same idea as Feature request, Allow additional directories included in config with include /etc/finit.d/*.conf #184).

    • I feel like having service enable/disable support without having to convert all of our services to dynamic services makes sense in my head. Although I guess you would never want to disable a static service (except when debugging).
    • I wonder if something like '/tmp/forcestop' (name pending) could be a good workaround similar to '/tmp/norespawn' .
    • It can be little unclear which services are built-in, and which ones have been generated when they all exist in the same folder. Maybe this doesn't really matter in practice.

The norespawn is an old hack from Finit v1 that should be dropped. The official way of interacting with Finit is via initctl.

By built-in here I guess you mean what's on your read-only filesystem at boot? Finit has it's own built-in services as well, e.g., keventd. Those are real confusing and will be phased out over time (5.0 will be a lot of changes!). But in your case, I'd say that's a you problem ;-)

  • It would be nice if initctl could show disabled services. It can be hard to parse 'initctl enable' and compare it with the currently running services.

    • Note I have modified initctl status to color the state of all services. This makes it really easy to spot Green/Yellow/White services at a glance.

Good point, never thought about that.

Color is one way to go, but maybe some other marker as well since there are color blind people (over represented in our field).

I've recently added a lot of JSON output support to initctl, for purposes of scripting (jq is awesome!) and for piping to web interfaces and the likes. The ls output is one of the last commands to not support JSON output, so that's probably what I'll do. Then you could use jq to compare the two lists of enabled/available.

troglobit added a commit that referenced this pull request Jan 7, 2023
This allows for easy access to the *disabled* services:

    root@anarchy:~# initctl ls --json |jq '.available - .enabled'
    [
      "chronyd.conf",
      "dnsmasq.conf",
      "gdbserver.conf",
      "inadyn.conf",
      "inetd.conf",
      "isisd.conf",
      "lldpd.conf",
      "mstpd.conf",
      "ntpd.conf",
      "ospf6d.conf",
      "ospfd.conf",
      "querierd.conf",
      "ripd.conf",
      "ripng.conf",
      "sshd.conf",
      "syslogd.conf",
      "telnetd.conf",
      "uftpd.conf",
      "wpa_supplicant.conf",
      "zebra.conf"
    ]

As discussed in PR issue #335

Signed-off-by: Joachim Wiberg <[email protected]>
@troglobit
Copy link
Owner

There, as of c29589c we now have initctl --json ls, which means you can do stuff like this:

root@anarchy:~# initctl ls --json |jq '.available - .enabled'
[
  "chronyd.conf",
  "dnsmasq.conf",
  "gdbserver.conf",
  "inadyn.conf",
  "inetd.conf",
  "isisd.conf",
  "lldpd.conf",
  "mstpd.conf",
  "ntpd.conf",
  "ospf6d.conf",
  "ospfd.conf",
  "querierd.conf",
  "ripd.conf",
  "ripng.conf",
  "sshd.conf",
  "syslogd.conf",
  "telnetd.conf",
  "uftpd.conf",
  "wpa_supplicant.conf",
  "zebra.conf"
]

@JackNewman12
Copy link
Contributor Author

JackNewman12 commented Jan 8, 2023

Looking good! Excited to see where this goes.

I'm wondering if parsing available/*.conf so that all services are listed would be a worthwhile change alongside this. Anything that is only listed in the available folder can have a BLOCK_DISABLED flag set, and the extra overhead of having to scan a few more files should be minimal since I imagine most people are not reloading constantly.

Edit: actually I realised this might not make sense. You can have multiple services in a conf file. So really you are enabling/disabling groups of services, and it might not make sense why you can see ServiceA in the list, but you'd have to enable SomethingElse.conf to get it running.

@troglobit
Copy link
Owner

Yeah, we can't scan available/*.conf, it is defined that we only read finit.conf, finit.d/*.conf and finit.d/enabled/*.conf.

By we I mean PID 1, the initctl tool does not scan the contents of these files, it queries Finit over /run/finit/socket for its current set of running services.

The initctl ls|enable|disable|et al are just glorfied wrappers of ls, ln and rm that sprinkle some policy on top.

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

2 participants