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