]>
Commit | Line | Data |
---|---|---|
beabd0a2 WC |
1 | #!/bin/sh |
2 | # | |
3 | # Template script for generating Linux for SPARC for LXC | |
4 | # based on lxc-fedora, lxc-ubuntu | |
5 | # | |
6 | # Copyright © 2011 Wim Coekaerts <wim.coekaerts@oracle.com> | |
7 | # Copyright © 2012 Dwight Engen <dwight.engen@oracle.com> | |
8 | # Copyright � 2015 Wim Coekaerts <wim.coekaerts@oracle.com> | |
9 | # | |
10 | # Modified for Oracle Linux 5 | |
11 | # Wim Coekaerts <wim.coekaerts@oracle.com> | |
12 | # | |
13 | # Modified for Oracle Linux 6,7 combined OL4,5,6 into one template script | |
14 | # Dwight Engen <dwight.engen@oracle.com> | |
15 | # | |
16 | # Modified for Linux for SPARC 1.0 | |
17 | # Wim Coekaerts <wim.coekaerts@oracle.com> | |
18 | # | |
19 | # This library is free software; you can redistribute it and/or | |
20 | # modify it under the terms of the GNU Lesser General Public | |
21 | # License as published by the Free Software Foundation; either | |
22 | # version 2.1 of the License, or (at your option) any later version. | |
23 | # | |
24 | # This library is distributed in the hope that it will be useful, | |
25 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 | # Lesser General Public License for more details. | |
28 | # | |
29 | # You should have received a copy of the GNU Lesser General Public | |
30 | # License along with this library; if not, write to the Free Software | |
31 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
32 | # | |
33 | ||
34 | # Detect use under userns (unsupported) | |
35 | for arg in "$@"; do | |
36 | [ "$arg" = "--" ] && break | |
37 | if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then | |
38 | echo "This template can't be used for unprivileged containers." 1>&2 | |
39 | echo "You may want to try the \"download\" template instead." 1>&2 | |
40 | exit 1 | |
41 | fi | |
42 | done | |
43 | ||
44 | # Make sure the usual locations are in PATH | |
45 | export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin | |
46 | ||
47 | # use virbr0 that is setup by default by libvirtd | |
48 | lxc_network_type=veth | |
49 | lxc_network_link=virbr0 | |
50 | ||
51 | die() | |
52 | { | |
53 | echo "failed: $1" | |
54 | exit 1 | |
55 | } | |
56 | ||
57 | is_btrfs_subvolume() | |
58 | { | |
59 | if which btrfs >/dev/null 2>&1 && \ | |
60 | btrfs subvolume list "$1" >/dev/null 2>&1; then | |
61 | return 0 | |
62 | fi | |
63 | return 1 | |
64 | } | |
65 | ||
66 | can_chcon() | |
67 | { | |
68 | if which chcon >/dev/null 2>&1; then | |
69 | selinuxenabled >/dev/null 2>&1 | |
70 | return $? | |
71 | fi | |
72 | return 1 | |
73 | } | |
74 | ||
75 | # fix up the container_rootfs | |
76 | container_rootfs_patch() | |
77 | { | |
78 | echo "Patching container rootfs $container_rootfs for Linux for SPARC $container_release_major.$container_release_minor" | |
79 | ||
80 | # copy ourself into the container to be used to --patch the rootfs when | |
81 | # yum update on certain packages is done. we do this here instead of in | |
82 | # container_rootfs_configure() in case the patching done in this function | |
83 | # is updated in the future, we can inject the updated version of ourself | |
84 | # into older containers. | |
85 | if [ $container_rootfs != "/" ]; then | |
86 | cp -f `readlink -f $0` $container_rootfs/usr/bin/lxc-patch | |
87 | mkdir -p $container_rootfs/usr/share/yum-plugins | |
88 | cp @DATADIR@/lxc/lxc-patch.py $container_rootfs/usr/share/yum-plugins | |
89 | mkdir -p $container_rootfs/etc/yum/pluginconf.d | |
90 | cat <<EOF > $container_rootfs/etc/yum/pluginconf.d/lxc-patch.conf | |
91 | [main] | |
92 | enabled=1 | |
93 | packages=dbus,initscripts,iptables,openssh-server,setup,selinux-policy,readahead,udev,util-linux,util-linux-ng | |
94 | EOF | |
95 | fi | |
96 | ||
97 | # "disable" selinux in the guest. The policy in the container isn't | |
98 | # likely to match the hosts (unless host == guest exactly) and the | |
99 | # kernel can only be enforcing one policy. | |
100 | # | |
101 | mkdir -p $container_rootfs/selinux | |
102 | echo 0 > $container_rootfs/selinux/enforce | |
103 | if [ -e $container_rootfs/etc/selinux/config ]; then | |
104 | sed -i 's|SELINUX=enforcing|SELINUX=disabled|' $container_rootfs/etc/selinux/config | |
105 | else | |
106 | mkdir -p $container_rootfs/etc/selinux | |
107 | echo "SELINUX=disabled" >$container_rootfs/etc/selinux/config | |
108 | fi | |
109 | sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/login | |
110 | sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/login | |
111 | sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*close|#session required pam_selinux.so close|' $container_rootfs/etc/pam.d/sshd | |
112 | sed -i 's|session[ \t]*required[ \t]*pam_selinux.so[ \t]*open|#session required pam_selinux.so open|' $container_rootfs/etc/pam.d/sshd | |
113 | ||
114 | # setting /proc/$$/loginuid doesn't work under user namespace, which | |
115 | # prevents logins from working | |
116 | sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/sshd | |
117 | sed -i 's|session[ \t]*required[ \t]*pam_loginuid.so|#session required pam_loginuid.so|' $container_rootfs/etc/pam.d/login | |
118 | ||
119 | if [ -f $container_rootfs/usr/sbin/selinuxenabled ]; then | |
120 | mv $container_rootfs/usr/sbin/selinuxenabled $container_rootfs/usr/sbin/selinuxenabled.lxcorig | |
121 | ln -s /bin/false $container_rootfs/usr/sbin/selinuxenabled | |
122 | fi | |
123 | ||
124 | # ensure /dev/ptmx refers to the newinstance devpts of the container, or | |
125 | # pty's will get crossed up with the hosts (https://lkml.org/lkml/2012/1/23/512) | |
126 | rm -f $container_rootfs/dev/ptmx | |
127 | ln -s pts/ptmx $container_rootfs/dev/ptmx | |
128 | ||
129 | # silence error in checking for selinux | |
130 | sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.sysinit | |
131 | sed -i 's|cat /proc/self/attr/current|cat /proc/self/attr/current 2>/dev/null|' $container_rootfs/etc/rc.d/rc.sysinit | |
132 | ||
133 | # disable ipv6 | |
134 | rm -f $container_rootfs/etc/sysconfig/network-scripts/init.ipv6-global | |
135 | ||
136 | # remove module stuff for iptables it just shows errors that are not | |
137 | # relevant in a container | |
138 | if [ -f "$container_rootfs/etc/sysconfig/iptables-config" ]; then | |
139 | sed -i 's|IPTABLES_MODULES=".*|IPTABLES_MODULES=""|' $container_rootfs/etc/sysconfig/iptables-config | |
140 | sed -i 's|IPTABLES_MODULES_UNLOAD=".*|IPTABLES_MODULES_UNLOAD="no"|' $container_rootfs/etc/sysconfig/iptables-config | |
141 | fi | |
142 | ||
143 | # disable readahead in the container | |
144 | if [ $container_release_major = "1" -a -e $container_rootfs/etc/sysconfig/readahead ]; then | |
145 | rm -f $container_rootfs/etc/init/readahead-collector.conf | |
146 | rm -f $container_rootfs/etc/init/readahead-disable-services.conf | |
147 | sed -i 's|READAHEAD="yes"|READAHEAD="no"|' $container_rootfs/etc/sysconfig/readahead | |
148 | fi | |
149 | ||
150 | ||
151 | # no need to attempt to mount / | |
152 | sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.sysinit | |
153 | sed -i 's|mount -f /$|# LXC mount -f /|' $container_rootfs/etc/rc.d/rc.sysinit | |
154 | sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.sysinit | |
155 | sed -i 's|action \$"Remounting root filesystem|/bin/true # LXC action $"Remounting root filesystem|' $container_rootfs/etc/rc.d/rc.sysinit | |
156 | ||
157 | # disable udev in the container | |
158 | sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.sysinit | |
159 | sed -i 's|.sbin.start_udev||' $container_rootfs/etc/rc.d/rc.sysinit | |
160 | ||
161 | sed -i 's|\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/init.d/halt | |
162 | sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.sysinit | |
163 | sed -i 's|^\[ -x /sbin/hwclock|\[ 0 -eq 1|' $container_rootfs/etc/rc.d/rc.sysinit | |
164 | sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.sysinit | |
165 | sed -i 's|^/sbin/hwclock|# LXC /sbin/nohwclock|' $container_rootfs/etc/rc.d/rc.sysinit | |
166 | ||
167 | touch $container_rootfs/.nolvm | |
168 | ||
169 | # fix assumptions that plymouth is available | |
170 | sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.sysinit | |
171 | sed -i 's|\[ "$PROMPT" != no \] && plymouth|[ "$PROMPT" != no ] \&\& [ -n "$PLYMOUTH" ] \&\& plymouth|' $container_rootfs/etc/rc.d/rc.sysinit | |
172 | rm -f $container_rootfs/etc/init/plymouth-shutdown.conf | |
173 | rm -f $container_rootfs/etc/init/quit-plymouth.conf | |
174 | rm -f $container_rootfs/etc/init/splash-manager.conf | |
175 | ||
176 | # dont try to unmount /dev/lxc devices | |
177 | sed -i 's|&& $1 !~ /^\\/dev\\/ram/|\&\& $2 !~ /^\\/dev\\/lxc/ \&\& $1 !~ /^\\/dev\\/ram/|' $container_rootfs/etc/init.d/halt | |
178 | ||
179 | # don't try to unmount swap | |
180 | sed -i 's|\[ -f /proc/swaps \]|# LXC [ -f /proc/swaps ]|' $container_rootfs/etc/init.d/halt | |
181 | ||
182 | sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.sysinit | |
183 | sed -i 's|mount -n -o remount /dev/shm >/dev/null 2>&1$|mkdir -p /dev/shm \&\& mount -t tmpfs tmpfs /dev/shm # LXC|' $container_rootfs/etc/rc.d/rc.sysinit | |
184 | ||
185 | # there might be other services that are useless but the below set is a good start | |
186 | # some of these might not exist in the image, so we silence chkconfig complaining | |
187 | # about the service file not being found | |
188 | for service in \ | |
189 | acpid apmd auditd autofs cpuspeed dund gpm haldaemon hidd \ | |
190 | ip6tables irqbalance iscsi iscsid isdn kdump kudzu \ | |
191 | lm_sensors lvm2-monitor mdmonitor microcode_ctl \ | |
192 | ntpd pcmcia postfix sendmail udev-post xfs ; | |
193 | do | |
194 | chroot $container_rootfs chkconfig 2>/dev/null $service off | |
195 | done | |
196 | ||
197 | for service in rsyslog ; | |
198 | do | |
199 | chroot $container_rootfs chkconfig 2>/dev/null $service on | |
200 | done | |
201 | } | |
202 | ||
203 | container_rootfs_configure() | |
204 | { | |
205 | container_rootfs_patch | |
206 | echo "Configuring container for Linux for SPARC $container_release_major.$container_release_minor" | |
207 | ||
208 | # configure the network to use dhcp. we set DHCP_HOSTNAME so the guest | |
209 | # will report its name and be resolv'able by the hosts dnsmasq | |
210 | cat <<EOF > $container_rootfs/etc/sysconfig/network-scripts/ifcfg-eth0 | |
211 | DEVICE=eth0 | |
212 | BOOTPROTO=dhcp | |
213 | ONBOOT=yes | |
214 | HOSTNAME=$name | |
215 | DHCP_HOSTNAME=\`hostname\` | |
216 | NM_CONTROLLED=no | |
217 | TYPE=Ethernet | |
218 | EOF | |
219 | ||
220 | cat <<EOF > $container_rootfs/etc/sysconfig/network | |
221 | NETWORKING=yes | |
222 | NETWORKING_IPV6=no | |
223 | HOSTNAME=$name | |
224 | EOF | |
225 | ||
226 | # set minimal hosts | |
227 | echo "127.0.0.1 localhost $name" > $container_rootfs/etc/hosts | |
228 | ||
229 | # this file has to exist for libvirt/Virtual machine monitor to boot the container | |
230 | touch $container_rootfs/etc/mtab | |
231 | ||
232 | # setup console and tty[1-4] for login. note that /dev/console and | |
233 | # /dev/tty[1-4] will be symlinks to the ptys /dev/lxc/console and | |
234 | # /dev/lxc/tty[1-4] so that package updates can overwrite the symlinks. | |
235 | # lxc will maintain these links and bind mount ptys over /dev/lxc/* | |
236 | # since lxc.devttydir is specified in the config. | |
237 | ||
238 | # allow root login on console, tty[1-4], and pts/0 for libvirt | |
239 | echo "# LXC (Linux Containers)" >>$container_rootfs/etc/securetty | |
240 | echo "lxc/console" >>$container_rootfs/etc/securetty | |
241 | for i in 1 2 3 4; do | |
242 | echo "lxc/tty$i" >>$container_rootfs/etc/securetty | |
243 | done | |
244 | echo "# For libvirt/Virtual Machine Monitor" >>$container_rootfs/etc/securetty | |
245 | for i in 0 1 2 3 4; do | |
246 | echo "pts/$i" >>$container_rootfs/etc/securetty | |
247 | done | |
248 | ||
249 | # prevent mingetty from calling vhangup(2) since it fails with userns | |
250 | if [ -f $container_rootfs/etc/init/tty.conf ]; then | |
251 | sed -i 's|mingetty|mingetty --nohangup|' $container_rootfs/etc/init/tty.conf | |
252 | fi | |
253 | ||
254 | # create maygetty which only spawns a getty on the console when running | |
255 | # under lxc, not libvirt-lxc which symlinks /dev/console to the same pty | |
256 | # as /dev/tty1 | |
257 | cat <<EOF >$container_rootfs/sbin/maygetty | |
258 | #!/bin/sh | |
259 | if [ "\$container" = "lxc" ]; then | |
260 | exec /sbin/mingetty \$@ | |
261 | fi | |
262 | exec sleep infinity | |
263 | EOF | |
264 | chmod 755 $container_rootfs/sbin/maygetty | |
265 | ||
266 | cat <<EOF > $container_rootfs/etc/init/console.conf | |
267 | # console - getty | |
268 | # | |
269 | # This service maintains a getty on the console from the point the system is | |
270 | # started until it is shut down again. | |
271 | ||
272 | start on stopped rc RUNLEVEL=[2345] | |
273 | stop on runlevel [!2345] | |
274 | env container | |
275 | ||
276 | respawn | |
277 | exec /sbin/maygetty --nohangup --noclear /dev/console | |
278 | EOF | |
279 | ||
280 | cat <<EOF > $container_rootfs/etc/init/power-status-changed.conf | |
281 | # power-status-changed - used to cleanly shut down the container | |
282 | # | |
283 | # This task is run whenever init receives SIGPWR | |
284 | # Used to shut down the machine. | |
285 | ||
286 | start on power-status-changed | |
287 | ||
288 | exec init 0 | |
289 | EOF | |
290 | ||
291 | # start with a clean /var/log/messages | |
292 | rm -f $container_rootfs/var/log/messages | |
293 | ||
294 | # add oracle user, set root password | |
295 | chroot $container_rootfs useradd -m -s /bin/bash oracle | |
296 | echo "oracle:oracle" | chroot $container_rootfs chpasswd | |
297 | echo "root:root" | chroot $container_rootfs chpasswd | |
298 | printf "Added container user:\033[1moracle\033[0m password:\033[1moracle\033[0m\n" | |
299 | printf "Added container user:\033[1mroot\033[0m password:\033[1mroot\033[0m\n" | |
300 | } | |
301 | ||
302 | # create the container's lxc config file | |
303 | container_config_create() | |
304 | { | |
305 | echo "Create configuration file $cfg_dir/config" | |
306 | mkdir -p $cfg_dir || die "unable to create config dir $cfg_dir" | |
307 | ||
308 | echo "# Common configuration" >> $cfg_dir/config | |
309 | if [ -e "@LXCTEMPLATECONFIG@/sparclinux.common.conf" ]; then | |
310 | echo "lxc.include = @LXCTEMPLATECONFIG@/sparclinux.common.conf" >> $cfg_dir/config | |
311 | fi | |
312 | ||
313 | # generate a hwaddr for the container with a high mac address | |
314 | # see http://sourceforge.net/tracker/?func=detail&aid=3411497&group_id=163076&atid=826303 | |
315 | local hwaddr="fe:`dd if=/dev/urandom bs=8 count=1 2>/dev/null |od -t x8 | \ | |
316 | head -n 1 |awk '{print $2}' | cut -c1-10 |\ | |
317 | sed 's/\(..\)/\1:/g; s/.$//'`" | |
318 | cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config" | |
319 | # Container configuration for Linux for SPARC $container_release_major.$container_release_minor | |
320 | lxc.arch = $arch | |
321 | lxc.utsname = $name | |
322 | EOF | |
323 | grep -q "^lxc.rootfs" $cfg_dir/config 2>/dev/null || echo "lxc.rootfs = $container_rootfs" >> $cfg_dir/config | |
324 | ||
325 | echo "lxc.cap.drop = sys_resource" >>$cfg_dir/config | |
326 | ||
327 | echo "lxc.cap.drop = setfcap setpcap" >>$cfg_dir/config | |
328 | ||
329 | echo "# Networking" >>$cfg_dir/config | |
330 | # see if the network settings were already specified | |
331 | lxc_network_type=`grep '^lxc.network.type' $cfg_dir/config | awk -F'[= \t]+' '{ print $2 }'` | |
332 | if [ -z "$lxc_network_type" -a \ | |
333 | \( $host_distribution = "SPARCLinux" -o \ | |
334 | $host_distribution = "Fedora" \) ]; then | |
335 | echo "lxc.network.type = veth" >>$cfg_dir/config | |
336 | echo "lxc.network.flags = up" >>$cfg_dir/config | |
337 | echo "lxc.network.link = virbr0" >>$cfg_dir/config | |
338 | fi | |
339 | ||
340 | cat <<EOF >> $cfg_dir/config || die "unable to create $cfg_dir/config" | |
341 | lxc.network.name = eth0 | |
342 | lxc.network.mtu = 1500 | |
343 | lxc.network.hwaddr = $hwaddr | |
344 | EOF | |
345 | } | |
346 | ||
347 | container_rootfs_clone() | |
348 | { | |
349 | if is_btrfs_subvolume $template_rootfs; then | |
350 | # lxc-create already made $container_rootfs a btrfs subvolume, but | |
351 | # in this case we want to snapshot the original subvolume so we we | |
352 | # have to delete the one that lxc-create made | |
353 | btrfs subvolume delete $container_rootfs | |
354 | btrfs subvolume snapshot $template_rootfs $container_rootfs || die "btrfs clone template" | |
355 | else | |
356 | echo "Copying rootfs ..." | |
357 | cp -axT $template_rootfs $container_rootfs || die "copy template" | |
358 | fi | |
359 | } | |
360 | ||
361 | container_rootfs_repo_create() | |
362 | { | |
363 | echo "# LXC generated .repo file" >$1 | |
364 | echo "[$2]" >>$1 | |
365 | echo "name=Linux for SPARC $container_release_major.$container_release_minor ($basearch)" >>$1 | |
366 | echo "baseurl=$3/" >>$1 | |
367 | echo "enabled=1" >>$1 | |
368 | echo "skip_if_unavailable=1" >>$1 | |
369 | ||
370 | if [ "$4" != "" ]; then | |
371 | echo "gpgkey=$yum_url/RPM-GPG-KEY-oracle-ol$container_release_major" >>$1 | |
372 | echo "gpgcheck=1" >>$1 | |
373 | else | |
374 | echo "gpgcheck=0" >>$1 | |
375 | fi | |
376 | } | |
377 | ||
378 | container_rootfs_dev_create() | |
379 | { | |
380 | # create required devices. note that /dev/console will be created by lxc | |
381 | # or libvirt itself to be a symlink to the right pty. | |
382 | # take care to not nuke /dev in case $container_rootfs isn't set | |
383 | dev_path="$container_rootfs/dev" | |
384 | if [ $container_rootfs != "/" -a -d $dev_path ]; then | |
385 | rm -rf $dev_path | |
386 | fi | |
387 | mkdir -p $dev_path | |
388 | if can_chcon; then | |
389 | # ensure symlinks created in /dev have the right context | |
390 | chcon -t device_t $dev_path | |
391 | fi | |
392 | mknod -m 666 $dev_path/null c 1 3 | |
393 | mknod -m 666 $dev_path/zero c 1 5 | |
394 | mknod -m 666 $dev_path/random c 1 8 | |
395 | mknod -m 666 $dev_path/urandom c 1 9 | |
396 | mkdir -m 755 $dev_path/pts | |
397 | mkdir -m 1777 $dev_path/shm | |
398 | mknod -m 666 $dev_path/tty c 5 0 | |
399 | mknod -m 666 $dev_path/tty1 c 4 1 | |
400 | mknod -m 666 $dev_path/tty2 c 4 2 | |
401 | mknod -m 666 $dev_path/tty3 c 4 3 | |
402 | mknod -m 666 $dev_path/tty4 c 4 4 | |
403 | mknod -m 666 $dev_path/full c 1 7 | |
404 | mknod -m 600 $dev_path/initctl p | |
405 | ||
406 | # set selinux labels same as host | |
407 | if can_chcon; then | |
408 | for node in null zero random urandom pts shm \ | |
409 | tty tty0 tty1 tty2 tty3 tty4 full ; | |
410 | do | |
411 | chcon --reference /dev/$node $dev_path/$node 2>/dev/null | |
412 | done | |
413 | fi | |
414 | } | |
415 | ||
416 | container_rootfs_create() | |
417 | { | |
418 | if can_chcon; then | |
419 | chcon --reference / $container_rootfs 2>/dev/null | |
420 | fi | |
421 | ||
422 | cmds="rpm wget yum" | |
423 | for cmd in $cmds; do | |
424 | which $cmd >/dev/null 2>&1 | |
425 | if [ $? -ne 0 ]; then | |
426 | die "The $cmd command is required, please install it" | |
427 | fi | |
428 | done | |
429 | ||
430 | mkdir -p @LOCALSTATEDIR@/lock/subsys | |
431 | ( | |
432 | flock -x 9 | |
433 | if [ $? -ne 0 ]; then | |
434 | die "The template is busy." | |
435 | fi | |
436 | ||
437 | echo "Yum installing release $container_release_major.$container_release_minor for $basearch" | |
438 | ||
439 | if [ -n "$repourl" ]; then | |
440 | yum_url=$repourl | |
441 | else | |
442 | yum_url=http://yum.oracle.com | |
443 | fi | |
444 | ||
445 | if [ -n "$baseurl" ]; then | |
446 | # create .repo pointing at baseurl | |
447 | repo="lxc-install" | |
448 | mkdir -p $container_rootfs/etc/yum.repos.d | |
449 | container_rootfs_repo_create \ | |
450 | $container_rootfs/etc/yum.repos.d/lxc-install.repo $repo $baseurl | |
451 | else | |
452 | # get public-yum repo file | |
453 | if [ $container_release_major = "1" ]; then | |
454 | repofile=yum-linux-sparc64.repo | |
455 | else | |
456 | die "Unsupported release $container_release_major" | |
457 | fi | |
458 | ||
459 | mkdir -p $container_rootfs/etc/yum.repos.d | |
460 | wget -q $yum_url/$repofile -O $container_rootfs/etc/yum.repos.d/$repofile | |
461 | if [ $? -ne 0 ]; then | |
462 | die "Unable to download repo file $yum_url/$repofile, release unavailable" | |
463 | fi | |
464 | ||
465 | # yum will take $basearch from host, so force the arch we want | |
466 | sed -i "s|\$basearch|$basearch|" $container_rootfs/etc/yum.repos.d/$repofile | |
467 | ||
468 | # replace url if they specified one | |
469 | if [ -n "$repourl" ]; then | |
470 | sed -i "s|baseurl=http://yum.oracle.com/|baseurl=$repourl/repo|" $container_rootfs/etc/yum.repos.d/$repofile | |
471 | sed -i "s|gpgkey=http://yum.oracle.com|gpgkey=$repourl|" $container_rootfs/etc/yum.repos.d/$repofile | |
472 | ||
473 | fi | |
474 | ||
475 | # disable all repos, then enable the repo for the version we are installing. | |
476 | if [ $container_release_minor = "latest" ]; then | |
477 | repo="lfs"_$container_release_minor | |
478 | else | |
479 | die "Unsupported release $container_release_major.$container_release_minor" | |
480 | fi | |
481 | sed -i "s|enabled=1|enabled=0|" $container_rootfs/etc/yum.repos.d/$repofile | |
482 | sed -i "/\[$repo\]/,/\[/ s/enabled=0/enabled=1/" $container_rootfs/etc/yum.repos.d/$repofile | |
483 | fi | |
484 | ||
485 | container_rootfs_dev_create | |
486 | ||
487 | # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt | |
488 | echo "" >$container_rootfs/etc/fstab | |
489 | ||
490 | # create rpm db, download and yum install minimal packages | |
491 | mkdir -p $container_rootfs/var/lib/rpm | |
492 | rpm --root $container_rootfs --initdb | |
493 | yum_args="--installroot $container_rootfs --disablerepo=* --enablerepo=$repo -y --nogpgcheck" | |
494 | min_pkgs="yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils sparclinux-release" | |
495 | ||
496 | # we unshare the mount namespace because yum installing the ol4 | |
497 | # packages causes $rootfs/proc to be mounted on | |
498 | lxc-unshare -s MOUNT yum -- $yum_args install $min_pkgs $user_pkgs | |
499 | if [ $? -ne 0 ]; then | |
500 | die "Failed to download and install the rootfs, aborting." | |
501 | fi | |
502 | ||
503 | # rsyslog and pam depend on coreutils for some common commands in | |
504 | # their POSTIN scriptlets, but coreutils wasn't installed yet. now | |
505 | # that coreutils is installed, reinstall the packages so their POSTIN | |
506 | # runs right. similarly, libutempter depends on libselinux.so.1 when | |
507 | # it runs /usr/sbin/groupadd, so reinstall it too | |
508 | redo_pkgs="" | |
509 | if [ x"$redo_pkgs" != x ]; then | |
510 | rpm --root $container_rootfs --nodeps -e $redo_pkgs | |
511 | lxc-unshare -s MOUNT yum -- $yum_args install $redo_pkgs | |
512 | if [ $? -ne 0 ]; then | |
513 | die "Unable to reinstall packages" | |
514 | fi | |
515 | fi | |
516 | ||
517 | # these distributions put the rpm database in a place the guest is | |
518 | # not expecting it, so move it | |
519 | if [ $host_distribution = "Ubuntu" -o $host_distribution = "Debian" ]; then | |
520 | mv $container_rootfs/$HOME/.rpmdb/* $container_rootfs/var/lib/rpm | |
521 | fi | |
522 | ||
523 | # if the native rpm created the db with Hash version 9, we need to | |
524 | # downgrade it to Hash version 8 for use with OL5.x | |
525 | db_version=`file $container_rootfs/var/lib/rpm/Packages | \ | |
526 | grep -o 'version [0-9]*' |awk '{print $2}'` | |
527 | ||
528 | # the host rpm may not be the same as the guest, rebuild the db with | |
529 | # the guest rpm version | |
530 | echo "Rebuilding rpm database" | |
531 | rm -f $container_rootfs/var/lib/rpm/__db* | |
532 | chroot $container_rootfs rpm --rebuilddb >/dev/null 2>&1 | |
533 | ||
534 | ) 9>@LOCALSTATEDIR@/lock/subsys/lxc-sparclinux-$name | |
535 | if [ $? -ne 0 ]; then | |
536 | exit 1 | |
537 | fi | |
538 | } | |
539 | ||
540 | container_release_get() | |
541 | { | |
542 | if [ -f $1/etc/sparclinux-release ]; then | |
543 | container_release_version=`cat $1/etc/sparclinux-release |awk '/^Linux/ {print $5}'` | |
544 | container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` | |
545 | container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` | |
546 | else | |
547 | echo "Unable to determine container release version" | |
548 | exit 1 | |
549 | fi | |
550 | } | |
551 | ||
552 | usage() | |
553 | { | |
554 | cat <<EOF | |
555 | -a|--arch=<arch> architecture (sparc64) | |
556 | -R|--release=<release> release to download for the new container | |
557 | --rootfs=<path> rootfs path | |
558 | -r|--rpms=<rpm name> additional rpms to install into container | |
559 | -u|--url=<url> replace yum repo url (ie. Oracle public-yum mirror) | |
560 | --baseurl=<url> use package repository (ie. file:///mnt) | |
561 | arch and release must also be specified | |
562 | -t|--templatefs=<path> copy/clone rootfs at path instead of downloading | |
563 | -P|--patch=<path> only patch the rootfs at path for use as a container | |
564 | -h|--help | |
565 | ||
566 | Release is of the format "major.minor", for example "1.0" or "1.latest" | |
567 | This template supports Linux for SPARC release 1.0 | |
568 | EOF | |
569 | return 0 | |
570 | } | |
571 | ||
572 | options=$(getopt -o hp:n:a:R:r:u:t: -l help,rootfs:,path:,name:,arch:,release:,rpms:,url:,templatefs:,patch:,baseurl: -- "$@") | |
573 | if [ $? -ne 0 ]; then | |
574 | usage $(basename $0) | |
575 | exit 1 | |
576 | fi | |
577 | ||
578 | eval set -- "$options" | |
579 | while true | |
580 | do | |
581 | case "$1" in | |
582 | -h|--help) usage $0 && exit 0;; | |
583 | -p|--path) cfg_dir=$2; shift 2;; | |
584 | --rootfs) container_rootfs=$2; shift 2;; | |
585 | -n|--name) name=$2; shift 2;; | |
586 | -a|--arch) arch=$2; shift 2;; | |
587 | -R|--release) container_release_version=$2; shift 2;; | |
588 | -r|--rpms) user_pkgs=$2; shift 2;; | |
589 | -u|--url) repourl=$2; shift 2;; | |
590 | -t|--templatefs) template_rootfs=$2; shift 2;; | |
591 | --patch) patch_rootfs=$2; shift 2;; | |
592 | --baseurl) baseurl=$2; shift 2;; | |
593 | --) shift 1; break ;; | |
594 | *) break ;; | |
595 | esac | |
596 | done | |
597 | ||
598 | # make sure mandatory args are given and valid | |
599 | if [ "$(id -u)" != "0" ]; then | |
600 | echo "This script should be run as 'root'" | |
601 | exit 1 | |
602 | fi | |
603 | ||
604 | if [ -n "$baseurl" ]; then | |
605 | if [ "$arch" = "" -o "$container_release_version" = "" ]; then | |
606 | echo "The --arch and --release must be specified when using --baseurl" | |
607 | usage | |
608 | exit 1 | |
609 | fi | |
610 | fi | |
611 | ||
612 | if [ "$arch" = "" ]; then | |
613 | arch=$(uname -m) | |
614 | fi | |
615 | ||
616 | if [ -n "$patch_rootfs" ]; then | |
617 | container_rootfs="$patch_rootfs" | |
618 | container_release_get $container_rootfs | |
619 | container_rootfs_patch | |
620 | exit 0 | |
621 | fi | |
622 | ||
623 | if [ -z $name ]; then | |
624 | echo "Container name must be given" | |
625 | usage | |
626 | exit 1 | |
627 | fi | |
628 | ||
629 | if [ -z $cfg_dir ]; then | |
630 | echo "Configuration directory must be given, check lxc-create" | |
631 | usage | |
632 | exit 1 | |
633 | fi | |
634 | ||
635 | basearch=$arch | |
636 | ||
637 | if [ "$arch" != "sparc64" ]; then | |
638 | echo "Bad architecture given, check lxc-create" | |
639 | usage | |
640 | exit 1 | |
641 | fi | |
642 | ||
643 | if [ -f /etc/sparclinux-release ]; then | |
644 | host_distribution="SPARCLinux" | |
645 | host_release_version=`cat /etc/sparclinux-release |awk '{print $5}'` | |
646 | host_release_major=`echo $host_release_version |awk -F '.' '{print $1}'` | |
647 | host_release_minor=`echo $host_release_version |awk -F '.' '{print $2}'` | |
648 | else | |
649 | echo "Unable to determine host distribution" | |
650 | exit 1 | |
651 | fi | |
652 | ||
653 | echo "Host is $host_distribution $host_release_version" | |
654 | ||
655 | if [ -z "$container_rootfs" ]; then | |
656 | container_rootfs="$cfg_dir/rootfs" | |
657 | fi | |
658 | ||
659 | if [ -n "$template_rootfs" ]; then | |
660 | container_release_get $template_rootfs | |
661 | else | |
662 | if [ -z "$container_release_version" ]; then | |
663 | if [ $host_distribution = "SPARCLinux" ]; then | |
664 | container_release_version=$host_release_version | |
665 | else | |
666 | echo "No release specified with -R, defaulting to 1.latest" | |
667 | container_release_version="1.latest" | |
668 | fi | |
669 | fi | |
670 | container_release_major=`echo $container_release_version |awk -F '.' '{print $1}'` | |
671 | container_release_minor=`echo $container_release_version |awk -F '.' '{print $2}'` | |
672 | fi | |
673 | ||
674 | container_config_create | |
675 | if [ -n "$template_rootfs" ]; then | |
676 | container_rootfs_clone | |
677 | else | |
678 | container_rootfs_create | |
679 | fi | |
680 | ||
681 | container_release_get $container_rootfs | |
682 | ||
683 | container_rootfs_configure | |
684 | ||
685 | echo "Container : $container_rootfs" | |
686 | echo "Config : $cfg_dir/config" | |
687 | echo "Network : eth0 ($lxc_network_type) on $lxc_network_link" |