gentoo: use /var/run for new /run compatibility
[util-vserver.git] / scripts / vserver-build.functions
1 # $Id$  --*- sh -*--
2
3 # Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 #  
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License.
8 #  
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #  
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 # Expected environment:
19 #     $VSERVER_NAME ... name of vserver
20
21 ROOTDIR=
22 ROOTDIR_REL=
23 CACHEDIR=
24 CACHEDIR_REL=
25 VSERVERDIRNAME=
26
27 VDIR=
28
29 _DEV_FILE=
30 _EXEC_DIR=
31
32 BUILD_INITPRE=
33 BUILD_INITPOST=
34
35 __BASE_GENERATED_FILES=()
36 __BASE_SUCCESS=
37
38 function makeDevEntry
39 {
40     local dst=$1/$2
41     case "$3" in
42         (c|b)   mknod -m$6 "$dst"  $3 $4 $5;;
43         (d)     mkdir -p -m$4 "$dst";;
44         (f)     touch "$dst"
45                 chmod $4 "$dst"
46                 ;;
47         (l)     ln -s "$4" "$dst"
48                 ;;
49         (*)     echo "Unknown dev-entry mode '$3'" >&2
50                 false
51                 ;;
52     esac
53 }
54
55 function populateDev
56 {
57     local spec
58
59     mkdir -p -m755 "$VDIR"/dev
60     mkdir -m755 "$VDIR"/dev/pts
61
62     while read spec; do
63         makeDevEntry "$VDIR"/dev $spec
64     done <$_DEV_FILE
65 }
66
67 function populateDirectory
68 {
69     local dst=$1
70     local i
71     
72     shift
73     for i; do
74         local file=
75         
76         for file in "$i"/*; do
77             isRegularFile "$file" || continue
78             
79             cp -a "$file" "$dst/"
80         done
81     done
82 }
83
84 function _setRootDir
85 {
86     test -z "$ROOTDIR" || return 0
87     
88     for item in "\"$__CONFDIR/.defaults/vdirbase\" 1" "$__DEFAULT_VSERVERDIR"; do
89         eval set -- "$item"
90         ROOTDIR=$1
91         ROOTDIR_REL=$2
92         test ! -d "$ROOTDIR" || break
93     done
94
95     test -d "$ROOTDIR" || {
96         echo "Root-directory '$ROOTDIR' does not exist or is invalid" >&2
97         exit 1
98     }
99 }
100
101 function _setCacheDir
102 {
103     test -z "$CACHEDIR" || return 0
104     
105     for item in "\"$__CONFDIR/.defaults/cachebase\" 1" "$__PKGCACHEDIR"; do
106         eval set -- "$item"
107         CACHEDIR=$1
108         CACHEDIR_REL=$2
109         test ! -d "$CACHEDIR" || break
110     done
111
112     test -d "$CACHEDIR" || {
113         echo "Cache-directory '$CACHEDIR' does not exist or is invalid" >&2
114         exit 1
115     }
116 }
117
118 function _setVserverDirName
119 {
120     test -z "$VSERVERDIRNAME" || return 0
121     VSERVERDIRNAME="$VSERVER_NAME"
122 }
123
124 function _setVdir
125 {
126     VDIR="$ROOTDIR/$VSERVERDIRNAME"
127 }
128
129 function say
130 {
131     test -z "$OPTION_SILENT" || return 0
132     echo "$@"
133 }
134
135 function _renameVserverCfg
136 {
137     local suffix=.~$(date +'%s')~
138     local i
139     
140     for i in "$VDIR" "$SETUP_CONFDIR"; do
141         test ! -e "$i" || isDirectoryEmpty "$i" || {
142             mv "$i" "$i$suffix"
143             say "Renamed '$i' to '$i$suffix'"
144         }
145     done
146 }
147
148
149 ## Usage: getDistribution [<default>] [<ignore-config>]
150 function getDistribution
151 {
152     local ignore_config=$2
153     
154     if test -z "$DISTRIBUTION"; then
155         if test -e /etc/fedora-release; then
156             set -- $(cat /etc/fedora-release)
157             DISTRIBUTION=fdr$4
158         elif test -e /etc/mandrake-release; then
159             set -- $(cat /etc/mandrake-release)
160             DISTRIBUTION=mdv$4
161         elif test -e /etc/redhat-release; then
162             set -- $(cat /etc/redhat-release)
163             DISTRIBUTION=rh$5
164         elif test -e /etc/debian_version; then
165             set -- $(cat /etc/debian_version)
166             DISTRIBUTION=deb$1
167         elif test -e /etc/SuSE-release; then
168             set -- $(cat /etc/SuSE-release)
169             DISTRIBUTION=suse$3
170         elif test -e /etc/gentoo-release; then
171             set -- $(cat /etc/gentoo-release)
172             DISTRIBUTION=gentoo$5
173         elif test -e /etc/slackware-version; then
174             set -- $(cat /etc/slackware-version)
175             DISTRIBUTION=slackware$2
176         elif test -n "$1"; then
177             DISTRIBUTION=$1
178         else
179             colpanic $"\
180 ERROR: Can not determine distribution; please specify it manually with
181   the '-d' option."
182         fi
183     fi
184
185     test -n "$ignore_config" -o \
186          -d "$__CONFDIR/.distributions/$DISTRIBUTION" -o \
187          -d "$__DISTRIBDIR/$DISTRIBUTION" ||
188             colpanic $"\
189 ERROR: Can not find configuration for the distribution '$DISTRIBUTION';
190   please read http://linux-vserver.org/HowToRegisterNewDistributions
191   for information how to add support for your own distribution."
192
193     export DISTRIBUTION
194 }
195
196 function base._addGeneratedFile
197 {
198     __BASE_GENERATED_FILES=( "${__BASE_GENERATED_FILES[@]}" "$@" )
199 }
200
201 ## Usage: initFilesystem [force]
202 function base.initFilesystem
203 {
204     test -z "$1" || _renameVserverCfg
205     { { test -n "$OPTION_SEMIFORCE" || isDirectoryEmpty "$VDIR" 1; } && test  ! -e "$SETUP_CONFDIR"; } || colpanic $"\
206 vserver-topdirectory '$VDIR' and/or configuration at '$SETUP_CONFDIR'
207 exist already; please try to use '--force', or remove them manually."
208
209     mkdir -p -m755 "$VDIR"
210     $_SETATTR --~barrier "$VDIR"
211     $_SETATTR --barrier "$VDIR"/.. || colwarn $"\
212 WARNING: could not set the barrier attribute on '$VDIR/..',
213          please set it manually."
214     base._addGeneratedFile "$VDIR"
215     
216     mkdir -p -m755 "$SETUP_CONFDIR"/apps "$VDIR"/etc
217     base._addGeneratedFile "$SETUP_CONFDIR"
218     
219     ln -s "$VDIR"                     "$SETUP_CONFDIR/vdir"
220     ln -s "$CACHEDIR/$VSERVERDIRNAME" "$SETUP_CONFDIR/cache"
221
222     populateDev
223
224     mkdir -p "$VDIR"/proc
225     findAndCopy "$VDIR"/etc/hosts         "$__CONFDIR"/.defaults/files/hosts "$__CONFDIR/.distributions/$DISTRIBUTION"/files/hosts \
226                                           "$__DISTRIBDIR/$DISTRIBUTION"/files/hosts "$__DISTRIBDIR"/defaults/files/hosts ""
227
228     for i in nsswitch.conf krb5.conf krb.conf krb.realms ldap.conf localtime; do
229         findAndCopy "$VDIR"/etc/$i  "$__CONFDIR/.defaults/files/$i" "$__CONFDIR/.distributions/$DISTRIBUTION/files/$i" ""
230     done
231     findAndCopy "$VDIR"/etc/resolv.conf "$__CONFDIR/.defaults/files/resolv.conf" \
232         "$__CONFDIR/.distributions/$DISTRIBUTION/files/resolv.conf" /etc/resolv.conf ""
233 }
234
235 function base._initVariables
236 {
237     _setRootDir
238     _setCacheDir
239     _setVserverDirName
240     _setVdir
241
242     findFile _DEV_FILE      "$__CONFDIR/.distributions/$DISTRIBUTION/devs"      "$__DISTRIBDIR/$DISTRIBUTION/devs"     "$__DISTRIBDIR/defaults/devs"
243     findDir  _EXECDIR       "$__CONFDIR/.distributions/$DISTRIBUTION/execdir"   "$__DISTRIBDIR/$DISTRIBUTION/execdir"  /
244     findFile BUILD_INITPRE  "$__CONFDIR/.distributions/$DISTRIBUTION/initpre"   "$__DISTRIBDIR/$DISTRIBUTION/initpre"  ""
245     findFile BUILD_INITPOST "$__CONFDIR/.distributions/$DISTRIBUTION/initpost"  "$__DISTRIBDIR/$DISTRIBUTION/initpost" ""
246 }
247
248 declare -a __BASE_CLEANUP
249 function base.pushCleanup
250 {
251     __BASE_CLEANUP=( "${__BASE_CLEANUP[@]}" "$*" )
252 }
253
254 function base.popCleanup
255 {
256     unset __BASE_CLEANUP[$((${#__BASE_CLEANUP[@]} - 1))]
257 }
258
259 function base.__cleanup
260 {
261     for cmd in "${__BASE_CLEANUP[@]}"; do
262         $cmd
263     done
264     
265     test -z "$__BASE_SUCCESS" || return 0
266     test -z "$OPTION_KEEP"    || return 0
267     rm -rf "${__BASE_GENERATED_FILES[@]}"
268 }
269
270 function base.init
271 {
272     test -z "$SETUP_CONTEXT" || ! $_VSERVER_INFO -q "$SETUP_CONTEXT" RUNNING || \
273         panic $"\
274 Context '$SETUP_CONTEXT' is already in use. Please select another one."
275
276     trap "base.__cleanup" EXIT
277     base._initVariables
278 }
279
280 function base.setSuccess
281 {
282     __BASE_SUCCESS=1
283 }
284
285 function startSleepingGuest
286 {
287     local guest="$1"
288     local timeout="${2:-15}"
289     $_VSERVER "$guest" start --rescue --rescue-init bash -c "
290         exec  > /dev/null
291         exec 2> /dev/null
292         trap 'kill -s 9 -- -1; exit 0' INT
293         sleep $timeout
294         kill -s 15 -- -1
295         sleep 1
296         kill -s 9 -- -1"
297 }
298
299 function stopSleepingGuest
300 {
301     local guest="$1"
302     $_VSERVER "$guest" stop --rescue-init
303 }