{"id":76,"date":"2013-11-28T10:24:05","date_gmt":"2013-11-28T10:24:05","guid":{"rendered":"http:\/\/esferas.org\/msqlu\/2013\/11\/28\/anadiendo-funciones-lsb-a-un-script-de-inicio\/"},"modified":"2013-11-28T10:24:05","modified_gmt":"2013-11-28T10:24:05","slug":"anadiendo-funciones-lsb-a-un-script-de-inicio","status":"publish","type":"post","link":"https:\/\/esferas.org\/msqlu\/2013\/11\/28\/anadiendo-funciones-lsb-a-un-script-de-inicio\/","title":{"rendered":"A\u00f1adiendo funciones LSB a un script de inicio &#8230;"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"debian-logo\" src=\"https:\/\/esferas.org\/mt\/msqlu\/logos\/openlogo-100.png\" class=\"mt-image-left\" style=\"float: left; margin: 0 20px 20px 0;\" height=\"123\" width=\"100\" \/>&#8230; de un servicio aprendo varias cosas sobre c\u00f3mo est\u00e1 organizado.<\/p>\n<p><!--more--><\/p>\n<p>En uno de los programas que ya he mencionado en <a href=\"https:\/\/esferas.org\/mt\/msqlu\/2013\/11\/resulta-descorazonador-revisar-tu-propio-codigo.html\">otra entrada<\/a>, un servidor de trabajos de impresi\u00f3n, tengo un <span style=\"text-decoration: underline;\"><em><\/em><\/span><em>script<\/em> para utilizarlo como servicio del sistema mediante el programa <em>init<\/em> y notaba que le faltaba algo de integraci\u00f3n. No ten\u00eda buen aspecto cuando se lanzaba con el resto y he cre\u00eddo conveniente incluirle algunas funciones que he visto disponibles en el paquete lsb-base.<\/p>\n<p>Primero he mirado la documentaci\u00f3n presente en el <a href=\"https:\/\/wiki.debian.org\/LSBInitScripts\">wiki de Debian<\/a> pero no mencionan directamente nada sobre las funciones a emplear en los <em>scripts<\/em>. S\u00ed que enlazan con la propia <a href=\"http:\/\/www.debian.org\/doc\/debian-policy\/ch-opersys.html#s9.4\">normativa<\/a> y con la p\u00e1gina de la <a href=\"http:\/\/refspecs.linuxfoundation.org\/LSB_3.1.0\/LSB-Core-generic\/LSB-Core-generic\/iniscrptact.html\">Fundaci\u00f3n Linux Base<\/a> de donde voy extrayendo fragmentos hasta encontrar\u00a0 lo que quiero: <a href=\"http:\/\/refspecs.linuxfoundation.org\/LSB_3.1.0\/LSB-Core-generic\/LSB-Core-generic\/iniscrptfunc.html\">Init Script Functions<\/a>. Sin embargo no est\u00e1 completamente actualizada y tengo que recurrir al archivo <em>\/usr\/share\/doc\/lsb-base\/README-Debian.gz<\/em> donde s\u00ed, ah\u00ed est\u00e1n todas. La leche, s\u00ed que ha costado.<\/p>\n<p>El\u00a0 texto ya avisa de que emplear las funciones LSB puras no cumple la normativa Debian y no es aconsejable excepto si se pretende portar el script a otras distribuciones o en paquetes LSB estrictos. As\u00ed pues voy a anotar primero las funciones LSB y luego hablar\u00e9 de la\u00a0<em>versi\u00f3n<\/em> Debian.<\/p>\n<p>Para que el script de control del servicio presente los mensajes cumpliendo con la normativa LSB debemos emplear las siguientes funciones cargadas directamente de <em>\/lib\/lsb\/init-functions<\/em>:<\/p>\n<ul>\n<li><strong>log_success_msg<\/strong>: para notificar buenas noticias o informaciones sin trascendencia en el proceso.<\/li>\n<li><strong>log_failure_msg<\/strong>: para dar las malas noticias, especialmente fallos cr\u00edticos.<\/li>\n<li><strong>log_warning_msg<\/strong>: para avisar de sucesos o resultados no cr\u00edticos.<\/li>\n<\/ul>\n<p>El mensaje que aceptan como par\u00e1metro no tiene un formato definido. Todas ellas, adem\u00e1s, pueden estar enviando los textos a archivos de registro previamente establecidos pero que la norma no define exactamente.<\/p>\n<p>As\u00ed que un fragmento de arranque del servicio puede quedar m\u00e1s o menos as\u00ed:<\/p>\n<pre>case $1 in<br \/>\"start\")<br \/>    log_success_msg \"Starting daemon impresor\" <br \/>    start_daemon -p $PIDFILE $DAEMON $DAEMON_ARGS<br \/>    if [ $? -eq 0 ]; then <br \/>       log_success_msg \" done\" <br \/>    else <br \/>       log_failure_msg \" fail\"<br \/>    fi<br \/>    ;;<\/pre>\n<p>Mencionar tambi\u00e9n las otras tres funciones b\u00e1sicas que ya de por s\u00ed encaminan la disposici\u00f3n del resto de los elementos que emplear\u00e1 el servidor:<\/p>\n<ul>\n<li><strong>start_daemon<\/strong>: para arrancar el servicio<\/li>\n<li><strong>kill_proc<\/strong>: para detenerlo<\/li>\n<li><strong>pidofproc<\/strong>: para obtener el PID del servicio<\/li>\n<\/ul>\n<h3>Las funciones Debian<\/h3>\n<p>La gente de Debian, intentando dar coherencia al arranque del sistema, han ampliado estas funciones y las han dotado de algunas caracter\u00edsticas interesantes tales como<\/p>\n<ul>\n<li>Texto coloreado: disponible mediante la variable de entorno <em>FANCYTTY<\/em>.<\/li>\n<li>Puntos de anclaje para a\u00f1adir o cambiar caracter\u00edsticas al mecanismo de registro:\n<ul>\n<li>Bien empleando la carga de archivos desde el directorio <em>\/lib\/lsb\/init-functions.d<\/em>.<em> <\/em><\/li>\n<li>Bien cargando el archivo <em>\/etc\/lsb-base-logging.sh<\/em> donde se pueden redefinir tambi\u00e9n funciones.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Las funciones de registro son entonces:<\/p>\n<ul>\n<li>Arranque y parada de servicios:\n<ul>\n<li><strong>log_daemon_msg <\/strong><em>message <\/em><em>daemon_name\u00a0<\/em>: para notificar el inicio de un proceso demonio.<\/li>\n<li><strong>log_progress_msg <\/strong><em>daemon2_name<\/em> : para notificar el inicio de un segundo proceso.<\/li>\n<li><strong>log_end_msg <\/strong><em>0\/1<\/em> : para notificar el \u00e9xito o el fallo de lo anterior.<\/li>\n<li><strong>status_of_proc <\/strong><em>[-p pidfile] pathname daemon_name<\/em> : Registra el estado de un proceso y puede emplearse para realizar la acci\u00f3n <em>status<\/em> del script.<\/li>\n<\/ul>\n<\/li>\n<li>Acciones que no toman tiempo como la asignaci\u00f3n de valores:\n<ul>\n<li><strong>log_action_msg<\/strong> <em>message<\/em><\/li>\n<\/ul>\n<\/li>\n<li>Acciones que s\u00ed toman tiempo y constan de varias fases:\n<ul>\n<li><strong>log_action_begin_msg<\/strong> <em>message<\/em><\/li>\n<li><strong>log_action_cont_msg<\/strong> <em>message<\/em><\/li>\n<li><strong>log_action_end_msg<\/strong> <em>0|1 [message]<\/em> : que indica que la acci\u00f3n anterior ha terminado correctamente (0) o ha fallado de alguna manera (1).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Con toda esta informaci\u00f3n he mejorado el script de inicio del servicio empleando estas funciones, tras a\u00f1adir a\u00a0<em>lsb-base<\/em> como dependencia del paquete:<\/p>\n<pre>#!\/bin\/sh\n### BEGIN INIT INFO\n# Provides:          impresor\n# Required-Start:    $network $local_fs $remote_fs\n# Required-Stop:     $remote_fs\n# Default-Start:     2 3 4 5\n# Default-Stop:      0 1 6\n# Short-Description: Trabajos de impresi\u00f3n de Multibase\n# Description:       Servidor de trabajos de impresi\u00f3n de \n#                    aplicaciones Multibase\n### END INIT INFO\n\n# Author: Victor Moral \n\n# PATH should only include \/usr\/* if it runs after the mountnfs.sh script\nPATH=\/sbin:\/usr\/sbin:\/bin:\/usr\/bin\nDESC=\"Trabajos de impresi\u00f3n de Multibase\"\nNAME=impresor    \nDAEMON=\/usr\/sbin\/impresor \nDAEMON_ARGS=\"\"            \nPIDFILE=\/var\/run\/$NAME.pid\nSCRIPTNAME=\/etc\/init.d\/$NAME\n\n# Exit if the package is not installed\n[ -x $DAEMON ] || exit 0\n\n# Read configuration variable file if it is present\n[ -r \/etc\/default\/$NAME ] &amp;&amp; . \/etc\/default\/$NAME\n\n# Lock the start process\n[ \"$START\" != \"yes\" ] &amp;&amp; exit 0\n\n# Load the VERBOSE setting and other rcS variables\n. \/lib\/init\/vars.sh\n\n# Define LSB log_* functions.\n# Depend on lsb-base (&gt;= 3.0-6) to ensure that this file is present.\n. \/lib\/lsb\/init-functions\n\ncase \"$1\" in\n  start)\n    log_daemon_msg \"Starting $DESC\" \"$NAME\"\n    start_daemon -p $PIDFILE $DAEMON $DAEMON_ARGS\n    log_end_msg $?\n  ;;\n\n  stop)\n\tlog_daemon_msg \"Stopping $DESC\" \"$NAME\"\n\tkillproc -p $PIDFILE $DAEMON\n    log_end_msg $?\n    ;;\n\n  status)\n       status_of_proc \"$DAEMON\" \"$NAME\" &amp;&amp; exit 0 || exit $?\n       ;;\n\n  restart|force-reload)\n\tlog_daemon_msg \"Restarting $DESC\" \"$NAME\"\n    killproc -p $PIDFILE $DAEMON\n    start_daemon -p $PIDFILE $DAEMON $DAEMON_ARGS\n    log_end_msg $?\n\t;;\n\n  *)\n\techo \"Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}\" &gt;&amp;2\n\texit 3\n\t;;\nesac\n\n:\n<\/pre>\n<p>A pesar de estar utilizando el m\u00f3dulo Perl <a href=\"http:\/\/search.cpan.org\/dist\/Net-Server\/\">Net::Server<\/a> -con sus excentricidades- la interacci\u00f3n de mi proceso demonio est\u00e1 ahora plenamente integrada en el arranque Debian.<\/p>\n<h3>Reflexionando<\/h3>\n<p>Y ahora viene donde la matan &#8230; \u00bf es que Debian no incluye nada como base ? S\u00ed, obviamente lo hace. El archivo <em>\/etc\/init.d\/skeleton<\/em> est\u00e1 pr\u00e1cticamente listo para usarse con s\u00f3lo cambiar las variables que nombran, sit\u00faan y describen el demonio.<\/p>\n<p>Es f\u00e1cil de usar y est\u00e1 documentado y lo \u00fanico que echo en falta -y es algo a lo que me he acostumbrado- es a verificar el valor de la variable <em>START<\/em> o <em>START_DAEMON<\/em> para lanzar o no el proceso. Supongo, y digo supongo porque bucear en las listas de Debian se me hace eterno, que si han decidido eso es porque puede que se intente detener el proceso cuando borras el paquete (lo normal, vamos) y que te encuentres con que falta la variable o el archivo y el servicio se quede ah\u00ed, s\u00f3lo y pelado sin nada debajo.<\/p>\n<p>De todas maneras yo prefiero emplearlo. Aunque no lo he escrito as\u00ed en el ejemplo de arriba la versi\u00f3n final de mi script incorpora la siguiente estrofa:<\/p>\n<pre>if [ \"$START\" != \"yes\" ]; then <br \/>   log_warning_msg \"Cancel process of $NAME edit \/etc\/default\/$NAME\"<br \/>   exit 0 <br \/>fi <\/pre>\n<p>de manera que el administrador del sistema (conocido como yo mismo) pueda entender mejor por qu\u00e9 no est\u00e1 funcionando el servicio.<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8230; de un servicio aprendo varias cosas sobre c\u00f3mo est\u00e1 organizado.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"1","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"footnotes":""},"categories":[6],"tags":[18,127,126],"class_list":["post-76","post","type-post","status-publish","format-standard","hentry","category-debian","tag-administracion-de-sistemas","tag-initd","tag-linux-fundation-base"],"_links":{"self":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/76","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/comments?post=76"}],"version-history":[{"count":0,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/posts\/76\/revisions"}],"wp:attachment":[{"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/media?parent=76"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/categories?post=76"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/esferas.org\/msqlu\/wp-json\/wp\/v2\/tags?post=76"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}