Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Aug 2015 16:21:20 +0300
From:      Pavel Timofeev <timp87@gmail.com>
To:        freebsd-hackers@freebsd.org, Devin Teske <dteske@freebsd.org>
Subject:   How to control and setup service?
Message-ID:  <CAAoTqfvxUznJp%2BtguAaYQ=5HfKXTG%2BGxY644wvqm4e9=E8WuHw@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi! Good day!

let me declare something first:
HOPE="I just should know about that dir/sruff and hope that nothing
will change in future releases";


I'm trying to write some automation code to manipulate services.
There is no problem with installing service, I can just use pkg(8) to
search/install/remove service.
Like following:
# pkg install mysql56-server
No problem. pkg(8) covers pretty much everything.



But I have problems with starting and enabling services.



Ok, to start a service we have rc scripts. If it's a base system
service then it has rc script in /etc/rc.d dir.
If a service is installed from packages (ports) then an rc script is
in /usr/local/etc/rc.d dir.
So, first, I should check one dir then another. But how can I be sure
I'm looking in right directories?
Is there any way to ask FreeBSD "Hey! Where is you startup dirs?". I'd
say yes, but only partially.

/etc/rc.d dir is hardcoded everywhere. So $HOPE, which is not good IMO.

"/usr/local/etc/rc.d" is ${local_startup} var which is defined in
/etc/defaults/rc.conf.
I can actually ask FreeBSD about that by calling:
# sh -c '. /etc/rc.subr; load_rc_config "XXX"; echo $local_startup'
Good!

But in geretal, there is no way to ask FreeBSD for a complete list of
startup dirs. So $HOPE.

It would be pretty useful if I could ask FreeBSD for one variable like
$all_startup, which would contain all of the startup dirs ("/etc/rc.d
${local_startup} ${new_startup_whatever}").
And it would be great if "/etc/rc.d" was defined as variable too. Like
${system_startup}="/etc/rc.d" (which is not simple I believe, it's
hardcoded everywhere!).


Thank god, there is a alternative way to start/stop services!
It's service(8) tool that can do this stuff for me. I can rely on it,
because it's a base system tool and I'm sure it knows everything about
startup dirs, no matter what FreeBSD release I'm using.
IMO service(8) covers this use case.
So we can forget my ideas above.
Or realize them because it can be useful for such tools like
service(8), sysrc(8) or even your_new_tool(8), and code written once
would not break in future ;)



Ok, imagine I started/stopped service.

Then, to enable/disable service I should know a lot of stuff!

To enable/disable service first thing that I should know is $rcvar of
a service. It can be different than $service name (which is rc script
name).
I should find rc script in right place, but thank again to service(8)
tool. I just can ask it with:
# service mysql-server rcvar
and get the $rcvar of service, no matter where startup script is. Good!

Second thing I should know is if it's already enabled/disabled.
# service mysql-server rcvar
will output YES/NO besides $rcvar var name.
FreeBSD 10 got good command for rc scripts - "enabled", which would
answer us by its exit code.
# service mysql-server enabled; echo $?
Excellent!

Third thing I should know is how I have to enable/disable service.
How would I do that? Where would I do that?
Is it directly disabled (if $sysadmin2 set mysql_enable="NO"), if so -
where, or it just not enabled anywhere?
How many config files do you know which can be used to enable/disable
(control) service? What's their precedence?

Well, most of us (probably) would use /etc/rc.conf to enable $service
or to check if it's directly disabled. We would use $rcvar (!), not rc
script name.
But, FreeBSD has more places with higher precedence than /etc/rc.conf!
It's /etc/rc.conf.local file,
then /etc/rc.conf.d/$service file,
then /etc/rc.conf.d/$service/* files.
Then even /usr/local/etc/rc.conf.d/$service files and subdirs which
appeared in FreeBSD 10!

And there is no way to ask FreeBSD "Hey! Where is your config files to
control services?".
You can ask about them, but again, partially by running:
# sh -c '. /etc/rc.subr; load_rc_config "XXX"; echo $rc_conf_files'
which outputs "/etc/rc.conf /etc/rc.conf.local".
Of course, there is no way to ask "Where this service is enabled/disabled?"
So we can catch $rc_conf_files, but not a bunch of rc.conf.d dirs and
subdirs. No way. So $HOPE, again, which is not good IMO.
Why $HOPE? Because such change already happened between FreeBSD 9 and
10. So I should track such changes in my own code manually.

As a way to solve this, I'd like to see some vars like $rc_conf_d_dirs
which would point to "/etc/rc.conf.d
${local_startup%/rc.d}/rc.conf.d/". Or any way to get them.
Now these dirs are "hardcoded" and used only in /etc/rc.subr here
https://github.com/freebsd/freebsd/blob/master/etc/rc.subr#L1336-L1354.
It's not used anywhere else.


Thank good we have an alternative to this hell of manual editing and
going through the list of dirs! You can forget about anything above. I
can rely on it, because it's in the base system and I'm sure it knows
any cases.
It's a ... Hmm, where is it?
Turns out, we don't have such tool. We have only sysrc(8), but it can
only edit $rc_conf_files in safe way. There is no support for
rc.conf.d dirs in sysrc(8).
And, in general, it's a tool to just `edit` $rc_conf_files, not to
control and configure services.

As a user I would love to have a cool tool to control and configure
services in way like OpenBSD's rcctl(8) does
http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/rcctl.8?query=rcctl.
# cooltool set mysql-server status on
That's all. It would take care of those things like getting right
$rcvar name, choose right rc config file to edit (remember, we have a
lot of places to check, see above) and enable service, etc.
This $cooltool can be an extended version of service(8) tool.
More difficult example:
# cooltool set flow_capture status on  flags "-e 2200 -n 23 -N 0 -V 5"
port "8787" datadir "/storage/flows/all_routers"
would enable flow_capture service and set other stuff using right $rcvar.
# cooltool get flow_capture
would print all of the configured stuff for $service
# cooltool get flow_capture status
would print only a status YES/NO (don't forget about exit code ;) )
and etc.
IMO such tools would be useful even for ansible/puppet and friends.
Not just for users ;)


I'm really sorry if I misunderstand something and wasted your time!
And I don't want to offend anyone in case I'm impolite!

P.S. Do you have any ideas?



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAAoTqfvxUznJp%2BtguAaYQ=5HfKXTG%2BGxY644wvqm4e9=E8WuHw>