5
CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}"
7
# Default container name
16
# These paths are within the container so do not need to obey configure prefixes
17
INITTAB="/etc/inittab"
19
SSHD_CONFIG="/etc/ssh/sshd_config"
21
################################################################################
22
# DISTRO custom configuration files
23
################################################################################
27
write_distro_selinux() {
28
mkdir -p ${ROOTFS}/selinux
29
echo 0 > ${ROOTFS}/selinux/enforce
34
write_distro_fstab() {
35
cat <<EOF > ${ROOTFS}/${FSTAB}
36
tmpfs /dev/shm tmpfs defaults 0 0
42
write_distro_inittab() {
43
cat <<EOF > ${ROOTFS}/${INITTAB}
45
si::sysinit:/etc/init.d/rcS
46
l0:0:wait:/etc/init.d/rc 0
47
l1:1:wait:/etc/init.d/rc 1
48
l2:2:wait:/etc/init.d/rc 2
49
l3:3:wait:/etc/init.d/rc 3
50
l4:4:wait:/etc/init.d/rc 4
51
l5:5:wait:/etc/init.d/rc 5
52
l6:6:wait:/etc/init.d/rc 6
53
# Normally not reached, but fallthrough in case of emergency.
54
z6:6:respawn:/sbin/sulogin
55
1:2345:respawn:/sbin/getty 38400 console
56
c1:12345:respawn:/sbin/getty 38400 tty1 linux
57
c2:12345:respawn:/sbin/getty 38400 tty2 linux
58
c3:12345:respawn:/sbin/getty 38400 tty3 linux
59
c4:12345:respawn:/sbin/getty 38400 tty4 linux
63
# custom network configuration
64
write_distro_network() {
65
cat <<EOF > ${ROOTFS}/etc/sysconfig/network-scripts/ifcfg-lo
70
# If you're having problems with gated making 127.0.0.0/8 a martian,
71
# you can change this to something else (255.255.255.255, for example)
72
BROADCAST=127.255.255.255
76
cat <<EOF > ${ROOTFS}/etc/sysconfig/network-scripts/ifcfg-eth0
79
HWADDR=52:54:00:12:34:56
85
NETWORK=$(ipcalc -sn ${IPV4} 255.255.255.0)
87
BROADCAST=$(ipcalc -sb ${IPV4} 255.255.255.0)
95
write_distro_hostname() {
96
cat <<EOF > ${ROOTFS}/sysconfig/network
102
# custom sshd configuration file
104
write_distro_sshd_config() {
105
cat <<EOF > ${ROOTFS}/${SSHD_CONFIG}
108
HostKey /etc/ssh/ssh_host_rsa_key
109
HostKey /etc/ssh/ssh_host_dsa_key
110
UsePrivilegeSeparation yes
111
KeyRegenerationInterval 3600
118
RSAAuthentication yes
119
PubkeyAuthentication yes
121
RhostsRSAAuthentication no
122
HostbasedAuthentication no
123
PermitEmptyPasswords yes
124
ChallengeResponseAuthentication no
128
################################################################################
129
# lxc configuration files
130
################################################################################
132
write_lxc_configuration() {
133
cat <<EOF > ${CONFFILE}
134
lxc.utsname = ${UTSNAME}
136
lxc.network.type = veth
137
lxc.network.flags = up
138
lxc.network.link = br0
139
lxc.network.name = eth0
140
lxc.network.mtu = ${MTU}
141
lxc.mount = ${MNTFILE}
142
lxc.rootfs = ${ROOTFS}
143
lxc.cgroup.devices.deny = a
145
lxc.cgroup.devices.allow = c 1:3 rwm
146
lxc.cgroup.devices.allow = c 1:5 rwm
148
lxc.cgroup.devices.allow = c 5:1 rwm
149
lxc.cgroup.devices.allow = c 5:0 rwm
150
lxc.cgroup.devices.allow = c 4:0 rwm
151
lxc.cgroup.devices.allow = c 4:1 rwm
153
lxc.cgroup.devices.allow = c 1:9 rwm
154
lxc.cgroup.devices.allow = c 1:8 rwm
155
# /dev/pts/* - pts namespaces are "coming soon"
156
lxc.cgroup.devices.allow = c 136:* rwm
157
lxc.cgroup.devices.allow = c 5:2 rwm
159
lxc.cgroup.devices.allow = c 254:0 rwm
164
cat <<EOF > ${MNTFILE}
171
# choose a container name, default is already in shell NAME variable
172
echo -n "What is the name for the container ? [${NAME}] "
175
if [ ! -z "${_NAME_}" ]; then
179
# choose a hostname, default is the container name
180
echo -n "What hostname do you wish for this container ? [${NAME}] "
183
if [ ! -z "${_UTSNAME_}" ]; then
189
# choose an ipv4 address, better to choose the same network than
191
echo -n "What IP address do you wish for this container ? [${IPV4}] "
194
if [ ! -z "${_IPV4_}" ]; then
198
# choose the gateway ip address
199
echo -n "What is the gateway IP address ? [${GATEWAY}] "
202
if [ ! -z "${_GATEWAY_}" ]; then
206
# choose the MTU size
207
echo -n "What is the MTU size ? [$MTU] "
210
if [ ! -z "$_MTU_" ]; then
214
# the rootfs name will be build with the container name
215
ROOTFS="./rootfs.${NAME}"
217
# check if the rootfs does already exist
218
if [ ! -e "${ROOTFS}" ]; then
219
mkdir -p @LOCALSTATEDIR@/lock/subsys/
225
if [ "${RES}" != "0" ]; then
226
echo "Cache repository is busy."
230
# check the mini distro was not already downloaded
231
echo -n "Checking cache download ..."
232
if [ ! -e "${CACHE}/rootfs" ]; then
236
# Rather than write a special yum config we just make the
237
# default RPM and yum layout in ${CACHE}. The alternative is
238
# to copy /etc/yum/yum.conf or /etc/yum.conf and fiddle with
240
mkdir -p "${CACHE}/partial/var/lib/rpm"
241
mkdir -p "${CACHE}/partial/var/log"
242
touch "${CACHE}/partial/var/log/yum.log"
244
RELEASE="$(yum info ${DISTRO}-release | \
245
awk -F '[[:space:]]*:[[:space:]]*' \
246
'/^Release/ { release = $2 }
247
/^Version/ { version = $2 }
248
END { print version "-" release }')"
249
PKG="${DISTRO}-release.noarch.rpm"
250
RPM="rpm --root \"${CACHE}/partial\""
252
echo "Initializing RPM cache ..."
254
echo "Downloading ${DISTRO} Release ${RELEASE} description ..."
255
yumdownloader --destdir="${CACHE}/partial" "${DISTRO}-release.noarch.rpm" && \
256
${RPM} --nodeps -ihv "${CACHE}/partial/${DISTRO}-release*.noarch.rpm"
257
echo "Downloading ${DISTRO} minimal ..."
258
yum --installroot="${CACHE}/partial" -y groupinstall Base
260
if [ "${RESULT}" != "0" ]; then
261
echo "Failed to download the rootfs, aborting."
264
mv "${CACHE}/partial" "${CACHE}/rootfs"
265
echo "Download complete."
270
# make a local copy of the mini
271
echo -n "Copying rootfs ..."
272
cp -a ${CACHE}/rootfs ${ROOTFS} && echo "Done." || exit
273
) 200> "@LOCALSTATEDIR@/lock/subsys/lxc"
278
write_lxc_configuration
282
write_distro_hostname
288
write_distro_sshd_config
292
@BINDIR@/lxc-create -n ${NAME} -f ${CONFFILE}
295
# remove the configuration files
299
if [ "${RES}" != "0" ]; then
300
echo "Failed to create '${NAME}'"
305
echo -e "\nYou can run your container with the 'lxc-start -n ${NAME}'\n"
310
echo -n "What is the name for the container ? [${NAME}] "
313
if [ ! -z "${_NAME_}" ]; then
317
@BINDIR@/lxc-destroy -n ${NAME}
319
if [ ! ${RETVAL} -eq 0 ]; then
320
echo "Failed to destroyed '${NAME}'"
324
ROOTFS="./rootfs.${NAME}"
326
echo -n "Shall I remove the rootfs [y/n] ? "
328
if [ "${REPLY}" = "y" ]; then
338
This script is a helper to create ${DISTRO} system containers.
340
The script will create the container configuration file following
341
the informations submitted interactively with 'lxc-${DISTRO} create'
343
The first creation will download, with yum, a ${DISTRO} minimal
344
install and store it into a cache.
346
The script will copy from the cache the root filesystem to the
349
If there is a problem with the container, (bad configuration for
350
example), you can destroy the container with 'lxc-${DISTRO} destroy'
351
but without removing the rootfs and recreate it again with
352
'lxc-${DISTRO} create'.
354
If you want to create another ${DISTRO} container, call the 'lxc-${DISTRO}
355
create' again, specifying another name and new parameters.
357
At any time you can purge the ${DISTRO} cache download by calling
358
'lxc-${DISTRO} purge'
367
if [ ! -e ${CACHE} ]; then
371
# lock, so we won't purge while someone is creating a repository
376
if [ "${RES}" != "0" ]; then
377
echo "Cache repository is busy."
381
echo -n "Purging the download cache..."
382
rm --preserve-root --one-file-system -rf ${CACHE} && echo "Done." || exit 1
385
) 200> "@LOCALSTATEDIR@/lock/subsys/lxc"
388
# Note: assuming uid==0 is root -- might break with userns??
389
if [ "$(id -u)" != "0" ]; then
390
echo "This script should be run as 'root'"
394
# Detect which executable we were run as, lxc-fedora or lxc-redhat
398
*) # default is fedora
401
CACHE="@LOCALSTATEDIR@/cache/lxc/${DISTRO}"
413
echo "Usage: $0 {create|destroy|purge|help}"