4 # template script for generating centos container for LXC
7 # lxc: linux Container library
10 # Daniel Lezcano <daniel.lezcano@free.fr>
11 # Ramez Hanna <rhanna@informatiq.org>
12 # Fajar A. Nugraha <github@fajar.net>
13 # Michael H. Warfield <mhw@WittsEnd.com>
15 # This library is free software; you can redistribute it and/or
16 # modify it under the terms of the GNU Lesser General Public
17 # License as published by the Free Software Foundation; either
18 # version 2.1 of the License, or (at your option) any later version.
20 # This library is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 # Lesser General Public License for more details.
25 # You should have received a copy of the GNU Lesser General Public
26 # License along with this library; if not, write to the Free Software
27 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 default_path
=@LXCPATH@
32 # Some combinations of the tunning knobs below do not exactly make sense.
35 # If the "root_password" is non-blank, use it, else set a default.
36 # This can be passed to the script as an environment variable and is
37 # set by a shell conditional assignment. Looks weird but it is what it is.
39 # If the root password contains a ding ($) then try to expand it.
40 # That will pick up things like ${name} and ${RANDOM}.
41 # If the root password contians more than 3 consecutive X's, pass it as
42 # a template to mktemp and take the result.
44 # If root_display_password = yes, display the temporary root password at exit.
45 # If root_store_password = yes, store it in the configuration directory
46 # If root_prompt_password = yes, invoke "passwd" to force the user to change
47 # the root password after the container is created.
49 # These are conditional assignments... The can be overridden from the
50 # preexisting environment variables...
52 # Make sure this is in single quotes to defer expansion to later!
53 # :{root_password='Root-${name}-${RANDOM}'}
54 : ${root_password='Root-${name}-XXXXXX'}
56 # Now, it doesn't make much sense to display, store, and force change
57 # together. But, we gotta test, right???
58 : ${root_display_password='no'}
59 : ${root_store_password='yes'}
60 # Prompting for something interactive has potential for mayhem
61 # with users running under the API... Don't default to "yes"
62 : ${root_prompt_password='no'}
64 # These are only going into comments in the resulting config...
66 lxc_network_link
=lxcbr0
69 # Alow for weird remixes like the Raspberry Pi
71 # Use the Mitre standard CPE identifier for the release ID if possible...
72 # This may be in /etc/os-release or /etc/system-release-cpe. We
73 # should be able to use EITHER. Give preference to /etc/os-release for now.
75 # Detect use under userns (unsupported)
77 [ "$arg" == "--" ] && break
78 if [ "$arg" == "--mapped-uid" -o "$arg" == "--mapped-gid" ]; then
79 echo "This template can't be used for unprivileged containers." 1>&2
80 echo "You may want to try the \"download\" template instead." 1>&2
85 if [ -e /etc
/os-release
]
87 # This is a shell friendly configuration file. We can just source it.
88 # What we're looking for in here is the ID, VERSION_ID and the CPE_NAME
90 echo "Host CPE ID from /etc/os-release: ${CPE_NAME}"
93 if [ "${CPE_NAME}" = "" -a -e /etc
/system-release-cpe
]
95 CPE_NAME
=$
(head -n1 /etc
/system-release-cpe
)
96 CPE_URI
=$
(expr ${CPE_NAME} : '\([^:]*:[^:]*\)')
97 if [ "${CPE_URI}" != "cpe:/o" ]
101 # Probably a better way to do this but sill remain posix
102 # compatible but this works, shrug...
103 # Must be nice and not introduce convenient bashisms here.
105 # According to the official registration at Mitre and NIST,
106 # this should have been something like this for CentOS:
107 # cpe:/o:centos:centos:6
109 # cpe:/o:centos:centos:6.5
111 ID
=$
(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)')
112 # The "enterprise_linux" is a bone toss back to RHEL.
113 # Since CentOS and RHEL are so tightly coupled, we'll
114 # take the RHEL version if we're running on it and do the
115 # equivalent version for CentOS.
116 if [ ${ID} = "linux" -o ${ID} = "enterprise_linux" ]
118 # Instead we got this: cpe:/o:centos:linux:6
119 ID
=$
(expr ${CPE_NAME} : '[^:]*:[^:]*:\([^:]*\)')
122 VERSION_ID
=$
(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)')
123 echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}"
127 if [ "${CPE_NAME}" != "" -a "${ID}" = "centos" -a "${VERSION_ID}" != "" ]
129 centos_host_ver
=${VERSION_ID}
131 elif [ "${CPE_NAME}" != "" -a "${ID}" = "redhat" -a "${VERSION_ID}" != "" ]
133 redhat_host_ver
=${VERSION_ID}
135 elif [ -e /etc
/centos-release
]
137 # Only if all other methods fail, try to parse the redhat-release file.
138 centos_host_ver
=$
( sed -e '/^CentOS /!d' -e 's/CentOS.*\srelease\s*\([0-9][0-9.]*\)\s.*/\1/' < /etc
/centos-release
)
139 if [ "$centos_host_ver" != "" ]
147 # delete a device node if exists, and create a new one
148 rm -f $2 && mknod
-m $1 $2 $3 $4 $5
154 # disable selinux in centos
155 mkdir
-p $rootfs_path/selinux
156 echo 0 > $rootfs_path/selinux
/enforce
158 # Also kill it in the /etc/selinux/config file if it's there...
159 if [ -f $rootfs_path/etc
/selinux
/config
]
161 sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc
/selinux
/config
164 # Nice catch from Dwight Engen in the Oracle template.
165 # Wantonly plagerized here with much appreciation.
166 if [ -f $rootfs_path/usr
/sbin
/selinuxenabled
]; then
167 mv $rootfs_path/usr
/sbin
/selinuxenabled
$rootfs_path/usr
/sbin
/selinuxenabled.lxcorig
168 ln -s /bin
/false
$rootfs_path/usr
/sbin
/selinuxenabled
171 # This is a known problem and documented in RedHat bugzilla as relating
172 # to a problem with auditing enabled. This prevents an error in
173 # the container "Cannot make/remove an entry for the specified session"
174 sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc
/pam.d
/login
175 sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc
/pam.d
/sshd
177 if [ -f ${rootfs_path}/etc
/pam.d
/crond
]
179 sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc
/pam.d
/crond
182 # In addition to disabling pam_loginuid in the above config files
183 # we'll also disable it by linking it to pam_permit to catch any
184 # we missed or any that get installed after the container is built.
186 # Catch either or both 32 and 64 bit archs.
187 if [ -f ${rootfs_path}/lib
/security
/pam_loginuid.so
]
189 ( cd ${rootfs_path}/lib
/security
/
190 mv pam_loginuid.so pam_loginuid.so.disabled
191 ln -s pam_permit.so pam_loginuid.so
195 if [ -f ${rootfs_path}/lib64
/security
/pam_loginuid.so
]
197 ( cd ${rootfs_path}/lib64
/security
/
198 mv pam_loginuid.so pam_loginuid.so.disabled
199 ln -s pam_permit.so pam_loginuid.so
203 # Deal with some dain bramage in the /etc/init.d/halt script.
204 # Trim it and make it our own and link it in before the default
205 # halt script so we can intercept it. This also preventions package
206 # updates from interferring with our interferring with it.
208 # There's generally not much in the halt script that useful but what's
209 # in there from resetting the hardware clock down is generally very bad.
210 # So we just eliminate the whole bottom half of that script in making
211 # ourselves a copy. That way a major update to the init scripts won't
212 # trash what we've set up.
213 if [ -f ${rootfs_path}/etc
/init.d
/halt
]
215 sed -e '/hwclock/,$d' \
216 < ${rootfs_path}/etc
/init.d
/halt \
217 > ${rootfs_path}/etc
/init.d
/lxc-halt
219 echo '$command -f' >> ${rootfs_path}/etc
/init.d
/lxc-halt
220 chmod 755 ${rootfs_path}/etc
/init.d
/lxc-halt
222 # Link them into the rc directories...
224 cd ${rootfs_path}/etc
/rc.d
/rc0.d
225 ln -s ..
/init.d
/lxc-halt S00lxc-halt
226 cd ${rootfs_path}/etc
/rc.d
/rc6.d
227 ln -s ..
/init.d
/lxc-halt S00lxc-reboot
231 # configure the network using the dhcp
232 cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0
243 cat <<EOF > ${rootfs_path}/etc/sysconfig/network
249 cat <<EOF > $rootfs_path/etc/hosts
250 127.0.0.1 localhost $name
254 cat <<EOF > $rootfs_path/etc/fstab
255 /dev/root / rootfs defaults 0 0
256 none /dev/shm tmpfs nosuid,nodev 0 0
259 # create lxc compatibility init script
260 if [ "$release" = "6" ]; then
261 cat <<EOF > $rootfs_path/etc/init/lxc-sysinit.conf
266 if [ "x$container" != "xlxc" -a "x$container" != "xlibvirt" ]; then
269 initctl start tty TTY=console
270 rm -f /var/lock/subsys/*
276 elif [ "$release" = "5" ]; then
277 cat <<EOF > $rootfs_path/etc/rc.d/lxc.sysinit
279 rm -f /etc/mtab /var/run/*.{pid,lock} /var/lock/subsys/*
280 rm -rf {/,/var}/tmp/*
281 echo "/dev/root / rootfs defaults 0 0" > /etc/mtab
284 chmod 755 $rootfs_path/etc
/rc.d
/lxc.sysinit
285 sed -i 's|si::sysinit:/etc/rc.d/rc.sysinit|si::bootwait:/etc/rc.d/lxc.sysinit|' $rootfs_path/etc
/inittab
286 sed -i 's|^1:|co:2345:respawn:/sbin/mingetty console\n1:|' $rootfs_path/etc
/inittab
287 sed -i 's|^\([56]:\)|#\1|' $rootfs_path/etc
/inittab
290 dev_path
="${rootfs_path}/dev"
293 mknod
-m 666 ${dev_path}/null c
1 3
294 mknod
-m 666 ${dev_path}/zero c
1 5
295 mknod
-m 666 ${dev_path}/random c
1 8
296 mknod
-m 666 ${dev_path}/urandom c
1 9
297 mkdir
-m 755 ${dev_path}/pts
298 mkdir
-m 1777 ${dev_path}/shm
299 mknod
-m 666 ${dev_path}/tty c
5 0
300 mknod
-m 666 ${dev_path}/tty0 c
4 0
301 mknod
-m 666 ${dev_path}/tty1 c
4 1
302 mknod
-m 666 ${dev_path}/tty2 c
4 2
303 mknod
-m 666 ${dev_path}/tty3 c
4 3
304 mknod
-m 666 ${dev_path}/tty4 c
4 4
305 mknod
-m 600 ${dev_path}/console c
5 1
306 mknod
-m 666 ${dev_path}/full c
1 7
307 mknod
-m 600 ${dev_path}/initctl p
308 mknod
-m 666 ${dev_path}/ptmx c
5 2
310 # setup console and tty[1-4] for login. note that /dev/console and
311 # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and
312 # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks.
313 # lxc will maintain these links and bind mount ptys over /dev/lxc/*
314 # since lxc.devttydir is specified in the config.
316 # allow root login on console, tty[1-4], and pts/0 for libvirt
317 echo "# LXC (Linux Containers)" >>${rootfs_path}/etc
/securetty
318 echo "lxc/console" >>${rootfs_path}/etc
/securetty
319 echo "lxc/tty1" >>${rootfs_path}/etc
/securetty
320 echo "lxc/tty2" >>${rootfs_path}/etc
/securetty
321 echo "lxc/tty3" >>${rootfs_path}/etc
/securetty
322 echo "lxc/tty4" >>${rootfs_path}/etc
/securetty
323 echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc
/securetty
324 echo "pts/0" >>${rootfs_path}/etc
/securetty
326 if [ ${root_display_password} = "yes" ]
328 echo "Setting root password to '$root_password'"
330 if [ ${root_store_password} = "yes" ]
332 touch ${config_path}/tmp_root_pass
333 chmod 600 ${config_path}/tmp_root_pass
334 echo ${root_password} > ${config_path}/tmp_root_pass
335 echo "Storing root password in '${config_path}/tmp_root_pass'"
338 echo "root:$root_password" | chroot
$rootfs_path chpasswd
339 # Also set this password as expired to force the user to change it!
340 chroot
$rootfs_path passwd
-e root
342 # This will need to be enhanced for CentOS 7 when systemd
343 # comes into play... /\/\|=mhw=|\/\/
348 configure_centos_init
()
350 sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc
/rc.sysinit
351 sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc
/rc.d
/rc.sysinit
352 if [ "$release" = "6" ]; then
353 chroot
${rootfs_path} chkconfig udev-post off
355 chroot
${rootfs_path} chkconfig network on
361 # check the mini centos was not already downloaded
362 INSTALL_ROOT
=$cache/partial
363 mkdir
-p $INSTALL_ROOT
364 if [ $?
-ne 0 ]; then
365 echo "Failed to create '$INSTALL_ROOT' directory"
369 # download a mini centos into a cache
370 echo "Downloading centos minimal ..."
371 YUM
="yum --installroot $INSTALL_ROOT -y --nogpgcheck"
372 PKG_LIST
="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils"
374 # use temporary repository definition
375 REPO_FILE
=$INSTALL_ROOT/etc
/yum.repos.d
/lxc-centos-temp.repo
376 mkdir
-p $
(dirname $REPO_FILE)
377 if [ -n "$repo" ]; then
378 cat <<EOF > $REPO_FILE
380 name=local repository
384 cat <<EOF > $REPO_FILE
386 name=CentOS-$release - Base
387 mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=os
390 name=CentOS-$release - Updates
391 mirrorlist=http://mirrorlist.centos.org/?release=$release&arch=$basearch&repo=updates
395 # create minimal device nodes, needed for "yum install" and "yum update" process
396 mkdir
-p $INSTALL_ROOT/dev
397 force_mknod
666 $INSTALL_ROOT/dev
/null c
1 3
398 force_mknod
666 $INSTALL_ROOT/dev
/urandom c
1 9
400 $YUM install $PKG_LIST
402 if [ $?
-ne 0 ]; then
403 echo "Failed to download the rootfs, aborting."
407 # use same nameservers as hosts, needed for "yum update later"
408 cp /etc
/resolv.conf
$INSTALL_ROOT/etc
/
410 # check whether rpmdb is under $HOME
411 if [ ! -e $INSTALL_ROOT/var
/lib
/rpm
/Packages
-a -e $INSTALL_ROOT/$HOME/.rpmdb
/Packages
]; then
412 echo "Fixing rpmdb location ..."
413 mv $INSTALL_ROOT/$HOME/.rpmdb
/[A-Z
]* $INSTALL_ROOT/var
/lib
/rpm
/
414 rm -rf $INSTALL_ROOT/$HOME/.rpmdb
415 chroot
$INSTALL_ROOT rpm
--rebuilddb 2>/dev
/null
418 # check whether rpmdb version is correct
419 chroot
$INSTALL_ROOT rpm
--quiet -q yum
2>/dev
/null
422 # if "rpm -q" doesn't work due to rpmdb version difference,
423 # then we need to redo the process using the newly-installed yum
424 if [ $ret -gt 0 ]; then
425 echo "Reinstalling packages ..."
426 mv $REPO_FILE $REPO_FILE.tmp
427 mkdir
$INSTALL_ROOT/etc
/yum.repos.disabled
428 mv $INSTALL_ROOT/etc
/yum.repos.d
/*.repo
$INSTALL_ROOT/etc
/yum.repos.disabled
/
429 mv $REPO_FILE.tmp
$REPO_FILE
430 mkdir
-p $INSTALL_ROOT/$INSTALL_ROOT/etc
431 cp /etc
/resolv.conf
$INSTALL_ROOT/$INSTALL_ROOT/etc
/
432 mkdir
-p $INSTALL_ROOT/$INSTALL_ROOT/dev
433 mknod
-m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev
/null c
1 3
434 mknod
-m 666 $INSTALL_ROOT/$INSTALL_ROOT/dev
/urandom c
1 9
435 mkdir
-p $INSTALL_ROOT/$INSTALL_ROOT/var
/cache
/yum
436 cp -al $INSTALL_ROOT/var
/cache
/yum
/* $INSTALL_ROOT/$INSTALL_ROOT/var
/cache
/yum
/
437 chroot
$INSTALL_ROOT $YUM install $PKG_LIST
438 if [ $?
-ne 0 ]; then
439 echo "Failed to download the rootfs, aborting."
442 mv $INSTALL_ROOT/$INSTALL_ROOT $INSTALL_ROOT.tmp
444 mv $INSTALL_ROOT.tmp
$INSTALL_ROOT
448 rm -rf $INSTALL_ROOT/var
/cache
/yum
/*
450 mv "$INSTALL_ROOT" "$cache/rootfs"
451 echo "Download complete."
459 # make a local copy of the mini centos
460 echo -n "Copying rootfs to $rootfs_path ..."
461 #cp -a $cache/rootfs-$arch $rootfs_path || return 1
462 # i prefer rsync (no reason really)
463 mkdir
-p $rootfs_path
464 rsync
-a $cache/rootfs
/ $rootfs_path/
471 YUM
="chroot $cache/rootfs yum -y --nogpgcheck"
473 if [ $?
-ne 0 ]; then
481 mkdir
-p /var
/lock
/subsys
/
484 if [ $?
-ne 0 ]; then
485 echo "Cache repository is busy."
489 echo "Checking cache download in $cache/rootfs ... "
490 if [ ! -e "$cache/rootfs" ]; then
492 if [ $?
-ne 0 ]; then
493 echo "Failed to download 'centos base'"
497 echo "Cache found. Updating..."
499 if [ $?
-ne 0 ]; then
500 echo "Failed to update 'centos base', continuing with last known good cache"
502 echo "Update finished"
506 echo "Copy $cache/rootfs to $rootfs_path ... "
508 if [ $?
-ne 0 ]; then
509 echo "Failed to copy rootfs"
515 ) 9>/var
/lock
/subsys
/lxc-centos
522 openssl rand
-hex 5 |
sed -e 's/\(..\)/:\1/g; s/^/fe/'
527 mkdir
-p $config_path
529 grep -q "^lxc.rootfs" $config_path/config
2>/dev
/null ||
echo "
530 lxc.rootfs = $rootfs_path
531 " >> $config_path/config
533 # The following code is to create static MAC addresses for each
534 # interface in the container. This code will work for multiple
535 # interfaces in the default config.
536 mv $config_path/config
$config_path/config.def
539 # This should catch variable expansions from the default config...
540 if expr "${LINE}" : '.*\$' > /dev
/null
2>&1
542 LINE
=$
(eval "echo \"${LINE}\"")
545 # There is a tab and a space in the regex bracket below!
546 # Seems that \s doesn't work in brackets.
547 KEY
=$
(expr "${LINE}" : '\s*\([^ ]*\)\s*=')
549 if [[ "${KEY}" != "lxc.network.hwaddr" ]]
551 echo ${LINE} >> $config_path/config
553 if [[ "${KEY}" == "lxc.network.link" ]]
555 echo "lxc.network.hwaddr = $(create_hwaddr)" >> $config_path/config
558 done < $config_path/config.def
560 rm -f $config_path/config.def
562 if [ -e "@LXCTEMPLATECONFIG@/centos.common.conf" ]; then
564 # Include common configuration
565 lxc.include = @LXCTEMPLATECONFIG@/centos.common.conf
566 " >> $config_path/config
569 # Append things which require expansion here...
570 cat <<EOF >> $config_path/config
571 lxc.utsname = $utsname
573 lxc.autodev = $auto_dev
575 # When using LXC with apparmor, uncomment the next line to run unconfined:
576 #lxc.aa_profile = unconfined
578 # example simple networking setup, uncomment to enable
579 #lxc.network.type = $lxc_network_type
580 #lxc.network.flags = up
581 #lxc.network.link = $lxc_network_link
582 #lxc.network.name = eth0
583 # Additional example for veth network type
584 # static MAC address,
585 #lxc.network.hwaddr = 00:16:3e:77:52:20
586 # persistent veth device name on host side
587 # Note: This may potentially collide with other containers of same name!
588 #lxc.network.veth.pair = v-$name-e0
592 if [ $?
-ne 0 ]; then
593 echo "Failed to add configuration"
603 if [ ! -e $cache ]; then
607 # lock, so we won't purge while someone is creating a repository
611 echo "Cache repository is busy."
615 echo -n "Purging the download cache for centos-$release..."
616 rm --preserve-root --one-file-system -rf $cache && echo "Done." ||
exit 1
619 ) 9>@LOCALSTATEDIR@
/lock
/subsys
/lxc-centos
626 $1 -n|--name=<container_name>
627 [-p|--path=<path>] [-c|--clean] [-R|--release=<CentOS_release>] [-A|--arch=<arch of the container>]
630 -n,--name container name, used to as an identifier for that container from now on
632 -p,--path path to where the container rootfs will be created, defaults to /var/lib/lxc/name.
633 -c,--clean clean the cache
634 -R,--release Centos release for the new container. if the host is Centos, then it will defaultto the host's release.
635 --fqdn fully qualified domain name (FQDN) for DNS and system naming
636 --repo repository to use (url)
637 -a,--arch Define what arch the container will be [i686,x86_64]
638 -h,--help print this help
643 options
=$
(getopt
-o a
:hp
:n
:cR
: -l help,path
:,rootfs
:,name
:,clean
,release
:,repo
:,arch
:,fqdn
: -- "$@")
644 if [ $?
-ne 0 ]; then
650 eval set -- "$options"
654 -h|
--help) usage
$0 && exit 0;;
655 -p|
--path) path
=$2; shift 2;;
656 --rootfs) rootfs
=$2; shift 2;;
657 -n|
--name) name
=$2; shift 2;;
658 -c|
--clean) clean
=$2; shift 2;;
659 -R|
--release) release
=$2; shift 2;;
660 --repo) repo
="$2"; shift 2;;
661 -a|
--arch) newarch
=$2; shift 2;;
662 --fqdn) utsname
=$2; shift 2;;
663 --) shift 1; break ;;
668 if [ ! -z "$clean" -a -z "$path" ]; then
674 # Map a few architectures to their generic CentOS repository archs.
675 # The two ARM archs are a bit of a guesstimate for the v5 and v6
676 # archs. V6 should have hardware floating point (Rasberry Pi).
677 # The "arm" arch is safer (no hardware floating point). So
678 # there may be cases where we "get it wrong" for some v6 other
681 i686
) basearch
=i386
;;
682 armv3l|armv4l|armv5l
) basearch
=arm
;;
683 armv6l|armv7l|armv8l
) basearch
=armhfp
;;
687 # Somebody wants to specify an arch. This is very limited case.
688 # i386/i586/i686 on i386/x86_64
691 if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ]
695 if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ]
697 # Make the arch a generic x86 32 bit...
709 if [ "${basearch}" = "bad" ]
711 echo "You cannot build a ${newarch} CentOS container on a ${arch} host. Sorry!"
716 cache_base
=@LOCALSTATEDIR@
/cache
/lxc
/centos
/$basearch
718 # Let's do something better for the initial root password.
719 # It's not perfect but it will defeat common scanning brute force
720 # attacks in the case where ssh is exposed. It will also be set to
721 # expired, forcing the user to change it at first login.
722 if [ "${root_password}" = "" ]
724 root_password
=Root-
${name}-${RANDOM}
726 # If it's got a ding in it, try and expand it!
727 if [ $
(expr "${root_password}" : '.*$.') != 0 ]
729 root_password
=$
(eval echo "${root_password}")
732 # If it has more than 3 consequtive X's in it, feed it
733 # through mktemp as a template.
734 if [ $
(expr "${root_password}" : '.*XXXX') != 0 ]
736 root_password
=$
(mktemp
-u ${root_password})
740 if [ -z "${utsname}" ]; then
744 # This follows a standard "resolver" convention that an FQDN must have
745 # at least two dots or it is considered a local relative host name.
746 # If it doesn't, append the dns domain name of the host system.
748 # This changes one significant behavior when running
749 # "lxc_create -n Container_Name" without using the
753 # utsname and hostname = Container_Name
755 # utsname and hostname = Container_Name.Domain_Name
757 if [ $
(expr "$utsname" : '.*\..*\.') = 0 ]; then
758 if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then
759 utsname
=${utsname}.$
(dnsdomainname
)
763 type yum
>/dev
/null
2>&1
764 if [ $?
-ne 0 ]; then
765 echo "'yum' command is missing"
769 if [ -z "$path" ]; then
770 path
=$default_path/$name
773 if [ -z "$release" ]; then
774 if [ "$is_centos" -a "$centos_host_ver" ]; then
775 release
=$centos_host_ver
776 elif [ "$is_redhat" -a "$redhat_host_ver" ]; then
777 # This is needed to clean out bullshit like 6workstation and 6server.
778 release
=$
(expr $redhat_host_ver : '\([0-9.]*\)')
780 echo "This is not a CentOS or Redhat host and release is missing, defaulting to 6 use -R|--release to specify release"
785 # CentOS 7 and above should run systemd. We need autodev enabled to keep
786 # systemd from causing problems.
788 # There is some ambiguity here due to the differnce between versioning
789 # of point specific releases such as 6.5 and the rolling release 6. We
790 # only want the major number here if it's a point release...
792 mrelease
=$
(expr $release : '\([0-9]*\)')
793 if [ $mrelease -gt 6 ]; then
799 if [ "$(id -u)" != "0" ]; then
800 echo "This script should be run as 'root'"
805 if [ -z "$rootfs_path" ]; then
806 rootfs_path
=$path/rootfs
807 # check for 'lxc.rootfs' passed in through default config by lxc-create
808 if grep -q '^lxc.rootfs' $path/config
2>/dev
/null
; then
809 rootfs_path
=$
(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \
810 -e 's/^lxc.rootfs\s*=\s*//' -e q
$path/config
)
814 cache
=$cache_base/$release
818 echo "Interrupted, so cleaning up"
820 # maybe was interrupted before copy config
826 trap revert SIGHUP SIGINT SIGTERM
829 if [ $?
-ne 0 ]; then
830 echo "failed write configuration file"
835 if [ $?
-ne 0 ]; then
836 echo "failed to install centos"
841 if [ $?
-ne 0 ]; then
842 echo "failed to configure centos for a container"
846 configure_centos_init
848 if [ ! -z $clean ]; then
853 Container rootfs and config have been created.
854 Edit the config file to check/enable networking setup.
857 if [ ${root_display_password} = "yes" ]
859 echo "The temporary password for root is: '$root_password'
861 You may want to note that password down before starting the container.
865 if [ ${root_store_password} = "yes" ]
867 echo "The temporary root password is stored in:
869 '${config_path}/tmp_root_pass'
873 if [ ${root_prompt_password} = "yes" ]
875 echo "Invoking the passwd command in the container to set the root password.
877 chroot ${rootfs_path} passwd
879 chroot
${rootfs_path} passwd
882 The root password is set up as "expired
" and will require it to be changed
883 at first login, which you should do as soon as possible. If you lose the
884 root password or wish to change it without starting the container, you
885 can change it from the host by running the following command (which will
886 also reset the expired flag):
888 chroot ${rootfs_path} passwd