Skip to content

Instantly share code, notes, and snippets.

@DennisLfromGA
Last active December 22, 2015 04:38
Show Gist options
  • Save DennisLfromGA/6418198 to your computer and use it in GitHub Desktop.
Save DennisLfromGA/6418198 to your computer and use it in GitHub Desktop.
A crouton tool to search and prompt for a Desktop Environment (I.E.) gnome, xbmc, xfce4, etc. in a specified chroot based upon the contents of the '(chroot)/etc/crouton/targets' file. Also allows checking the 'crouton' version and optionally updating all targets in a chroot.
#!/bin/sh
echo_e='/bin/echo -e'
#######################
## Declare Variables ##
#######################
APPLICATION="${0##*/}"
Chroot_loc=/usr/local/chroots
[ -d /var/crouton/chroots ] && Chroot_loc='/var/crouton/chroots'
[ ! -d "$Chroot_loc" ] && Chroot_loc=''
Chroot_par="$(dirname "${Chroot_loc}")"
Color='y'
Gry_text=''; Red_text=''; Grn_text=''; Yel_text=''
Vio_text=''; Pur_text=''; Blu_text=''; Wht_text=''; Nrm_text=''
Bkgrd='-b'; Bkmsg="(run in background)"; SFX=f # Bkgrd=''; Bkmsg=''
List=''; Targs=''
GO='';GOAGAIN=''; CrU=''; UP=''; key=''
CurrentCrVer=''; LatestCrVer=''; ChrootCrVer=''
DE=''; nDE=0; DE_choice=''; DENumber=''
CR=''; nCR=1; CR_choice=''; CRNumber=''
DEBUG=''
USAGE="
USAGE: $ ${APPLICATION} [options] [chroot_name]
A program to search and prompt for a Desktop Environment (I.E.) gnome, xbmc, xfce4, etc.
in a specified chroot based upon the contents of the '(chroot)/etc/crouton/targets' file.
Also allows checking the 'crouton' version and optionally updating all targets in a chroot.
Options:
-b Run the specified command in the background - Default
-f Run the specified command in the foreground - Default: background
-l List chroots in '$Chroot_loc' & exit
-t List a chroot's targets & exit - requires chroot name
-w No colors displayed, only black & white - Default: color
-c CHROOTS Directory the chroots are in - Default: ${Chroot_loc}
[-n] CHROOT Name of the chroot to enter - Default: only chroot or none if more than one
plus:
-h Help - print help and usage summary & exit
-H Help & History - print help and usage summary plus version history & exit
-v Version - print version number & exit
-V Version & History - print version number plus version history & exit
"
#FORMAT: ${APPLICATION} [-b] [-f] [-l] [-t] [-w] [-c chroots_directory] [-n] chroot_name
# VERSION format: date '+%Y%m%d%H%M%S'
VERSION='20140710150511'
VERHIST="\
$APPLICATION-20140710150511 : Added the option to check the APPLICATION name to see if
$APPLICATION-20140710150511 + it ends in 'f' which will then operate in foreground mode
$APPLICATION-20140515134853 : Changed xinit target to be added only when .xinitrc exists
$APPLICATION-20140319173413 : Added detection & implemtation of CROUTON partition
$APPLICATION-20140319173413 + also added 'elementary' DE/target
$APPLICATION-20140119153310 : Added Version tracking and version history options
$APPLICATION-20140114001139 : Added Version number and option"
# If the APPLICATION name ends in 'f' then operate in foreground mode
if [ ! ${APPLICATION%$SFX} = "${APPLICATION}" ]; then Bkgrd=''; Bkmsg=''; fi
#########################
#### FUNCTIONS START ####
#########################
Get_Args() {
while getopts bdDfltwhc:n:hHvV OPT
do
case ${OPT} in
b) Bkgrd='-b'; Bkmsg="(run in background)" ;;
d) DEBUG='y'
$echo_e "\n### ${Yel_text}DEBUG output selected${Nrm_text} ###" ;;
D) DEBUG=$(($DEBUG+1))
[ "$DEBUG" = '1' ] && $echo_e "\n### ${Yel_text}special DEBUG output selected${Nrm_text} ###"
[ "$DEBUG" = '2' ] && ($echo_e "### ${Yel_text}extra-special DEBUG output selected${Nrm_text} ###\n"; sleep 3) ;;
f) Bkgrd=''; Bkmsg='' ;;
l) List='y' ;;
t) Targs='y';;
w) Color='' ;;
c) Chroot_loc="`readlink -f "$OPTARG"`"
if [ ! -d "${Chroot_loc}" ]; then
error 3 "${Red_text}No chroots folder found at ${Chroot_loc} - exiting...${Nrm_text}"
else
Chroot_par=$(dirname "${Chroot_loc}")
fi ;;
n) Chroot="${OPTARG}"
if [ -d "${Chroot_loc}/${Chroot}" ]; then
Cname="${Chroot_loc}/${Chroot}"
else
error 3 "${Red_text}No chroot named '${Chroot}' found in '${Chroot_loc}' - exiting...${Nrm_text}"
fi ;;
h) error 0 "${USAGE}" ;;
H) error 0 "${USAGE}\n${VERHIST}" ;;
v) error 0 "${APPLICATION}-${VERSION}" ;;
V) error 0 "${APPLICATION}-${VERSION}\n${VERHIST}" ;;
\?) error 2 "${USAGE}" ;;
esac
done
shift "$((OPTIND-1))"
[ -n "$Color" ] && Gry_text="\e[01;30m"
[ -n "$Color" ] && Red_text="\e[01;31m"
[ -n "$Color" ] && Grn_text="\e[01;32m"
[ -n "$Color" ] && Yel_text="\e[01;33m"
[ -n "$Color" ] && Vio_text="\e[01;34m"
[ -n "$Color" ] && Pur_text="\e[01;35m"
[ -n "$Color" ] && Blu_text="\e[01;36m"
[ -n "$Color" ] && Wht_text="\e[01;37m"
[ -n "$Color" ] && Nrm_text="\e[0m"
#
[ "$DEBUG" = '1' ] && $echo_e "\n# ${Yel_text}'APPLICATION' is: '$APPLICATION'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}------------- is: ---------${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Bkgrd' is: '$Bkgrd'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Bkmsg' is: '$Bkmsg'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'DEBUG' is: '$DEBUG'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'List' is: '$List'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Targs' is: '$Targs'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Chroot' is: '$Chroot'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Chroot_loc' is: '$Chroot_loc'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'Chroot_par' is: '$Chroot_par'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "# ${Yel_text}'USAGE' is: '$USAGE'${Nrm_text}"
[ "$DEBUG" = '1' ] && $echo_e "\n# (${Wht_text}Press ENTER to continue${Nrm_text})${Nrm_text} #\b\c" && read key
[ "$DEBUG" = '2' ] && set -x
#
### If just listing chroots, do it and exit
if [ "${List}" = 'y' ]; then
$echo_e "Chroots: \c"
ls "${Chroot_loc}" 2>/dev/null ; $echo_e "\c"
error 0
fi
## Call next function ##
Get_Chroots $*
}
Get_Chroots() {
### Make a temporary file and auto-remove it when the script ends.
CRname="/tmp/${APPLICATION}.CR.$$"; touch ${CRname}
TRAP="rm -f '${CRname}';${TRAP}"
trap "${TRAP}" INT HUP 0
### Need a chroot listed if not using -n.
if [ $# = 0 ] && [ ! -n "${Chroot}" ]; then
Nbr=$(ls -1 "${Chroot_loc}" 2>/dev/null | wc -l)
if [ "$Nbr" = 0 ]; then
error 0 "${Red_text}Sorry, no chroots found in '${Chroot_loc}'${Nrm_text}"
elif [ "$Nbr" = 1 ]; then
Chroot=$(ls -1 "${Chroot_loc}" 2>/dev/null)
Cname="${Chroot_loc}/${Chroot}"
else
### Put them in a numbered file for selection
for CR in $(ls "${Chroot_loc}" 2>/dev/null)
do
echo "${nCR}) ${CR}" >> ${CRname}
nCR="$((${nCR} + 1))"
done
$echo_e "\nBelow are the Chroots found in '${Chroot_loc}' -\n"
cat "${CRname}" | sed 's/^/ /g'
$echo_e "\n${Wht_text}Please select a number from one of the above $((${nCR} - 1)) entries -"
$echo_e "Optionally enter an 'r' to restart the selections: [#,r] ${Nrm_text}'_'\b\b\c"; read CRNumber
if [ -z "${CRNumber}" ]; then error 0 "Okay, got nothin' so quitting anyway..."; fi
Chroot="$(grep ^${CRNumber}\) ${CRname} | cut -d ' ' -f2)"
if [ "${CRNumber}" = 'r' ]; then
echo "Okay, got an 'r' so restarting..."
rm -f "${CRname}"; exec $0
fi
if [ -z "${Chroot}" ]; then
error 1 "${Red_text}No selection made - Aborting...${Nrm_text}"
else
if [ -d "${Chroot_loc}/${Chroot}" ]; then
Cname="${Chroot_loc}/${Chroot}"
else
error 3 "${Red_text}No chroot named '${Chroot}' found in '${Chroot_loc}' - exiting...${Nrm_text}"
fi
fi
fi
fi
### Get the chroot specified on the command line, if given
if [ -z "${Chroot}" -a "${#}" -gt 0 ]; then
Chroot="${1}"
if [ -d "${Chroot_loc}/${Chroot}" ]; then
Cname="${Chroot_loc}/${Chroot}"
else
error 3 "${Red_text}No chroot named '${Chroot}' found in '${Chroot_loc}' - exiting...${Nrm_text}"
fi
elif [ -z "${Chroot}" ]; then
$echo_e "${Red_text}No chroot specified - see below...${Nrm_text}"
ls "${Chroot_loc}" 2>/dev/null
error 1 "\n${USAGE}"
fi
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Chroot' is: '$Chroot'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'Cname' is: '$Cname'${Nrm_text}"
#
## Call next function ##
Chk_Targets
}
Chk_Targets() {
if [ -z "${Cname}/etc/crouton/targets" -o ! -f "${Cname}/etc/crouton/targets" ]; then
error 3 "${Red_text}No valid '$Chroot/etc/crouton/targets' file found - exiting...${Nrm_text}"
else
TargetsFile="${Cname}/etc/crouton/targets"
All_Targets="-t $(cat "${TargetsFile}" | sed "s/'//g")"
fi
if [ "${Targs}" = 'y' ]; then
$echo_e "\n${Chroot} targets: \c"
cat "${TargetsFile}"; $echo_e "\c"
error 0
fi
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'TargetsFile' is: '$TargetsFile'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'All_Targets' is: '$All_Targets'${Nrm_text}"
#
## Call next function ##
Get_Targets
}
Get_Targets() {
### Make a temporary file and auto-remove it when the script ends.
DEname="/tmp/${APPLICATION}.DE.$$"; touch ${DEname}
TRAP="rm -f '${DEname}';${TRAP}"
trap "${TRAP}" INT HUP 0
### Get the chroot's targets
DE_list=$(cat "${TargetsFile}" | sed "s/'//g" | sed 's/,/ /g')
passwd="$Cname/etc/passwd"
uid='1000'
USERNAME="`awk -F: '$3=='"$uid"'{print $1; exit}' "$passwd"`"
CHROOTHOME="$Cname/`awk -F: '$1=="'"$USERNAME"'"{print $6; exit}' "$passwd"`"
if [ -s $CHROOTHOME/.xinitrc ]; then
DE_list="update-all-targets enter-chroot ${DE_list} xinit quit"
else
DE_list="update-all-targets enter-chroot ${DE_list} quit"
fi
### Put them in a numbered file for selection
for DE in $(echo "${DE_list}")
do
if [ "$(echo "${DE}" | grep -e audio -e gtk-extra -e chrom -e celme -e core -e keyb -e touch -e vnc -e x11 -e extension)" ]; then
continue
else
echo "${nDE}) ${DE}" >> ${DEname}
nDE="$((${nDE} + 1))"
fi
done
$echo_e "\nBelow are the Desktop Environments found for '${Chroot}' -\n"
cat "${DEname}" | sed 's/^/ /g'
$echo_e "\n${Wht_text}Please select a number from one of the above ${nDE} entries -"
$echo_e "Optionally enter an 'r' to restart the selections: [#,r] ${Nrm_text}'_'\b\b\c"; read DENumber
if [ -z "${DENumber}" ]; then error 0 "Okay, got nothin' so quitting anyway..."; fi
DE_choice="$(grep ^${DENumber}\) ${DEname} | cut -d ' ' -f2)"
case "${DE_choice}" in
update*) Start_script='update' ;;
enter*) Start_script='enter-chroot'; Bkgrd='' Bkmsg='' ;;
cli*) Start_script='startcli'; Bkgrd='' Bkmsg='' ;;
e17) Start_script='starte17' ;;
cinn*) Start_script='startcinnamon' ;;
elem*) Start_script='startelementary' ;;
gnome) Start_script='startgnome' ;;
kde*) Start_script='startkde' ;;
lxde*) Start_script='startlxde' ;;
open*) Start_script='startob' ;;
unity*) Start_script='startunity' ;;
xbmc) Start_script='startxbmc' ;;
xfce*) Start_script='startxfce4' ;;
xinit) Start_script='startxi' ;;
quit) error 0 "Okay, quitting..." ;;
*) if [ "${DENumber}" = 'r' ]; then
echo "Okay, got an 'r' so restarting..."
rm -f "${CRname}" "${DEname}"; exec $0
elif [ "${DENumber}" = 'q' ]; then
error 0 "Okay, got a 'q' so quitting ..."
else
error 2 "Option '${DENumber}' not recognized - Aborting..."
fi ;;
esac
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'DE_list' is: '$DE_list'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'DE_choice' is: '$DE_choice'${Nrm_text}"
#
## Call next function ##
Set_Action
}
Set_Action() {
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Start_script' is: '$Start_script'${Nrm_text}"
#
if [ "${Start_script}" = 'update' ]; then
## Call next function ##
Chk_Crouton $Chroot "$Cname"
$echo_e "\n${Gry_text}sudo sh -e ${Cr} -n ${Chroot} -p ${Chroot_par} -u${Nrm_text}"
$echo_e "${Wht_text}Enter 'y' to update '${Chroot}' - anything else to abort - ${Nrm_text}'_'\b\b\c"; read GO
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'GO' is: '$GO'${Nrm_text}"
#
if [ "${GO}" = 'r' -o "${GO}" = 'R' ]; then
rm ${CRname} ${DEname} 2>/dev/null && exec $0 ${Chroot}
fi
if [ "${GO}" = 'y' -o "${GO}" = 'Y' ]; then
if [ ! -s "${Chroot_par}/Cr-${Chroot}.log" ]; then
sudo touch "${Chroot_par}/Cr-${Chroot}.log"
sudo chmod 664 "${Chroot_par}/Cr-${Chroot}.log"
sudo chown root:chronos "${Chroot_par}/Cr-${Chroot}.log"
fi
$echo_e "\n# ${Yel_text}You can view the output of this update in ${Chroot_par}/Cr-${Chroot}.log${Nrm_text} #"; sleep 3
$echo_e "\n\n*** UPDATED - `date` ***\n${Cr} -p ${Chroot_par} -n ${Chroot} -u ***\n***\n" |\
sudo tee -a "${Chroot_par}/Cr-${Chroot}.log"
sudo sh -e "${Cr}" -n "${Chroot}" -p "${Chroot_par}" -u 2>&1 |\
sudo tee -a "${Chroot_par}/Cr-${Chroot}.log"
$echo_e "\n${Blu_text}The '${Chroot}' chroot has been updated.${Nrm_text}"
$echo_e "${Wht_text}Enter 'y' to restart - anything else to quit - ${Nrm_text}'_'\b\b\c"; read GOAGAIN
if [ "${GOAGAIN}" = 'y' -o "${GOAGAIN}" = 'Y' ]; then
rm ${CRname} ${DEname} 2>/dev/null && exec $0 ${Chroot}
fi
else
error 0 "Okay, ABORTING ..."
fi
else
$echo_e "\n${Gry_text}sudo ${Start_script} -n ${Chroot} -c ${Chroot_loc} ${Bkgrd} ${Bkmsg}${Nrm_text}"
oldtrap="$TRAP"; trap - INT
$echo_e "${Wht_text}Executing in 5 seconds - Press 'Ctrl-C' TO ABORT! ${Nrm_text}'_'\b\b\c"; sleep 5
# read -t 5 -p "Executing in 5 seconds - ENTER 'a' TO ABORT! " GO
if [ -n "${GO}" ]; then error 0 "Okay, ABORTING ..."; fi
TRAP="$oldtrap"; trap "${TRAP}" INT HUP 0
sudo "${Start_script}" -n "${Chroot}" -c "${Chroot_loc}" ${Bkgrd}
fi
}
Chk_Crouton() {
### Ask if you want to check for updates
$echo_e "\n${Wht_text}Do you want to check for a newer version of 'crouton'"
$echo_e "before we update-all-targets for '${Chroot}' ? (Y/n) ${Nrm_text}'_'\b\b\c"; read CrU
if [ -n "${CrU}" -a "${CrU}" = 'n' ]; then
$echo_e "\n${Blu_text}Okay, no version check of crouton will be done...${Nrm_text}"
else
### Download latest version of 'crouton' & report it
LatestCr='/tmp/crouton.latest'; sudo rm $LatestCr >/dev/null 2>&1
"${Cname}/usr/local/bin/croutonversion" -duf $LatestCr >/dev/null 2>&1
if [ ! -r $LatestCr ]; then wget -qO $LatestCr http://goo.gl/fd3zc; fi
LatestCrVer=$(sh $LatestCr -V | cut -d' ' -f3 | sed "s/'//g")
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'LatestCrVer' is: '$LatestCrVer'${Nrm_text}"
#
$echo_e "\n${Yel_text}The latest version of 'crouton' is: ${LatestCrVer}${Nrm_text}"
### Attempt to find a local version of 'crouton' & report it
if [ -r "${Chroot_par}/bin/crouton" ]; then Cr="${Chroot_par}/bin/crouton"
elif [ -r /usr/local/bin/crouton ]; then Cr=/usr/local/bin/crouton
elif [ -r $HOME/Downloads/crouton ]; then Cr=$HOME/Downloads/crouton
else Cr=$(which crouton 2>/dev/null)
fi
### Notify that if one wasn't found, one will be put in Downloads
if [ -s "${Cr}" ]; then
CrFound='y'
CurrentCrVer=$(sh "$Cr" -V | cut -d' ' -f3 | sed "s/'//g")
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Cr' is: '$Cr'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'CurrentCrVer' is: '$CurrentCrVer'${Nrm_text}\n"
#
$echo_e "${Blu_text}The local version of 'crouton' is: ${CurrentCrVer}${Nrm_text}"
else
CrFound='n'
$echo_e "\n'crouton' is not in your Downloads folder or \$PATH ..."
$echo_e "${Blu_text}Installing the latest version in '$HOME/Downloads'${Nrm_text}"
Cr="$HOME/Downloads/crouton"
sudo cp -f "$LatestCr" "$Cr" && sudo chmod +x "${Cr}"
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'Cr' is: '$Cr'${Nrm_text}"
[ -n "$DEBUG" ] && $echo_e "# ${Yel_text}'CurrentCrVer' is: 'NULL'${Nrm_text}\n"
#
fi
### Get the chroot's version of 'crouton' when installed or updated & report it
ChrootCrVer=$(grep '^VERSION=' "${Cname}/usr/local/bin/croutonversion" | cut -d= -f2 | sed "s/'//g")
if [ -z "$ChrootCrVer" ]; then ChrootCrVer='* NULL *'; fi
#
[ -n "$DEBUG" ] && $echo_e "\n# ${Yel_text}'ChrootCrVer' is: '$ChrootCrVer'${Nrm_text}\n"
#
$echo_e "${Blu_text}The '$Chroot' version of 'crouton' is: ${ChrootCrVer}${Nrm_text}"
### Now compare local crouton version with the latest
if [ "$CrFound" = 'y' ]; then
if [ "$LatestCrVer" = "$CurrentCrVer" ]; then
$echo_e "\n${Grn_text}Your local 'crouton' version is the latest - that's good.${Nrm_text}"
else
$echo_e "\n${Red_text}Your local 'crouton' version is NOT the latest!${Nrm_text}"
$echo_e "${Wht_text}Shall we update 'crouton' now ? (Y/n) ${Nrm_text}'_'\b\b\c"; read UP
if [ -n "${UP}" -a "${UP}" = 'n' ]; then
echo "Okay, skipping update ..."
else
$echo_e "${Blu_text}Installing the latest version in '`dirname "$Cr"`'${Nrm_text}"
sudo mv -f "${Cr}" "${Cr}.bak"
sudo cp -f "$LatestCr" "$Cr" && sudo chmod +x "${Cr}"
fi
fi
fi
### Now compare local chroot version with the latest
if [ "$LatestCrVer" = "$ChrootCrVer" ]; then
$echo_e "\n${Grn_text}Your local '${Chroot}' version is the latest - that's good.${Nrm_text}"
echo "You can safely elect to not update it when asked next."
else
$echo_e "\n${Red_text}Your local '${Chroot}' version is NOT the latest!${Nrm_text}"
echo "You can elect to update it when asked next."
fi
fi
}
### exit with exit code $1, spitting out message $@ to stderr
error() {
local ecode="${1}"
shift
$echo_e "${*}" 1>&2
exit "${ecode}"
}
#########################
#### FUNCTIONS END ####
#########################
Get_Args $*
[ "$DEBUG" = '2' ] && set +x
@DennisLfromGA
Copy link
Author

Some fairly significant changes made in the last update.
Most of them concerning updating 'crouton' and applying it to both the system and the chroot.

...Get it while it's hot... ;-)

@DennisLfromGA
Copy link
Author

Corrected some of the logic when updating crouton and the chroots.
Cleaned up the whole thing ( the best I could ;) and added a few tweaks and more comments.

@DennisLfromGA
Copy link
Author

Changed script to add a color output by default, color can be turned off with the '-w' option.
The original non-color script has been renamed to 'startcr.b+w' and is no longer ...

@DennisLfromGA
Copy link
Author

Added Version tracking and version history options. Also added detection & implemtation of CROUTON partition, plus added 'elementary' DE/target

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment