]> CyberLeo.Net >> Repos - CDN/j.git/blob - j
j: clean up chroot service start/stop
[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   # Start all services in /etc/rcJ.d
138   j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort | sed -e "s/$/ start/" | sh )'
139 }
140
141 # Execute command in chroot as root
142 j_root_eval() {
143   jname="${1:-${jname}}"
144   j_up "${jname}" || wtf "chroot not running"
145   eval "$(j_params "${jname}")"
146   shift
147   env -i ${jenv} /usr/bin/chroot "${jdir}" /bin/sh -c "${*}"
148 }
149
150 # Execute command in chroot
151 j_eval() {
152   jname="${1:-${jname}}"
153   j_up "${jname}" || wtf "chroot not running"
154   eval "$(j_params "${jname}")"
155   shift
156   env -i ${jenv} /usr/bin/chroot "${jdir}" /bin/su "${juser:-${USER}}" -c "${*}"
157 }
158
159 j_shell() {
160   jname="${1:-${jname}}"
161   eval "$(j_params "${jname}")"
162   j_eval "${jname}" "cd; exec ${jshell} -l"
163 }
164
165 # Unmount /dev/pts and /proc in the chroot
166 j_stop() {
167   jname="${1:-${jname}}"
168   eval "$(j_params "${jname}")"
169   j_up "${jname}" || return 0
170   meh "stopping ${jname} ..."
171
172   # Stop all services in /etc/rcJ.d
173   j_root_eval "${jname}" '[ -d /etc/rcJ.d ] && ( ls -1 /etc/rcJ.d/* 2>&- | grep /S | sort -r | sed -e "s/$/ stop/" | sh )'
174
175   umount "${jdir}/proc"
176   umount "${jdir}/dev/pts"
177 }
178
179 case "${cmd}" in
180 ls|list) j_ls ;;
181 status) j_status "${jname}" "${@}" ;;
182 start) j_start "${jname}" ;;
183 shell|enter) j_shell "${jname}" ;;
184 eval) j_eval "${jname}" "${*}" ;;
185 stop) j_stop "${jname}" ;;
186 *) pebkac ;;
187 esac