4 # template script for generating fedora container for LXC
8 # lxc: linux Container library
11 # Daniel Lezcano <daniel.lezcano@free.fr>
12 # Ramez Hanna <rhanna@informatiq.org>
14 # This library is free software; you can redistribute it and/or
15 # modify it under the terms of the GNU Lesser General Public
16 # License as published by the Free Software Foundation; either
17 # version 2.1 of the License, or (at your option) any later version.
19 # This library is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 # Lesser General Public License for more details.
24 # You should have received a copy of the GNU Lesser General Public
25 # License along with this library; if not, write to the Free Software
26 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 cache_base
=/var
/cache
/lxc
/fedora
/$arch
31 default_path
=/var
/lib
/lxc
35 [ -f /etc
/fedora-release
] && is_fedora
=true
37 if [ "$arch" = "i686" ]; then
44 # disable selinux in fedora
45 mkdir
-p $rootfs_path/selinux
46 echo 0 > $rootfs_path/selinux
/enforce
48 # configure the network using the dhcp
49 cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
60 cat <<EOF > ${rootfs_path}/etc/sysconfig/network
66 cat <<EOF > $rootfs_path/etc/hosts
67 127.0.0.1 localhost $name
70 dev_path
="${rootfs_path}/dev"
73 mknod
-m 666 ${dev_path}/null c
1 3
74 mknod
-m 666 ${dev_path}/zero c
1 5
75 mknod
-m 666 ${dev_path}/random c
1 8
76 mknod
-m 666 ${dev_path}/urandom c
1 9
77 mkdir
-m 755 ${dev_path}/pts
78 mkdir
-m 1777 ${dev_path}/shm
79 mknod
-m 666 ${dev_path}/tty c
5 0
80 mknod
-m 666 ${dev_path}/tty0 c
4 0
81 mknod
-m 666 ${dev_path}/tty1 c
4 1
82 mknod
-m 666 ${dev_path}/tty2 c
4 2
83 mknod
-m 666 ${dev_path}/tty3 c
4 3
84 mknod
-m 666 ${dev_path}/tty4 c
4 4
85 mknod
-m 600 ${dev_path}/console c
5 1
86 mknod
-m 666 ${dev_path}/full c
1 7
87 mknod
-m 600 ${dev_path}/initctl p
88 mknod
-m 666 ${dev_path}/ptmx c
5 2
90 echo "setting root passwd to $root_password"
91 echo "root:$root_password" | chroot
$rootfs_path chpasswd
93 # specifying this in the initial packages doesn't always work.
94 echo "installing fedora-release package"
95 chroot
${rootfs_path} yum
--releasever=${release} -y install fedora-release
97 # silence some needless startup errors
98 touch ${rootfs_path}/etc
/fstab
100 # give us a console on /dev/console
101 sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \
102 ${rootfs_path}/etc
/sysconfig
/init
106 configure_fedora_init
()
108 sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc
/rc.sysinit
109 sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc
/rc.d
/rc.sysinit
110 # don't mount devpts, for pete's sake
111 sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc
/rc.sysinit
112 sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc
/rc.d
/rc.sysinit
113 chroot
${rootfs_path} chkconfig udev-post off
114 chroot
${rootfs_path} chkconfig network on
117 configure_fedora_systemd
()
119 unlink
${rootfs_path}/etc
/systemd
/system
/default.target
120 touch ${rootfs_path}/etc
/fstab
121 chroot
${rootfs_path} ln -s /dev
/null
//etc
/systemd
/system
/udev.service
122 chroot
${rootfs_path} ln -s /lib
/systemd
/system
/multi-user.target
/etc
/systemd
/system
/default.target
123 #dependency on a device unit fails it specially that we disabled udev
124 sed -i 's/After=dev-%i.device/After=/' ${rootfs_path}/lib
/systemd
/system
/getty\@.service
130 # check the mini fedora was not already downloaded
131 INSTALL_ROOT
=$cache/partial
132 mkdir
-p $INSTALL_ROOT
133 if [ $?
-ne 0 ]; then
134 echo "Failed to create '$INSTALL_ROOT' directory"
138 # download a mini fedora into a cache
139 echo "Downloading fedora minimal ..."
140 YUM
="yum --installroot $INSTALL_ROOT -y --nogpgcheck"
141 PKG_LIST
="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils fedora-release"
142 MIRRORLIST_URL
="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch"
145 for trynumber
in 1 2 3; do
146 [ $trynumber != 1 ] && echo "Trying again..."
147 MIRROR_URL
=$
(curl
-s -S -f "$MIRRORLIST_URL" |
head -n2 |
tail -n1)
148 if [ $?
-ne 0 ] ||
[ -z "$MIRROR_URL" ]; then
149 echo "Failed to get a mirror"
152 RELEASE_URL
="$MIRROR_URL/Packages/fedora-release-$release-1.noarch.rpm"
153 echo "Fetching from $RELEASE_URL"
154 curl
-f "$RELEASE_URL" > $INSTALL_ROOT/fedora-release-
$release.noarch.rpm
155 if [ $?
-ne 0 ]; then
156 echo "Failed to download fedora release rpm"
162 if [ $DOWNLOAD_OK != yes ]; then
167 mkdir
-p $INSTALL_ROOT/var
/lib
/rpm
168 rpm
--root $INSTALL_ROOT --initdb
169 rpm
--root $INSTALL_ROOT -ivh $INSTALL_ROOT/fedora-release-
$release.noarch.rpm
170 $YUM install $PKG_LIST
172 if [ $?
-ne 0 ]; then
173 echo "Failed to download the rootfs, aborting."
177 mv "$INSTALL_ROOT" "$cache/rootfs"
178 echo "Download complete."
186 # make a local copy of the minifedora
187 echo -n "Copying rootfs to $rootfs_path ..."
188 #cp -a $cache/rootfs-$arch $rootfs_path || return 1
189 # i prefer rsync (no reason really)
190 mkdir
-p $rootfs_path
191 rsync
-a $cache/rootfs
/ $rootfs_path/
197 YUM
="yum --installroot $cache/rootfs -y --nogpgcheck"
203 mkdir
-p /var
/lock
/subsys
/
206 if [ $?
-ne 0 ]; then
207 echo "Cache repository is busy."
211 echo "Checking cache download in $cache/rootfs ... "
212 if [ ! -e "$cache/rootfs" ]; then
214 if [ $?
-ne 0 ]; then
215 echo "Failed to download 'fedora base'"
219 echo "Cache found. Updating..."
221 if [ $?
-ne 0 ]; then
222 echo "Failed to update 'fedora base', continuing with last known good cache"
224 echo "Update finished"
228 echo "Copy $cache/rootfs to $rootfs_path ... "
230 if [ $?
-ne 0 ]; then
231 echo "Failed to copy rootfs"
237 ) 200>/var
/lock
/subsys
/lxc
245 mkdir
-p $config_path
246 cat <<EOF >> $config_path/config
250 lxc.rootfs = $rootfs_path
251 lxc.mount = $config_path/fstab
253 # When using LXC with apparmor, uncomment the next line to run unconfined:
254 #lxc.aa_profile = unconfined
257 lxc.cgroup.devices.deny = a
259 lxc.cgroup.devices.allow = c 1:3 rwm
260 lxc.cgroup.devices.allow = c 1:5 rwm
262 lxc.cgroup.devices.allow = c 5:1 rwm
263 lxc.cgroup.devices.allow = c 5:0 rwm
264 lxc.cgroup.devices.allow = c 4:0 rwm
265 lxc.cgroup.devices.allow = c 4:1 rwm
267 lxc.cgroup.devices.allow = c 1:9 rwm
268 lxc.cgroup.devices.allow = c 1:8 rwm
269 lxc.cgroup.devices.allow = c 136:* rwm
270 lxc.cgroup.devices.allow = c 5:2 rwm
272 lxc.cgroup.devices.allow = c 254:0 rwm
275 cat <<EOF > $config_path/fstab
276 proc proc proc nodev,noexec,nosuid 0 0
277 sysfs sys sysfs defaults 0 0
279 if [ $?
-ne 0 ]; then
280 echo "Failed to add configuration"
290 if [ ! -e $cache ]; then
294 # lock, so we won't purge while someone is creating a repository
298 echo "Cache repository is busy."
302 echo -n "Purging the download cache for Fedora-$release..."
303 rm --preserve-root --one-file-system -rf $cache && echo "Done." ||
exit 1
306 ) 200>/var
/lock
/subsys
/lxc
313 $1 -n|--name=<container_name>
314 [-p|--path=<path>] [-c|--clean] [-R|--release=<Fedora_release>] [-A|--arch=<arch of the container>]
317 -n,--name container name, used to as an identifier for that container from now on
319 -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc. The container config will go under /var/lib/lxc in that case
320 -c,--clean clean the cache
321 -R,--release Fedora release for the new container. if the host is Fedora, then it will defaultto the host's release.
322 -A,--arch NOT USED YET. Define what arch the container will be [i686,x86_64]
323 -h,--help print this help
328 options
=$
(getopt
-o hp
:n
:cR
: -l help,path
:,name
:,clean
,release
: -- "$@")
329 if [ $?
-ne 0 ]; then
333 eval set -- "$options"
338 -h|
--help) usage
$0 && exit 0;;
339 -p|
--path) path
=$2; shift 2;;
340 -n|
--name) name
=$2; shift 2;;
341 -c|
--clean) clean
=$2; shift 2;;
342 -R|
--release) release
=$2; shift 2;;
343 --) shift 1; break ;;
348 if [ ! -z "$clean" -a -z "$path" ]; then
354 type yum
>/dev
/null
2>&1
355 if [ $?
-ne 0 ]; then
356 needed_pkgs
="yum $needed_pkgs"
360 type curl
>/dev
/null
2>&1
361 if [ $?
-ne 0 ]; then
362 needed_pkgs
="curl $needed_pkgs"
365 if [ -n "$needed_pkgs" ]; then
366 echo "Missing commands: $needed_pkgs"
367 echo "Please install these using \"sudo apt-get install $needed_pkgs\""
371 if [ -z "$path" ]; then
375 if [ -z "$release" ]; then
376 if [ "$is_fedora" ]; then
377 release
=$
(cat /etc
/fedora-release |
awk '/^Fedora/ {print $3}')
379 echo "This is not a fedora host and release missing, defaulting to 14. use -R|--release to specify release"
384 if [ "$(id -u)" != "0" ]; then
385 echo "This script should be run as 'root'"
390 rootfs_path
=$path/$name/rootfs
391 # check for 'lxc.rootfs' passed in through default config by lxc-create
392 if grep -q '^lxc.rootfs' $path/config
2>/dev
/null
; then
393 rootfs_path
=`grep 'lxc.rootfs =' $path/config | awk -F= '{ print $2 }'`
395 config_path
=$default_path/$name
396 cache
=$cache_base/$release
400 echo "Interrupted, so cleaning up"
402 # maybe was interrupted before copy config
404 rm -rf $default_path/$name
409 trap revert SIGHUP SIGINT SIGTERM
412 if [ $?
-ne 0 ]; then
413 echo "failed write configuration file"
418 if [ $?
-ne 0 ]; then
419 echo "failed to install fedora"
424 if [ $?
-ne 0 ]; then
425 echo "failed to configure fedora for a container"
429 type /bin
/systemd
>/dev
/null
2>&1
430 if [ $?
-ne 0 ]; then
431 configure_fedora_init
433 configure_fedora_systemd
436 if [ ! -z $clean ]; then
440 echo "container rootfs and config created"