]> git.proxmox.com Git - mirror_lxc.git/blob - scripts/lxc-fedora.in
liblxc: create a fedore template container
[mirror_lxc.git] / scripts / lxc-fedora.in
1 #!/bin/bash
2 # set -ex
3
4 DISTRO="fedora"
5 CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}"
6
7 # Default container name
8 NAME="fedora"
9 CONFFILE="lxc.conf"
10 MNTFILE="mount.conf"
11 UTSNAME=
12 IPV4="172.20.0.21"
13 GATEWAY="172.20.0.1"
14
15 # These paths are within the container so do not need to obey configure prefixes
16 INITTAB="/etc/inittab"
17 FSTAB="/etc/fstab"
18 SSHD_CONFIG="/etc/ssh/sshd_config"
19
20 ################################################################################
21 # DISTRO custom configuration files
22 ################################################################################
23
24 # custom selinux
25
26 write_distro_selinux() {
27 mkdir -p ${ROOTFS}/selinux
28 echo 0 > ${ROOTFS}/selinux/enforce
29 }
30
31 # custom fstab
32
33 write_distro_fstab() {
34 cat <<EOF > ${ROOTFS}/${FSTAB}
35 tmpfs /dev/shm tmpfs defaults 0 0
36 EOF
37 }
38
39 # custom inittab
40
41 write_distro_inittab() {
42 cat <<EOF > ${ROOTFS}/${INITTAB}
43 id:3:initdefault:
44 si::sysinit:/etc/init.d/rcS
45 l0:0:wait:/etc/init.d/rc 0
46 l1:1:wait:/etc/init.d/rc 1
47 l2:2:wait:/etc/init.d/rc 2
48 l3:3:wait:/etc/init.d/rc 3
49 l4:4:wait:/etc/init.d/rc 4
50 l5:5:wait:/etc/init.d/rc 5
51 l6:6:wait:/etc/init.d/rc 6
52 # Normally not reached, but fallthrough in case of emergency.
53 z6:6:respawn:/sbin/sulogin
54 1:2345:respawn:/sbin/getty 38400 console
55 c1:12345:respawn:/sbin/getty 38400 tty1 linux
56 c2:12345:respawn:/sbin/getty 38400 tty2 linux
57 c3:12345:respawn:/sbin/getty 38400 tty3 linux
58 c4:12345:respawn:/sbin/getty 38400 tty4 linux
59 EOF
60 }
61
62 # custom network configuration
63 write_distro_network() {
64 cat <<EOF > ${ROOTFS}/etc/sysconfig/network-scripts/ifcfg-lo
65 DEVICE=lo
66 IPADDR=127.0.0.1
67 NETMASK=255.0.0.0
68 NETWORK=127.0.0.0
69 # If you're having problems with gated making 127.0.0.0/8 a martian,
70 # you can change this to something else (255.255.255.255, for example)
71 BROADCAST=127.255.255.255
72 ONBOOT=yes
73 NAME=loopback
74 EOF
75 cat <<EOF > ${ROOTFS}/etc/sysconfig/network-scripts/ifcfg-eth0
76 DEVICE=eth0
77 BOOTPROTO=static
78 HWADDR=52:54:00:12:34:56
79 ONBOOT=yes
80 HOSTNAME=${UTSNAME}
81 NM_CONTROLLED=no
82 TYPE=Ethernet
83 IPADDR=${IPV4}
84 NETWORK=$(ipcalc -sn ${IPV4} 255.255.255.0)
85 GATEWAY=${GATEWAY}
86 BROADCAST=$(ipcalc -sb ${IPV4} 255.255.255.0)
87 NETMASK=255.255.255.0
88 EOF
89 }
90
91 # custom hostname
92
93 write_distro_hostname() {
94 cat <<EOF > ${ROOTFS}/sysconfig/network
95 NETWORKING=yes
96 HOSTNAME=${UTSNAME}
97 EOF
98 }
99
100 # custom sshd configuration file
101
102 write_distro_sshd_config() {
103 cat <<EOF > ${ROOTFS}/${SSHD_CONFIG}
104 Port 22
105 Protocol 2
106 HostKey /etc/ssh/ssh_host_rsa_key
107 HostKey /etc/ssh/ssh_host_dsa_key
108 UsePrivilegeSeparation yes
109 KeyRegenerationInterval 3600
110 ServerKeyBits 768
111 SyslogFacility AUTH
112 LogLevel INFO
113 LoginGraceTime 120
114 PermitRootLogin yes
115 StrictModes yes
116 RSAAuthentication yes
117 PubkeyAuthentication yes
118 IgnoreRhosts yes
119 RhostsRSAAuthentication no
120 HostbasedAuthentication no
121 PermitEmptyPasswords yes
122 ChallengeResponseAuthentication no
123 EOF
124 }
125
126 ################################################################################
127 # lxc configuration files
128 ################################################################################
129
130 write_lxc_configuration() {
131 cat <<EOF > ${CONFFILE}
132 lxc.utsname = ${UTSNAME}
133 lxc.tty = 4
134 lxc.network.type = veth
135 lxc.network.flags = up
136 lxc.network.link = br0
137 lxc.network.name = eth0
138 lxc.mount = ${MNTFILE}
139 lxc.rootfs = ${ROOTFS}
140 lxc.cgroup.devices.deny = a
141 # /dev/null and zero
142 lxc.cgroup.devices.allow = c 1:3 rwm
143 lxc.cgroup.devices.allow = c 1:5 rwm
144 # consoles
145 lxc.cgroup.devices.allow = c 5:1 rwm
146 lxc.cgroup.devices.allow = c 5:0 rwm
147 lxc.cgroup.devices.allow = c 4:0 rwm
148 lxc.cgroup.devices.allow = c 4:1 rwm
149 # /dev/{,u}random
150 lxc.cgroup.devices.allow = c 1:9 rwm
151 lxc.cgroup.devices.allow = c 1:8 rwm
152 # /dev/pts/* - pts namespaces are "coming soon"
153 lxc.cgroup.devices.allow = c 136:* rwm
154 lxc.cgroup.devices.allow = c 5:2 rwm
155 # rtc
156 lxc.cgroup.devices.allow = c 254:0 rwm
157 EOF
158 }
159
160 write_lxc_mounts() {
161 cat <<EOF > ${MNTFILE}
162
163 EOF
164 }
165
166 create() {
167
168 # choose a container name, default is already in shell NAME variable
169 echo -n "What is the name for the container ? [${NAME}] "
170 read _NAME_
171
172 if [ ! -z "${_NAME_}" ]; then
173 NAME=${_NAME_}
174 fi
175
176 # choose a hostname, default is the container name
177 echo -n "What hostname do you wish for this container ? [${NAME}] "
178 read _UTSNAME_
179
180 if [ ! -z "${_UTSNAME_}" ]; then
181 UTSNAME=${_UTSNAME_}
182 else
183 UTSNAME=${NAME}
184 fi
185
186 # choose an ipv4 address, better to choose the same network than
187 # your host
188 echo -n "What IP address do you wish for this container ? [${IPV4}] "
189 read _IPV4_
190
191 if [ ! -z "${_IPV4_}" ]; then
192 IPV4=${_IPV4_}
193 fi
194
195 # choose the gateway ip address
196 echo -n "What is the gateway IP address ? [${GATEWAY}] "
197 read _GATEWAY_
198
199 if [ ! -z "${_GATEWAY_}" ]; then
200 GATEWAY=${_GATEWAY_}
201 fi
202
203 # the rootfs name will be build with the container name
204 ROOTFS="./rootfs.${NAME}"
205
206 # check if the rootfs does already exist
207 if [ ! -e "${ROOTFS}" ]; then
208 mkdir -p @LOCALSTATEDIR@/lock/subsys/
209 (
210 flock -n -x 200
211
212
213 RES=$?
214 if [ "${RES}" != "0" ]; then
215 echo "Cache repository is busy."
216 break
217 fi
218
219 # check the mini distro was not already downloaded
220 echo -n "Checking cache download ..."
221 if [ ! -e "${CACHE}/rootfs" ]; then
222
223 echo "not cached"
224
225 # Rather than write a special yum config we just make the
226 # default RPM and yum layout in ${CACHE}. The alternative is
227 # to copy /etc/yum/yum.conf or /etc/yum.conf and fiddle with
228 # some settings.
229 mkdir -p "${CACHE}/partial/var/lib/rpm"
230 mkdir -p "${CACHE}/partial/var/log"
231 touch "${CACHE}/partial/var/log/yum.log"
232
233 RELEASE="$(yum info ${DISTRO}-release | \
234 awk -F '[[:space:]]*:[[:space:]]*' \
235 '/^Release/ { release = $2 }
236 /^Version/ { version = $2 }
237 END { print version "-" release }')"
238 PKG="${DISTRO}-release.noarch.rpm"
239 RPM="rpm --root \"${CACHE}/partial\""
240
241 echo "Initializing RPM cache ..."
242 ${RPM} --initdb
243 echo "Downloading ${DISTRO} Release ${RELEASE} description ..."
244 yumdownloader --destdir="${CACHE}/partial" "${DISTRO}-release.noarch.rpm" && \
245 ${RPM} --nodeps -ihv "${CACHE}/partial/${DISTRO}-release*.noarch.rpm"
246 echo "Downloading ${DISTRO} minimal ..."
247 yum --installroot="${CACHE}/partial" -y groupinstall Base
248 RESULT=$?
249 if [ "${RESULT}" != "0" ]; then
250 echo "Failed to download the rootfs, aborting."
251 exit 1
252 fi
253 mv "${CACHE}/partial" "${CACHE}/rootfs"
254 echo "Download complete."
255 else
256 echo "Found."
257 fi
258
259 # make a local copy of the mini
260 echo -n "Copying rootfs ..."
261 cp -a ${CACHE}/rootfs ${ROOTFS} && echo "Done." || exit
262 ) 200> "@LOCALSTATEDIR@/lock/subsys/lxc"
263 fi
264
265 write_lxc_mounts
266
267 write_lxc_configuration
268
269 write_distro_inittab
270
271 write_distro_hostname
272
273 write_distro_fstab
274
275 write_distro_network
276
277 write_distro_sshd_config
278
279 write_distro_selinux
280
281 @BINDIR@/lxc-create -n ${NAME} -f ${CONFFILE}
282 RES=$?
283
284 # remove the configuration files
285 rm -f ${CONFFILE}
286 rm -f ${MNTFILE}
287
288 if [ "${RES}" != "0" ]; then
289 echo "Failed to create '${NAME}'"
290 exit 1
291 fi
292
293 echo "Done."
294 echo -e "\nYou can run your container with the 'lxc-start -n ${NAME}'\n"
295 }
296
297 destroy() {
298
299 echo -n "What is the name for the container ? [${NAME}] "
300 read _NAME_
301
302 if [ ! -z "${_NAME_}" ]; then
303 NAME=${_NAME_}
304 fi
305
306 @BINDIR@/lxc-destroy -n ${NAME}
307 RETVAL=$?
308 if [ ! ${RETVAL} -eq 0 ]; then
309 echo "Failed to destroyed '${NAME}'"
310 return ${RETVAL}
311 fi
312
313 ROOTFS="./rootfs.${NAME}"
314
315 echo -n "Shall I remove the rootfs [y/n] ? "
316 read
317 if [ "${REPLY}" = "y" ]; then
318 rm -rf ${ROOTFS}
319 fi
320
321 return 0
322 }
323
324 help() {
325 cat <<EOF
326
327 This script is a helper to create ${DISTRO} system containers.
328
329 The script will create the container configuration file following
330 the informations submitted interactively with 'lxc-${DISTRO} create'
331
332 The first creation will download, with yum, a ${DISTRO} minimal
333 install and store it into a cache.
334
335 The script will copy from the cache the root filesystem to the
336 current directory.
337
338 If there is a problem with the container, (bad configuration for
339 example), you can destroy the container with 'lxc-${DISTRO} destroy'
340 but without removing the rootfs and recreate it again with
341 'lxc-${DISTRO} create'.
342
343 If you want to create another ${DISTRO} container, call the 'lxc-${DISTRO}
344 create' again, specifying another name and new parameters.
345
346 At any time you can purge the ${DISTRO} cache download by calling
347 'lxc-${DISTRO} purge'
348
349 Have fun :)
350
351 EOF
352 }
353
354 purge() {
355
356 if [ ! -e ${CACHE} ]; then
357 exit 0
358 fi
359
360 # lock, so we won't purge while someone is creating a repository
361 (
362 flock -n -x 200
363
364 RES=$?
365 if [ "${RES}" != "0" ]; then
366 echo "Cache repository is busy."
367 exit 1
368 fi
369
370 echo -n "Purging the download cache..."
371 rm --preserve-root --one-file-system -rf ${CACHE} && echo "Done." || exit 1
372 exit 0
373
374 ) 200> "@LOCALSTATEDIR@/lock/subsys/lxc"
375 }
376
377 # Note: assuming uid==0 is root -- might break with userns??
378 if [ "$(id -u)" != "0" ]; then
379 echo "This script should be run as 'root'"
380 exit 1
381 fi
382
383 # Detect which executable we were run as, lxc-fedora or lxc-redhat
384 case "$0" in
385 *lxc-redhat)
386 DISTRO="redhat";;
387 *) # default is fedora
388 DISTRO="fedora";;
389 esac
390 CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}"
391
392 case "$1" in
393 create)
394 create;;
395 destroy)
396 destroy;;
397 help)
398 help;;
399 purge)
400 purge;;
401 *)
402 echo "Usage: $0 {create|destroy|purge|help}"
403 exit 1;;
404 esac