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>