How to control and setup service?

Pavel Timofeev timp87 at gmail.com
Fri Aug 28 08:47:48 UTC 2015


2015-08-27 18:00 GMT+03:00 Allan Jude <allanjude at freebsd.org>:
> On 2015-08-27 09:21, Pavel Timofeev wrote:
>> 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 ;)
>>
>
> You don't need to do all of that. There is the service(8) command, and
> it will do the searching for you.
>
> You can get a list of all of the rc scripts, in the correct order that
> they are run during system startup using this command:
>
> service -e
>
> You can also do: service -l
>
> And it will list every installed service for you.

Exactly! That's what I wanted to say actually as a conclusion.
The following sentence about `realizing bla bla` is just a mad idea.


>>
>>
>> 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.
>
> sysrc automatically detects values from rc.conf.d directories, and can
> edit them if you ask it to. It just defaults to writing your changes to
> /etc/rc.conf

I wouldn't say sysrc *automatically* detects values from rc.conf.d directories.

>
> My puppet scripts use:
> sysrc -f /etc/rc.conf.d/varnish varnishd_identity="PDX1-01"
>
> and the the like all the time

Exactly, you point sysrc(8) manually to file.
In such case it works only with this specific file, ignoring
/etc/rc.conf and /etc/rc.conf.local, which is not critical.
But what is worse it ignores "/etc/rc.conf.d/$service/*",
"/usr/local/etc/rc.conf.d/$service" and
"/usr/local/etc/rc.conf.d/$service/*" files, which have higher
precedence than your /etc/rc.conf.d/$service.
So you should still manually track that cases.


>
>>
>> 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.
>
> sysrc can do that, it will search all of the directories and find the
> final answer.

Well, it can't. It still needs your manual intervention.

> The only thing it doesn't do is the translation between the 'service
> name' (mysql-server) and the 'rcvar prefix' (mysql_), which might be a
> useful addition, but might make more sense in the service command,
> because when I pass something to sysrc, I expect it to be interpreted
> literally. I guess it could be a flag for sysrc to specify the service
> instead of the rcvar.
>
> sysrc -s mysql datadir=/var/db/mysql
>
>> IMO such tools would be useful even for ansible/puppet and friends.
>> Not just for users ;)
>>
>
> Teaching service to use sysrc might be useful. Making sysrc detect that
> /etc/rc.conf.d/<service> exists, and use it, else fallback to
> /etc/rc.conf might also be nice.
>
> service mysql-server enable|disable
>         sets mysql_enable="YES|NO"
> service mysql-server set datadir=/var/db/mysql
>         sets mysql_datadir="/var/db/mysql"
>
> I am currently doing all of this in puppet with sysrc.

Such tools is what I wrote this email for.



>>
>> 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?
>> _______________________________________________
>> freebsd-hackers at freebsd.org mailing list
>> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
>>
>
>
> --
> Allan Jude
>


More information about the freebsd-hackers mailing list