Skip to content

Instantly share code, notes, and snippets.

@DennisLfromGA
Last active July 17, 2020 17:27
  • Star 3 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save DennisLfromGA/6443733 to your computer and use it in GitHub Desktop.
A ChromeOS upstart script to kick-off a crouton chroot desktop environment.
# Copyright (c) 2016 The crouton Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
## Filename: /etc/init/crouton.conf
## NOTE: 'rootfs' verification needs to be removed.
## crouton chroot - Start session
##
## This will start a (crouton) chroot Desktop Environment session
description "Crouton Chroot Session daemon"
author "github/DennisLfromGA"
## Choose when the crouton chroot will be started - 4 choices below -
## NOTE: use only 1, prepend the others with the remark character: #
#start on starting ui # 1st - starts when the user interface begins
# + only 1 chroot will run in this mode
# + must use XMETHOD: 'xorg'
#start on started ui # 2nd - starts when the user interface appears
# + only 1 chroot will run in this mode
# + must use XMETHOD: 'xorg'
#start on login-prompt-visible # 3rd - starts when the login screen appears
# + only 1 chroot will run in this mode
# + must use XMETHOD: 'xorg'
start on start-user-session # 4th - starts when the user logs in - DEFAULT
# + multiple chroots could run in this mode
# + can use either XMETHOD: 'xiwi' or 'xorg'
# + ensures user ~/Downloads is available
stop on stopping ui or starting halt or starting reboot
############################################################################
## NOTE: This job can be controlled externally by placing the file ##
#+ 'crouton.init' in the User's Downloads folder on a per User ##
#+ basis or in the chroots parent folder per system with the ##
#+ following six optional variables set: ##
#+ 1) DELAY 2) CHROOT 3) START_DE 4) CHROOT_APP 5) XMETHOD 6) RUN_STATE ##
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
#+ [ the 'env ' prefix must be omitted in the control file ] ##
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
## Start of control file variables ##
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
env DELAY=10 # delay desired number of seconds before starting ##
env CHROOT=xenial # enter desired chroot to start ##
env START_DE=startxfce4 # enter desired Desktop Envirnoment to use ##
env CHROOT_APP=none # enter desired chroot application to run ##
env XMETHOD=default # enter temporary X-Window Envirnoment to use ##
env RUN_STATE=y # change to 'n' to disable running $CHROOT ##
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
## End of control file variables ##
############################################################################
##########################################################################
## System control parameters ##
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
env DEBUG=on # change to 'on' for DEBUGGING output ##
env MASTER_SW=on # change to 'off' to override running any $CHROOT ##
env MULTIPLES=on # change to 'off' to allow running only 1 $CHROOT ##
##########################################################################
script
PID="$$"
touch /tmp/$UPSTART_JOB-$PID.log
## For output, use 'grep $PID /var/log/messages'
LOGGER="logger -p local3.info -t $UPSTART_JOB($PID)"
trap "$LOGGER '### Exiting...'" EXIT
$LOGGER "###############"
$LOGGER "### Starting..."
if [ "$DEBUG" = 'on' ]; then
exec >> /tmp/$UPSTART_JOB-$PID.log 2>&1
set -x
$LOGGER "*** DEBUGGING turned ON."
$LOGGER "*** See '/tmp/$UPSTART_JOB-$PID.log' for output."
else
$LOGGER "*** DEBUGGING is OFF."
fi
if [ "$MASTER_SW" = "off" ]; then
## No chroots will run even if allowed by external control file(s).
$LOGGER "!!! The MASTER_SW has been turned OFF"
$LOGGER "No CHROOTS will run - period. Exiting."
$LOGGER "###############"
$LOGGER "### Ending....."
$LOGGER "###############"
exit 255
fi
MULTS="`pgrep -l crouton|head -n 1`"
if [ "$MULTIPLES" = "off" ]; then
## Multiple chroots cannot be run when more than one user is logged in.
if [ -n "$MULTS" ]; then
$LOGGER "!!! MULTIPLE CHROOTS has been turned OFF"
$LOGGER "No more CHROOTS will be run now. Exiting."
$LOGGER "###############"
$LOGGER "### Ending....."
$LOGGER "###############"
exit 255
fi
elif [ -n "$MULTS" ]; then
$LOGGER "*** MULTIPLE CHROOTS is turned ON"
$LOGGER "Now running an additional CHROOT."
$LOGGER "###############"
fi
$LOGGER "##- Main checks started."
if [ -d /var/crouton/chroots ]; then
## Uses the @drinkcat 'separate_partition' branch - as DEFAULT
CROUTON_BIN=/var/crouton/bin
CROUTON_CHROOTS=/var/crouton/chroots
# if [ ! -x $CROUTON_BIN ]; then
mount -i -o remount,exec /var
$LOGGER "*** '/var' directory is being mounted as executable."
# else
# $LOGGER "*** '$CROUTON_BIN' directory is already mounted as executable."
# fi
$LOGGER "###############"
elif [ -d /usr/local/chroots ]; then
## Uses the @dnschneid 'master' branch
CROUTON_BIN=/usr/local/bin
CROUTON_CHROOTS=/usr/local/chroots
$LOGGER "###############"
else
## Nothing found...
$LOGGER "*** Crouton 'chroots' directory is missing. Aborting!"
$LOGGER "###############"
exit 1
fi
if [ ! -d $CROUTON_BIN ]; then
$LOGGER "*** Crouton 'bin' directory is missing. Aborting!"
$LOGGER "###############"
exit 1
fi
$LOGGER "*** Crouton 'bin' directory is $CROUTON_BIN"
$LOGGER "*** Crouton 'chroots' directory is $CROUTON_CHROOTS"
$LOGGER "##- Check for external control."
USER_DOWNLOADS="/home/chronos/user/Downloads"
DOWNLOADS_INIT="$USER_DOWNLOADS/${UPSTART_JOB}.init"
CHROOTS_PARENT=`dirname $CROUTON_CHROOTS`
CROUTON_INIT="$CHROOTS_PARENT/${UPSTART_JOB}.init"
if [ -r $DOWNLOADS_INIT ]; then INIT_FILE="$DOWNLOADS_INIT"
elif [ -r $CROUTON_INIT ]; then INIT_FILE="$CROUTON_INIT"; fi
if [ -r $INIT_FILE ] && [ -s $INIT_FILE ]; then
$LOGGER "*** External control enabled via '$INIT_FILE' file."
## Pull in variables from external control file
Delay="` awk -F= '/^DELAY=/ {print $2; exit}' "$INIT_FILE"`"
Chroot="` awk -F= '/^CHROOT=/ {print $2; exit}' "$INIT_FILE"`"
Start_DE="` awk -F= '/^START_DE=/ {print $2; exit}' "$INIT_FILE"`"
Chroot_App="` awk -F= '/^CHROOT_APP=/ {print $2; exit}' "$INIT_FILE"`"
XMethod="` awk -F= '/^XMETHOD=/ {print $2; exit}' "$INIT_FILE"`"
Run_state="` awk -F= '/^RUN_STATE=/ {print $2; exit}' "$INIT_FILE"`"
if [ -n "$Delay" -a "$Delay" != "$DELAY" ]; then
$LOGGER "##* DELAY changed from: '$DELAY' to '$Delay'."
DELAY="$Delay"
fi
if [ -n "$Chroot" -a "$Chroot" != "$CHROOT" ]; then
$LOGGER "##* CHROOT changed from: '$CHROOT' to '$Chroot'."
CHROOT="$Chroot"
fi
if [ -n "$Start_DE" -a "$Start_DE" != "$START_DE" ]; then
$LOGGER "##* START_DE changed from: '$START_DE' to '$Start_DE'."
START_DE="$Start_DE"
fi
if [ -n "$Chroot_App" -a "$Chroot_App" != "$CHROOT_APP" ]; then
$LOGGER "##* CHROOT_APP: '$Chroot_App' will be executed."
CHROOT_APP="$Chroot_App"
else
CHROOT_APP=
fi
if [ -n "$XMethod" -a "$XMethod" != "$XMETHOD" ]; then
$LOGGER "##* XMETHOD changed from: '$XMETHOD' to '$XMethod'."
XMETHOD=$XMethod
elif [ "$XMETHOD" != "default" ]; then
$LOGGER "##* XMETHOD changed from: 'default' to '$XMETHOD'."
else
$LOGGER "##* XMETHOD unchanged - set to '$XMETHOD'."
fi
if [ -n "$Run_state" -a "$Run_state" != "$RUN_STATE" ]; then
$LOGGER "##* RUN_STATE changed from: '$RUN_STATE' to '$Run_state'."
RUN_STATE="$Run_state"
fi
else
$LOGGER "### NO external control file found, using internal defaults."
fi
$LOGGER "##- Secondary checks started."
if [ ! -d $CROUTON_CHROOTS/$CHROOT ]; then
$LOGGER "*** Crouton '$CHROOT' directory is missing. Aborting!"
$LOGGER "###############"
exit 1
elif [ ! -s $CROUTON_BIN/$START_DE -o ! -x $CROUTON_BIN/$START_DE ]; then
$LOGGER "*** Crouton '$START_DE' script is missing or not executable. Aborting!"
$LOGGER "###############"
exit 1
fi
case $XMETHOD in
xorg|xiwi*)
XMARG="-X $XMETHOD"
;;
default)
XMARG=
;;
*)
XMARG=
$LOGGER "##* XMETHOD: '$XMETHOD' is invalid so not set."
;;
esac
if [ "$RUN_STATE" = "n" -o "$MASTER_SW" = off ]; then
$LOGGER "*** The RUN_STATE for chroot '$CHROOT' is DISABLED. Exiting."
$LOGGER "###############"
exit 0
fi
$LOGGER "##- Starting main process in $DELAY seconds."
sleep $DELAY
$LOGGER "##$ $CROUTON_BIN/$START_DE -c $CROUTON_CHROOTS -n $CHROOT $XMARG $CHROOT_APP"
eval sudo $CROUTON_BIN/$START_DE -c $CROUTON_CHROOTS -n "$CHROOT" $XMARG "$CHROOT_APP"
$LOGGER "##- Completed: status $?"
$LOGGER "### Ending....."
$LOGGER "###############"
if [ "$DEBUG" = "y" ]; then
set +x
fi
end script
@DennisLfromGA
Copy link
Author

This latest version allows the script to be controlled externally by -

  1. placing the file '${UPSTART_JOB}.init' ( usually 'crouton.init' ) in the User's Downloads folder on a per User basis or
  2. in the chroots parent folder per system

It also now runs in the foreground so it's an active process that can be accessed via 'initctl'.

@DennisLfromGA
Copy link
Author

Added additional System control parameters MASTER_SW and MULTIPLES.
Also added a bit more explanation and rules for starting the chroot(s).

@DennisLfromGA
Copy link
Author

Added XMETHOD option to allow starting the chroot using xorg, xephyr, or xiwi if installed.

@Timvrakas
Copy link

I believe the bin folder location is wrong for separate_partition. Also the default START_DE needs to be startxfce, not just xfce.
I don't know If you can "pull" a gist, but my fork has the changes.

@DennisLfromGA
Copy link
Author

Updated release to use 'xenial'.

@DennisLfromGA
Copy link
Author

Updated to mount /var as exec if needed.

@DennisLfromGA
Copy link
Author

Updated & improved mounting /var logic.

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