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