Stuff that has not yet gone into the official build.
Post a reply

Using hooks

Mon Nov 26, 2012 4:44 pm

I did some testing for dzz. Bottom line: I think we should just edit 9990-hooks and be done with it.
(I apologize for the big code and quote blocks, but I'm too lazy to edit out all the slashes.)

add to cmdline -
hooks=file:///lib/live/mount/medium/live/myscript

myscript must be in place and executable. In this case, it contains:
touch /home/user/Desktop/testhooks


/lib/live/config/9990-hooks has an error that prevents it from using the hook.
Create /lib/live/config/9991-hooks with correction, and it will execute myscript. I've got the testhooks file on my desktop when I log in.



As a test, I also created 9992-hooks:
Code:
#!/bin/sh

if [ -n "${LIVE_HOOKS}" ]; then
   echo "LIVE_HOOKS = ${LIVE_HOOKS}" > /home/user/Desktop/livehooks
elif [ -z "${LIVE_HOOKS}" ]; then
   echo "LIVE_HOOKS is null." > /home/user/Desktop/nohooks
else
   echo "Something else is going on." > /home/user/Desktop/something_else
fi

echo "${_CMDLINE}" > /home/user/Desktop/cmdline

exit 0

Two files appeared on the desktop - nohooks and cmdline
${_CMDLINE} is set in /lib/live/config thus:
_CMDLINE="$(cat /proc/cmdline)"


Why does _CMDLINE exist outside the script in which it gets its value?

I tried exporting LIVE_HOOKS in the first script, so it would be available to the second, but that didn't work.


9991-hooks:
Code:
#!/bin/sh

## live-config(7) - System Configuration Scripts
## Copyright (C) 2006-2012 Daniel Baumann <daniel@debian.org>
##
## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
## This is free software, and you are welcome to redistribute it
## under certain conditions; see COPYING for details.
#### This version was modified by dzz and fsr

Hooks ()
{
   echo -n " hooks"

   for _PARAMETER in ${_CMDLINE}
   do
      case "${_PARAMETER}" in
         live-config.hooks=*|hooks=*)
            LIVE_HOOKS="${_PARAMETER#*hooks=}"
            ;;
      esac
   done

   if [ -z "${LIVE_HOOKS}" ]
   then
      return
   fi

#   export LIVE_HOOKS     # This didn't work

   Process_hooks
}

Process_hooks ()
{
   if [ -z "${LIVE_HOOKS}" ]
   then
      return
   fi

   for _HOOK in $(echo ${LIVE_HOOKS} | sed -e 's/|/ /g')
   do
      case "${_HOOK}" in
         filesystem)
            if ls /lib/live/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/config-hooks/*; do echo file://${_FILE}; done)"
            fi
            ;;

         medium)
            if ls /lib/live/mount/medium/live/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/mount/medium/live/config-hooks/*; do echo file://${_FILE}; done)"
            fi
            ;;

         *)
            _HOOKS="${_HOOKS} ${_HOOK}"
            ;;
      esac
   done

   for _HOOK in ${_HOOKS}
   do
      _TMPFILE="$(mktemp -t live-config.XXXXXXXX)"

      if echo "${_HOOK}" | grep -qs file://
      then
         # local file
         cp $(echo ${_HOOK} | sed 's|file://||') "${_TMPFILE}"
      else
         # remote file
         Start_network

         wget --quiet "${_HOOK}" -O "${_TMPFILE}"
      fi

      chmod 0755 "${_TMPFILE}"
      ./"${_TMPFILE}"
      rm -f "${_TMPFILE}"
   done
}

Hooks

Re: Using hooks

Mon Nov 26, 2012 9:03 pm

Still looking at the "hooks" issue... not sure yet what is best to do. Hooks are invaluable here, I do a lot with live-usb sometimes on different machines. You can, for example, insert one-time only a specific nonfree firmware or latest clamav defs, quickly and simply at user level, into a standard live-image. No need to remaster.

BTW the code chunk in "hooks" function

Code:
if [ -z "${LIVE_HOOKS}" ]
   then
      return
   fi


is actually redundant because it is repeated at the top of the following function "Process_hooks"

##############

The cmdline here is getting rather long. It is possible in theory to place your hook in /lib/live/mount/medium/${LIVEMEDIADIR}/config-hooks/

EDIT ${LIVEMEDIADIR} is normally "live" but can be changed <live-media-path=path_to_filesystem.squashfs> or <findiso=path_to_whatever.iso> for example if you use a multiboot usb setup where /live is inappropriate

Then if
Code:
config=hooks hooks=medium
is on cmdline it (they) should be found
EDIT typo above now corrected

I made another variation which should get that working but haven't tested it yet (have to include it a new snapshot first)

Code:
#!/bin/sh

## live-config(7) - System Configuration Scripts
## Copyright (C) 2006-2012 Daniel Baumann <daniel@debian.org>
##
## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
## This is free software, and you are welcome to redistribute it
## under certain conditions; see COPYING for details.

#########################################################################################

## This version is a (hopefully temporary) experimental fix for a regression in Sid

## The "official" version should be dpkg-diverted to /lib/live/config/9990-hooks.debian
## and the "executable" flag removed till this version is deinstalled

## This should be replaced with the official version when the "upstream" fix arrives

## This version was modified by dzz and fsr 26-12-2012
##

#########################################################################################

Hooks ()
{

# Checking if package is installed or already configured
   if  [ -e /var/lib/live/config/hooks ]
   then
      return
   fi

   for _PARAMETER in ${_CMDLINE}
   do
      case "${_PARAMETER}" in
         live-config.hooks=*|hooks=*)
            LIVE_HOOKS="${_PARAMETER#*hooks=}"
            ;;
      esac
   done

   if [ -z "${LIVE_HOOKS}" ]
   then
      return
   else
   echo "Hooks are set.. Processing... "
   fi

   Process_hooks
}

Process_hooks ()
{
   if [ -z "${LIVE_HOOKS}" ]
   then
      return
   fi

   echo -n " hooks"

   for _HOOK in $(echo ${LIVE_HOOKS} | sed -e 's/|/ /g')
   do
      case "${_HOOK}" in
         filesystem)
            if ls /lib/live/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/config-hooks/*; do echo file://${_FILE}; done)"
            fi
         ;;

         medium)
            if ls /lib/live/mount/medium/live/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/mount/medium/live/config-hooks/*; do echo file://${_FILE}; done)"
            fi

            LIVEMEDIA_DIR=$(cat /proc/cmdline|grep -o "live-media-path=.*" |sed 's: .*::' |sed 's:live-media-path=/::')
            if [ -z $LIVEMEDIA_DIR ]; then
            LIVEMEDIA_DIR=$(cat /proc/cmdline|grep -o "findiso=.*" |sed 's: .*::' |sed 's:findiso=/::')
            fi

            if [ -z $LIVEMEDIA_DIR ]; then
            LIVEMEDIA_DIR=live
            fi

            if ls /lib/live/mount/medium/${LIVEMEDIADIR}/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/mount/medium/${LIVEMEDIADIR}/config-hooks/*; do echo file://${_FILE}; done)"
            fi

            if ls /lib/live/mount/findiso/${LIVEMEDIADIR}/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/mount/findiso/${LIVEMEDIADIR}/config-hooks/*; do echo file://${_FILE}; done)"
            fi

            # TODO : The live-media volume could be mounted on /lib/live/mount/persistence/sd[a-z][0-9]
            if ls /lib/live/mount/persistence/sd[a-z][0-9]/${LIVEMEDIADIR}/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/mount/persistence/sd[a-z][0-9]/${LIVEMEDIADIR}/config-hooks/*; do echo file://${_FILE}; done)"
            fi
         ;;

         *)
            _HOOKS="${_HOOKS} ${_HOOK}"
            ;;
      esac
   done

   for _HOOK in ${_HOOKS}
   do
      _TMPFILE="$(mktemp -t live-config.XXXXXXXX)"

      if echo "${_HOOK}" | grep -qs file://
      then
         # local file
         cp $(echo ${_HOOK} | sed 's|file://||') "${_TMPFILE}"
      else
         # remote file
         Start_network

         wget --quiet "${_HOOK}" -O "${_TMPFILE}"
      fi

      chmod 0755 "${_TMPFILE}"
      ./"${_TMPFILE}"
      rm -f "${_TMPFILE}"
   done

# Creating state file
   if [ -n "${_HOOKS}" ]; then
      touch /var/lib/live/config/hooks
   fi
}

Hooks




I also made a deb (first attempt) so this can be done more cleanly without directly modifying "official" packages

http://exegnulinux.net/refracta/

Also at that url is a patch to make the live-media partition mount RW (very useful for usb... persistence without multiple partitions) You need to extract the initrd and patch the file /lib/live/boot/9990-misc-helpers.sh Then repack and use the new initrd to boot with. No need to rebuild the squashfs or iso.
Last edited by dzz on Thu Nov 29, 2012 3:26 am, edited 1 time in total.

Re: Using hooks

Tue Nov 27, 2012 4:28 am

I raised this issue once again on debian-live mailing lists.

I also posted of the RW patch and got a (so far) positive response from Daniel Baumann

We must wait and see what happens. In the meantime hacks are necessary because (some of us at least) want it working now...

Re: Using hooks

Thu Nov 29, 2012 2:37 am

Script posted before was not right, this is much better

Code:
#!/bin/sh

## live-config(7) - System Configuration Scripts
## Copyright (C) 2006-2012 Daniel Baumann <daniel@debian.org>
##
## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING.
## This is free software, and you are welcome to redistribute it
## under certain conditions; see COPYING for details.

#########################################################################################

## script name: 9989-hooks
## script location: /lib/live/config/

## This version is a (hopefully temporary) experimental fix for a regression in Sid

## David Hare and fsr 26-12-2012

## If "hooks" or "live-hooks" is called, this will run before (official) 9990-hooks.

## If hooks are found 9990-hooks gets "-x"ed then cannot be executed

## When the official version gets fixed this version should be removed and <chmod +x /lib/live/config/9990-hooks>

#########################################################################################

Hooks ()
{

# Checking if package is installed or already configured
   if  [ -e /var/lib/live/config/hooks ]
   then
      return
   fi

   for _PARAMETER in ${_CMDLINE}
   do
      case "${_PARAMETER}" in
         live-config.hooks=*|hooks=*)
            LIVE_HOOKS="${_PARAMETER#*hooks=}"
            ;;
      esac
   done

   if [ -z "${LIVE_HOOKS}" ]
   then
      return
   else
   echo "Hooks are set.. Processing... "
   fi

   Process_hooks
}

Process_hooks ()
{
   if [ -z "${LIVE_HOOKS}" ]
   then
      return
   fi

   echo -n " hooks"

   for _HOOK in $(echo ${LIVE_HOOKS} | sed -e 's/|/ /g')
   do
      case "${_HOOK}" in
         filesystem)
            if ls /lib/live/config-hooks/* 2>&1
            then
               _HOOKS="${_HOOKS} $(for _FILE in /lib/live/config-hooks/*; do echo file://${_FILE}; done)"
            fi
         ;;

         medium)

#######################################################

# live-media-path directory is /live by default... but user might have set a different one

# if custom live-media-path was used
if (cat /proc/cmdline|grep -q "live-media-path="); then

LIVEMEDIA_PATH="$(cat /proc/cmdline|grep -o "live-media-path=.*" |sed 's: .*::' |sed 's:live-media-path=/::'|sed 's:live-media-path=::')"

   # see if it is a sub-dir
   if (echo $LIVEMEDIA_PATH|grep -q "/"); then
   LIVEMEDIA_DIR=$(dirname $LIVEMEDIA_PATH)
   else
   LIVEMEDIA_DIR="$LIVEMEDIA_PATH"
   fi

# if findiso was used it's different. It could be a partition root, directory or subdirectory
elif (cat /proc/cmdline|grep -q "findiso="); then

LIVEMEDIA_PATH="$(cat /proc/cmdline|grep -o "findiso=.*" |sed 's: .*::' |sed 's:findiso=/::'|sed 's:findiso=::')"

   # if it's a sub-dir the output will have a slash in it
   if (echo $LIVEMEDIA_PATH|grep -q "/"); then
   LIVEMEDIA_DIR=$(dirname $LIVEMEDIA_PATH)

   else
   # it is not in a sub-dir
   LIVEMEDIA_DIR="$LIVEMEDIA_PATH"

      # if iso is in partition root, look for hooks only in /live
      if (grep -q "\.iso" ${LIVEMEDIA_PATH}); then
      LIVEMEDIA_DIR="live"
      fi
   fi
fi

   if [ -z "${LIVEMEDIA_DIR}" ]; then
   # live-media-path or findiso were not used so look for hooks only in /live
   LIVEMEDIA_DIR="live"
   fi

#######################################################

            # look for hooks in all likely mountpoints/${LIVEMEDIA_DIR}/config-hooks/*

            # suppress stderr from ls if nothing found

            # if booting direct from squash
            if ls /lib/live/mount/medium/${LIVEMEDIA_DIR}/config-hooks/* 2> /dev/null
            then
               _HOOKS="${_HOOKS} $(for _FILE in $(ls /lib/live/mount/medium/${LIVEMEDIA_DIR}/config-hooks/*) ; do echo file://${_FILE}; done)"

# TODO "find" might be better than then "ls" in case config-hooks/ has any subdirs
#               _HOOKS="${_HOOKS} $(for _FILE in $(find /lib/live/mount/medium/${LIVEMEDIA_DIR}/config-hooks/* -type f) ; do echo file://${_FILE}; done)"

            fi

            # if booting findiso
            if ls /lib/live/mount/findiso/${LIVEMEDIA_DIR}/config-hooks/* 2> /dev/null
            then
               _HOOKS="${_HOOKS} $(for _FILE in $(ls /lib/live/mount/findiso/${LIVEMEDIA_DIR}/config-hooks/*); do echo file://${_FILE}; done)"
            fi

            # EXPERIMENTAL : If 9990-misc-helpers.sh was patched and persistence is on
            # The live-media volume might be mounted on /lib/live/mount/persistence/sd[a-z][0-9]
            if ls /lib/live/mount/persistence/sd[a-z][0-9]/${LIVEMEDIA_DIR}/config-hooks/* 2> /dev/null
            then
               _HOOKS="${_HOOKS} $(for _FILE in $(ls /lib/live/mount/persistence/sd[a-z][0-9]/${LIVEMEDIA_DIR}/config-hooks/*); do echo file://${_FILE}; done)"
            fi
         ;;

         *)
            _HOOKS="${_HOOKS} ${_HOOK}"
            ;;
      esac
   done

   for _HOOK in ${_HOOKS}
   do
      _TMPFILE="$(mktemp -t live-config.XXXXXXXX)"

      if echo "${_HOOK}" | grep -qs file://
      then
         # local file
         cp $(echo ${_HOOK} | sed 's|file://||') "${_TMPFILE}"
      else
         # remote file
         Start_network

         wget --quiet "${_HOOK}" -O "${_TMPFILE}"
      fi

      chmod 0755 "${_TMPFILE}"
      ./"${_TMPFILE}"
      rm -f "${_TMPFILE}"
   done

# Creating state file
   if [ -n "${_HOOKS}" ]; then
      touch /var/lib/live/config/hooks

   # this will be done only after thist script has successfully run, in a live session
   # disable original hook script
   chmod -x /lib/live/config/9990-hooks

   fi
}

Hooks


This one should additionally find custom hook scripts placed in /live /config-hooks/ or live-media-path /config-hooks/ on the live-media by using just "hooks=medium" on cmdline. Seems a better way to do it and probably what was originally intended.

It is "9989 hooks" and runs before the "official" 9990-hooks. It will "-x" 9990-hooks so that can't run. No dpkg-diverts used.

Updated the deb also, same url. Anyone who used the old one, purge it first. i always found a deb package to be a cleaner way to do system stuff. Or just put the code in /lib/live/config/9989 hooks and "+x" it.

And remember this is experimental and not properly tested.
Post a reply