Moved getlimits and other support functions out to planetlab.[ch].
[util-vserver.git] / scripts / vserver
1 #! /bin/bash
2 # $Id: vserver,v 1.30 2005/04/28 18:03:42 ensc Exp $
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]
35              [--] <vserver> <command> <args>*
36
37 <vserver> is the name of a vserver.
38
39 Possible commands are:
40     start [--rescue] [--rescue-cmd <cmd>]
41                 ... starts the specified vserver
42     stop        ... stops the specified vserver
43     restart     ... restarts the specified vserver; this is the subsequent
44                     execution of a synchronized 'stop' and a 'start'
45     condrestart ... restarts the vserver when it is running already
46     suexec <user> <shell-command> <args*>
47                 ... executes a command as the specified user in the vserver
48     exec <shell-command> <args*>
49                 ... executes a command as root in the vserver
50     enter       ... executes the configured shell in the vserver
51     chkconfig <chkconfig-options*>
52                 ... modifies the init-system; currently, only Red Hat's
53                     chkconfig is supported
54     running     ... succeeds iff the vserver is running
55     status      ... gives out some human readable status information about
56                     the vserver, and succeeds iff the vserver is running
57
58     build <buildopts>*
59                 ... builds a new vserver from scratch
60
61     unify [-R]
62                 ... (de)unify vserver
63                 
64     pkg install <pkg>
65                 ... installs package(s) in the vserver
66                 
67     apt-get,apt-config,apt-cache <apt-opts>*
68                 ... execute the apt-* command for the given vserver
69     rpm <rpm-opts>*
70                 ... execute the rpm command for the given vserver
71
72     pkgmgmt externalize|internalize [-y]
73                 ... externalize or internalize the package-management for the
74                     given vserver. 'Externalize' means that package metadata
75                     and management tools (apt-get,rpm) are living in the host,
76                     while 'internalize' means that data and programs from the
77                     vserver will be used.
78
79     unify <vunify-opts>*
80                 ... unify the vserver with its reference vserver(s).
81                     
82
83 Please report bugs to $PACKAGE_BUGREPORT"
84     exit 0
85 }
86
87 function showVersion()
88 {
89     echo \
90 $"vserver $PACKAGE_VERSION -- manages the state of vservers
91 This program is part of $PACKAGE_STRING
92
93 Copyright (C) 2003,2004,2005 Enrico Scholz
94 This program is free software; you may redistribute it under the terms of
95 the GNU General Public License.  This program has absolutely no warranty."
96     exit 0
97 }
98
99 function suexec()
100 {
101     . $__PKGLIBDIR/vserver.suexec
102 }
103
104 function restart()
105 {
106     "${SELF[@]}" --sync "$vserver" stop
107     exec "${SELF[@]}" "$vserver" start
108 }
109
110 function msg()
111 {
112     test -z "$OPTION_SILENT" || return 0
113     echo "$@"
114 }
115
116 ### main starts here
117
118 set +e
119
120 OPTIONS_ORIG=( "$@" )
121 tmp=$(getopt -o +sv --long nonamespace,--nonamespace,--insecure,defaulttty,help,debug,version,sync,verbose,silent -n "$0" -- "$@") || exit 1
122 eval set -- "$tmp"
123
124 OPTION_FORCE_SYNC=
125 OPTION_VERBOSE=
126 OPTION_SILENT=
127 OPTION_DEBUG=
128 OPTION_NONAMESPACE=
129 OPTION_INSECURE=
130 OPTION_DEFAULTTTY=
131
132 while true; do
133     case "$1" in
134         (--help)        showHelp $0 ;;
135         (--version)     showVersion ;;
136         (--debug)       OPTION_DEBUG=$1; set -x;;
137         (-v|--verbose)  OPTION_VERBOSE=$1;;
138         (-s|--sync)     OPTION_FORCE_SYNC=$1;;
139         (--silent)      OPTION_SILENT=$1;;
140         (----nonamespace)OPTION_NONAMESPACE=$1;;
141         (--defaulttty)  OPTION_DEFAULTTTY=$1;;
142         (----insecure)  OPTION_INSECURE=1;;
143         (--)            shift; break;;
144         (*)             echo $"vserver: internal error; arg=='$1'" >&2; exit 1;;
145     esac
146     shift
147 done
148
149 OPTION_ALL=( $OPTION_SILENT $OPTION_VERBOSE $OPTION_DEBUG $OPTION_DEFAULTTTY )
150 SELF=( "$0" "${OPTION_ALL[@]}" )
151
152 vserver=$1
153 cmd=$2
154
155 test "$cmd" != build || { shift 2; exec "$_VSERVER_BUILD" -n "$vserver" "$@"; }
156
157
158 allow_legacy=
159
160 case "$vserver" in
161     (./*) VSERVER_DIR=`pwd`/$vserver;;
162     (/*)  VSERVER_DIR=$vserver;;
163     (*)   VSERVER_DIR=$__CONFDIR/$vserver
164           allow_legacy=1
165           ;;
166 esac
167
168 if test -n "$allow_legacy"; then
169     do_legacy=
170     test ! -e "$VSERVER_DIR/legacy" || do_legacy=1
171     test -d "$VSERVER_DIR" -o ! -e "$__CONFDIR/$vserver.conf" || do_legacy=1
172
173     test -z "$do_legacy" || {
174         echo $"WARNING: can not find configuration, assuming legacy method" >&2
175         exec "$_VSERVER_LEGACY" "$@"
176     }
177 fi
178
179 test -d "$VSERVER_DIR" || {
180     echo $"\
181 Can not find a vserver-setup at '$VSERVER_DIR/'.
182
183 Possible solutions:
184 * fix the spelling of the '$vserver' vserver name
185 * read 'vserver $vserver build --help' about ways to create a new vserver
186 * see 'vserver --help' for the syntax of this command
187 "
188     exit 5
189 } >&2
190
191 if test -e "$VSERVER_DIR"/name; then
192     read VSERVER_NAME <"$VSERVER_DIR"/name
193 else
194     VSERVER_NAME=$(basename "$VSERVER_DIR")
195 fi
196
197 test "$2" != start -o -n "$OPTION_NONAMESPACE" || isAvoidNamespace "$VSERVER_DIR" || \
198     exec $_VNAMESPACE --new -- $_VSERVER ----nonamespace "${OPTIONS_ORIG[@]}"
199
200 . $__PKGLIBDIR/vserver.functions
201 case "$2" in
202     (start|stop)
203         shift 2
204         . $__PKGLIBDIR/vserver.$cmd
205         ;;
206     (suexec|restart)
207         shift 2
208         $cmd "$@"
209         ;;
210     (condrestart)
211         test ! isVserverRunning "$VSERVER_DIR" || restart
212         ;;
213     (exec)
214         shift 2
215         suexec root "$@"
216         ;;
217     (chkconfig)
218         shift 2
219         suexec root chkconfig "$@"
220         ;;
221     (enter)
222         getEnterShell "$VSERVER_DIR"
223         suexec root "${ENTER_SHELL[@]}"
224         ;;
225     (running)
226         isVserverRunning "$VSERVER_DIR"
227         ;;
228
229     (unify)
230         shift 2
231         exec $_VUNIFY "$@" "$vserver"
232         ;;
233
234     (hashify)
235         shift 2
236         exec $_VHASHIFY "$@" "$vserver"
237         ;;
238                 
239     (pkg)
240         shift 2
241         exec $_VPKG "$vserver" "$@"
242         ;;
243
244     (pkgmgmt)
245         op=$3
246         shift 3
247         exec $_VNAMESPACE --new -- $_PKGMGMT ${op:+--$op} "$@" -- "$vserver"
248         ;;
249
250     (apt-get|apt-config|apt-cache)
251         export _APT_GET=$2
252         shift 2
253         exec $_VAPT_GET -- "$@"
254         ;;
255     (rpm)
256         exec $_VRPM -- "$@"
257         ;;
258         
259     (status)
260         if getVserverStatus "$VSERVER_DIR" ctx procnum; then
261             msg $"Vserver '$vserver' is running at context '$ctx'"
262
263             if test "$2" = status; then
264                 msg $"Number of processes: " $procnum
265                 msg $"Uptime:              "    $("$_FILETIME" "$VSERVER_DIR/run")
266             fi
267             exit 0
268         else
269             msg $"Vserver '$vserver' is stopped"
270             exit 3
271         fi
272         ;;
273     (*)
274         echo $"Usage: $0 {start|stop|suexec|restart|condrestart|exec|enter|chkconfig|running|status}" >&2
275         exit 2
276         ;;
277 esac