implemented CLONE_NS and --rbind mounting
[util-vserver.git] / util-vserver / scripts / vserver
1 #! /bin/bash
2 # $Id$
3
4 # Copyright (C) 2003 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; aborting..."
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 [--nodeps] <start-vservers-opts>*
41                 ... starts the specified vserver
42     stop [--nodeps] <start-vservers-opts>*
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
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 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 ### main starts here
112
113 set +e
114
115 OPTIONS_ORIG=( "$@" )
116 tmp=$(getopt -o +sv --long nonamespace,--nonamespace,help,debug,version,sync,verbose,silent -n "$0" -- "$@") || exit 1
117 eval set -- "$tmp"
118
119 OPTION_FORCE_SYNC=
120 OPTION_VERBOSE=
121 OPTION_SILENT=
122 OPTION_DEBUG=
123 OPTION_NONAMESPACE=
124
125 while true; do
126     case "$1" in
127         --help)         showHelp $0 ;;
128         --version)      showVersion ;;
129         --debug)        OPTION_DEBUG=$1; set -x;;
130         -v|--verbose)   OPTION_VERBOSE=$1;;
131         -s|--sync)      OPTION_FORCE_SYNC=$1;;
132         --silent)       OPTION_SILENT=$1;;
133         ----nonamespace)OPTION_NONAMESPACE=$1;;
134         --)             shift; break;;
135         *)              echo $"vserver: internal error; arg=='$1'"; exit 1;;
136     esac
137     shift
138 done
139
140 OPTION_ALL=( $OPTION_SILENT $OPTION_VERBOSE $OPTION_DEBUG )
141 SELF=( "$0" "${OPTION_ALL[@]}" )
142
143 vserver=$1
144 cmd=$2
145
146 test "$cmd" != build || { shift 2; exec "$_VSERVER_BUILD" -n "$vserver" "$@"; }
147
148
149 allow_legacy=
150
151 case "$vserver" in
152     ./*) VSERVER_DIR=`pwd`/$vserver;;
153     /*)  VSERVER_DIR=$vserver;;
154     *)   VSERVER_DIR=$CONFDIR/$vserver
155          allow_legacy=1
156          ;;
157 esac
158
159 if test "$allow_legacy"; then
160     do_legacy=
161     test ! -e "$VSERVER_DIR/legacy" || do_legacy=1
162     test -d "$VSERVER_DIR" -o ! -e "$CONFDIR/$vserver.conf" || do_legacy=1
163
164     test -z "$do_legacy" || {
165         echo $"WARNING: can not find configuration, assuming legacy method"
166         exec "$_VSERVER_LEGACY" "$@"
167     }
168 fi
169
170 test -d "$VSERVER_DIR" || {
171     echo "Can not find vserver-setup"
172     exit 1
173 }
174
175 if test -e "$VSERVER_DIR"/name; then
176     read VSERVER_NAME <"$VSERVER_DIR"/name
177 else
178     VSERVER_NAME=$(basename "$VSERVER_DIR")
179 fi
180
181 test "$2" != start -o -e "$VSERVER_DIR"/nonamespace -o "$OPTION_NONAMESPACE" || \
182     exec $_NEW_NAMESPACE "$0" ----nonamespace "${OPTIONS_ORIG[@]}"
183
184 . $PKGLIBDIR/vserver.functions
185 case "$2" in
186     start|stop)
187         shift 2
188         . $PKGLIBDIR/vserver.$cmd
189         ;;
190     suexec|restart)
191         shift 2
192         $cmd "$@"
193         ;;
194     condrestart)
195         test ! isVserverRunning "$VSERVER_DIR" || restart
196         ;;
197     exec)
198         shift 2
199         suexec root "$@"
200         ;;
201     chkconfig)
202         shift 2
203         suexec root chkconfig "$@"
204         ;;
205     enter)
206         getEnterShell "$VSERVER_DIR"
207         suexec root "${ENTER_SHELL[@]}"
208         ;;
209     running)
210         isVserverRunning "$VSERVER_DIR"
211         ;;
212
213     unify)
214         shift 2
215         exec $_VUNIFY "$@" "$vserver"
216         ;;
217         
218     pkg)
219         shift 2
220         exec $_VPKG "$vserver" "$@"
221         ;;
222
223     apt-get|apt-config|apt-cache)
224         export _APT_GET=$2
225         shift 2
226         exec $_VAPT_GET -- "$@"
227         ;;
228     rpm)
229         exec $_VRPM -- "$@"
230         ;;
231         
232     status)
233         if getVserverStatus "$VSERVER_DIR" ctx procnum; then
234             echo $"Vserver '$vserver' is running at context '$ctx'"
235
236             if test "$2" = status; then
237                 echo    $"Number of processes:" $procnum
238                 echo -n $"Uptime:              "
239                 "$_FILETIME" "$VSERVER_DIR/run"
240             fi
241             exit 0
242         else
243             echo $"Vserver '$vserver' is not running"
244             exit 1
245         fi
246         ;;
247     *)
248         echo $"Usage: $0 {start|stop|suexec|restart|condrestart|exec|enter|chkconfig|running|status}"
249         exit 2
250         ;;
251 esac