gentoo: use /var/run for new /run compatibility
[util-vserver.git] / scripts / vserver
1 #! /bin/bash
2 # $Id$
3
4 # Copyright (C) 2003,2004,2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
5 #  
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; version 2 of the License.
9 #  
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #  
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 # set -e
20
21 : ${UTIL_VSERVER_VARS:=/usr/lib/util-vserver/util-vserver-vars}
22 test -e "$UTIL_VSERVER_VARS" || {
23     echo $"Can not find util-vserver installation (the file '$UTIL_VSERVER_VARS' would be expected); aborting..." >&2
24     exit 1
25 }
26 . "$UTIL_VSERVER_VARS"
27 . "$_LIB_FUNCTIONS"
28
29 ### Some local functions
30
31 function showHelp()
32 {
33     echo \
34 $"Usage: $(basename $0) [-s|--sync] [-v|--verbose] [--silent] [--debug]
35              [--] <vserver> <command> <args>*
36
37 <vserver> is the name of a vserver.
38
39 Possible commands are:
40     start [--rescue [--rescue-init] <rescue-cmd> <args>*]]
41                 ... starts the specified vserver
42     stop [--rescue-init]
43                 ... stops the specified vserver
44     restart     ... restarts the specified vserver; this is the subsequent
45                     execution of a synchronized 'stop' and a 'start'
46     condrestart ... restarts the vserver when it is running already
47     suexec <user> <command> <args*>
48                 ... executes a command as the specified user in the vserver
49     exec <command> <args*>
50                 ... executes a command as root in the vserver
51     enter       ... executes the configured shell in the vserver
52     chkconfig <chkconfig-options*>
53                 ... modifies the init-system; currently, only Red Hat's
54                     chkconfig is supported
55     running     ... succeeds iff the vserver is running
56     status      ... gives out some human readable status information about
57                     the vserver, and succeeds iff the vserver is running
58
59     build <buildopts>*
60                 ... builds a new vserver from scratch, see
61                     vserver ... build --help for details
62     delete      ... remove a vserver
63
64     unify [-R] <vunify-opts>*
65                 ... (de)unify the vserver with its reference vserver(s).
66                 
67     pkg install <pkg>
68                 ... installs package(s) in the vserver
69                 
70     apt-get,apt-config,apt-cache <apt-opts>*
71                 ... execute the apt-* command for the given vserver
72     rpm <rpm-opts>*
73                 ... execute the rpm command for the given vserver
74
75     pkgmgmt externalize|internalize [-y]
76                 ... externalize or internalize the package-management for the
77                     given vserver. 'Externalize' means that package metadata
78                     and management tools (apt-get,rpm) are living in the host,
79                     while 'internalize' means that data and programs from the
80                     vserver will be used.
81
82     hashify
83                 ... hashify the guest.
84                     
85
86 Please report bugs to $PACKAGE_BUGREPORT"
87     exit 0
88 }
89
90 function showVersion()
91 {
92     echo \
93 $"vserver $PACKAGE_VERSION -- manages the state of vservers
94 This program is part of $PACKAGE_STRING
95
96 Copyright (C) 2003,2004,2005 Enrico Scholz
97 This program is free software; you may redistribute it under the terms of
98 the GNU General Public License.  This program has absolutely no warranty."
99     exit 0
100 }
101
102 function suexec()
103 {
104     . $__PKGLIBDIR/vserver.suexec
105 }
106
107 function restart()
108 {
109     "${SELF[@]}" --sync "$vserver" stop
110     exec "${SELF[@]}" "$vserver" start
111 }
112
113 function msg()
114 {
115     test -z "$OPTION_SILENT" || return 0
116     echo "$@"
117 }
118
119 ### main starts here
120
121 set +e
122
123 OPTIONS_ORIG=( "$@" )
124 tmp=$(getopt -o +sv --long nonamespace,--nonamespace,--insecure,defaulttty,help,debug,strace,debug-sysv,version,sync,verbose,silent -n "$0" -- "$@") || exit 1
125 eval set -- "$tmp"
126
127 OPTION_FORCE_SYNC=
128 OPTION_VERBOSE=
129 OPTION_SILENT=
130 OPTION_DEBUG=
131 OPTION_NONAMESPACE=
132 OPTION_INSECURE=
133 OPTION_DEFAULTTTY=
134 OPTION_STRACE=
135 OPTION_DEBUG_SYSV=
136
137 while true; do
138     case "$1" in
139         (--help)        showHelp $0 ;;
140         (--version)     showVersion ;;
141         (--debug)       OPTION_DEBUG=$1; set -x;;
142         (-v|--verbose)  OPTION_VERBOSE=$1;;
143         (-s|--sync)     OPTION_FORCE_SYNC=$1;;
144         (--silent)      OPTION_SILENT=$1;;
145         (----nonamespace)OPTION_NONAMESPACE=$1;;
146         (--defaulttty)  OPTION_DEFAULTTTY=$1;;
147         (----insecure)  OPTION_INSECURE=1;;
148         (--strace)      OPTION_STRACE=1;;
149         (--debug-sysv*) OPTION_DEBUG_SYSV=$1;;
150         (--)            shift; break;;
151         (*)             echo $"vserver: internal error; arg=='$1'" >&2; exit 1;;
152     esac
153     shift
154 done
155
156 OPTION_ALL=( $OPTION_SILENT $OPTION_VERBOSE $OPTION_DEBUG $OPTION_DEFAULTTTY )
157 SELF=( "$0" "${OPTION_ALL[@]}" )
158
159 vserver=$1
160 cmd=$2
161
162 test "$cmd" != build || { shift 2; exec $_VNAMESPACE --new -- \
163     "$_VSERVER_BUILD" $OPTION_DEBUG -n "$vserver" "$@"; }
164
165
166 allow_legacy=
167
168 vserver="${vserver%%/}"
169 case "$vserver" in
170     (./*)   VSERVER_DIR="`pwd`/$vserver";;
171     (/*)    VSERVER_DIR="$vserver";;
172     (*)     # Check if this is a context id
173             context=$(vuname --get --xid "$vserver" 2>/dev/null)
174             if test -d "$context"; then
175                 VSERVER_DIR="$context"
176             else
177                 VSERVER_DIR="$__CONFDIR/$vserver"
178                 do_legacy=
179                 test ! -e "$VSERVER_DIR/legacy" || do_legacy=1
180                 test -d "$VSERVER_DIR" -o ! -e "$__CONFDIR/$vserver.conf" || do_legacy=1
181
182                 test -z "$do_legacy" || {
183                     echo $"WARNING: can not find configuration, assuming legacy method" >&2
184                     exec "$_VSERVER_LEGACY" "$@"
185                 }
186             fi
187             ;;
188 esac
189
190 test -d "$VSERVER_DIR" || {
191     echo $"\
192 Can not find a vserver-setup at '$VSERVER_DIR/'.
193
194 Possible solutions:
195 * fix the spelling of the '$vserver' vserver name
196 * read 'vserver $vserver build --help' about ways to create a new vserver
197 * see 'vserver --help' for the syntax of this command
198 "
199     exit 5
200 } >&2
201
202 _setVserverName
203
204 # Create a new namespace when starting the guest
205 test "$cmd" != start -o -n "$OPTION_NONAMESPACE" || isAvoidNamespace "$VSERVER_DIR" || \
206     exec $_VNAMESPACE --new -- $_VSERVER ----nonamespace "${OPTIONS_ORIG[@]}"
207
208 # Enter the namespace early so we can test for files inside the guest
209 test "$cmd" != enter -a "$cmd" != stop || \
210     test -n "$OPTION_NONAMESPACE" || isAvoidNamespace "$VSERVER_DIR" || \
211     ! isVserverRunning "$VSERVER_DIR" || \
212     exec $_VNAMESPACE --enter "$VSERVER_DIR" -- $_VSERVER ----nonamespace "${OPTIONS_ORIG[@]}"
213
214 set_init_cwd
215 cd /
216
217 . $__PKGLIBDIR/vserver.functions
218 case "$2" in
219     (start|stop|delete)
220         shift 2
221         . $__PKGLIBDIR/vserver.$cmd
222         ;;
223     (suexec|restart)
224         shift 2
225         $cmd "$@"
226         ;;
227     (condrestart)
228         ! isVserverRunning "$VSERVER_DIR" || restart
229         ;;
230     (exec)
231         shift 2
232         suexec 0 "$@"
233         ;;
234     (chkconfig)
235         shift 2
236         suexec 0 chkconfig "$@"
237         ;;
238     (enter)
239         useVlogin && \
240           OPTS_VCONTEXT_ENTER=( "${OPTS_VCONTEXT_ENTER[@]}" --vlogin )
241         getEnterShell "$VSERVER_DIR"
242         suexec 0 "${ENTER_SHELL[@]}"
243         ;;
244     (running)
245         isVserverRunning "$VSERVER_DIR"
246         ;;
247
248     (unify)
249         shift 2
250         exec $_VUNIFY "$@" "$vserver"
251         ;;
252
253     (hashify)
254         shift 2
255         exec $_VHASHIFY "$@" "$vserver"
256         ;;
257                 
258     (pkg)
259         shift 2
260         exec $_VPKG "$vserver" "$@"
261         ;;
262
263     (pkgmgmt)
264         op=$3
265         shift 3
266         exec $_VNAMESPACE --new -- $_PKGMGMT ${op:+--$op} "$@" -- "$vserver"
267         ;;
268
269     (apt-get|apt-config|apt-cache)
270         export APT_GET=$2
271         shift 2
272         exec $_VAPT_GET "$VSERVER_DIR" -- "$@"
273         ;;
274
275     (rpm)
276         shift 2
277         exec $_VRPM "$VSERVER_DIR" -- "$@"
278         ;;
279         
280     (status)
281         if getVserverStatus "$VSERVER_DIR" ctx procnum; then
282             msg $"Vserver '$vserver' is running at context '$ctx'"
283
284             if test "$2" = status; then
285                 msg $"Number of processes: " $procnum
286                 msg $"Uptime:              "    $("$_FILETIME" "$VSERVER_DIR/run")
287             fi
288             exit 0
289         else
290             msg $"Vserver '$vserver' is stopped"
291             exit 3
292         fi
293         ;;
294     (*)
295         echo $"Usage: $0 <vserver> {start|stop|suexec|restart|condrestart|exec|enter|chkconfig|running|status|delete}" >&2
296         exit 2
297         ;;
298 esac