]> CyberLeo.Net >> Repos - CDN/j.git/blob - j
j: support 'ls' verb for listing chroots
[CDN/j.git] / j
1 #!/bin/sh
2 # Copyright 2011 CyberLeo, All Rights Reserved
3 # http://wiki.cyberleo.net/wiki/CyberLeo/COPYRIGHT
4
5 # Need root beyond here
6 [ "$(id -u)" -eq 0 ] || exec sudo env J_BASE=${J_BASE} J_NAME=${J_NAME} J_USER=${J_USER:-${USER}} "${0}" "${@}"
7
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; }
11 pebkac() {
12   [ "${*}" ] && printf "%s\n\n" "${*}"
13   cat <<EOF
14 Usage:
15   <command> <name> [arguments]
16   list
17   ls      list available chroots
18
19   status  show jail status
20
21   start   prepare an existing chroot for use
22
23   stop    undo what 'start' did
24
25   enter
26   shell   spawn a shell or command within the chroot
27
28   eval    evaluate a shell command line within the chroot
29
30 EOF
31   exit 1
32 }
33
34 cmd="$(basename "${0}")"
35 jbase="${J_BASE:-$(realpath "$(dirname "${0}")/../")}"
36 jname="${J_NAME:-$(basename "${1}")}" #"
37 juser="${J_USER}"
38
39 # Remove chroot name from argument stack, if passed in
40 [ "${J_NAME}" ] || shift
41
42 # Propagate certain environment variables; sterilize the rest of the environment
43 jenv="
44   LANG=${LANG}
45   TERM=${TERM}
46   USER=${USER}
47 "
48
49 # Create a new chroot, somehow
50 j_init() {
51   # Either a debian chroot with debootstrap or a gentoo chroot with stage3 + portage tarballs
52   DEBOOTSTRAP_DIR="$(base)/debootstrap" "${DEBOOTSTRAP_DIR}/debootstrap" --arch=amd64 squeeze "${jdir}"
53 }
54
55 # Figure out and set chroot parameters; needed for all functions that follow
56 j_params() {
57   ( jname="${1:-jname}"
58
59     # Make sure jname is not empty
60     if [ -z "${jname}" ]
61     then
62       printf "jerror='%s'\n" "jname empty"
63       return 1
64     fi
65
66     # Given a chroot name, find and set up the chroot dir
67     jdir="${jbase}/${jname}"
68     if [ ! -d "${jdir}" ]
69     then
70       printf "jerror='%s'\n" "not a directory"
71       return 1
72     fi
73
74     # Where is the shell?
75     jshell=""
76     for shell in /bin/bash /usr/bin/bash /usr/local/bin/bash /bin/sh
77     do
78       if [ -f "${jdir}/${shell}" ]
79       then
80         jshell=${shell}
81         break
82       fi
83     done
84     if [ -z "${jshell}" ]
85     then
86       printf "jerror='%s'\n" "unable to locate usable shell; is this a jail?"
87       return 1
88     fi
89
90     printf "jerror='' jname='%s' jdir='%s' jshell='%s'\n" "${jname}" "${jdir}" "${jshell}"
91   )
92 }
93
94 # Is this a chroot?
95 j_is() {
96   eval $(j_params "${1}")
97   [ "${jerror}" ] && return 1 || return 0
98 }
99
100 # List available chroots
101 j_ls() {
102   ( cd "${jbase}"; ls -1 ) | while read jname
103   do
104     j_is "${jname}" && echo "${jname}"
105   done
106 }
107
108 # Chroot is 'up' if /dev/pts and /proc are mounted
109 j_up() {
110   jname="${1:-${jname}}"
111   eval "$(j_params "${jname}")"
112   [ "${jerror}" ] && wtf "${jerror}"
113   grep -q "^devpts ${jdir}/dev/pts devpts" /proc/mounts || return 1
114   grep -q "^proc ${jdir}/proc proc" /proc/mounts || return 1
115   return 0
116 }
117
118 # Poll chroot status (j_up)
119 j_status() {
120   [ -z "${1}" ] && set - $(l_ls)
121   while [ "${1}" ]
122   do
123     j_up "${1}" && meh "$(printf '\033[1;32mup\033[0m')" || meh "$(printf '\033[1;31mdown\033[0m')"
124     shift
125   done
126 }
127
128 # Mount /dev/pts and /proc in the chroot
129 j_start() {
130   jname="${1:-${jname}}"
131   j_up "${jname}" && return 0
132   eval "$(j_params "${jname}")"
133   meh "starting ${jname} ..."
134   mount -t devpts devpts "${jdir}/dev/pts"
135   mount -t proc proc "${jdir}/proc"
136 }
137
138 # Execute command in chroot
139 j_eval() {
140   jname="${1:-${jname}}"
141   j_up "${jname}" || wtf "chroot not running"
142   eval "$(j_params "${jname}")"
143   shift
144   env -i ${jenv} /usr/bin/chroot "${jdir}" /bin/su "${juser:-${USER}}" -c "${*}"
145 }
146
147 j_shell() {
148   jname="${1:-${jname}}"
149   eval "$(j_params "${jname}")"
150   j_eval "${jname}" "${jshell} -l"
151 }
152
153 # Unmount /dev/pts and /proc in the chroot
154 j_stop() {
155   jname="${1:-${jname}}"
156   eval "$(j_params "${jname}")"
157   j_up "${jname}" || return 0
158   meh "stopping ${jname} ..."
159   umount "${jdir}/proc"
160   umount "${jdir}/dev/pts"
161 }
162
163 case "${cmd}" in
164 ls|list) j_ls ;;
165 status) j_status "${jname}" "${@}" ;;
166 start) j_start "${jname}" ;;
167 shell|enter) j_shell "${jname}" ;;
168 eval) j_eval "${jname}" "${*}" ;;
169 stop) j_stop "${jname}" ;;
170 *) pebkac ;;
171 esac