Open JackNewman12 opened 1 year ago
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.
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.
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:
/etc/finit.d/{available,enabled}
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:
Keep all your static services and finit configuration in /etc/finit.d/*.conf
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
At boot, copy from a template directory (or generate, however you do it) all possible dynamic services to /var/finit.d/available/*.conf
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 .
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
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 #184).
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.
Thanks for all your time and effort, have a great weekend.
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.
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"
]
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 reload
ing 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.
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.
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.