2 # Copyright 2011 CyberLeo, All Rights Reserved
3 # http://wiki.cyberleo.net/wiki/CyberLeo/COPYRIGHT
5 : ${ORIG_USER=$(id -un)}
7 # Need root beyond here
8 [ "$(id -u)" -eq 0 ] || exec sudo env "J_ARCH=${J_ARCH}" "J_BASE=${J_BASE}" "J_NAME=${J_NAME}" "J_USER=${J_USER:-${USER}}" "ORIG_USER=${ORIG_USER}" "DISPLAY=${DISPLAY}" "${0}" "${@}"
10 meh() { printf " \033[1;32m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; }
11 omg() { printf " \033[1;33m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; }
12 wtf() { printf " \033[1;31m*\033[0m %s%s\n" "${jname:+${jname}: }" "${*}"; exit 1; }
14 [ "${*}" ] && printf "%s\n\n" "${*}"
17 <command> <name> [arguments]
19 ls list available chroots
21 status show jail status
23 start prepare an existing chroot for use
25 stop undo what 'start' did
28 shell spawn a shell or command within the chroot
30 eval evaluate a shell command line within the chroot
36 cmd="$(basename "${0}")"
37 jarch="${J_ARCH:-$(uname -m)}"
38 jbase="${J_BASE:-$(realpath "$(dirname "${0}")/../")}"
39 jname="${J_NAME:-$(basename "${1}")}" #"
42 # Remove chroot name from argument stack, if passed in
43 [ "${J_NAME}" ] || shift
45 # Propagate certain environment variables; sterilize the rest of the environment
52 # Debian-specific init: prepare Debian chroot with debootstrap
55 suite="$(echo "${2:-squeeze}" | tr 'A-Z' 'a-z')"
58 [ "$(which debootstrap 2>&-)" ] || pebkac "j_init_debian: debootstrap not found"
59 [ "${jdir}" ] || pebkac "j_init_debian: jdir must be specified"
60 [ ! -d "${jdir}" ] || pebkac "j_init_debian: jdir must not exist ('${jdir}')"
61 [ -d "$(dirname "${jdir}")" ] || pebkac "j_init_debian: parent of jdir must exist ('${jdir}')"
65 x86|i386) arch=i386 ;;
66 amd64|x86_64|x64) arch=amd64 ;;
67 *) pebkac "Unsupported arch '${jarch}'" ;;
70 cmd="debootstrap --arch=${arch} --include=curl,file,less,locales,sudo,build-essential,libreadline-dev,zlib1g-dev '${suite}' '${jdir}'"
71 echo "Executing ${cmd}"
74 # Make sure locales are generated on first start
75 mkdir -p "${jdir}/etc/rcJ.d"
76 cat > "${jdir}/etc/rcJ.d/S00localegen" <<"EOF"
78 /bin/sed -i '/en_US/s/^# //' /etc/locale.gen
82 chmod 755 "${jdir}/etc/rcJ.d/S00localegen"
85 # Gentoo-specific init: prepare Gentoo chroot with stage3+portage tarballs
88 base="http://distfiles.gentoo.org/releases/${arch}/autobuilds"
89 pointer="${base}/latest-stage3.txt"
97 # Create a new chroot, somehow
99 # Make sure this does NOT exist
101 dist="$(echo "${2:-debian}" | tr 'A-Z' 'a-z')"
102 jdir="${jbase}/${jname}"
103 [ -d "${jdir}" ] && pebkac "j_init: ${jname} already exists"
106 debian) j_init_debian "${jdir}" "${@}" ;;
107 gentoo) j_init_gentoo "${jdir}" "${@}" ;;
108 *) pebkac "Unsupported distro '${dist}'" ;;
112 # Figure out and set chroot parameters; needed for all functions that follow
114 ( jname="${1:-jname}"
116 # Make sure jname is not empty
119 printf "jerror='%s'\n" "jname empty"
123 # Given a chroot name, find and set up the chroot dir
124 jdir="${jbase}/${jname}"
126 if [ ! -d "${jdir}" -o ! -d "${jroot}" ]
128 printf "jerror='%s'\n" "not a directory"
132 # Where is the shell?
134 for shell in /bin/bash /usr/bin/bash /usr/local/bin/bash /bin/sh
136 if [ -f "${jroot}/${shell}" ]
142 if [ -z "${jshell}" ]
144 printf "jerror='%s'\n" "unable to locate usable shell; is this a jail?"
148 printf "jerror='' jname='%s' jdir='%s' jroot='%s' jshell='%s'\n" "${jname}" "${jdir}" "${jroot}" "${jshell}"
152 # Copy ipcc into the jail and add helpful symlinks, so it can communicate
153 # simple commands to the outside
155 ipcc="$(dirname "${0}")/ipcc"
156 cp -f "${ipcc}" "${jroot}/bin"
158 [ -e ee ] || ln -s ipcc ee
159 [ -e ff ] || ln -s ipcc ff
163 # Launch ipcd on jail
165 ipcd_pid="${jdir}/ipcd.pid"
166 su "${ORIG_USER}" "${jbase}/j/ipcd" "${jdir}" &
167 echo "${!}" > "${ipcd_pid}"
172 ipcd_pid="${jdir}/ipcd.pid"
173 [ -f "${ipcd_pid}" ] && pid="$(cat "${ipcd_pid}")"
174 [ "${pid}" ] && kill -TERM ${pid}
179 eval $(j_params "${1}")
180 [ "${jerror}" ] && return 1 || return 0
183 # List available chroots
185 ( cd "${jbase}"; ls -1 ) | while read jname
187 j_is "${jname}" && echo "${jname}"
191 # Chroot is 'up' if /dev/pts and /proc are mounted
193 jname="${1:-${jname}}"
194 eval "$(j_params "${jname}")"
195 [ "${jerror}" ] && wtf "${jerror}"
196 grep -q "^devpts ${jroot}/dev/pts devpts" /proc/mounts || return 1
197 grep -q "^proc ${jroot}/proc proc" /proc/mounts || return 1
201 # Poll chroot status (j_up)
203 [ -z "${1}" ] && set - $(j_ls)
206 j_up "${1}" && meh "$(printf '\033[1;32mup\033[0m')" || meh "$(printf '\033[1;31mdown\033[0m')"
211 # Mount /dev/pts and /proc in the chroot
213 jname="${1:-${jname}}"
214 j_up "${jname}" && return 0
215 eval "$(j_params "${jname}")"
216 meh "starting ${jname} ..."
217 mount -t devpts devpts "${jroot}/dev/pts"
218 mount -t proc proc "${jroot}/proc"
220 # Copy in ipcc and launch ipcd
224 # Start all services in /etc/rcJ.d
225 j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort | sed -e "s/$/ start/" | sh )'
228 # Execute command in chroot as root
230 jname="${1:-${jname}}"
231 j_up "${jname}" || wtf "chroot not running"
232 eval "$(j_params "${jname}")"
234 env -i ${jenv} /usr/bin/chroot "${jroot}" /bin/sh -c "${*}"
237 # Execute command in chroot
239 jname="${1:-${jname}}"
240 j_up "${jname}" || wtf "chroot not running"
241 eval "$(j_params "${jname}")"
243 env -i ${jenv} /usr/bin/chroot "${jroot}" /bin/su "${juser:-${USER}}" -c "${*}"
247 jname="${1:-${jname}}"
248 eval "$(j_params "${jname}")"
249 j_eval "${jname}" "cd; exec ${jshell} -l"
252 # Unmount /dev/pts and /proc in the chroot
254 jname="${1:-${jname}}"
255 eval "$(j_params "${jname}")"
256 j_up "${jname}" || return 0
257 meh "stopping ${jname} ..."
259 # Stop all services in /etc/rcJ.d
260 j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort -r | sed -e "s/$/ stop/" | sh )'
265 umount "${jroot}/proc"
266 umount "${jroot}/dev/pts"
270 init|create) j_init "${jname}" "${@}" ;;
272 status) j_status "${jname}" "${@}" ;;
273 start) j_start "${jname}" ;;
274 shell|enter) j_shell "${jname}" ;;
275 eval) j_eval "${jname}" "${*}" ;;
276 stop) j_stop "${jname}" ;;