From owner-freebsd-hackers@freebsd.org Thu Aug 27 13:21:22 2015 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4E3FD9C4C2A for ; Thu, 27 Aug 2015 13:21:22 +0000 (UTC) (envelope-from timp87@gmail.com) Received: from mail-wi0-x231.google.com (mail-wi0-x231.google.com [IPv6:2a00:1450:400c:c05::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D38CE189E; Thu, 27 Aug 2015 13:21:21 +0000 (UTC) (envelope-from timp87@gmail.com) Received: by wicgk12 with SMTP id gk12so9226733wic.1; Thu, 27 Aug 2015 06:21:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=ts4jY9XINnB077H+M77tIsgB6B6K6lX6kGcJ+8DCkFU=; b=wt81+ueHKGZPNnbtpbJ+gZfhk+2RsqTiROqw90m2UxhlOJNOzrqbDwYiTp0XbfsqMl t7NcfEJ61qml3FyQF/IbDWmX8TUUcb2gO7xvXYJIhZXyb7uMjljmxK4aoSx2c8ZiUOMZ U9iPVne9HSosL1C2a99sTQI1Riv8Pznh2Iq1ppHsSK53idcF+xlkmB8zYPDw6mOPJMsH /wE8K28kNw1ok6i3D3M0J9cKE1Z4IC/K03Nqr0Gs6DUqV29LJa3J3W15RJaE1k50hHi6 phDX9QmxHxPkR6ZYI2a5x0sSW4L2GU7ud+DPJmAPbNfngN6rhqXUMZMsr/8tHAeJt0be Lrpg== MIME-Version: 1.0 X-Received: by 10.194.2.9 with SMTP id 9mr4707641wjq.95.1440681680320; Thu, 27 Aug 2015 06:21:20 -0700 (PDT) Received: by 10.28.9.195 with HTTP; Thu, 27 Aug 2015 06:21:20 -0700 (PDT) Date: Thu, 27 Aug 2015 16:21:20 +0300 Message-ID: Subject: How to control and setup service? From: Pavel Timofeev To: freebsd-hackers@freebsd.org, Devin Teske Content-Type: text/plain; charset=UTF-8 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Aug 2015 13:21:22 -0000 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?