c776201cc62df71755d2dfa0f5adfbf62e3aec94
[util-vserver.git] / scripts / vserver
1 #! /bin/bash
2 # $Id: vserver 2418 2006-12-08 13:28:02Z 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]
63                 ... (de)unify vserver
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     unify <vunify-opts>*
81                 ... unify the vserver with its reference vserver(s).
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,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
133 while true; do
134     case "$1" in
135         (--help)        showHelp $0 ;;
136         (--version)     showVersion ;;
137         (--debug)       OPTION_DEBUG=$1; set -x;;
138         (-v|--verbose)  OPTION_VERBOSE=$1;;
139         (-s|--sync)     OPTION_FORCE_SYNC=$1;;
140         (--silent)      OPTION_SILENT=$1;;
141         (----nonamespace)OPTION_NONAMESPACE=$1;;
142         (--defaulttty)  OPTION_DEFAULTTTY=$1;;
143         (----insecure)  OPTION_INSECURE=1;;
144         (--)            shift; break;;
145         (*)             echo $"vserver: internal error; arg=='$1'" >&2; exit 1;;
146     esac
147     shift
148 done
149
150 OPTION_ALL=( $OPTION_SILENT $OPTION_VERBOSE $OPTION_DEBUG $OPTION_DEFAULTTTY )
151 SELF=( "$0" "${OPTION_ALL[@]}" )
152
153 vserver=$1
154 cmd=$2
155
156 test "$cmd" != build || { shift 2; exec $_VNAMESPACE --new -- \
157     "$_VSERVER_BUILD" $OPTION_DEBUG -n "$vserver" "$@"; }
158
159
160 allow_legacy=
161
162 case "$vserver" in
163     (./*) VSERVER_DIR=`pwd`/$vserver;;
164     (/*)  VSERVER_DIR=$vserver;;
165     (*)   VSERVER_DIR=$__CONFDIR/$vserver
166           allow_legacy=1
167           ;;
168 esac
169
170 if test -n "$allow_legacy"; then
171     do_legacy=
172     test ! -e "$VSERVER_DIR/legacy" || do_legacy=1
173     test -d "$VSERVER_DIR" -o ! -e "$__CONFDIR/$vserver.conf" || do_legacy=1
174
175     test -z "$do_legacy" || {
176         echo $"WARNING: can not find configuration, assuming legacy method" >&2
177         exec "$_VSERVER_LEGACY" "$@"
178     }
179 fi
180
181 test -d "$VSERVER_DIR" || {
182     echo $"\
183 Can not find a vserver-setup at '$VSERVER_DIR/'.
184
185 Possible solutions:
186 * fix the spelling of the '$vserver' vserver name
187 * read 'vserver $vserver build --help' about ways to create a new vserver
188 * see 'vserver --help' for the syntax of this command
189 "
190     exit 5
191 } >&2
192
193 if test -e "$VSERVER_DIR"/name; then
194     read VSERVER_NAME <"$VSERVER_DIR"/name
195 else
196     VSERVER_NAME=$(basename "$VSERVER_DIR")
197 fi
198
199 # Create a new namespace when starting the guest
200 test "$2" != start -o -n "$OPTION_NONAMESPACE" || isAvoidNamespace "$VSERVER_DIR" || \
201     exec $_VNAMESPACE --new -- $_VSERVER ----nonamespace "${OPTIONS_ORIG[@]}"
202
203 # Enter the namespace early so we can test for files inside the guest
204 test "$2" != enter -a "$2" != stop || \
205     test -n "$OPTION_NONAMESPACE" || isAvoidNamespace "$VSERVER_DIR" || \
206     ! isVserverRunning "$VSERVER_DIR" || \
207     exec $_VNAMESPACE --enter "$VSERVER_DIR" -- $_VSERVER ----nonamespace "${OPTIONS_ORIG[@]}"
208
209 set_init_cwd
210 cd /
211
212 . $__PKGLIBDIR/vserver.functions
213 case "$2" in
214     (start|stop|delete)
215         shift 2
216         . $__PKGLIBDIR/vserver.$cmd
217         ;;
218     (suexec|restart)
219         shift 2
220         $cmd "$@"
221         ;;
222     (condrestart)
223         ! isVserverRunning "$VSERVER_DIR" || restart
224         ;;
225     (exec)
226         shift 2
227         suexec 0 "$@"
228         ;;
229     (chkconfig)
230         shift 2
231         suexec 0 chkconfig "$@"
232         ;;
233     (enter)
234         useVlogin && \
235           OPTS_VCONTEXT_ENTER=( "${OPTS_VCONTEXT_ENTER[@]}" --vlogin )
236         getEnterShell "$VSERVER_DIR"
237         suexec 0 "${ENTER_SHELL[@]}"
238         ;;
239     (running)
240         isVserverRunning "$VSERVER_DIR"
241         ;;
242
243     (unify)
244         shift 2
245         exec $_VUNIFY "$@" "$vserver"
246         ;;
247
248     (hashify)
249         shift 2
250         exec $_VHASHIFY "$@" "$vserver"
251         ;;
252                 
253     (pkg)
254         shift 2
255         exec $_VPKG "$vserver" "$@"
256         ;;
257
258     (pkgmgmt)
259         op=$3
260         shift 3
261         exec $_VNAMESPACE --new -- $_PKGMGMT ${op:+--$op} "$@" -- "$vserver"
262         ;;
263
264     (apt-get|apt-config|apt-cache)
265         export APT_GET=$2
266         shift 2
267         exec $_VAPT_GET "$VSERVER_DIR" -- "$@"
268         ;;
269
270     (rpm)
271         shift 2
272         exec $_VRPM "$VSERVER_DIR" -- "$@"
273         ;;
274         
275     (status)
276         if getVserverStatus "$VSERVER_DIR" ctx procnum; then
277             msg $"Vserver '$vserver' is running at context '$ctx'"
278
279             if test "$2" = status; then
280                 msg $"Number of processes: " $procnum
281                 msg $"Uptime:              "    $("$_FILETIME" "$VSERVER_DIR/run")
282             fi
283             exit 0
284         else
285             msg $"Vserver '$vserver' is stopped"
286             exit 3
287         fi
288         ;;
289     (*)
290         echo $"Usage: $0 <vserver> {start|stop|suexec|restart|condrestart|exec|enter|chkconfig|running|status|delete}" >&2
291         exit 2
292         ;;
293 esac