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