/var/lib/sorcery/modules/libinitd

     1	#---------------------------------------------------------------------
     2	##
     3	## @Synopsis Functions for automatic init-script installation.
     4	##
     5	## Installation steps performed by this script:
     6	## <pre>
     7	## pre install:
     8	##    <li>Determine if the script is a facility provider, if it is then
     9	##    ask the user whether it should be the default provider.
    10	##
    11	## install:
    12	##  <ul>
    13	##   <li>Determine which runlevel the script should be placed in.
    14	##   <li>Make a backup if there already is a different version of the script in
    15	##    the target location.
    16	##   <li>Install the script with permissions 754.
    17	##   <li>Determine if the script sources any config file from /etc/sysconfig.
    18	##   <li>For each config file:
    19	##    <ul>
    20	##      <li>Install the config file if there is no existing copy installed.
    21	##      </li>Otherwise merge new options into existing copy.
    22	##   </ul></ul>
    23	##
    24	## post install:
    25	##
    26	##  <li> When the spell has been installed successfully then change the
    27	##    /etc/sysconfig/facilities-file if the user wanted the script to be a
    28	##    default provider.
    29	## </pre>
    30	## @Copyright Copyright (C) 2003 The Source Mage Team <http://www.sourcemage.org>
    31	##
    32	##
    33	## @Contributors Robert Helgesson <rycee@home.se>
    34	##
    35	#---------------------------------------------------------------------
    36	
    37	
    38	#---------------------------------------------------------------------
    39	## @param new file
    40	## @param old file
    41	## Makes a backup of "old file" if it differs from "new file"
    42	##
    43	#---------------------------------------------------------------------
    44	function _init_make_backup()
    45	{
    46	
    47	  # Don't bother if the old file doesn't exist
    48	  [ -f $2 ] || return
    49	
    50	  # Do the files differ? Return if they don't.
    51	  cmp -s $2 $1 && return
    52	
    53	  local savetime=$( date +'%Y%m%d%H%M' )
    54	  bck_file=$2.$savetime.backup
    55	
    56	  message "Making a backup of $2 due to differing content..."
    57	  mv $2 $bck_file
    58	  chmod 644 $bck_file
    59	
    60	}
    61	
    62	
    63	#---------------------------------------------------------------------
    64	## @param init script
    65	## @Stdout filelist
    66	## Extracts the files in /etc/sysconfig which are sourced by the script and
    67	## prints them to stdout separated by newlines.
    68	##
    69	#---------------------------------------------------------------------
    70	function _init_get_conf_files()
    71	{
    72	
    73	  sed -n -f - $1 <<EOF
    74	s!^\.\s\s*/etc/sysconfig/\([^[:space:]]*\).*!\1!p
    75	s!^source\s\s*/etc/sysconfig/\([^[:space:]]*\).*!\1!p
    76	EOF
    77	
    78	}
    79	
    80	
    81	#---------------------------------------------------------------------
    82	## @param new config file
    83	## @param old config file
    84	## Inserts new options from the new file into the old, existing, file
    85	##
    86	#---------------------------------------------------------------------
    87	function _init_merge_config_file()
    88	{
    89	
    90	  # Get newly added options
    91	  local new_opts=$( sed -n -e 's/[[:space:]]*\([[:alnum:]_]*\)=.*/\1/p' $1 $2 |
    92	                          sort | uniq -u )
    93	
    94	  # for now the file is always modified...
    95	  if [ -z "$new_opts" ] ; then
    96	    message "  No new options to merge into $2..."
    97	    track_manual $2 # but we still need to track it.
    98	    return 0
    99	  fi
   100	
   101	  # no need for a backup when staging, since the installation will be deffered
   102	  if [[ $STAGED_INSTALL != on ]]; then
   103	    local savetime=$( date +'%Y%m%d%H%M' )
   104	    install -g root -o root $2 $2.$savetime.backup
   105	  fi
   106	
   107	  for opt in $new_opts ; do
   108	    message "  Merging option $opt into $2..."
   109	    sed -n -f - $1 <<EOF >> $2
   110	# If we encounter an empty line then clear hold space since another
   111	# variable is coming up...
   112	/^$/ { x ; d ; h ; }
   113	
   114	# The variable we're looking for has come, add it to the hold space and
   115	# then print everything, quit when done...
   116	/^[[:space:]]*$opt=/ { H ; x ; p; q; }
   117	
   118	# Default action, append line to hold space
   119	H
   120	EOF
   121	  done
   122	
   123	}
   124	
   125	
   126	#---------------------------------------------------------------------
   127	## @param configuration file...
   128	##
   129	## Installs or merges a list of init-script configuration-files.
   130	##
   131	#---------------------------------------------------------------------
   132	function _init_install_conf_files()
   133	{
   134	
   135	  mkdir -p $INSTALL_ROOT/etc/sysconfig
   136	  for file in "$@" ; do
   137	    local target_file=${INSTALL_ROOT}/etc/sysconfig/$file
   138	    local file=$SCRIPT_DIRECTORY/init.d/$file.conf
   139	
   140	    if [ ! -f "$file" ] ; then
   141	      [ ! -f "$target_file" ] &&
   142	        message "${PROBLEM_COLOR}Unable to find file $file...${DEFAULT_COLOR}"
   143	      continue
   144	    fi
   145	
   146	    if [ -f "$target_file" ] ; then
   147	      check_if_modified "$target_file" &&
   148	      if [[ $STAGED_INSTALL == on ]]; then
   149	        mark_file_modified "$STAGE_DIRECTORY/TRANSL$target_file"
   150	      else
   151	        mark_file_modified "$target_file"
   152	      fi
   153	      _init_merge_config_file $file $target_file
   154	    else
   155	      install -m 644 -g root -o root $file $target_file
   156	      touch $target_file
   157	    fi
   158	  done
   159	
   160	}
   161	
   162	
   163	#---------------------------------------------------------------------
   164	## @param init script
   165	## @param previous cast instance's answers, if any
   166	## @param init script
   167	## Prepares installation of an init-script.
   168	## Creates the variable $INITPROVIDES which contains facility provided by the
   169	##   script (if any)
   170	##
   171	#---------------------------------------------------------------------
   172	function init_prepare_install()
   173	{
   174	
   175	  local service="$1"
   176	  local old_provides="$2"
   177	  local result_list="$3"
   178	  local script_path="$SCRIPT_DIRECTORY/init.d/$service"
   179	  local script_provides=$( grep '^[[:space:]]*PROVIDES' $script_path )
   180	  script_provides=$( eval "( ${script_provides:=:} ; echo \$PROVIDES ; )" )
   181	
   182	  [ -z "$script_provides" ] && return
   183	
   184	  local default=n
   185	  if test -f $INSTALL_ROOT/etc/sysconfig/facilities &&
   186	     grep -q "$script_provides=$service" \
   187	              $INSTALL_ROOT/etc/sysconfig/facilities ||
   188	     list_find "$service:$script_provides" $old_provides; then
   189	    default=y
   190	  fi
   191	  local question="Set $service to be the default provider of $script_provides?"
   192	  if query "$question" $default; then
   193	    list_add "$result_list" "$service:$script_provides"
   194	  fi
   195	}
   196	
   197	
   198	#---------------------------------------------------------------------
   199	## @param init script
   200	## * Makes a backup of an existing script.
   201	## * Installs the new script into the correct runlevel.
   202	## * Installs any config file used by the script.
   203	##
   204	#---------------------------------------------------------------------
   205	function init_install()
   206	{
   207	
   208	  local enable_script="$1"
   209	  local script_name="$2"
   210	  local script_path="$SCRIPT_DIRECTORY/init.d/$script_name"
   211	  local script_runlevel=$( grep '^[[:space:]]*RUNLEVEL' $script_path )
   212	  script_runlevel=$( eval "( $script_runlevel ; echo \$RUNLEVEL )" )
   213	
   214	  [ "$script_runlevel" = "s" ] && script_runlevel="S"
   215	
   216	  if [ -z "$script_runlevel" ] ; then
   217	    message "Init script $script_name doesn't contain good RUNLEVEL variable..."
   218	    return
   219	  fi
   220	
   221	  message "Installing $script_name to runlevel $script_runlevel..."
   222	
   223	  (
   224	    . ${INSTALL_ROOT}/etc/sysconfig/init
   225	
   226	    # /etc/sysconfig/init might not exist yet so we define this in case
   227	    RUNLEVELS_DIR=${INSTALL_ROOT}${RUNLEVELS_DIR:-/etc/init.d/runlevels}
   228	
   229	    local runlevel_dir="$RUNLEVELS_DIR/%$script_runlevel"
   230	
   231	    if [ ! -d "$runlevel_dir" ] ; then
   232	      message -n "${PROBLEM_COLOR}"
   233	      message -n "Unable to install $script_name to runlevel $script_runlevel. "
   234	      message "Runlevel do not exist or is not implemented as a directory."
   235	      message -n ${DEFAULT_COLOR}
   236	      exit 1
   237	    else
   238	      _init_make_backup $script_path $runlevel_dir/$script_name
   239	      if [ "$enable_script" == "enabled" ] ; then
   240	        install -m 754 -g root -o root $script_path $runlevel_dir
   241	        message "  script $script_name installed and ${MESSAGE_COLOR}enabled${DEFAULT_COLOR}. Disable with 'telinit disable $script_name'."
   242	        message "${MESSAGE_COLOR}If you want to [re]start the service now${DEFAULT_COLOR}, issue 'telinit run $script_name [re]start'."
   243	      else
   244	        install -m 644 -g root -o root $script_path $runlevel_dir
   245	        message "  script $script_name installed and ${MESSAGE_COLOR}disabled${DEFAULT_COLOR}. Enable with 'telinit enable $script_name'."
   246	      fi
   247	      _init_install_conf_files $( _init_get_conf_files $script_path )
   248	    fi
   249	  )
   250	
   251	}
   252	
   253	
   254	#---------------------------------------------------------------------
   255	##
   256	## Does cleanup if necessary. Must be run _after_ installwatch has stopped.
   257	##
   258	#---------------------------------------------------------------------
   259	function init_post_install()
   260	{
   261	  (
   262	    IFS="$WHITESPACE_IFS"
   263	    for sp in $INIT_PROVIDES ; do
   264	      mkdir -p $INSTALL_ROOT/etc/sysconfig
   265	      mark_file_modified "$INSTALL_ROOT/etc/sysconfig/facilities"
   266	      IFS=":"
   267	      set $sp   # $1 - script name, $2 - facility
   268	      if ! sedit "s/^\([[:space:]]*$2\)=.*/\1=$1/" \
   269	            $INSTALL_ROOT/etc/sysconfig/facilities ; then
   270	        message -n "${PROBLEM_COLOR}Unable to modify facilities file to make "
   271	        message "$1 provider of $2.${DEFAULT_COLOR}"
   272	      else
   273	        message "Made $1 provider of $2"
   274	      fi
   275	    done
   276	  )
   277	}
   278	
   279	#---------------------------------------------------------------------
   280	##
   281	## This software is free software; you can redistribute it and/or modify
   282	## it under the terms of the GNU General Public License as published by
   283	## the Free Software Foundation; either version 2 of the License, or
   284	## (at your option) any later version.
   285	##
   286	## This software is distributed in the hope that it will be useful,
   287	## but WITHOUT ANY WARRANTY; without even the implied warranty of
   288	## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   289	## GNU General Public License for more details.
   290	##
   291	## You should have received a copy of the GNU General Public License
   292	## along with this software; if not, write to the Free Software
   293	## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   294	##
   295	#---------------------------------------------------------------------