]>
Commit | Line | Data |
---|---|---|
cab79123 KY |
1 | #!/bin/bash |
2 | ||
3 | # | |
4 | # template script for generating Plamo Linux container for LXC | |
5 | # | |
6 | ||
7 | # | |
8 | # lxc: linux Container library | |
9 | ||
10 | # Authors: | |
11 | # KATOH Yasufumi <karma@jazz.email.ne.jp> | |
12 | # TAMUKI Shoichi <tamuki@linet.gr.jp> | |
13 | ||
14 | # This library is free software; you can redistribute it and/or | |
15 | # modify it under the terms of the GNU Lesser General Public | |
16 | # License as published by the Free Software Foundation; either | |
17 | # version 2.1 of the License, or (at your option) any later version. | |
18 | ||
19 | # This library is distributed in the hope that it will be useful, | |
20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
22 | # Lesser General Public License for more details. | |
23 | ||
24 | # You should have received a copy of the GNU Lesser General Public | |
25 | # License along with this library; if not, write to the Free Software | |
26 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
27 | ||
28 | # ref. https://github.com/Ponce/lxc-slackware/blob/master/lxc-slackware | |
29 | # lxc-ubuntu script | |
30 | ||
31 | [ -r /etc/default/lxc ] && . /etc/default/lxc | |
32 | ||
33 | MIRRORSRV=${MIRRORSRV:-"ftp.ne.jp"} | |
34 | MIRRORPATH=${MIRRORPATH:-"/Linux/distributions/plamolinux"} | |
35 | CATEGORY[0]=${CATEGORY:-"00_base"} | |
36 | PACKAGES[0]=${PACKAGES:-"aaa_base acl at attr bash btrfs_progs bzip2 | |
37 | coreutils cracklib dcron devs dhcp dialog dosfstools dump e2fsprogs | |
38 | ed eject etc extipl file findutils gawk glibc grep groff grub gzip | |
39 | hdsetup hibernate_script iproute2 iputils kbd kmod less libcap | |
40 | libgcc libtirpc lilo linux_pam logrotate lvm2 man | |
41 | mdadm microcode_ctl mlocate ncurses net_tools netkit_combo | |
42 | network_configs nvi openbsd_inetd openssh openssl os_prober pciutils | |
43 | pm_utils procinfo_ng procps_ng readline reiserfsprogs rsyslog sed | |
44 | shadow sudo sysfsutils syslinux sysvinit tar tcp_wrappers tcsh | |
45 | timezone traceroute udev unicon_tools util_linux xz zlib"} | |
46 | CATEGORY[1]="01_minimum" | |
47 | PACKAGES[1]="FDclone autofs bc berkeley_db bsd_games cpio cpufreqd | |
48 | cpufrequtils fortune_mod gc gdbm gpm hddtemp hdparm keyutils libelf | |
49 | libieee1284 libusb libusb_compat libxml2 libzip linux_howto lm_sensors | |
50 | lshw lsof lv man_pages man_pages_ja nilfs_utils nkf pcre perl popt | |
51 | psmisc python recode rpm2targz ruby screen sg3_utils sharutils sqlite | |
52 | squashfs_lzma sysstat texinfo time tree unzip usbutils utempter which | |
53 | yaml zip zsh" | |
54 | CATEGORY[2]="01_minimum/alsa.txz" | |
55 | PACKAGES[2]="alsa_lib alsa_plugins alsa_utils" | |
56 | CATEGORY[3]="01_minimum/aspell.txz" | |
57 | PACKAGES[3]="aspell aspell6_en" | |
58 | CATEGORY[4]="01_minimum/devel.txz" | |
59 | PACKAGES[4]="autoconf automake binutils bison cloog cvs diffutils flex | |
60 | g++ gcc gdb gettext gmp indent intltool kernel_headers libc libtool | |
61 | m4 make mpc mpfr onig patch pkg_config ppl pth slang strace yasm" | |
62 | CATEGORY[5]="01_minimum/gnupg_tls.txz" | |
63 | PACKAGES[5]="gnupg gnutls gpgme libassuan libgcrypt libgpg_error libksba | |
64 | libtasn1" | |
65 | CATEGORY[6]="01_minimum/network.txz" | |
66 | PACKAGES[6]="bind bridge_utils curl cyrus_sasl dnsmasq ethtool fetchmail | |
67 | heimdal hostapd iptables iw libidn libiec61883 libnl3 libpcap | |
68 | libraw1394 libssh2 mailx metamail ncftp ntrack parprouted postfix | |
69 | ppp procmail rsync setserial uml_utilities w3m wget wireless_tools | |
70 | wpa_supplicant" | |
71 | CATEGORY[7]="01_minimum/nfs.txz" | |
72 | PACKAGES[7]="libevent libnfsidmap nfs_utils rpcbind" | |
73 | CATEGORY[8]="01_minimum/tcl.txz" | |
74 | PACKAGES[8]="expect itcl tcl tclx" | |
75 | ||
76 | download_plamo() { | |
77 | # check the mini plamo was not already downloaded | |
78 | if ! mkdir -p $ptcache ; then | |
79 | echo "Failed to create '$ptcache' directory." | |
80 | return 1 | |
81 | fi | |
82 | # download a mini plamo into a cache | |
83 | echo "Downloading Plamo-$release minimal..." | |
84 | echo "open $MIRRORSRV" > /tmp/getpkg | |
85 | for i in `seq 0 $((${#CATEGORY[@]} - 1))` ; do | |
86 | for p in ${PACKAGES[$i]} ; do | |
87 | cat <<- EOF >> /tmp/getpkg | |
88 | mget $MIRRORPATH/Plamo-$release/$arch/plamo/${CATEGORY[$i]}/$p-*.t?z | |
89 | EOF | |
90 | done | |
91 | done | |
92 | echo "close" >> /tmp/getpkg | |
93 | cd $ptcache | |
94 | if ! lftp -f /tmp/getpkg ; then | |
95 | echo "Failed to download the rootfs, aborting." | |
96 | return 1 | |
97 | fi | |
98 | rm -f /tmp/getpkg | |
99 | mv $ptcache $dlcache | |
100 | echo "Download complete." | |
101 | return 0 | |
102 | } | |
103 | ||
104 | copy_plamo() { | |
105 | # make a local copy of the mini plamo | |
106 | echo "Copying $rtcache to $rootfs..." | |
107 | mkdir -p $rootfs | |
108 | find $rtcache -mindepth 1 -maxdepth 1 -exec cp -a {} $rootfs \; || return 1 | |
109 | return 0 | |
110 | } | |
111 | ||
112 | install_plamo() { | |
113 | mkdir -p @LOCALSTATEDIR@/lock/subsys | |
114 | ( | |
115 | if ! flock -n 200 ; then | |
116 | echo "Cache repository is busy." | |
117 | return 1 | |
118 | fi | |
119 | echo "Checking cache download in $dlcache..." | |
120 | if [ ! -d $dlcache ] ; then | |
121 | if ! download_plamo ; then | |
122 | echo "Failed to download plamo $release base packages." | |
123 | return 1 | |
124 | fi | |
125 | fi | |
92cbfdaf KY |
126 | if [ ! -x /sbin/installpkg ] ; then |
127 | echo "'installpkg' command is missing." | |
128 | echo "Installing 'installpkg' command into $dlcache/sbin..." | |
129 | ( cd $dlcache ; tar xpJf hdsetup-*.txz ; rm -rf tmp usr var ) | |
130 | sed -i "/ldconfig/!s@/sbin@$dlcache&@g" $dlcache/sbin/installpkg* | |
131 | PATH=$dlcache/sbin:$PATH | |
132 | fi | |
cab79123 KY |
133 | echo "Installing packages to $rtcache..." |
134 | if [ ! -d $rtcache ] ; then | |
135 | mkdir -p $rtcache | |
136 | for i in `seq 0 $((${#CATEGORY[@]} - 1))` ; do | |
137 | for p in ${PACKAGES[$i]} ; do | |
138 | installpkg -root $rtcache -priority ADD $dlcache/$p-*.t?z | |
139 | done | |
140 | done | |
141 | fi | |
142 | echo "Copy $rtcache to $rootfs..." | |
143 | if ! copy_plamo ; then | |
144 | echo "Failed to copy rootfs." | |
145 | return 1 | |
146 | fi | |
147 | return 0 | |
148 | ) 200> @LOCALSTATEDIR@/lock/subsys/lxc | |
149 | } | |
150 | ||
151 | configure_plamo() { | |
152 | # create /dev | |
153 | mknod -m 666 $rootfs/dev/zero c 1 5 | |
154 | chmod 666 $rootfs/dev/random | |
155 | mknod -m 666 $rootfs/dev/urandom c 1 9 | |
156 | mkdir -m 755 $rootfs/dev/pts | |
157 | chmod 666 $rootfs/dev/tty | |
158 | chmod 600 $rootfs/dev/console | |
159 | mknod -m 666 $rootfs/dev/tty0 c 4 0 | |
160 | mknod -m 666 $rootfs/dev/tty1 c 4 1 | |
161 | mknod -m 666 $rootfs/dev/tty2 c 4 2 | |
162 | mknod -m 666 $rootfs/dev/tty3 c 4 3 | |
163 | mknod -m 666 $rootfs/dev/tty4 c 4 4 | |
164 | mknod -m 666 $rootfs/dev/full c 1 7 | |
165 | mknod -m 600 $rootfs/dev/initctl p | |
166 | mknod -m 666 $rootfs/dev/ptmx c 5 2 | |
167 | # suppress log level output for udev | |
168 | sed -i 's/="err"/=0/' $rootfs/etc/udev/udev.conf | |
169 | # /etc/fstab | |
170 | cat <<- "EOF" > $rootfs/etc/fstab | |
171 | none /proc proc defaults 0 0 | |
172 | none /sys sysfs defaults 0 0 | |
173 | none /dev tmpfs defaults 0 0 | |
174 | none /tmp tmpfs defaults 0 0 | |
175 | none /dev/pts devpts gid=5,mode=620 0 0 | |
176 | none /proc/bus/usb usbfs noauto 0 0 | |
177 | none /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0 | |
178 | EOF | |
179 | # /etc/inittab | |
180 | cat <<- "EOF" | patch $rootfs/etc/inittab | |
181 | 47a48 | |
182 | > 1:1235:respawn:/sbin/agetty 38400 console | |
183 | 52,53d52 | |
184 | < c5:1235:respawn:/sbin/agetty 38400 tty5 linux | |
185 | < c6:12345:respawn:/sbin/agetty 38400 tty6 linux | |
186 | EOF | |
187 | # set the hostname | |
188 | echo "$name" > $rootfs/etc/HOSTNAME | |
189 | # set minimal hosts | |
190 | echo "127.0.0.1 localhost $name" > $rootfs/etc/hosts | |
191 | # configure the network using the dhcp | |
192 | echo "DHCP" > $rootfs/var/run/inet1-scheme | |
193 | # localtime (JST) | |
194 | ln -s ../usr/share/zoneinfo/Asia/Tokyo $rootfs/etc/localtime | |
195 | # disable pam_loginuid.so in /etc/pam.d/login (for libvirt's lxc driver) | |
196 | sed -i '/pam_loginuid/s/^/#/' $rootfs/etc/pam.d/login | |
a1e4c206 | 197 | # glibc configure |
0dc29614 | 198 | mv $rootfs/etc/ld.so.conf{.new,} |
a1e4c206 | 199 | chroot $rootfs ldconfig |
cab79123 KY |
200 | # root password |
201 | echo "Setting root password to 'root'..." | |
202 | echo "root:root" | chroot $rootfs chpasswd | |
203 | echo "Please change root password!" | |
204 | # /etc/rc.d/rc.S | |
205 | ed - $rootfs/etc/rc.d/rc.S <<- "EOF" | |
206 | 230,261d | |
207 | 156,163d | |
208 | 26,147d | |
209 | 16,22d | |
210 | w | |
211 | EOF | |
212 | # /etc/rc.d/rc.M | |
213 | ed - $rootfs/etc/rc.d/rc.M <<- "EOF" | |
41e8e807 KY |
214 | 269,270d |
215 | 56,82d | |
cab79123 KY |
216 | 31,38d |
217 | w | |
218 | EOF | |
219 | # /etc/rc.d/rc.inet1.tradnet | |
220 | head -n-93 $rootfs/sbin/netconfig.tradnet > /tmp/netconfig.rconly | |
221 | cat <<- EOF >> /tmp/netconfig.rconly | |
222 | PCMCIA=n | |
223 | RC=$rootfs/etc/rc.d/rc.inet1.tradnet | |
224 | IFCONFIG=sbin/ifconfig | |
225 | ROUTE=sbin/route | |
226 | INET1SCHEME=var/run/inet1-scheme | |
227 | IPADDR=127.0.0.1 | |
228 | NETWORK=127.0.0.0 | |
229 | DHCPCD=usr/sbin/dhclient | |
230 | LOOPBACK=y | |
231 | make_config_file | |
232 | EOF | |
233 | rm -f $rootfs/etc/rc.d/rc.inet1.tradnet | |
234 | sh /tmp/netconfig.rconly | |
235 | rm -f /tmp/netconfig.rconly | |
236 | return 0 | |
237 | } | |
238 | ||
239 | copy_configuration() { | |
240 | if ! cat <<- EOF >> $path/config ; then | |
241 | lxc.utsname = $name | |
242 | ||
243 | lxc.tty = 4 | |
244 | lxc.pts = 1024 | |
245 | lxc.mount.auto = proc sys cgroup | |
246 | lxc.arch = $arch | |
247 | lxc.cap.drop = sys_module mac_admin mac_override sys_time | |
248 | ||
249 | lxc.cgroup.devices.deny = a | |
250 | # /dev/null and zero | |
251 | lxc.cgroup.devices.allow = c 1:3 rwm | |
252 | lxc.cgroup.devices.allow = c 1:5 rwm | |
253 | # consoles | |
254 | lxc.cgroup.devices.allow = c 5:0 rwm | |
255 | lxc.cgroup.devices.allow = c 5:1 rwm | |
256 | # /dev/{,u}random | |
257 | lxc.cgroup.devices.allow = c 1:8 rwm | |
258 | lxc.cgroup.devices.allow = c 1:9 rwm | |
259 | lxc.cgroup.devices.allow = c 5:2 rwm | |
260 | lxc.cgroup.devices.allow = c 136:* rwm | |
261 | # rtc | |
262 | lxc.cgroup.devices.allow = c 254:0 rm | |
263 | # fuse | |
264 | lxc.cgroup.devices.allow = c 10:229 rwm | |
265 | EOF | |
266 | echo "Failed to add configuration." | |
267 | return 1 | |
268 | fi | |
269 | return 0 | |
270 | } | |
271 | ||
272 | post_process() { | |
273 | # nothing do in Plamo Linux | |
274 | true | |
275 | } | |
276 | ||
277 | do_bindhome() { | |
278 | # bind-mount the user's path into the container's /home | |
279 | h=`getent passwd $bindhome | cut -d: -f6` | |
280 | mkdir -p $rootfs/$h | |
281 | echo "$h $rootfs/$h none bind 0 0" >> $path/fstab | |
282 | # copy /etc/passwd, /etc/shadow, and /etc/group entries into container | |
283 | if ! pwd=`getent passwd $bindhome` ; then | |
284 | echo "Warning: failed to copy password entry for $bindhome." | |
285 | else | |
286 | echo $pwd >> $rootfs/etc/passwd | |
287 | fi | |
288 | echo `getent shadow $bindhome` >> $rootfs/etc/shadow | |
289 | } | |
290 | ||
291 | cleanup() { | |
292 | [ -d $dlcache -a -d $rtcache ] || return 0 | |
293 | # lock, so we won't purge while someone is creating a repository | |
294 | ( | |
295 | if ! flock -n 200 ; then | |
296 | echo "Cache repository is busy." | |
297 | return 1 | |
298 | fi | |
299 | echo "Purging the download cache..." | |
300 | rm -rf --one-file-system $dlcache $rtcache || return 1 | |
301 | echo "Done." | |
302 | return 0 | |
303 | ) 200> @LOCALSTATEDIR@/lock/subsys/lxc | |
304 | } | |
305 | ||
306 | usage() { | |
307 | cat <<- EOF | |
308 | $prog [-h|--help] -p|--path=<path> -n|--name=<name> --rootfs=<rootfs> | |
309 | [--clean] [-r|--release=<release>] [-b|--bindhome=<user>] | |
310 | [-a|--arch=<arch>] | |
311 | release: $release | |
312 | bindhome: bind <user>'s home into the container | |
313 | arch: x86 or x86_64: defaults to host arch | |
314 | EOF | |
315 | } | |
316 | ||
317 | prog=`basename $0` | |
318 | path="" ; name="" ; rootfs="" | |
319 | clean=0 | |
320 | release=${release:-5.x} | |
321 | bindhome="" | |
322 | arch=`uname -m | sed 's/i.86/x86/'` ; hostarch=$arch | |
323 | sopts=hp:n:cr:b:a: | |
324 | lopts=help,path:,name:,rootfs:,clean,release:,bindhome:,arch: | |
325 | if ! options=`getopt -o $sopts -l $lopts -- "$@"` ; then | |
326 | usage | |
327 | exit 1 | |
328 | fi | |
329 | eval set -- "$options" | |
330 | while true ; do | |
331 | case "$1" in | |
332 | -h|--help) usage && exit 0 ;; | |
333 | -p|--path) path=$2 ; shift 2 ;; | |
334 | -n|--name) name=$2 ; shift 2 ;; | |
335 | --rootfs) rootfs=$2 ; shift 2 ;; | |
336 | -c|--clean) clean=1 ; shift 1 ;; | |
337 | -r|--release) release=$2 ; shift 2 ;; | |
338 | -b|--bindhome) bindhome=$2 ; shift 2 ;; | |
339 | -a|--arch) arch=$2 ; shift 2 ;; | |
340 | --) shift 1 ; break ;; | |
341 | *) break ;; | |
342 | esac | |
343 | done | |
344 | if [ $clean -eq 1 -a -z "$path" ] ; then | |
345 | cleanup || exit 1 | |
346 | exit 0 | |
347 | fi | |
348 | if [ $hostarch == "x86" -a $arch == "x86_64" ] ; then | |
349 | echo "Can't create x86_64 container on x86." | |
350 | exit 1 | |
351 | fi | |
cab79123 KY |
352 | if [ -z "$path" ] ; then |
353 | echo "'path' parameter is required." | |
354 | exit 1 | |
355 | fi | |
356 | if [ -z "$name" ] ; then | |
357 | echo "'name' parameter is required." | |
358 | exit 1 | |
359 | fi | |
360 | if [ `id -u` -ne 0 ] ; then | |
361 | echo "This script should be run as 'root'." | |
362 | exit 1 | |
363 | fi | |
364 | cache=@LOCALSTATEDIR@/cache/lxc | |
365 | ptcache=$cache/partial-${prog##*-}-$release-$arch | |
366 | dlcache=$cache/cache-${prog##*-}-$release-$arch | |
367 | rtcache=$cache/rootfs-${prog##*-}-$release-$arch | |
368 | if [ -z "$rootfs" ] ; then | |
369 | if grep -q "^lxc.rootfs" $path/config ; then | |
853d58fd | 370 | rootfs=$(awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config) |
cab79123 KY |
371 | else |
372 | rootfs=$path/rootfs | |
373 | fi | |
374 | fi | |
375 | if ! install_plamo ; then | |
376 | echo "Failed to install plamo $release." | |
377 | exit 1 | |
378 | fi | |
379 | if ! configure_plamo ; then | |
380 | echo "Failed to configure plamo $release for a container." | |
381 | exit 1 | |
382 | fi | |
383 | if ! copy_configuration ; then | |
384 | echo "Failed to write configuration file." | |
385 | exit 1 | |
386 | fi | |
387 | post_process | |
388 | if [ -n "$bindhome" ] ; then | |
389 | do_bindhome | |
390 | fi | |
391 | if [ $clean -eq 1 ] ; then | |
392 | cleanup || exit 1 | |
393 | exit 0 | |
394 | fi |