]>
Commit | Line | Data |
---|---|---|
54b1eb68 | 1 | #!/bin/bash |
54b1eb68 | 2 | |
b6e91b67 DL |
3 | # |
4 | # template script for generating fedora container for LXC | |
5 | # | |
54b1eb68 | 6 | |
b6e91b67 DL |
7 | # |
8 | # lxc: linux Container library | |
54b1eb68 | 9 | |
b6e91b67 DL |
10 | # Authors: |
11 | # Daniel Lezcano <daniel.lezcano@free.fr> | |
579ebf12 | 12 | # Ramez Hanna <rhanna@informatiq.org> |
449989ac | 13 | # Michael H. Warfield <mhw@WittsEnd.com> |
54b1eb68 | 14 | |
b6e91b67 DL |
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. | |
54b1eb68 | 19 | |
b6e91b67 DL |
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. | |
54b1eb68 | 24 | |
b6e91b67 DL |
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 | |
250b1eec | 27 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
54b1eb68 | 28 | |
579ebf12 | 29 | #Configurations |
e29bf450 | 30 | default_path=@LXCPATH@ |
b4f7af7a | 31 | |
826cde7c | 32 | # Some combinations of the tuning knobs below do not exactly make sense. |
b4f7af7a MW |
33 | # but that's ok. |
34 | # | |
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. | |
38 | # | |
39 | # If the root password contains a ding ($) then try to expand it. | |
40 | # That will pick up things like ${name} and ${RANDOM}. | |
ec64264d | 41 | # If the root password contains more than 3 consecutive X's, pass it as |
b4f7af7a MW |
42 | # a template to mktemp and take the result. |
43 | # | |
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. | |
826cde7c MW |
48 | # If root_expire_password = yes, you will be prompted to change the root |
49 | # password at the first login. | |
b4f7af7a MW |
50 | # |
51 | # These are conditional assignments... The can be overridden from the | |
52 | # preexisting environment variables... | |
53 | # | |
54 | # Make sure this is in single quotes to defer expansion to later! | |
55 | # :{root_password='Root-${name}-${RANDOM}'} | |
56 | : ${root_password='Root-${name}-XXXXXX'} | |
57 | ||
58 | # Now, it doesn't make much sense to display, store, and force change | |
59 | # together. But, we gotta test, right??? | |
60 | : ${root_display_password='no'} | |
61 | : ${root_store_password='yes'} | |
62 | # Prompting for something interactive has potential for mayhem | |
63 | # with users running under the API... Don't default to "yes" | |
64 | : ${root_prompt_password='no'} | |
65 | ||
826cde7c MW |
66 | # Expire root password? Default to yes, but can be overridden from |
67 | # the environment variable | |
68 | : ${root_expire_password='yes'} | |
69 | ||
b4f7af7a MW |
70 | # These are only going into comments in the resulting config... |
71 | lxc_network_type=veth | |
72 | lxc_network_link=lxcbr0 | |
579ebf12 I |
73 | |
74 | # is this fedora? | |
627fe3b4 | 75 | # Alow for weird remixes like the Raspberry Pi |
b9b3a92f MW |
76 | # |
77 | # Use the Mitre standard CPE identifier for the release ID if possible... | |
78 | # This may be in /etc/os-release or /etc/system-release-cpe. We | |
79 | # should be able to use EITHER. Give preference to /etc/os-release for now. | |
80 | ||
8ec981fc | 81 | # Detect use under userns (unsupported) |
c63c04fc | 82 | for arg in "$@"; do |
96283b54 SG |
83 | [ "$arg" = "--" ] && break |
84 | if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then | |
8ec981fc SG |
85 | echo "This template can't be used for unprivileged containers." 1>&2 |
86 | echo "You may want to try the \"download\" template instead." 1>&2 | |
87 | exit 1 | |
88 | fi | |
89 | done | |
90 | ||
207bf0e4 SG |
91 | # Make sure the usual locations are in PATH |
92 | export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin | |
93 | ||
b9b3a92f MW |
94 | if [ -e /etc/os-release ] |
95 | then | |
96 | # This is a shell friendly configuration file. We can just source it. | |
97 | # What we're looking for in here is the ID, VERSION_ID and the CPE_NAME | |
98 | . /etc/os-release | |
99 | echo "Host CPE ID from /etc/os-release: ${CPE_NAME}" | |
100 | fi | |
101 | ||
102 | if [ "${CPE_NAME}" = "" -a -e /etc/system-release-cpe ] | |
103 | then | |
104 | CPE_NAME=$(head -n1 /etc/system-release-cpe) | |
53bd92ea | 105 | CPE_URI=$(expr ${CPE_NAME} : '\([^:]*:[^:]*\)') |
b9b3a92f MW |
106 | if [ "${CPE_URI}" != "cpe:/o" ] |
107 | then | |
108 | CPE_NAME= | |
109 | else | |
110 | echo "Host CPE ID from /etc/system-release-cpe: ${CPE_NAME}" | |
111 | # Probably a better way to do this but sill remain posix | |
112 | # compatible but this works, shrug... | |
113 | # Must be nice and not introduce convenient bashisms here. | |
114 | ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:\([^:]*\)') | |
115 | VERSION_ID=$(expr ${CPE_NAME} : '[^:]*:[^:]*:[^:]*:[^:]*:\([^:]*\)') | |
116 | fi | |
117 | fi | |
118 | ||
dfa7aa3a | 119 | if [ "${CPE_NAME}" != "" -a "${ID}" = "fedora" -a "${VERSION_ID}" != "" ] |
627fe3b4 | 120 | then |
b9b3a92f MW |
121 | fedora_host_ver=${VERSION_ID} |
122 | is_fedora=true | |
123 | elif [ -e /etc/redhat-release ] | |
124 | then | |
125 | # Only if all other methods fail, try to parse the redhat-release file. | |
627fe3b4 MW |
126 | fedora_host_ver=$( sed -e '/^Fedora /!d' -e 's/Fedora.*\srelease\s*\([0-9][0-9]*\)\s.*/\1/' < /etc/redhat-release ) |
127 | if [ "$fedora_host_ver" != "" ] | |
128 | then | |
129 | is_fedora=true | |
130 | fi | |
7d303dea TS |
131 | fi |
132 | ||
b6e91b67 DL |
133 | configure_fedora() |
134 | { | |
b6e91b67 DL |
135 | |
136 | # disable selinux in fedora | |
579ebf12 I |
137 | mkdir -p $rootfs_path/selinux |
138 | echo 0 > $rootfs_path/selinux/enforce | |
54b1eb68 | 139 | |
5266cf0a MW |
140 | # Also kill it in the /etc/selinux/config file if it's there... |
141 | if [[ -f $rootfs_path/etc/selinux/config ]] | |
142 | then | |
143 | sed -i '/^SELINUX=/s/.*/SELINUX=disabled/' $rootfs_path/etc/selinux/config | |
144 | fi | |
145 | ||
146 | # Nice catch from Dwight Engen in the Oracle template. | |
147 | # Wantonly plagerized here with much appreciation. | |
148 | if [ -f $rootfs_path/usr/sbin/selinuxenabled ]; then | |
149 | mv $rootfs_path/usr/sbin/selinuxenabled $rootfs_path/usr/sbin/selinuxenabled.lxcorig | |
150 | ln -s /bin/false $rootfs_path/usr/sbin/selinuxenabled | |
151 | fi | |
152 | ||
153 | # This is a known problem and documented in RedHat bugzilla as relating | |
67660331 MW |
154 | # to a problem with auditing enabled. This prevents an error in |
155 | # the container "Cannot make/remove an entry for the specified session" | |
156 | sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/login | |
5266cf0a | 157 | sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/sshd |
67660331 | 158 | |
53bd92ea MW |
159 | if [ -f ${rootfs_path}/etc/pam.d/crond ] |
160 | then | |
161 | sed -i '/^session.*pam_loginuid.so/s/^session/# session/' ${rootfs_path}/etc/pam.d/crond | |
162 | fi | |
163 | ||
164 | # In addition to disabling pam_loginuid in the above config files | |
165 | # we'll also disable it by linking it to pam_permit to catch any | |
166 | # we missed or any that get installed after the container is built. | |
167 | # | |
168 | # Catch either or both 32 and 64 bit archs. | |
169 | if [ -f ${rootfs_path}/lib/security/pam_loginuid.so ] | |
170 | then | |
171 | ( cd ${rootfs_path}/lib/security/ | |
172 | mv pam_loginuid.so pam_loginuid.so.disabled | |
173 | ln -s pam_permit.so pam_loginuid.so | |
174 | ) | |
175 | fi | |
176 | ||
177 | if [ -f ${rootfs_path}/lib64/security/pam_loginuid.so ] | |
178 | then | |
179 | ( cd ${rootfs_path}/lib64/security/ | |
180 | mv pam_loginuid.so pam_loginuid.so.disabled | |
181 | ln -s pam_permit.so pam_loginuid.so | |
182 | ) | |
183 | fi | |
184 | ||
f5067ecb MW |
185 | # Set default localtime to the host localtime if not set... |
186 | if [ -e /etc/localtime -a ! -e ${rootfs_path}/etc/localtime ] | |
187 | then | |
188 | # if /etc/localtime is a symlink, this should preserve it. | |
189 | cp -a /etc/localtime ${rootfs_path}/etc/localtime | |
190 | fi | |
191 | ||
99c2fb07 MW |
192 | # Deal with some dain bramage in the /etc/init.d/halt script. |
193 | # Trim it and make it our own and link it in before the default | |
194 | # halt script so we can intercept it. This also preventions package | |
195 | # updates from interferring with our interferring with it. | |
196 | # | |
197 | # There's generally not much in the halt script that useful but what's | |
198 | # in there from resetting the hardware clock down is generally very bad. | |
199 | # So we just eliminate the whole bottom half of that script in making | |
200 | # ourselves a copy. That way a major update to the init scripts won't | |
201 | # trash what we've set up. | |
202 | # | |
203 | # This is mostly for legacy distros since any modern systemd Fedora | |
204 | # release will not have this script so we won't try to intercept it. | |
205 | if [ -f ${rootfs_path}/etc/init.d/halt ] | |
206 | then | |
207 | sed -e '/hwclock/,$d' \ | |
208 | < ${rootfs_path}/etc/init.d/halt \ | |
209 | > ${rootfs_path}/etc/init.d/lxc-halt | |
210 | ||
211 | echo '$command -f' >> ${rootfs_path}/etc/init.d/lxc-halt | |
212 | chmod 755 ${rootfs_path}/etc/init.d/lxc-halt | |
213 | ||
214 | # Link them into the rc directories... | |
215 | ( | |
216 | cd ${rootfs_path}/etc/rc.d/rc0.d | |
217 | ln -s ../init.d/lxc-halt S00lxc-halt | |
218 | cd ${rootfs_path}/etc/rc.d/rc6.d | |
219 | ln -s ../init.d/lxc-halt S00lxc-reboot | |
220 | ) | |
221 | fi | |
222 | ||
67660331 | 223 | # configure the network using the dhcp |
579ebf12 I |
224 | cat <<EOF > ${rootfs_path}/etc/sysconfig/network-scripts/ifcfg-eth0 |
225 | DEVICE=eth0 | |
226 | BOOTPROTO=dhcp | |
227 | ONBOOT=yes | |
b9b3a92f | 228 | HOSTNAME=${utsname} |
579ebf12 I |
229 | NM_CONTROLLED=no |
230 | TYPE=Ethernet | |
231 | MTU=${MTU} | |
54b1eb68 | 232 | EOF |
54b1eb68 | 233 | |
b6e91b67 | 234 | # set the hostname |
579ebf12 I |
235 | cat <<EOF > ${rootfs_path}/etc/sysconfig/network |
236 | NETWORKING=yes | |
b9b3a92f | 237 | HOSTNAME=${utsname} |
b6e91b67 | 238 | EOF |
54b1eb68 | 239 | |
627fe3b4 MW |
240 | # set hostname on systemd Fedora systems |
241 | if [ $release -gt 14 ]; then | |
b9b3a92f | 242 | echo "${utsname}" > ${rootfs_path}/etc/hostname |
627fe3b4 MW |
243 | fi |
244 | ||
579ebf12 I |
245 | # set minimal hosts |
246 | cat <<EOF > $rootfs_path/etc/hosts | |
b9b3a92f | 247 | 127.0.0.1 localhost.localdomain localhost $utsname |
627fe3b4 | 248 | ::1 localhost6.localdomain6 localhost6 |
b6e91b67 | 249 | EOF |
54b1eb68 | 250 | |
5266cf0a MW |
251 | # These mknod's really don't make any sense with modern releases of |
252 | # Fedora with systemd, devtmpfs, and autodev enabled. They are left | |
253 | # here for legacy reasons and older releases with upstart and sysv init. | |
579ebf12 I |
254 | dev_path="${rootfs_path}/dev" |
255 | rm -rf $dev_path | |
256 | mkdir -p $dev_path | |
257 | mknod -m 666 ${dev_path}/null c 1 3 | |
258 | mknod -m 666 ${dev_path}/zero c 1 5 | |
259 | mknod -m 666 ${dev_path}/random c 1 8 | |
260 | mknod -m 666 ${dev_path}/urandom c 1 9 | |
261 | mkdir -m 755 ${dev_path}/pts | |
262 | mkdir -m 1777 ${dev_path}/shm | |
263 | mknod -m 666 ${dev_path}/tty c 5 0 | |
264 | mknod -m 666 ${dev_path}/tty0 c 4 0 | |
265 | mknod -m 666 ${dev_path}/tty1 c 4 1 | |
266 | mknod -m 666 ${dev_path}/tty2 c 4 2 | |
267 | mknod -m 666 ${dev_path}/tty3 c 4 3 | |
268 | mknod -m 666 ${dev_path}/tty4 c 4 4 | |
269 | mknod -m 600 ${dev_path}/console c 5 1 | |
270 | mknod -m 666 ${dev_path}/full c 1 7 | |
271 | mknod -m 600 ${dev_path}/initctl p | |
272 | mknod -m 666 ${dev_path}/ptmx c 5 2 | |
273 | ||
1ecee40b MW |
274 | # setup console and tty[1-4] for login. note that /dev/console and |
275 | # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and | |
276 | # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks. | |
277 | # lxc will maintain these links and bind mount ptys over /dev/lxc/* | |
278 | # since lxc.devttydir is specified in the config. | |
279 | ||
280 | # allow root login on console, tty[1-4], and pts/0 for libvirt | |
281 | echo "# LXC (Linux Containers)" >>${rootfs_path}/etc/securetty | |
282 | echo "lxc/console" >>${rootfs_path}/etc/securetty | |
283 | echo "lxc/tty1" >>${rootfs_path}/etc/securetty | |
284 | echo "lxc/tty2" >>${rootfs_path}/etc/securetty | |
285 | echo "lxc/tty3" >>${rootfs_path}/etc/securetty | |
286 | echo "lxc/tty4" >>${rootfs_path}/etc/securetty | |
287 | echo "# For libvirt/Virtual Machine Monitor" >>${rootfs_path}/etc/securetty | |
288 | echo "pts/0" >>${rootfs_path}/etc/securetty | |
289 | ||
b4f7af7a MW |
290 | if [ ${root_display_password} = "yes" ] |
291 | then | |
292 | echo "Setting root password to '$root_password'" | |
293 | fi | |
294 | if [ ${root_store_password} = "yes" ] | |
295 | then | |
296 | touch ${config_path}/tmp_root_pass | |
297 | chmod 600 ${config_path}/tmp_root_pass | |
298 | echo ${root_password} > ${config_path}/tmp_root_pass | |
299 | echo "Storing root password in '${config_path}/tmp_root_pass'" | |
300 | fi | |
301 | ||
579ebf12 | 302 | echo "root:$root_password" | chroot $rootfs_path chpasswd |
826cde7c MW |
303 | |
304 | if [ ${root_expire_password} = "yes" ] | |
305 | then | |
306 | # Also set this password as expired to force the user to change it! | |
307 | chroot $rootfs_path passwd -e root | |
308 | fi | |
54b1eb68 | 309 | |
cb26f1a5 | 310 | # specifying this in the initial packages doesn't always work. |
449989ac | 311 | # Even though it should have... |
cb26f1a5 | 312 | echo "installing fedora-release package" |
449989ac MW |
313 | mount -o bind /dev ${rootfs_path}/dev |
314 | mount -t proc proc ${rootfs_path}/proc | |
315 | # Always make sure /etc/resolv.conf is up to date in the target! | |
316 | cp /etc/resolv.conf ${rootfs_path}/etc/ | |
317 | # Rebuild the rpm database based on the target rpm version... | |
318 | rm -f ${rootfs_path}/var/lib/rpm/__db* | |
319 | chroot ${rootfs_path} rpm --rebuilddb | |
320 | chroot ${rootfs_path} yum -y install fedora-release | |
67660331 MW |
321 | |
322 | if [[ ! -e ${rootfs_path}/sbin/NetworkManager ]] | |
323 | then | |
324 | # NetworkManager has not been installed. Use the | |
325 | # legacy chkconfig command to enable the network startup | |
326 | # scripts in the container. | |
327 | chroot ${rootfs_path} chkconfig network on | |
328 | fi | |
329 | ||
449989ac MW |
330 | umount ${rootfs_path}/proc |
331 | umount ${rootfs_path}/dev | |
cb26f1a5 SG |
332 | |
333 | # silence some needless startup errors | |
334 | touch ${rootfs_path}/etc/fstab | |
335 | ||
336 | # give us a console on /dev/console | |
337 | sed -i 's/ACTIVE_CONSOLES=.*$/ACTIVE_CONSOLES="\/dev\/console \/dev\/tty[1-4]"/' \ | |
338 | ${rootfs_path}/etc/sysconfig/init | |
339 | ||
b6e91b67 DL |
340 | return 0 |
341 | } | |
5266cf0a | 342 | |
f9d0d2cb I |
343 | configure_fedora_init() |
344 | { | |
345 | sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.sysinit | |
346 | sed -i 's|.sbin.start_udev||' ${rootfs_path}/etc/rc.d/rc.sysinit | |
cb26f1a5 SG |
347 | # don't mount devpts, for pete's sake |
348 | sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.sysinit | |
349 | sed -i 's/^.*dev.pts.*$/#\0/' ${rootfs_path}/etc/rc.d/rc.sysinit | |
f9d0d2cb I |
350 | chroot ${rootfs_path} chkconfig udev-post off |
351 | chroot ${rootfs_path} chkconfig network on | |
779b47fd MW |
352 | |
353 | if [ -d ${rootfs_path}/etc/init ] | |
354 | then | |
355 | # This is to make upstart honor SIGPWR. Should do no harm | |
356 | # on systemd systems and some systems may have both. | |
357 | cat <<EOF >${rootfs_path}/etc/init/power-status-changed.conf | |
358 | # power-status-changed - shutdown on SIGPWR | |
359 | # | |
360 | start on power-status-changed | |
361 | ||
362 | exec /sbin/shutdown -h now "SIGPWR received" | |
363 | EOF | |
364 | fi | |
f9d0d2cb I |
365 | } |
366 | ||
367 | configure_fedora_systemd() | |
368 | { | |
b4f7af7a | 369 | rm -f ${rootfs_path}/etc/systemd/system/default.target |
f9d0d2cb | 370 | touch ${rootfs_path}/etc/fstab |
5bb4a226 | 371 | chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/udev.service |
f9d0d2cb | 372 | chroot ${rootfs_path} ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target |
779b47fd | 373 | # Make systemd honor SIGPWR |
e5469dad | 374 | chroot ${rootfs_path} ln -s /usr/lib/systemd/system/halt.target /etc/systemd/system/sigpwr.target |
c2af3084 MA |
375 | |
376 | # if desired, prevent systemd from over-mounting /tmp with tmpfs | |
377 | if [ $masktmp -eq 1 ]; then | |
378 | chroot ${rootfs_path} ln -s /dev/null /etc/systemd/system/tmp.mount | |
379 | fi | |
380 | ||
f9d0d2cb | 381 | #dependency on a device unit fails it specially that we disabled udev |
d1240f03 MW |
382 | # sed -i 's/After=dev-%i.device/After=/' ${rootfs_path}/lib/systemd/system/getty\@.service |
383 | # | |
384 | # Actually, the After=dev-%i.device line does not appear in the | |
385 | # Fedora 17 or Fedora 18 systemd getty\@.service file. It may be left | |
386 | # over from an earlier version and it's not doing any harm. We do need | |
387 | # to disable the "ConditionalPathExists=/dev/tty0" line or no gettys are | |
388 | # started on the ttys in the container. Lets do it in an override copy of | |
389 | # the service so it can still pass rpm verifies and not be automatically | |
390 | # updated by a new systemd version. -- mhw /\/\|=mhw=|\/\/ | |
391 | ||
392 | sed -e 's/^ConditionPathExists=/# ConditionPathExists=/' \ | |
393 | -e 's/After=dev-%i.device/After=/' \ | |
8983aa6e SG |
394 | < ${rootfs_path}/lib/systemd/system/getty\@.service \ |
395 | > ${rootfs_path}/etc/systemd/system/getty\@.service | |
d1240f03 MW |
396 | # Setup getty service on the 4 ttys we are going to allow in the |
397 | # default config. Number should match lxc.tty | |
398 | ( cd ${rootfs_path}/etc/systemd/system/getty.target.wants | |
399 | for i in 1 2 3 4 ; do ln -sf ../getty\@.service getty@tty${i}.service; done ) | |
f9d0d2cb | 400 | } |
54b1eb68 | 401 | |
449989ac MW |
402 | ### BEGIN Bootstrap Environment Code... Michael H. Warfield /\/\|=mhw=|\/\/ |
403 | ||
404 | # Ok... Heads up. If you're reading these comments, you're either a | |
405 | # template owner or someone wondering how the hell I did this (or, worse, | |
406 | # someone in the future trying to maintain it). This code is slightly | |
407 | # "evil coding bastard" code with one significant hack / dirty trick | |
408 | # that you would probably miss just reading the code below. I'll mark | |
409 | # it out with comments. | |
0655a606 | 410 | # |
449989ac MW |
411 | # Because of what this code does, it deserves a lot of comments so people |
412 | # can understand WHY I did it this way... | |
413 | # | |
414 | # Ultimate Objective - Build a Fedora container on a host system which does | |
415 | # not have a (complete compatible) version of rpm and/or yum. That basically | |
416 | # means damn near any distro other than Fedora and Ubuntu (which has rpm and | |
417 | # yum available). Only requirements for this function are rsync and | |
418 | # squashfs available to the kernel. If you don't have those, why are you | |
419 | # even attempting to build containers? | |
420 | # | |
421 | # Challenge for this function - Bootstrap a Fedora install bootstrap | |
422 | # run time environment which has all the pieces to run rpm and yum and | |
423 | # from which we can build targets containers even where the host system | |
424 | # has no support for rpm, yum, or fedora. | |
425 | # | |
426 | # Steps: | |
427 | # Stage 0 - Download a Fedora LiveOS squashfs core (netinst core). | |
428 | # Stage 1 - Extract filesystem from Stage 0 and update to full rpm & yum | |
429 | # Stage 2 - Use Stage 1 to build a rootfs with python, rpm, and yum. | |
430 | # | |
431 | # Stage 2 becomes our bootstrap file system which can be cached | |
432 | # and then used to build other arbitrary vesions of Fedora of a | |
08754f30 | 433 | # given architecture. Note that this only has to run once for |
449989ac | 434 | # Fedora on a given architecture since rpm and yum can build other |
1ecee40b | 435 | # versions. We'll arbitrarily pick Fedora 20 to build this. This |
449989ac MW |
436 | # will need to change as time goes on. |
437 | ||
438 | # Programmers Note... A future fall back may be to download the netinst | |
439 | # iso image instead of the LiveOS squasfs image and work from that. | |
440 | # That may be more general but will introduce another substep | |
441 | # (mounting the iso) to the stage0 setup. | |
442 | ||
443 | # This system is designed to be as autonomous as possible so all whitelists | |
ec64264d | 444 | # and controls are self-contained. |
449989ac MW |
445 | |
446 | # Initial testing - Whitelist nobody. Build for everybody... | |
447 | # Initial deployment - Whitelist Fedora. | |
448 | # Long term - Whitelist Fedora, Debian, Ubuntu, CentOs, Scientific, and NST. | |
449 | ||
450 | # List of distros which do not (should not) need a bootstrap (but we will test | |
451 | # for rpm and yum none the less... OS SHOULD be taken from CPE values but | |
452 | # Debian / Ubuntu doesn't support CPE yet. | |
453 | ||
454 | # BOOTSTRAP_WHITE_LIST="" | |
455 | BOOTSTRAP_WHITE_LIST="fedora" | |
456 | # BOOTSTRAP_WHITE_LIST="fedora debian ubuntu centos scientific sl nst" | |
457 | ||
458 | BOOTSTRAP=0 | |
459 | BOOTSTRAP_DIR= | |
460 | BOOTSTRAP_CHROOT= | |
461 | ||
462 | fedora_get_bootstrap() | |
463 | { | |
464 | echo "Bootstrap Environment testing..." | |
465 | ||
466 | WHITE_LISTED=1 | |
467 | ||
468 | # We need rpm. No rpm - not possible to white list... | |
469 | if ! which rpm > /dev/null 2>&1 | |
470 | then | |
471 | WHITE_LISTED=0 | |
472 | fi | |
473 | ||
474 | # We need yum No yum - not possible to white list... | |
475 | if ! which yum > /dev/null 2>&1 | |
476 | then | |
477 | WHITE_LISTED=0 | |
478 | fi | |
479 | ||
480 | if [[ ${WHITE_LISTED} != 0 ]] | |
481 | then | |
482 | for OS in ${BOOTSTRAP_WHITE_LIST} | |
483 | do | |
484 | if [[ ${ID} = ${OS} ]] | |
485 | then | |
486 | echo " | |
487 | OS ${ID} is whitelisted. Installation Bootstrap Environment not required. | |
488 | " | |
489 | return 0; | |
490 | fi | |
491 | done | |
492 | fi | |
493 | ||
494 | echo " | |
495 | Fedora Installation Bootstrap Build..." | |
496 | ||
497 | if ! which rsync > /dev/null 2>&1 | |
498 | then | |
499 | echo " | |
500 | Unable to locate rsync. Cravely bailing out before even attempting to build | |
501 | an Installation Bootstrap Please install rsync and then rerun this process. | |
502 | " | |
503 | ||
504 | return 255 | |
505 | fi | |
506 | ||
507 | [[ -d ${cache_base} ]] || mkdir -p ${cache_base} | |
508 | ||
509 | cd ${cache_base} | |
510 | ||
511 | # We know we don't have a cache directory of this version or we | |
512 | # would have never reached this code to begin with. But we may | |
513 | # have another Fedora cache directory from which we could run... | |
ec64264d | 514 | # We'll give a preference for close matches preferring higher over |
449989ac MW |
515 | # lower - which makes for really ugly code... |
516 | ||
517 | # Is this a "bashism" that will need cleaning up???? | |
518 | BOOTSTRAP_LIST="$(( $release + 1 ))/rootfs $(( $release - 1 ))/rootfs \ | |
519 | $(( $release + 2 ))/rootfs $(( $release - 2 ))/rootfs \ | |
520 | $(( $release + 3 ))/rootfs $(( $release - 3 ))/rootfs \ | |
521 | bootstrap" | |
522 | ||
523 | for bootstrap in ${BOOTSTRAP_LIST} | |
524 | do | |
525 | if [[ -d ${bootstrap} ]] | |
526 | then | |
527 | echo " | |
528 | Existing Bootstrap found. Testing..." | |
529 | ||
530 | mount -o bind /dev ${bootstrap}/dev | |
531 | mount -t proc proc ${bootstrap}/proc | |
532 | # Always make sure /etc/resolv.conf is up to date in the target! | |
533 | cp /etc/resolv.conf ${bootstrap}/etc/ | |
534 | rm -f ${bootstrap}/var/lib/rpm/__db* | |
535 | chroot ${bootstrap} rpm --rebuilddb | |
536 | chroot ${bootstrap} yum -y update | |
537 | RC=$? | |
538 | umount ${bootstrap}/proc | |
539 | umount ${bootstrap}/dev | |
540 | ||
541 | if [[ 0 == ${RC} ]] | |
542 | then | |
543 | BOOTSTRAP=1 | |
544 | BOOTSTRAP_DIR="${cache_base}/${bootstrap}" | |
545 | BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} " | |
546 | BOOTSTRAP_INSTALL_ROOT=/run/install | |
547 | ||
548 | echo " | |
549 | Functional Installation Bootstrap exists and appears to be completed. | |
550 | Will use existing Bootstrap: ${BOOTSTRAP_DIR} | |
551 | " | |
552 | return 0 | |
553 | fi | |
554 | echo " | |
555 | Installation Bootstrap in ${BOOTSTRAP_DIR} exists | |
556 | but appears to be non-functional. Skipping... It should be removed. | |
557 | " | |
558 | fi | |
559 | done | |
560 | ||
561 | TMP_BOOTSTRAP_DIR=$( mktemp -d --tmpdir=${cache_base} bootstrap_XXXXXX ) | |
562 | ||
563 | cd ${TMP_BOOTSTRAP_DIR} | |
564 | ||
565 | mkdir squashfs stage0 stage1 bootstrap | |
566 | ||
567 | ### Stage 0 setup. | |
568 | # Download the LiveOS squashfs image | |
569 | # mount image to "squashfs" | |
570 | # mount contained LiveOS to stage0 | |
571 | ||
572 | # We're going to use the kernel.org mirror for the initial stages... | |
573 | # 1 - It's generally up to date and comnplete | |
574 | # 2 - It's has high bandwidth access | |
575 | # 3 - It supports rsync and wildcarding (and we need both) | |
576 | # 4 - Not all the mirrors carry the LiveOS images | |
577 | ||
578 | if [[ ! -f ../LiveOS/squashfs.img ]] | |
579 | then | |
580 | echo " | |
581 | Downloading stage 0 LiveOS squashfs file system from mirrors.kernel.org... | |
582 | Have a beer or a cup of coffee. This will take a bit (~300MB). | |
583 | " | |
584 | sleep 3 # let him read it... | |
585 | ||
1ecee40b | 586 | # Right now, we are using Fedora 20 for the inial bootstrap. |
449989ac MW |
587 | # We could make this the "current" Fedora rev (F > 15). |
588 | ||
08754f30 | 589 | rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/LiveOS . |
449989ac MW |
590 | |
591 | if [[ 0 == $? ]] | |
592 | then | |
593 | echo "Download of squashfs image complete." | |
594 | mv LiveOS .. | |
595 | else | |
596 | echo " | |
597 | Download of squashfs image failed. | |
598 | " | |
599 | return 255 | |
600 | fi | |
601 | else | |
602 | echo "Using cached stage 0 LiveOS squashfs file system." | |
603 | fi | |
604 | ||
605 | mount -o loop ../LiveOS/squashfs.img squashfs | |
606 | ||
607 | if [[ $? != 0 ]] | |
608 | then | |
609 | echo " | |
610 | Mount of LiveOS squashfs image failed! You mush have squashfs support | |
611 | available to mount image. Unable to continue. Correct and retry | |
612 | process later! LiveOS image not removed. Process may be rerun | |
613 | without penalty of downloading LiveOS again. If LiveOS is corrupt, | |
614 | remove ${cache_base}/LiveOS before rerunning to redownload. | |
615 | " | |
616 | return 255 | |
617 | fi | |
618 | ||
619 | mount -o loop squashfs/LiveOS/rootfs.img stage0 | |
620 | ||
621 | if [[ $? != 0 ]] | |
622 | then | |
623 | echo " | |
624 | Mount of LiveOS stage0 rootfs image failed! LiveOS download may be corrupt. | |
625 | Remove ${cache_base}/LiveOS to force a new download or | |
626 | troubleshoot cached image and then rerun process. | |
627 | " | |
628 | return 255 | |
629 | fi | |
630 | ||
631 | ||
632 | ### Stage 1 setup. | |
633 | # Copy stage0 (which is ro) to stage1 area (rw) for modification. | |
634 | # Unmount stage0 mounts - we're done with stage 0 at this point. | |
635 | # Download our rpm and yum rpm packages. | |
636 | # Force install of rpm and yum into stage1 image (dirty hack!) | |
637 | ||
638 | echo "Stage 0 complete, building Stage 1 image... | |
639 | This will take a couple of minutes. Patience..." | |
640 | ||
641 | echo "Creating Stage 1 r/w copy of r/o Stage 0 squashfs image from LiveOS." | |
642 | ||
643 | rsync -aAHS stage0/. stage1/ | |
644 | ||
645 | umount stage0 | |
646 | umount squashfs | |
647 | ||
648 | cd stage1 | |
649 | ||
650 | # Setup stage1 image with pieces to run installs... | |
651 | ||
652 | ||
653 | mount -o bind /dev dev | |
654 | mount -t proc proc proc | |
655 | # Always make sure /etc/resolv.conf is up to date in the target! | |
656 | cp /etc/resolv.conf etc/ | |
657 | ||
658 | mkdir run/install | |
659 | ||
660 | echo "Updating Stage 1 image with full rpm and yum packages" | |
661 | ||
662 | # Retrieve our 2 rpm packages we need to force down the throat | |
663 | # of this LiveOS image we're camped out on. This is the beginning | |
664 | # of the butt ugly hack. Look close or you may missing it... | |
665 | ||
08754f30 MW |
666 | rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/Packages/r/rpm-[0-9]* \ |
667 | mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/Packages/y/yum-[0-9]* . | |
449989ac MW |
668 | |
669 | # And here it is... | |
670 | # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! | |
671 | chroot . rpm -ivh --nodeps rpm-* yum-* | |
672 | # Did you catch it? | |
673 | ||
674 | # The LiveOS image contains rpm (but not rpmdb) and yum (but not | |
675 | # yummain.py - What the hell good does yum do with no | |
676 | # yummain.py?!?! - Sigh...). It contains all the supporting | |
677 | # pieces but the rpm database has not be initialized and it | |
678 | # doesn't know all the dependences (seem to) have been met. | |
679 | # So we do a "--nodeps" rpm install in the chrooted environment | |
680 | # to force the installation of the full rpm and yum packages. | |
681 | # | |
682 | # For the purists - Yes, I know the rpm database is wildly out | |
683 | # of whack now. That's why this is a butt ugly hack / dirty trick. | |
684 | # But, this is just the stage1 image that we are going to discard as | |
685 | # soon as the stage2 image is built, so we don't care. All we care | |
686 | # is that the stage2 image ends up with all the pieces it need to | |
687 | # run yum and rpm and that the stage2 rpm database is coherent. | |
688 | # | |
689 | # NOW we can really go to work! | |
690 | ||
691 | ### Stage 2 setup. | |
692 | # Download our Fedora Release rpm packages. | |
693 | # Install fedora-release into bootstrap to initialize fs and databases. | |
694 | # Install rpm, and yum into bootstrap image using yum | |
695 | ||
696 | echo "Stage 1 creation complete. Building stage 2 Installation Bootstrap" | |
697 | ||
698 | mount -o bind ../bootstrap run/install | |
08754f30 | 699 | rsync -av mirrors.kernel.org::fedora/releases/20/Fedora/$basearch/os/Packages/f/fedora-release-20* . |
449989ac MW |
700 | |
701 | # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! | |
702 | chroot . rpm --root /run/install --nodeps -ivh fedora-release-* | |
08754f30 MW |
703 | |
704 | # yum will take $basearch from host, so force the arch we want | |
dfb2291e | 705 | sed -i "s|\$basearch|$basearch|" ./run/install/etc/yum.repos.d/* |
08754f30 | 706 | |
449989ac MW |
707 | chroot . yum -y --nogpgcheck --installroot /run/install install python rpm yum |
708 | ||
709 | umount run/install | |
710 | umount proc | |
711 | umount dev | |
712 | ||
713 | # That's it! We should now have a viable installation BOOTSTRAP in | |
714 | # bootstrap We'll do a yum update in that to verify and then | |
715 | # move it to the cache location before cleaning up. | |
716 | ||
717 | cd ../bootstrap | |
718 | mount -o bind /dev dev | |
719 | mount -t proc proc proc | |
720 | # Always make sure /etc/resolv.conf is up to date in the target! | |
721 | cp /etc/resolv.conf etc/ | |
722 | ||
08754f30 MW |
723 | # yum will take $basearch from host, so force the arch we want |
724 | sed -i "s|\$basearch|$basearch|" ./etc/yum.repos.d/* | |
725 | ||
449989ac MW |
726 | chroot . yum -y update |
727 | ||
728 | RC=$? | |
729 | ||
730 | umount proc | |
731 | umount dev | |
732 | ||
733 | cd .. | |
734 | ||
735 | if [[ ${RC} != 0 ]] | |
736 | then | |
737 | echo " | |
738 | Build of Installation Bootstrap failed. Temp directory | |
739 | not removed so it can be investigated. | |
740 | " | |
741 | return 255 | |
742 | fi | |
743 | ||
744 | # We know have a working run time environment in rootfs... | |
745 | mv bootstrap .. | |
746 | cd .. | |
747 | rm -rf ${TMP_BOOTSTRAP_DIR} | |
748 | ||
749 | echo " | |
750 | Build of Installation Bootstrap complete! We now return you to your | |
751 | normally scheduled template creation. | |
752 | " | |
753 | ||
754 | BOOTSTRAP=1 | |
755 | BOOTSTRAP_DIR="${cache_base}/bootstrap" | |
756 | BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} " | |
757 | BOOTSTRAP_INSTALL_ROOT=/run/install | |
758 | ||
759 | return 0 | |
760 | } | |
761 | ||
762 | ||
763 | fedora_bootstrap_mounts() | |
764 | { | |
765 | if [[ ${BOOTSTRAP} -ne 1 ]] | |
766 | then | |
767 | return 0 | |
768 | fi | |
769 | ||
770 | BOOTSTRAP_CHROOT="chroot ${BOOTSTRAP_DIR} " | |
771 | ||
772 | echo "Mounting Bootstrap mount points" | |
773 | ||
774 | [[ -d ${BOOTSTRAP_DIR}/run/install ]] || mkdir -p ${BOOTSTRAP_DIR}/run/install | |
775 | ||
776 | mount -o bind ${INSTALL_ROOT} ${BOOTSTRAP_DIR}/run/install | |
777 | mount -o bind /dev ${BOOTSTRAP_DIR}/dev | |
778 | mount -t proc proc ${BOOTSTRAP_DIR}/proc | |
779 | # Always make sure /etc/resolv.conf is up to date in the target! | |
780 | cp /etc/resolv.conf ${BOOTSTRAP_DIR}/etc/ | |
781 | } | |
782 | ||
783 | fedora_bootstrap_umounts() | |
784 | { | |
785 | if [[ ${BOOTSTRAP} -ne 1 ]] | |
786 | then | |
787 | return 0 | |
788 | fi | |
789 | ||
790 | umount ${BOOTSTRAP_DIR}/proc | |
791 | umount ${BOOTSTRAP_DIR}/dev | |
792 | umount ${BOOTSTRAP_DIR}/run/install | |
793 | } | |
794 | ||
795 | ||
796 | # This is the code to create the initial roofs for Fedora. It may | |
797 | # require a run time environment by calling the routines above... | |
798 | ||
b6e91b67 DL |
799 | download_fedora() |
800 | { | |
b44cb779 | 801 | |
b6e91b67 | 802 | # check the mini fedora was not already downloaded |
579ebf12 I |
803 | INSTALL_ROOT=$cache/partial |
804 | mkdir -p $INSTALL_ROOT | |
b6e91b67 | 805 | if [ $? -ne 0 ]; then |
14d9c0f0 SG |
806 | echo "Failed to create '$INSTALL_ROOT' directory" |
807 | return 1 | |
b44cb779 RT |
808 | fi |
809 | ||
b6e91b67 DL |
810 | # download a mini fedora into a cache |
811 | echo "Downloading fedora minimal ..." | |
449989ac | 812 | |
0655a606 | 813 | # These will get changed if it's decided that we need a |
dfb2291e MW |
814 | # boostrap environment (can not build natively). These |
815 | # are the defaults for the non-boostrap (native) mode. | |
449989ac MW |
816 | |
817 | BOOTSTRAP_INSTALL_ROOT=${INSTALL_ROOT} | |
818 | BOOTSTRAP_CHROOT= | |
dfb2291e | 819 | BOOTSTRAP_DIR= |
449989ac | 820 | |
5266cf0a | 821 | PKG_LIST="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils fedora-release" |
08754f30 | 822 | MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$basearch" |
7bd44bf6 | 823 | |
449989ac MW |
824 | if [[ ${release} -lt 17 ]] |
825 | then | |
826 | # The reflects the move of db_dump and db_load from db4_utils to | |
827 | # libdb_utils in Fedora 17 and above and it's inclusion as a dep... | |
828 | # Prior to Fedora 11, we need to explicitly include it! | |
829 | PKG_LIST="${PKG_LIST} db4-utils" | |
830 | fi | |
831 | ||
afc55ed2 MA |
832 | if [[ ${release} -ge 21 ]] |
833 | then | |
834 | # Since Fedora 21, a separate fedora-repos package is needed. | |
835 | # Before, the information was conained in fedora-release. | |
836 | PKG_LIST="${PKG_LIST} fedora-repos" | |
837 | fi | |
838 | ||
7bd44bf6 | 839 | DOWNLOAD_OK=no |
b9b3a92f MW |
840 | |
841 | # We're splitting the old loop into two loops plus a directory retrival. | |
842 | # First loop... Try and retrive a mirror list with retries and a slight | |
843 | # delay between attempts... | |
844 | for trynumber in 1 2 3 4; do | |
7bd44bf6 | 845 | [ $trynumber != 1 ] && echo "Trying again..." |
8983aa6e | 846 | # This code is mildly "brittle" in that it assumes a certain |
b9b3a92f MW |
847 | # page format and parsing HTML. I've done worse. :-P |
848 | MIRROR_URLS=$(curl -s -S -f "$MIRRORLIST_URL" | sed -e '/^http:/!d' -e '2,6!d') | |
849 | if [ $? -eq 0 ] && [ -n "$MIRROR_URLS" ] | |
850 | then | |
8983aa6e SG |
851 | break |
852 | fi | |
b9b3a92f MW |
853 | |
854 | echo "Failed to get a mirror on try $trynumber" | |
855 | sleep 3 | |
856 | done | |
857 | ||
858 | # This will fall through if we didn't get any URLS above | |
859 | for MIRROR_URL in ${MIRROR_URLS} | |
860 | do | |
449989ac | 861 | if [ "$release" -gt "16" ]; then |
b9b3a92f | 862 | RELEASE_URL="$MIRROR_URL/Packages/f" |
29e18143 | 863 | else |
b9b3a92f MW |
864 | RELEASE_URL="$MIRROR_URL/Packages/" |
865 | fi | |
866 | ||
afc55ed2 | 867 | echo "Fetching release rpm name from $RELEASE_URL..." |
8983aa6e | 868 | # This code is mildly "brittle" in that it assumes a certain directory |
b9b3a92f | 869 | # page format and parsing HTML. I've done worse. :-P |
8983aa6e | 870 | RELEASE_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-release-${release}-/!d" -e 's/.*<a href=\"//' -e 's/\">.*//' ) |
b9b3a92f MW |
871 | if [ $? -ne 0 -o "${RELEASE_RPM}" = "" ]; then |
872 | echo "Failed to identify fedora release rpm." | |
873 | continue | |
29e18143 | 874 | fi |
b9b3a92f MW |
875 | |
876 | echo "Fetching fedora release rpm from ${RELEASE_URL}/${RELEASE_RPM}......" | |
877 | curl -L -f "${RELEASE_URL}/${RELEASE_RPM}" > ${INSTALL_ROOT}/${RELEASE_RPM} | |
7bd44bf6 | 878 | if [ $? -ne 0 ]; then |
b9b3a92f | 879 | echo "Failed to download fedora release rpm ${RELEASE_RPM}." |
7bd44bf6 TS |
880 | continue |
881 | fi | |
b9b3a92f | 882 | |
afc55ed2 MA |
883 | # F21 and newer need fedora-repos in addition to fedora-release. |
884 | if [ "$release" -ge "21" ]; then | |
885 | echo "Fetching repos rpm name from $RELEASE_URL..." | |
886 | REPOS_RPM=$(curl -L -f "$RELEASE_URL" | sed -e "/fedora-repos-${release}-/!d" -e 's/.*<a href=\"//' -e 's/\">.*//' ) | |
887 | if [ $? -ne 0 -o "${REPOS_RPM}" = "" ]; then | |
888 | echo "Failed to identify fedora repos rpm." | |
889 | continue | |
890 | fi | |
891 | ||
892 | echo "Fetching fedora repos rpm from ${RELEASE_URL}/${REPOS_RPM}..." | |
893 | curl -L -f "${RELEASE_URL}/${REPOS_RPM}" > ${INSTALL_ROOT}/${REPOS_RPM} | |
894 | if [ $? -ne 0 ]; then | |
895 | echo "Failed to download fedora repos rpm ${RELEASE_RPM}." | |
896 | continue | |
897 | fi | |
898 | fi | |
899 | ||
900 | ||
7bd44bf6 TS |
901 | DOWNLOAD_OK=yes |
902 | break | |
903 | done | |
b9b3a92f | 904 | |
7bd44bf6 TS |
905 | if [ $DOWNLOAD_OK != yes ]; then |
906 | echo "Aborting" | |
907 | return 1 | |
908 | fi | |
579ebf12 | 909 | |
449989ac | 910 | mkdir -p ${INSTALL_ROOT}/var/lib/rpm |
579ebf12 | 911 | |
449989ac MW |
912 | if ! fedora_get_bootstrap |
913 | then | |
914 | echo "Fedora Bootstrap setup failed" | |
915 | return 1 | |
916 | fi | |
917 | ||
918 | fedora_bootstrap_mounts | |
919 | ||
920 | ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --initdb | |
afc55ed2 | 921 | |
449989ac MW |
922 | # The --nodeps is STUPID but F15 had a bogus dependency on RawHide?!?! |
923 | ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} --nodeps -ivh ${BOOTSTRAP_INSTALL_ROOT}/${RELEASE_RPM} | |
08754f30 | 924 | |
afc55ed2 MA |
925 | # F21 and newer need fedora-repos in addition to fedora-release... |
926 | # Note that fedora-release and fedora-system have a mutual dependency. | |
927 | # So installing the reops package after the release package we can | |
928 | # spare one --nodeps. | |
929 | if [ "$release" -ge "21" ]; then | |
930 | ${BOOTSTRAP_CHROOT}rpm --root ${BOOTSTRAP_INSTALL_ROOT} -ivh ${BOOTSTRAP_INSTALL_ROOT}/${REPOS_RPM} | |
931 | fi | |
932 | ||
08754f30 | 933 | # yum will take $basearch from host, so force the arch we want |
dfb2291e | 934 | sed -i "s|\$basearch|$basearch|" ${BOOTSTRAP_DIR}/${BOOTSTRAP_INSTALL_ROOT}/etc/yum.repos.d/* |
08754f30 | 935 | |
449989ac MW |
936 | ${BOOTSTRAP_CHROOT}yum --installroot ${BOOTSTRAP_INSTALL_ROOT} -y --nogpgcheck install ${PKG_LIST} |
937 | ||
938 | RC=$? | |
939 | ||
940 | if [[ ${BOOTSTRAP} -eq 1 ]] | |
941 | then | |
942 | # Here we have a bit of a sticky problem. We MIGHT have just installed | |
943 | # this template cache using versions of yum and rpm in the bootstrap | |
944 | # chroot that use a different database version than the target version. | |
945 | # That can be a very big problem. Solution is to rebuild the rpmdatabase | |
946 | # with the target database now that we are done building the cache. In the | |
947 | # vast majority of cases, this is a do-not-care with no harm done if we | |
948 | # didn't do it. But it catches several corner cases with older unsupported | |
949 | # releases and it really doesn't cost us a lot of time for a one shot | |
950 | # install that will never be done again for this rev. | |
951 | # | |
952 | # Thanks and appreciation to Dwight Engen and the Oracle template for the | |
953 | # database rewrite hint! | |
954 | ||
955 | echo "Fixing up rpm databases" | |
956 | ||
957 | # Change to our target install directory (if we're not already | |
958 | # there) just to simplify some of the logic to follow... | |
959 | cd ${INSTALL_ROOT} | |
960 | ||
961 | rm -f var/lib/rpm/__db* | |
962 | # Programmers Note (warning): | |
963 | # | |
964 | # Pay careful attention to the following commands! It | |
965 | # crosses TWO chroot boundaries linked by a bind mount! | |
966 | # In the bootstrap case, that's the bind mount of ${INSTALL_ROOT} | |
967 | # to the ${BOOTSTRAP_CHROOT}/run/install directory! This is | |
968 | # a deliberate hack across that bind mount to do a database | |
969 | # translation between two environments, neither of which may | |
970 | # be the host environment! It's ugly and hard to follow but, | |
971 | # if you don't understand it, don't mess with it! The pipe | |
972 | # is in host space between the two chrooted environments! | |
973 | # This is also why we cd'ed into the INSTALL_ROOT directory | |
974 | # in advance of this loop, so everything is relative to the | |
975 | # current working directory and congruent with the same working | |
976 | # space in both chrooted environments. The output into the new | |
977 | # db is also done in INSTALL_ROOT space but works in either host | |
978 | # space or INSTALL_ROOT space for the mv, so we don't care. It's | |
979 | # just not obvious what's happening in the db_dump and db_load | |
980 | # commands... | |
981 | # | |
982 | for db in var/lib/rpm/* ; do | |
983 | ${BOOTSTRAP_CHROOT} db_dump ${BOOTSTRAP_INSTALL_ROOT}/$db | chroot . db_load $db.new | |
984 | mv $db.new $db | |
985 | done | |
986 | # finish up by rebuilding the database... | |
987 | # This should be redundant but we do it for completeness and | |
988 | # any corner cases I may have missed... | |
989 | mount -t proc proc proc | |
990 | mount -o bind /dev dev | |
991 | chroot . rpm --rebuilddb | |
992 | umount dev | |
993 | umount proc | |
994 | fi | |
995 | ||
996 | fedora_bootstrap_umounts | |
997 | ||
998 | if [ ${RC} -ne 0 ]; then | |
14d9c0f0 SG |
999 | echo "Failed to download the rootfs, aborting." |
1000 | return 1 | |
54b1eb68 MH |
1001 | fi |
1002 | ||
579ebf12 | 1003 | mv "$INSTALL_ROOT" "$cache/rootfs" |
b6e91b67 | 1004 | echo "Download complete." |
54b1eb68 | 1005 | |
b6e91b67 DL |
1006 | return 0 |
1007 | } | |
54b1eb68 | 1008 | |
b6e91b67 DL |
1009 | copy_fedora() |
1010 | { | |
54b1eb68 | 1011 | |
b6e91b67 | 1012 | # make a local copy of the minifedora |
579ebf12 | 1013 | echo -n "Copying rootfs to $rootfs_path ..." |
08754f30 | 1014 | #cp -a $cache/rootfs-$basearch $rootfs_path || return 1 |
579ebf12 I |
1015 | # i prefer rsync (no reason really) |
1016 | mkdir -p $rootfs_path | |
44d39789 | 1017 | rsync -Ha $cache/rootfs/ $rootfs_path/ |
b4f7af7a | 1018 | echo |
b6e91b67 | 1019 | return 0 |
54b1eb68 MH |
1020 | } |
1021 | ||
579ebf12 I |
1022 | update_fedora() |
1023 | { | |
449989ac MW |
1024 | mount -o bind /dev ${cache}/rootfs/dev |
1025 | mount -t proc proc ${cache}/rootfs/proc | |
1026 | # Always make sure /etc/resolv.conf is up to date in the target! | |
1027 | cp /etc/resolv.conf ${cache}/rootfs/etc/ | |
1028 | chroot ${cache}/rootfs yum -y update | |
1029 | umount ${cache}/rootfs/proc | |
1030 | umount ${cache}/rootfs/dev | |
579ebf12 I |
1031 | } |
1032 | ||
b6e91b67 DL |
1033 | install_fedora() |
1034 | { | |
e29bf450 | 1035 | mkdir -p @LOCALSTATEDIR@/lock/subsys/ |
b6e91b67 | 1036 | ( |
1ecee40b | 1037 | flock -x 9 |
14d9c0f0 SG |
1038 | if [ $? -ne 0 ]; then |
1039 | echo "Cache repository is busy." | |
1040 | return 1 | |
1041 | fi | |
1042 | ||
1043 | echo "Checking cache download in $cache/rootfs ... " | |
1044 | if [ ! -e "$cache/rootfs" ]; then | |
1045 | download_fedora | |
1046 | if [ $? -ne 0 ]; then | |
1047 | echo "Failed to download 'fedora base'" | |
1048 | return 1 | |
1049 | fi | |
579ebf12 | 1050 | else |
14d9c0f0 | 1051 | echo "Cache found. Updating..." |
579ebf12 | 1052 | update_fedora |
14d9c0f0 SG |
1053 | if [ $? -ne 0 ]; then |
1054 | echo "Failed to update 'fedora base', continuing with last known good cache" | |
579ebf12 I |
1055 | else |
1056 | echo "Update finished" | |
14d9c0f0 SG |
1057 | fi |
1058 | fi | |
54b1eb68 | 1059 | |
14d9c0f0 SG |
1060 | echo "Copy $cache/rootfs to $rootfs_path ... " |
1061 | copy_fedora | |
1062 | if [ $? -ne 0 ]; then | |
1063 | echo "Failed to copy rootfs" | |
1064 | return 1 | |
1065 | fi | |
54b1eb68 | 1066 | |
14d9c0f0 | 1067 | return 0 |
1ecee40b | 1068 | ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-fedora |
54b1eb68 | 1069 | |
b6e91b67 | 1070 | return $? |
54b1eb68 MH |
1071 | } |
1072 | ||
b4f7af7a MW |
1073 | # Generate a random hardware (MAC) address composed of FE followed by |
1074 | # 5 random bytes... | |
1075 | create_hwaddr() | |
b6e91b67 | 1076 | { |
08754f30 | 1077 | openssl rand -hex 5 | sed -e 's/\(..\)/:\1/g; s/^/fe/' |
b4f7af7a | 1078 | } |
54b1eb68 | 1079 | |
b4f7af7a MW |
1080 | copy_configuration() |
1081 | { | |
579ebf12 | 1082 | mkdir -p $config_path |
b4f7af7a MW |
1083 | |
1084 | grep -q "^lxc.rootfs" $config_path/config 2>/dev/null || echo " | |
1085 | lxc.rootfs = $rootfs_path | |
1086 | " >> $config_path/config | |
1087 | ||
1088 | # The following code is to create static MAC addresses for each | |
1089 | # interface in the container. This code will work for multiple | |
1090 | # interfaces in the default config. It will also strip any | |
1091 | # hwaddr stanzas out of the default config since we can not share | |
1092 | # MAC addresses between containers. | |
1093 | mv $config_path/config $config_path/config.def | |
1094 | while read LINE | |
1095 | do | |
1096 | # This should catch variable expansions from the default config... | |
1097 | if expr "${LINE}" : '.*\$' > /dev/null 2>&1 | |
1098 | then | |
1099 | LINE=$(eval "echo \"${LINE}\"") | |
1100 | fi | |
1101 | ||
1102 | # There is a tab and a space in the regex bracket below! | |
1103 | # Seems that \s doesn't work in brackets. | |
1104 | KEY=$(expr "${LINE}" : '\s*\([^ ]*\)\s*=') | |
1105 | ||
1106 | if [[ "${KEY}" != "lxc.network.hwaddr" ]] | |
1107 | then | |
1108 | echo "${LINE}" >> $config_path/config | |
1109 | ||
1110 | if [[ "${KEY}" == "lxc.network.link" ]] | |
1111 | then | |
1112 | echo "lxc.network.hwaddr = $(create_hwaddr)" >> $config_path/config | |
1113 | fi | |
1114 | fi | |
1115 | done < $config_path/config.def | |
1116 | ||
1117 | rm -f $config_path/config.def | |
1118 | ||
1ecee40b MW |
1119 | if [ -e "@LXCTEMPLATECONFIG@/fedora.common.conf" ]; then |
1120 | echo " | |
1121 | # Include common configuration | |
1122 | lxc.include = @LXCTEMPLATECONFIG@/fedora.common.conf | |
1123 | " >> $config_path/config | |
1124 | fi | |
1125 | ||
1126 | # Append things which require expansion here... | |
579ebf12 | 1127 | cat <<EOF >> $config_path/config |
e13923c7 | 1128 | lxc.arch = $arch |
b9b3a92f | 1129 | lxc.utsname = $utsname |
f02ce27d SG |
1130 | |
1131 | # When using LXC with apparmor, uncomment the next line to run unconfined: | |
1132 | #lxc.aa_profile = unconfined | |
1133 | ||
b4f7af7a MW |
1134 | # example simple networking setup, uncomment to enable |
1135 | #lxc.network.type = $lxc_network_type | |
1136 | #lxc.network.flags = up | |
1137 | #lxc.network.link = $lxc_network_link | |
1138 | #lxc.network.name = eth0 | |
1139 | # Additional example for veth network type | |
1140 | # static MAC address, | |
1141 | #lxc.network.hwaddr = 00:16:3e:77:52:20 | |
1142 | # persistent veth device name on host side | |
1143 | # Note: This may potentially collide with other containers of same name! | |
1144 | #lxc.network.veth.pair = v-$name-e0 | |
1145 | ||
a30ce0ac | 1146 | EOF |
b4f7af7a | 1147 | |
b6e91b67 | 1148 | if [ $? -ne 0 ]; then |
14d9c0f0 SG |
1149 | echo "Failed to add configuration" |
1150 | return 1 | |
b6e91b67 | 1151 | fi |
54b1eb68 | 1152 | |
b6e91b67 | 1153 | return 0 |
54b1eb68 MH |
1154 | } |
1155 | ||
b6e91b67 DL |
1156 | clean() |
1157 | { | |
54b1eb68 | 1158 | |
b6e91b67 | 1159 | if [ ! -e $cache ]; then |
14d9c0f0 | 1160 | exit 0 |
54b1eb68 MH |
1161 | fi |
1162 | ||
1163 | # lock, so we won't purge while someone is creating a repository | |
1164 | ( | |
1ecee40b | 1165 | flock -x 9 |
14d9c0f0 SG |
1166 | if [ $? != 0 ]; then |
1167 | echo "Cache repository is busy." | |
1168 | exit 1 | |
1169 | fi | |
54b1eb68 | 1170 | |
14d9c0f0 SG |
1171 | echo -n "Purging the download cache for Fedora-$release..." |
1172 | rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1 | |
1173 | exit 0 | |
1ecee40b | 1174 | ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-fedora |
b6e91b67 DL |
1175 | } |
1176 | ||
1177 | usage() | |
1178 | { | |
1179 | cat <<EOF | |
579ebf12 I |
1180 | usage: |
1181 | $1 -n|--name=<container_name> | |
fccc348b MA |
1182 | [-p|--path=<path>] [-c|--clean] [-R|--release=<Fedora_release>] |
1183 | [--fqdn=<network name of container>] [-a|--arch=<arch of the container>] | |
c2af3084 | 1184 | [--mask-tmp] |
579ebf12 I |
1185 | [-h|--help] |
1186 | Mandatory args: | |
fccc348b | 1187 | -n,--name container name, used to as an identifier for that container |
579ebf12 | 1188 | Optional args: |
fccc348b MA |
1189 | -p,--path path to where the container will be created, |
1190 | defaults to @LXCPATH@. | |
1897e3bc | 1191 | --rootfs path for actual rootfs. |
579ebf12 | 1192 | -c,--clean clean the cache |
fccc348b MA |
1193 | -R,--release Fedora release for the new container. |
1194 | Defaults to host's release if the host is Fedora. | |
b9b3a92f | 1195 | --fqdn fully qualified domain name (FQDN) for DNS and system naming |
08754f30 | 1196 | -a,--arch Define what arch the container will be [i686,x86_64] |
c2af3084 | 1197 | --mask-tmp Prevent systemd from over-mounting /tmp with tmpfs. |
579ebf12 | 1198 | -h,--help print this help |
b6e91b67 DL |
1199 | EOF |
1200 | return 0 | |
54b1eb68 MH |
1201 | } |
1202 | ||
c2af3084 | 1203 | options=$(getopt -o a:hp:n:cR: -l help,path:,rootfs:,name:,clean,release:,arch:,fqdn:,mask-tmp -- "$@") |
b6e91b67 DL |
1204 | if [ $? -ne 0 ]; then |
1205 | usage $(basename $0) | |
1206 | exit 1 | |
1207 | fi | |
b6e91b67 | 1208 | |
4849ab99 | 1209 | arch=$(uname -m) |
c2af3084 MA |
1210 | masktmp=0 |
1211 | ||
08754f30 | 1212 | eval set -- "$options" |
b6e91b67 DL |
1213 | while true |
1214 | do | |
1215 | case "$1" in | |
14d9c0f0 SG |
1216 | -h|--help) usage $0 && exit 0;; |
1217 | -p|--path) path=$2; shift 2;; | |
9f177a00 | 1218 | --rootfs) rootfs_path=$2; shift 2;; |
14d9c0f0 | 1219 | -n|--name) name=$2; shift 2;; |
98d316e2 | 1220 | -c|--clean) clean=1; shift 1;; |
579ebf12 | 1221 | -R|--release) release=$2; shift 2;; |
08754f30 | 1222 | -a|--arch) newarch=$2; shift 2;; |
b9b3a92f | 1223 | --fqdn) utsname=$2; shift 2;; |
c2af3084 | 1224 | --mask-tmp) masktmp=1; shift 1;; |
14d9c0f0 | 1225 | --) shift 1; break ;; |
b6e91b67 DL |
1226 | *) break ;; |
1227 | esac | |
1228 | done | |
1229 | ||
1230 | if [ ! -z "$clean" -a -z "$path" ]; then | |
1231 | clean || exit 1 | |
1232 | exit 0 | |
1233 | fi | |
1234 | ||
08754f30 MW |
1235 | |
1236 | basearch=${arch} | |
1237 | # Map a few architectures to their generic Fedora repository archs. | |
1238 | # The two ARM archs are a bit of a guesstimate for the v5 and v6 | |
1239 | # archs. V6 should have hardware floating point (Rasberry Pi). | |
1240 | # The "arm" arch is safer (no hardware floating point). So | |
1241 | # there may be cases where we "get it wrong" for some v6 other | |
1242 | # than RPi. | |
1243 | case "$arch" in | |
1244 | i686) basearch=i386 ;; | |
1245 | armv3l|armv4l|armv5l) basearch=arm ;; | |
1246 | armv6l|armv7l|armv8l) basearch=armhfp ;; | |
1247 | *) ;; | |
1248 | esac | |
1249 | ||
1250 | # Somebody wants to specify an arch. This is very limited case. | |
1251 | # i386/i586/i686 on i386/x86_64 | |
1252 | # - or - | |
1253 | # x86_64 on x86_64 | |
1254 | if [ "${newarch}" != "" -a "${newarch}" != "${arch}" ] | |
1255 | then | |
1256 | case "${newarch}" in | |
1257 | i386|i586|i686) | |
1258 | if [ "${basearch}" = "i386" -o "${basearch}" = "x86_64" ] | |
1259 | then | |
1260 | # Make the arch a generic x86 32 bit... | |
1261 | arch=${newarch} | |
1262 | basearch=i386 | |
1263 | else | |
1264 | basearch=bad | |
1265 | fi | |
1266 | ;; | |
1267 | *) | |
1268 | basearch=bad | |
1269 | ;; | |
1270 | esac | |
1271 | ||
1272 | if [ "${basearch}" = "bad" ] | |
1273 | then | |
1274 | echo "You cannot build a ${newarch} Fedora container on a ${arch} host. Sorry!" | |
1275 | exit 1 | |
1276 | fi | |
1277 | fi | |
1278 | ||
1279 | cache_base=@LOCALSTATEDIR@/cache/lxc/fedora/$basearch | |
1280 | ||
b4f7af7a MW |
1281 | # Let's do something better for the initial root password. |
1282 | # It's not perfect but it will defeat common scanning brute force | |
1283 | # attacks in the case where ssh is exposed. It will also be set to | |
1284 | # expired, forcing the user to change it at first login. | |
1285 | if [ "${root_password}" = "" ] | |
1286 | then | |
1287 | root_password=Root-${name}-${RANDOM} | |
1288 | else | |
1289 | # If it's got a ding in it, try and expand it! | |
1290 | if [ $(expr "${root_password}" : '.*$.') != 0 ] | |
1291 | then | |
1292 | root_password=$(eval echo "${root_password}") | |
1293 | fi | |
1294 | ||
ec64264d | 1295 | # If it has more than 3 consecutive X's in it, feed it |
b4f7af7a MW |
1296 | # through mktemp as a template. |
1297 | if [ $(expr "${root_password}" : '.*XXXX') != 0 ] | |
1298 | then | |
1299 | root_password=$(mktemp -u ${root_password}) | |
1300 | fi | |
1301 | fi | |
1302 | ||
b9b3a92f MW |
1303 | if [ -z "${utsname}" ]; then |
1304 | utsname=${name} | |
1305 | fi | |
1306 | ||
1307 | # This follows a standard "resolver" convention that an FQDN must have | |
1308 | # at least two dots or it is considered a local relative host name. | |
1309 | # If it doesn't, append the dns domain name of the host system. | |
1310 | # | |
1311 | # This changes one significant behavior when running | |
1312 | # "lxc_create -n Container_Name" without using the | |
1313 | # --fqdn option. | |
1314 | # | |
1315 | # Old behavior: | |
1316 | # utsname and hostname = Container_Name | |
1317 | # New behavior: | |
1318 | # utsname and hostname = Container_Name.Domain_Name | |
1319 | ||
1320 | if [ $(expr "$utsname" : '.*\..*\.') = 0 ]; then | |
b4f7af7a | 1321 | if [[ "$(dnsdomainname)" != "" && "$(dnsdomainname)" != "localdomain" ]]; then |
b9b3a92f MW |
1322 | utsname=${utsname}.$(dnsdomainname) |
1323 | fi | |
1324 | fi | |
1325 | ||
cb26f1a5 | 1326 | needed_pkgs="" |
cb26f1a5 SG |
1327 | |
1328 | type curl >/dev/null 2>&1 | |
1329 | if [ $? -ne 0 ]; then | |
1330 | needed_pkgs="curl $needed_pkgs" | |
1331 | fi | |
1332 | ||
1333 | if [ -n "$needed_pkgs" ]; then | |
1334 | echo "Missing commands: $needed_pkgs" | |
627fe3b4 | 1335 | echo "Please install these using \"sudo yum install $needed_pkgs\"" |
b6e91b67 DL |
1336 | exit 1 |
1337 | fi | |
1338 | ||
1339 | if [ -z "$path" ]; then | |
5bb4a226 | 1340 | path=$default_path/$name |
579ebf12 I |
1341 | fi |
1342 | ||
1343 | if [ -z "$release" ]; then | |
627fe3b4 MW |
1344 | if [ "$is_fedora" -a "$fedora_host_ver" ]; then |
1345 | release=$fedora_host_ver | |
579ebf12 | 1346 | else |
1ecee40b MW |
1347 | echo "This is not a fedora host and release missing, defaulting to 20 use -R|--release to specify release" |
1348 | release=20 | |
579ebf12 | 1349 | fi |
b6e91b67 DL |
1350 | fi |
1351 | ||
54b1eb68 | 1352 | if [ "$(id -u)" != "0" ]; then |
b6e91b67 DL |
1353 | echo "This script should be run as 'root'" |
1354 | exit 1 | |
1355 | fi | |
1356 | ||
1897e3bc SH |
1357 | if [ -z "$rootfs_path" ]; then |
1358 | rootfs_path=$path/rootfs | |
1359 | # check for 'lxc.rootfs' passed in through default config by lxc-create | |
1360 | if grep -q '^lxc.rootfs' $path/config 2>/dev/null ; then | |
08754f30 MW |
1361 | rootfs_path=$(sed -e '/^lxc.rootfs\s*=/!d' -e 's/\s*#.*//' \ |
1362 | -e 's/^lxc.rootfs\s*=\s*//' -e q $path/config) | |
1897e3bc | 1363 | fi |
cb26f1a5 | 1364 | fi |
08754f30 | 1365 | config_path=$path |
579ebf12 I |
1366 | cache=$cache_base/$release |
1367 | ||
29ec8f84 RH |
1368 | revert() |
1369 | { | |
1370 | echo "Interrupted, so cleaning up" | |
1371 | lxc-destroy -n $name | |
1372 | # maybe was interrupted before copy config | |
f9d0d2cb | 1373 | rm -rf $path |
29ec8f84 RH |
1374 | echo "exiting..." |
1375 | exit 1 | |
1376 | } | |
1377 | ||
1378 | trap revert SIGHUP SIGINT SIGTERM | |
1379 | ||
1380 | copy_configuration | |
1381 | if [ $? -ne 0 ]; then | |
1382 | echo "failed write configuration file" | |
1383 | exit 1 | |
1384 | fi | |
1385 | ||
579ebf12 | 1386 | install_fedora |
b6e91b67 DL |
1387 | if [ $? -ne 0 ]; then |
1388 | echo "failed to install fedora" | |
1389 | exit 1 | |
54b1eb68 MH |
1390 | fi |
1391 | ||
579ebf12 | 1392 | configure_fedora |
b6e91b67 DL |
1393 | if [ $? -ne 0 ]; then |
1394 | echo "failed to configure fedora for a container" | |
1395 | exit 1 | |
1396 | fi | |
1397 | ||
bf7d3153 MW |
1398 | # If the systemd configuration directory exists - set it up for what we need. |
1399 | if [ -d ${rootfs_path}/etc/systemd/system ] | |
1400 | then | |
f9d0d2cb I |
1401 | configure_fedora_systemd |
1402 | fi | |
b6e91b67 | 1403 | |
bf7d3153 MW |
1404 | # This configuration (rc.sysinit) is not inconsistent with the systemd stuff |
1405 | # above and may actually coexist on some upgraded systems. Let's just make | |
1406 | # sure that, if it exists, we update this file, even if it's not used... | |
1407 | if [ -f ${rootfs_path}/etc/rc.sysinit ] | |
1408 | then | |
1409 | configure_fedora_init | |
1410 | fi | |
1411 | ||
9aed78fa | 1412 | if [ ! -z "$clean" ]; then |
b6e91b67 DL |
1413 | clean || exit 1 |
1414 | exit 0 | |
1415 | fi | |
b4f7af7a MW |
1416 | echo " |
1417 | Container rootfs and config have been created. | |
1418 | Edit the config file to check/enable networking setup. | |
1419 | " | |
449989ac MW |
1420 | |
1421 | if [[ -d ${cache_base}/bootstrap ]] | |
1422 | then | |
b4f7af7a | 1423 | echo "You have successfully built a Fedora container and cache. This cache may |
449989ac MW |
1424 | be used to create future containers of various revisions. The directory |
1425 | ${cache_base}/bootstrap contains a bootstrap | |
1426 | which may no longer needed and can be removed. | |
1427 | " | |
1428 | fi | |
1429 | ||
1430 | if [[ -e ${cache_base}/LiveOS ]] | |
1431 | then | |
1432 | echo "A LiveOS directory exists at ${cache_base}/LiveOS. | |
1433 | This is only used in the creation of the bootstrap run-time-environment | |
1434 | and may be removed. | |
1435 | " | |
1436 | fi | |
b4f7af7a MW |
1437 | |
1438 | if [ ${root_display_password} = "yes" ] | |
1439 | then | |
1440 | echo "The temporary password for root is: '$root_password' | |
1441 | ||
1442 | You may want to note that password down before starting the container. | |
1443 | " | |
1444 | fi | |
1445 | ||
1446 | if [ ${root_store_password} = "yes" ] | |
1447 | then | |
1448 | echo "The temporary root password is stored in: | |
1449 | ||
1450 | '${config_path}/tmp_root_pass' | |
1451 | " | |
1452 | fi | |
1453 | ||
1454 | if [ ${root_prompt_password} = "yes" ] | |
1455 | then | |
1456 | echo "Invoking the passwd command in the container to set the root password. | |
1457 | ||
1458 | chroot ${rootfs_path} passwd | |
1459 | " | |
1460 | chroot ${rootfs_path} passwd | |
1461 | else | |
826cde7c MW |
1462 | if [ ${root_expire_password} = "yes" ] |
1463 | then | |
1464 | echo " | |
b4f7af7a MW |
1465 | The root password is set up as "expired" and will require it to be changed |
1466 | at first login, which you should do as soon as possible. If you lose the | |
1467 | root password or wish to change it without starting the container, you | |
1468 | can change it from the host by running the following command (which will | |
1469 | also reset the expired flag): | |
1470 | ||
1471 | chroot ${rootfs_path} passwd | |
1472 | " | |
826cde7c | 1473 | fi |
b4f7af7a | 1474 | fi |