when building new vservers allow empty directories for their roots
[util-vserver.git] / util-vserver / 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 VSERVERDIRNAME=
24
25 VDIR=
26
27 _DEV_FILE=
28 _EXEC_DIR=
29
30 BUILD_INITPRE=
31 BUILD_INITPOST=
32
33 __BASE_GENERATED_FILES=()
34 __BASE_SUCCESS=
35
36 function makeDevEntry
37 {
38     local dst=$1/$2
39     case "$3" in
40         (c|b)   mknod -m$6 "$dst"  $3 $4 $5;;
41         (d)     mkdir -p -m$4 "$dst";;
42         (f)     touch "$dst"
43                 chmod $4 "$dst"
44                 ;;
45         (*)     echo "Unknown dev-entry mode '$3'" >&2
46                 false
47                 ;;
48     esac
49 }
50
51 function populateDirectory
52 {
53     local dst=$1
54     local i
55     
56     shift
57     for i; do
58         local file=
59         
60         for file in "$i"/*; do
61             isRegularFile "$file" || continue
62             
63             cp -a "$file" "$dst/"
64         done
65     done
66 }
67
68 function _setRootDir
69 {
70     test -z "$ROOTDIR" || return 0
71     
72     for item in "\"$__CONFDIR/.defaults/vdirbase\" 1" "$__DEFAULT_VSERVERDIR"; do
73         eval set -- "$item"
74         ROOTDIR=$1
75         ROOTDIR_REL=$2
76         test ! -d "$ROOTDIR" || break
77     done
78
79     test -d "$ROOTDIR" || {
80         echo "Root-directory '$ROOTDIR' does not exist or is invalid" >&2
81         exit 1
82     }
83 }
84
85 function _setVserverDir
86 {
87     test -z "$VSERVERDIRNAME" || return 0
88     VSERVERDIRNAME="$VSERVER_NAME"
89 }
90
91 function _setVdir
92 {
93     VDIR="$ROOTDIR/$VSERVERDIRNAME"
94 }
95
96 function say
97 {
98     test -z "$OPTION_SILENT" || return 0
99     echo "$@"
100 }
101
102 function _renameVserverCfg
103 {
104     local suffix=.~$(date +'%s')~
105     local i
106     
107     for i in "$VDIR" "$SETUP_CONFDIR"; do
108         test ! -e "$i" || isDirectoryEmpty "$i" || {
109             mv "$i" "$i$suffix"
110             say "Renamed '$i' to '$i$suffix'"
111         }
112     done
113 }
114
115
116 ## Usage: getDistribution [<default>] [<ignore-config>]
117 function getDistribution
118 {
119     local ignore_config=$2
120     
121     if test -z "$DISTRIBUTION"; then
122         if test -e /etc/fedora-release; then
123             set -- $(cat /etc/fedora-release)
124             DISTRIBUTION=fdr$4
125         elif test -e /etc/redhat-release; then
126             set -- $(cat /etc/redhat-release)
127             DISTRIBUTION=rh$5
128         elif test -e /etc/debian_version; then
129             set -- $(cat /etc/debian_version)
130             DISTRIBUTION=deb$1
131         elif test -e /etc/SuSE-release; then
132             set -- $(cat /etc/SuSE-release)
133             DISTRIBUTION=suse$3
134         elif test -e /etc/gentoo-release; then
135             set -- $(cat /etc/gentoo-release)
136             DISTRIBUTION=gentoo$5
137         elif test -e /etc/slackware-release; then
138             set -- $(cat /etc/slackware-release)
139             DISTRIBUTION=slackware$2
140         elif test -n "$1"; then
141             DISTRIBUTION=$1
142         else
143             colpanic $"\
144 ERROR: Can not determine distribution; please specify it manually with
145   the '-d' option."
146         fi
147     fi
148
149     test -n "$ignore_config" -o \
150          -d "$__CONFDIR/.distributions/$DISTRIBUTION" -o \
151          -d "$__DISTRIBDIR/$DISTRIBUTION" ||
152             colpanic $"\
153 ERROR: Can not find configuration for the distribution '$DISTRIBUTION';
154   please read http://linux-vserver.org/HowToRegisterNewDistributions
155   for information how to add support for your own distribution."
156 }
157
158 function base._addGeneratedFile
159 {
160     __BASE_GENERATED_FILES=( "${__BASE_GENERATED_FILES[@]}" "$@" )
161 }
162
163 ## Usage: initFilesystem [force]
164 function base.initFilesystem
165 {
166     test -z "$1" || _renameVserverCfg
167     { isDirectoryEmpty "$VDIR" && test  ! -e "$SETUP_CONFDIR"; } || colpanic $"\
168 vserver-topdirectory '$VDIR' and/or configuration at '$SETUP_CONFDIR'
169 exist already; please try to use '--force', or remove them manually."
170
171     mkdir -p -m755 "$VDIR"
172     chattr -t "$VDIR"
173     base._addGeneratedFile "$VDIR"
174     
175     mkdir -p -m755 "$SETUP_CONFDIR"/apps "$VDIR"/{dev/pts,etc}
176     base._addGeneratedFile "$SETUP_CONFDIR"
177     
178     ln -s "$VDIR"       "$SETUP_CONFDIR/vdir"
179
180     local spec
181     while read spec; do
182         makeDevEntry "$VDIR"/dev $spec
183     done <$_DEV_FILE
184
185     mkdir -p "$VDIR"/proc
186     findAndCopy "$VDIR"/etc/hosts         "$__CONFDIR"/.defaults/files/hosts "$__CONFDIR/.distributions/$DISTRIBUTION"/files/hosts \
187                                           "$__DISTRIBDIR/$DISTRIBUTION"/files/hosts "$__DISTRIBDIR"/defaults/files/hosts ""
188
189     for i in nsswitch.conf krb5.conf krb.conf krb.realms ldap.conf localtime resolv.conf; do
190         findAndCopy "$VDIR"/etc/$i  "$__CONFDIR/.defaults/files/$i" "$__CONFDIR/.distributions/$DISTRIBUTION/files/$i" ""
191     done
192 }
193
194 function base._initVariables
195 {
196     _setRootDir
197     _setVserverDir
198     _setVdir
199
200     findFile _DEV_FILE      "$__CONFDIR/.distributions/$DISTRIBUTION/devs"      "$__DISTRIBDIR/$DISTRIBUTION/devs"     "$__DISTRIBDIR/defaults/devs"
201     findDir  _EXECDIR       "$__CONFDIR/.distributions/$DISTRIBUTION/execdir"   "$__DISTRIBDIR/$DISTRIBUTION/execdir"  /
202     findFile BUILD_INITPRE  "$__CONFDIR/.distributions/$DISTRIBUTION/initpre"   "$__DISTRIBDIR/$DISTRIBUTION/initpre"  ""
203     findFile BUILD_INITPOST "$__CONFDIR/.distributions/$DISTRIBUTION/initpost"  "$__DISTRIBDIR/$DISTRIBUTION/initpost" ""
204 }
205
206 function base.__cleanup
207 {
208     test -z "$OPTION_KEEP"    || return 0
209     test -z "$__BASE_SUCCESS" || return 0
210     
211     rm -rf "${__BASE_GENERATED_FILES[@]}"
212 }
213
214 function base.init
215 {
216     test -z "$SETUP_CONTEXT" || ! $_VSERVER_INFO -q "$SETUP_CONTEXT" RUNNING || \
217         panic $"\
218 Context '$SETUP_CONTEXT' is already in use. Please select another one."
219
220     trap "base.__cleanup" EXIT
221     base._initVariables
222 }
223
224 function base.setSuccess
225 {
226     __BASE_SUCCESS=1
227 }