2 # Copyright 2011 CyberLeo, All Rights Reserved
3 # http://wiki.cyberleo.net/wiki/CyberLeo/COPYRIGHT
5 # Need root beyond here
6 [ "$(id -u)" -eq 0 ] || exec sudo env "J_ARCH=${J_ARCH}" "J_BASE=${J_BASE}" "J_NAME=${J_NAME}" "J_USER=${J_USER:-${USER}}" "${0}" "${@}"
8 meh() { printf " \033[1;32m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; }
9 omg() { printf " \033[1;33m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; }
10 wtf() { printf " \033[1;31m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; exit 1; }
12 [ "${*}" ] && printf "%s\n\n" "${*}"
15 <command> <name> [arguments]
17 ls list available chroots
19 status show jail status
21 start prepare an existing chroot for use
23 stop undo what 'start' did
26 shell spawn a shell or command within the chroot
28 eval evaluate a shell command line within the chroot
34 cmd="$(basename "${0}")"
35 jarch="${J_ARCH:-$(uname -m)}"
36 jbase="${J_BASE:-$(realpath "$(dirname "${0}")/../")}"
37 jname="${J_NAME:-$(basename "${1}")}" #"
40 # Remove chroot name from argument stack, if passed in
41 [ "${J_NAME}" ] || shift
43 # Propagate certain environment variables; sterilize the rest of the environment
50 # Debian-specific init: prepare Debian chroot with debootstrap
53 suite="$(echo "${2:-squeeze}" | tr 'A-Z' 'a-z')"
56 [ "$(which debootstrap 2>&-)" ] || pebkac "j_init_debian: debootstrap not found"
57 [ "${jdir}" ] || pebkac "j_init_debian: jdir must be specified"
58 [ ! -d "${jdir}" ] || pebkac "j_init_debian: jdir must not exist ('${jdir}')"
59 [ -d "$(dirname "${jdir}")" ] || pebkac "j_init_debian: parent of jdir must exist ('${jdir}')"
63 x86|i386) arch=i386 ;;
64 amd64|x86_64|x64) arch=amd64 ;;
65 *) pebkac "Unsupported arch '${jarch}'" ;;
68 cmd="debootstrap --arch=${arch} --include=curl,file,less,locales,sudo,build-essential,libreadline-dev,zlib1g-dev '${suite}' '${jdir}'"
69 echo "Executing ${cmd}"
72 # Make sure locales are generated on first start
73 mkdir -p "${jdir}/etc/rcJ.d"
74 cat > "${jdir}/etc/rcJ.d/S00localegen" <<"EOF"
76 /bin/sed -i '/en_US/s/^# //' /etc/locale.gen
80 chmod 755 "${jdir}/etc/rcJ.d/S00localegen"
83 # Gentoo-specific init: prepare Gentoo chroot with stage3+portage tarballs
86 base="http://distfiles.gentoo.org/releases/${arch}/autobuilds"
87 pointer="${base}/latest-stage3.txt"
95 # Create a new chroot, somehow
97 # Make sure this does NOT exist
99 dist="$(echo "${2:-debian}" | tr 'A-Z' 'a-z')"
100 jdir="${jbase}/${jname}"
101 [ -d "${jdir}" ] && pebkac "j_init: ${jname} already exists"
104 debian) j_init_debian "${jdir}" "${@}" ;;
105 gentoo) j_init_gentoo "${jdir}" "${@}" ;;
106 *) pebkac "Unsupported distro '${dist}'" ;;
110 # Figure out and set chroot parameters; needed for all functions that follow
112 ( jname="${1:-jname}"
114 # Make sure jname is not empty
117 printf "jerror='%s'\n" "jname empty"
121 # Given a chroot name, find and set up the chroot dir
122 jdir="${jbase}/${jname}"
123 if [ ! -d "${jdir}" ]
125 printf "jerror='%s'\n" "not a directory"
129 # Where is the shell?
131 for shell in /bin/bash /usr/bin/bash /usr/local/bin/bash /bin/sh
133 if [ -f "${jdir}/${shell}" ]
139 if [ -z "${jshell}" ]
141 printf "jerror='%s'\n" "unable to locate usable shell; is this a jail?"
145 printf "jerror='' jname='%s' jdir='%s' jshell='%s'\n" "${jname}" "${jdir}" "${jshell}"
151 eval $(j_params "${1}")
152 [ "${jerror}" ] && return 1 || return 0
155 # List available chroots
157 ( cd "${jbase}"; ls -1 ) | while read jname
159 j_is "${jname}" && echo "${jname}"
163 # Chroot is 'up' if /dev/pts and /proc are mounted
165 jname="${1:-${jname}}"
166 eval "$(j_params "${jname}")"
167 [ "${jerror}" ] && wtf "${jerror}"
168 grep -q "^devpts ${jdir}/dev/pts devpts" /proc/mounts || return 1
169 grep -q "^proc ${jdir}/proc proc" /proc/mounts || return 1
173 # Poll chroot status (j_up)
175 [ -z "${1}" ] && set - $(l_ls)
178 j_up "${1}" && meh "$(printf '\033[1;32mup\033[0m')" || meh "$(printf '\033[1;31mdown\033[0m')"
183 # Mount /dev/pts and /proc in the chroot
185 jname="${1:-${jname}}"
186 j_up "${jname}" && return 0
187 eval "$(j_params "${jname}")"
188 meh "starting ${jname} ..."
189 mount -t devpts devpts "${jdir}/dev/pts"
190 mount -t proc proc "${jdir}/proc"
192 # Start all services in /etc/rcJ.d
193 j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort | sed -e "s/$/ start/" | sh )'
196 # Execute command in chroot as root
198 jname="${1:-${jname}}"
199 j_up "${jname}" || wtf "chroot not running"
200 eval "$(j_params "${jname}")"
202 env -i ${jenv} /usr/bin/chroot "${jdir}" /bin/sh -c "${*}"
205 # Execute command in chroot
207 jname="${1:-${jname}}"
208 j_up "${jname}" || wtf "chroot not running"
209 eval "$(j_params "${jname}")"
211 env -i ${jenv} /usr/bin/chroot "${jdir}" /bin/su "${juser:-${USER}}" -c "${*}"
215 jname="${1:-${jname}}"
216 eval "$(j_params "${jname}")"
217 j_eval "${jname}" "cd; exec ${jshell} -l"
220 # Unmount /dev/pts and /proc in the chroot
222 jname="${1:-${jname}}"
223 eval "$(j_params "${jname}")"
224 j_up "${jname}" || return 0
225 meh "stopping ${jname} ..."
227 # Stop all services in /etc/rcJ.d
228 j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort -r | sed -e "s/$/ stop/" | sh )'
230 umount "${jdir}/proc"
231 umount "${jdir}/dev/pts"
235 init|create) j_init "${jname}" "${@}" ;;
237 status) j_status "${jname}" "${@}" ;;
238 start) j_start "${jname}" ;;
239 shell|enter) j_shell "${jname}" ;;
240 eval) j_eval "${jname}" "${*}" ;;
241 stop) j_stop "${jname}" ;;