Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
elif [ -d /usr/local/chroots ]; then
## Uses the @dnschneid 'master' branch
CROUTON_BIN=/usr/local/bin
CROUTON_CHROOTS=/usr/local/chroots
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. 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 "##$ sudo $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

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Mar 5, 2014

NOTE: I also tried using the file 'rc.local' containing 'sleep 60 && exec /usr/local/bin/startgnome -n raring -b' but that didn't work either :(

Owner

DennisLfromGA commented Mar 5, 2014

NOTE: I also tried using the file 'rc.local' containing 'sleep 60 && exec /usr/local/bin/startgnome -n raring -b' but that didn't work either :(

@dnschneid

This comment has been minimized.

Show comment
Hide comment
@dnschneid

dnschneid Mar 27, 2014

L29, try this:
exec /bin/sh -e "$LOCAL_BIN/$START_DE" -n "$CHROOT" -b || logger -t "$UPSTART_JOB" "$CHROOT-$START_DE start: status $?"

dnschneid commented Mar 27, 2014

L29, try this:
exec /bin/sh -e "$LOCAL_BIN/$START_DE" -n "$CHROOT" -b || logger -t "$UPSTART_JOB" "$CHROOT-$START_DE start: status $?"

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Mar 28, 2014

Hurray! It Works finally.

If anyone else decides to use this please note that -

  1. It requires the REMOVAL of rootfs verification on the active kernel partition.
    2) This version is using @drinkcat's 'separate_partition' branch which uses '/var/crouton' instead of '/usr/local' as the parent location for your 'bin' & 'chroots' folders.
  2. So... edit the lines prefixed with 'env ...' and make them your own ;-)
Owner

DennisLfromGA commented Mar 28, 2014

Hurray! It Works finally.

If anyone else decides to use this please note that -

  1. It requires the REMOVAL of rootfs verification on the active kernel partition.
    2) This version is using @drinkcat's 'separate_partition' branch which uses '/var/crouton' instead of '/usr/local' as the parent location for your 'bin' & 'chroots' folders.
  2. So... edit the lines prefixed with 'env ...' and make them your own ;-)
@dnschneid

This comment has been minimized.

Show comment
Hide comment
@dnschneid

dnschneid Mar 28, 2014

Don't you need to set XAUTHORITY in there?

dnschneid commented Mar 28, 2014

Don't you need to set XAUTHORITY in there?

@dnschneid

This comment has been minimized.

Show comment
Hide comment
@dnschneid

dnschneid Mar 28, 2014

Also, you may want to get rid of the || true and the set +x at the end...

dnschneid commented Mar 28, 2014

Also, you may want to get rid of the || true and the set +x at the end...

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Mar 28, 2014

Fixes & (hopefully) improvements:

  • made changes to handle both the 'master' and 'separate_partition' branch.
  • added some option fors DELAY, DEBUG, and start on ... possibilities.
Owner

DennisLfromGA commented Mar 28, 2014

Fixes & (hopefully) improvements:

  • made changes to handle both the 'master' and 'separate_partition' branch.
  • added some option fors DELAY, DEBUG, and start on ... possibilities.
@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Mar 28, 2014

Added $XAUTHORITY - duh ;(

Owner

DennisLfromGA commented Mar 28, 2014

Added $XAUTHORITY - duh ;(

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Mar 30, 2014

enable disable

Owner

DennisLfromGA commented Mar 30, 2014

enable disable

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Mar 31, 2014

Improved & tweaked:

  • Renamed to 'crouton.conf' for simplification
  • Added comments & options to start at different boot / login states
  • Added option to use an external control file to define DELAY, CHROOT, START_DE, and RUN_STATE
  • The external control file name should track the UPSTART_JOB name with an '.init' suffix (I.E.) crouton.init

Some of the various boot / login states are listed below, the 4th option is the default:

#start on starting ui          # 1st - starts when the user interface begins
#start on started ui           # 2nd - starts when the user interface appears
#start on login-prompt-visible # 3rd - starts when the login screen appears
 start on start-user-session   # 4th - starts when the user logs in - DEFAULT
                               #     + ensures user ~/Downloads is available

A typical 'crouton.init' file, placed in the chroot's parent directory, is as follows:

##############################################################
## Place a '#' in the 1st column before the variable if you ##
#+ don't want to change it from the crouton.conf defaults.  ##
##############################################################

## change to desired number of seconds before starting
#DELAY=5
DELAY=30

## change to desired chroot to use
#CHROOT=elementary
CHROOT=raring
#CHROOT=trusty

## change to desired Desktop Envirnoment to use
#START_DE=startgnome
START_DE=startkde
#START_DE=startxfce4

## change to 'n' to disable running crouton.conf
#RUN_STATE=n
Owner

DennisLfromGA commented Mar 31, 2014

Improved & tweaked:

  • Renamed to 'crouton.conf' for simplification
  • Added comments & options to start at different boot / login states
  • Added option to use an external control file to define DELAY, CHROOT, START_DE, and RUN_STATE
  • The external control file name should track the UPSTART_JOB name with an '.init' suffix (I.E.) crouton.init

Some of the various boot / login states are listed below, the 4th option is the default:

#start on starting ui          # 1st - starts when the user interface begins
#start on started ui           # 2nd - starts when the user interface appears
#start on login-prompt-visible # 3rd - starts when the login screen appears
 start on start-user-session   # 4th - starts when the user logs in - DEFAULT
                               #     + ensures user ~/Downloads is available

A typical 'crouton.init' file, placed in the chroot's parent directory, is as follows:

##############################################################
## Place a '#' in the 1st column before the variable if you ##
#+ don't want to change it from the crouton.conf defaults.  ##
##############################################################

## change to desired number of seconds before starting
#DELAY=5
DELAY=30

## change to desired chroot to use
#CHROOT=elementary
CHROOT=raring
#CHROOT=trusty

## change to desired Desktop Envirnoment to use
#START_DE=startgnome
START_DE=startkde
#START_DE=startxfce4

## change to 'n' to disable running crouton.conf
#RUN_STATE=n
@dnschneid

This comment has been minimized.

Show comment
Hide comment
@dnschneid

dnschneid commented Apr 1, 2014

So fancy!

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Apr 19, 2014

For mounting the CROUTON partition auto-magically at startup (made possible via @drinkcat's crouton/separate_partition branch), see mnt-crouton.conf.

Owner

DennisLfromGA commented Apr 19, 2014

For mounting the CROUTON partition auto-magically at startup (made possible via @drinkcat's crouton/separate_partition branch), see mnt-crouton.conf.

@technotion

This comment has been minimized.

Show comment
Hide comment
@technotion

technotion Apr 21, 2014

thank you both for your work on this project! i am still trying to grasp where I am creating these files. I simply need the DE of linux to come up at startup. No intervention. eg. If power goes out, then the Chromebox should simply run as Linux. Some detailed steps would be greatly appreciated. Thank you!

technotion commented Apr 21, 2014

thank you both for your work on this project! i am still trying to grasp where I am creating these files. I simply need the DE of linux to come up at startup. No intervention. eg. If power goes out, then the Chromebox should simply run as Linux. Some detailed steps would be greatly appreciated. Thank you!

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Apr 23, 2014

@technotion,

ℹ️ Autostart crouton chroot at ChromeOS startup

You first need to remove rootfs verification and make the rootfs read-writable, check out this script 'rw-rootfs' for that. I've read that this supposedly 'breaks' updates but I've been doing this literally for years and I still get each and every update.

Then you have to place one or possibly two custom .conf scripts in the /etc/init folder, the first script 'mnt-crouton.conf is only needed if you are using @drinkcat's 'separate-partition branch' and the second script, 'crouton.conf' is the one that will kick-off a chroot without opening a shell.

~~Lastly, you can optionally place a file named 'crouton.init' in your /Downloads folder or the chroot parent folder for external control, see one of the above comments for the format of this file.

Owner

DennisLfromGA commented Apr 23, 2014

@technotion,

ℹ️ Autostart crouton chroot at ChromeOS startup

You first need to remove rootfs verification and make the rootfs read-writable, check out this script 'rw-rootfs' for that. I've read that this supposedly 'breaks' updates but I've been doing this literally for years and I still get each and every update.

Then you have to place one or possibly two custom .conf scripts in the /etc/init folder, the first script 'mnt-crouton.conf is only needed if you are using @drinkcat's 'separate-partition branch' and the second script, 'crouton.conf' is the one that will kick-off a chroot without opening a shell.

~~Lastly, you can optionally place a file named 'crouton.init' in your /Downloads folder or the chroot parent folder for external control, see one of the above comments for the format of this file.

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Jul 20, 2014

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'.

Owner

DennisLfromGA commented Jul 20, 2014

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

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Jan 26, 2015

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

Owner

DennisLfromGA commented Jan 26, 2015

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

@DennisLfromGA

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Feb 7, 2015

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

Owner

DennisLfromGA commented Feb 7, 2015

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

@Timvrakas

This comment has been minimized.

Show comment
Hide comment
@Timvrakas

Timvrakas Mar 16, 2015

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.

Timvrakas commented Mar 16, 2015

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

This comment has been minimized.

Show comment
Hide comment
@DennisLfromGA

DennisLfromGA Oct 29, 2017

Updated release to use 'xenial'.

Owner

DennisLfromGA commented Oct 29, 2017

Updated release to use 'xenial'.

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