]>
Commit | Line | Data |
---|---|---|
7a49a081 | 1 | #!/bin/bash -eu |
cab79123 KY |
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 | ||
7a49a081 | 33 | DLSCHEME=${DLSCHEME:-"http"} |
adf4b408 | 34 | MIRRORSRV=${MIRRORSRV:-"www.ring.gr.jp"} |
7a49a081 | 35 | MIRRORPATH=${MIRRORPATH:-"/pub/linux/Plamo"} |
8c3a756e KY |
36 | CATEGORIES=${CATEGORIES-"00_base 01_minimum"} |
37 | EXTRACTGRS=${EXTRACTGRS-""} | |
38 | IGNOREPKGS=${IGNOREPKGS-"grub kernel lilo linux_firmware microcode_ctl | |
adf4b408 | 39 | cpufreqd cpufrequtils gpm"} |
8c3a756e | 40 | ADDONPKGS=${ADDONPKGS-"`echo contrib/Hamradio/{morse,qrq}`"} |
cab79123 KY |
41 | |
42 | download_plamo() { | |
43 | # check the mini plamo was not already downloaded | |
44 | if ! mkdir -p $ptcache ; then | |
45 | echo "Failed to create '$ptcache' directory." | |
46 | return 1 | |
47 | fi | |
48 | # download a mini plamo into a cache | |
49 | echo "Downloading Plamo-$release minimal..." | |
8adef761 | 50 | cd $ptcache |
7a49a081 KY |
51 | case $DLSCHEME in http) depth=2 ;; ftp) depth=3 ;; esac |
52 | rej=${IGNOREPKGS%% *} ; [ -n "$rej" ] && rej="$rej-*" | |
8c3a756e | 53 | if [ `echo $IGNOREPKGS | wc -w` -gt 1 ] ; then |
adf4b408 KY |
54 | for p in ${IGNOREPKGS#* } ; do rej="$rej,$p-*" ; done |
55 | fi | |
7a49a081 | 56 | for i in $CATEGORIES ; do |
adf4b408 | 57 | wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \ |
7a49a081 KY |
58 | -I $MIRRORPATH/Plamo-$release/$arch/plamo/$i \ |
59 | -X $MIRRORPATH/Plamo-$release/$arch/plamo/$i/old \ | |
60 | $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/plamo/$i | |
61 | if [ $? -ne 0 ] ; then | |
62 | echo "Failed to download the rootfs, aborting." | |
63 | return 1 | |
64 | fi | |
65 | done | |
66 | for i in $EXTRACTGRS ; do | |
adf4b408 | 67 | wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \ |
7a49a081 KY |
68 | -I $MIRRORPATH/Plamo-$release/$arch/contrib/$i \ |
69 | -X $MIRRORPATH/Plamo-$release/$arch/contrib/$i/old \ | |
70 | $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/contrib/$i | |
71 | if [ $? -ne 0 ] ; then | |
72 | echo "Failed to download the rootfs, aborting." | |
8adef761 KY |
73 | return 1 |
74 | fi | |
cab79123 | 75 | done |
adf4b408 KY |
76 | for p in $ADDONPKGS ; do |
77 | wget -nv -e robots=off -r -l $depth -nd -A "`basename $p`-*" \ | |
78 | -I $MIRRORPATH/Plamo-$release/$arch/`dirname $p` \ | |
79 | -X $MIRRORPATH/Plamo-$release/$arch/`dirname $p`/old \ | |
80 | $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/`dirname $p` | |
81 | if [ $? -ne 0 ] ; then | |
82 | echo "Failed to download the rootfs, aborting." | |
83 | return 1 | |
84 | fi | |
85 | done | |
cab79123 KY |
86 | mv $ptcache $dlcache |
87 | echo "Download complete." | |
88 | return 0 | |
89 | } | |
90 | ||
91 | copy_plamo() { | |
92 | # make a local copy of the mini plamo | |
93 | echo "Copying $rtcache to $rootfs..." | |
94 | mkdir -p $rootfs | |
95 | find $rtcache -mindepth 1 -maxdepth 1 -exec cp -a {} $rootfs \; || return 1 | |
96 | return 0 | |
97 | } | |
98 | ||
99 | install_plamo() { | |
100 | mkdir -p @LOCALSTATEDIR@/lock/subsys | |
101 | ( | |
102 | if ! flock -n 200 ; then | |
103 | echo "Cache repository is busy." | |
104 | return 1 | |
105 | fi | |
106 | echo "Checking cache download in $dlcache..." | |
107 | if [ ! -d $dlcache ] ; then | |
108 | if ! download_plamo ; then | |
109 | echo "Failed to download plamo $release base packages." | |
110 | return 1 | |
111 | fi | |
112 | fi | |
92cbfdaf KY |
113 | if [ ! -x /sbin/installpkg ] ; then |
114 | echo "'installpkg' command is missing." | |
115 | echo "Installing 'installpkg' command into $dlcache/sbin..." | |
116 | ( cd $dlcache ; tar xpJf hdsetup-*.txz ; rm -rf tmp usr var ) | |
117 | sed -i "/ldconfig/!s@/sbin@$dlcache&@g" $dlcache/sbin/installpkg* | |
118 | PATH=$dlcache/sbin:$PATH | |
119 | fi | |
cab79123 KY |
120 | echo "Installing packages to $rtcache..." |
121 | if [ ! -d $rtcache ] ; then | |
122 | mkdir -p $rtcache | |
7a49a081 | 123 | for p in `ls -cr $dlcache/*.t?z` ; do |
8adef761 | 124 | installpkg -root $rtcache -priority ADD $p |
cab79123 KY |
125 | done |
126 | fi | |
127 | echo "Copy $rtcache to $rootfs..." | |
128 | if ! copy_plamo ; then | |
129 | echo "Failed to copy rootfs." | |
130 | return 1 | |
131 | fi | |
132 | return 0 | |
420dfb59 | 133 | ) 200> @LOCALSTATEDIR@/lock/subsys/lxc-plamo |
cab79123 KY |
134 | } |
135 | ||
136 | configure_plamo() { | |
137 | # create /dev | |
138 | mknod -m 666 $rootfs/dev/zero c 1 5 | |
139 | chmod 666 $rootfs/dev/random | |
140 | mknod -m 666 $rootfs/dev/urandom c 1 9 | |
141 | mkdir -m 755 $rootfs/dev/pts | |
142 | chmod 666 $rootfs/dev/tty | |
143 | chmod 600 $rootfs/dev/console | |
144 | mknod -m 666 $rootfs/dev/tty0 c 4 0 | |
145 | mknod -m 666 $rootfs/dev/tty1 c 4 1 | |
146 | mknod -m 666 $rootfs/dev/tty2 c 4 2 | |
147 | mknod -m 666 $rootfs/dev/tty3 c 4 3 | |
148 | mknod -m 666 $rootfs/dev/tty4 c 4 4 | |
149 | mknod -m 666 $rootfs/dev/full c 1 7 | |
150 | mknod -m 600 $rootfs/dev/initctl p | |
151 | mknod -m 666 $rootfs/dev/ptmx c 5 2 | |
152 | # suppress log level output for udev | |
153 | sed -i 's/="err"/=0/' $rootfs/etc/udev/udev.conf | |
154 | # /etc/fstab | |
155 | cat <<- "EOF" > $rootfs/etc/fstab | |
156 | none /proc proc defaults 0 0 | |
157 | none /sys sysfs defaults 0 0 | |
158 | none /dev tmpfs defaults 0 0 | |
159 | none /tmp tmpfs defaults 0 0 | |
160 | none /dev/pts devpts gid=5,mode=620 0 0 | |
161 | none /proc/bus/usb usbfs noauto 0 0 | |
162 | none /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0 | |
163 | EOF | |
164 | # /etc/inittab | |
165 | cat <<- "EOF" | patch $rootfs/etc/inittab | |
db821c3a KY |
166 | 32,33c32,33 |
167 | < # What to do when power fails (shutdown to single user). | |
168 | < pf::powerfail:/sbin/shutdown -f +5 "THE POWER IS FAILING" | |
169 | --- | |
170 | > # What to do when power fails (shutdown). | |
171 | > pf::powerfail:/sbin/shutdown -h +0 "THE POWER IS FAILING" | |
cab79123 KY |
172 | 47a48 |
173 | > 1:1235:respawn:/sbin/agetty 38400 console | |
174 | 52,53d52 | |
175 | < c5:1235:respawn:/sbin/agetty 38400 tty5 linux | |
176 | < c6:12345:respawn:/sbin/agetty 38400 tty6 linux | |
177 | EOF | |
178 | # set the hostname | |
179 | echo "$name" > $rootfs/etc/HOSTNAME | |
180 | # set minimal hosts | |
181 | echo "127.0.0.1 localhost $name" > $rootfs/etc/hosts | |
182 | # configure the network using the dhcp | |
183 | echo "DHCP" > $rootfs/var/run/inet1-scheme | |
184 | # localtime (JST) | |
185 | ln -s ../usr/share/zoneinfo/Asia/Tokyo $rootfs/etc/localtime | |
186 | # disable pam_loginuid.so in /etc/pam.d/login (for libvirt's lxc driver) | |
187 | sed -i '/pam_loginuid/s/^/#/' $rootfs/etc/pam.d/login | |
a1e4c206 | 188 | # glibc configure |
0dc29614 | 189 | mv $rootfs/etc/ld.so.conf{.new,} |
a1e4c206 | 190 | chroot $rootfs ldconfig |
cab79123 KY |
191 | # root password |
192 | echo "Setting root password to 'root'..." | |
193 | echo "root:root" | chroot $rootfs chpasswd | |
194 | echo "Please change root password!" | |
195 | # /etc/rc.d/rc.S | |
196 | ed - $rootfs/etc/rc.d/rc.S <<- "EOF" | |
197 | 230,261d | |
198 | 156,163d | |
199 | 26,147d | |
200 | 16,22d | |
201 | w | |
202 | EOF | |
203 | # /etc/rc.d/rc.M | |
204 | ed - $rootfs/etc/rc.d/rc.M <<- "EOF" | |
41e8e807 KY |
205 | 269,270d |
206 | 56,82d | |
cab79123 KY |
207 | 31,38d |
208 | w | |
209 | EOF | |
210 | # /etc/rc.d/rc.inet1.tradnet | |
211 | head -n-93 $rootfs/sbin/netconfig.tradnet > /tmp/netconfig.rconly | |
212 | cat <<- EOF >> /tmp/netconfig.rconly | |
213 | PCMCIA=n | |
214 | RC=$rootfs/etc/rc.d/rc.inet1.tradnet | |
215 | IFCONFIG=sbin/ifconfig | |
216 | ROUTE=sbin/route | |
217 | INET1SCHEME=var/run/inet1-scheme | |
218 | IPADDR=127.0.0.1 | |
219 | NETWORK=127.0.0.0 | |
220 | DHCPCD=usr/sbin/dhclient | |
221 | LOOPBACK=y | |
222 | make_config_file | |
223 | EOF | |
224 | rm -f $rootfs/etc/rc.d/rc.inet1.tradnet | |
225 | sh /tmp/netconfig.rconly | |
226 | rm -f /tmp/netconfig.rconly | |
227 | return 0 | |
228 | } | |
229 | ||
230 | copy_configuration() { | |
7a49a081 KY |
231 | ret=0 |
232 | cat <<- EOF >> $path/config || let ret++ | |
cab79123 | 233 | lxc.utsname = $name |
bf3e09c0 | 234 | lxc.mount = $path/fstab |
7a49a081 | 235 | lxc.arch = $arch |
cab79123 | 236 | EOF |
7a49a081 KY |
237 | if [ -f "@LXCTEMPLATECONFIG@/plamo.common.conf" ] ; then |
238 | cat <<- "EOF" >> $path/config || let ret++ | |
239 | ||
240 | lxc.include = @LXCTEMPLATECONFIG@/plamo.common.conf | |
241 | EOF | |
242 | fi | |
243 | # create the fstab (empty by default) | |
244 | touch $path/fstab || let ret++ | |
245 | if [ $ret -ne 0 ] ; then | |
cab79123 KY |
246 | echo "Failed to add configuration." |
247 | return 1 | |
248 | fi | |
249 | return 0 | |
250 | } | |
251 | ||
252 | post_process() { | |
253 | # nothing do in Plamo Linux | |
254 | true | |
255 | } | |
256 | ||
257 | do_bindhome() { | |
258 | # bind-mount the user's path into the container's /home | |
259 | h=`getent passwd $bindhome | cut -d: -f6` | |
260 | mkdir -p $rootfs/$h | |
261 | echo "$h $rootfs/$h none bind 0 0" >> $path/fstab | |
262 | # copy /etc/passwd, /etc/shadow, and /etc/group entries into container | |
263 | if ! pwd=`getent passwd $bindhome` ; then | |
264 | echo "Warning: failed to copy password entry for $bindhome." | |
265 | else | |
266 | echo $pwd >> $rootfs/etc/passwd | |
267 | fi | |
268 | echo `getent shadow $bindhome` >> $rootfs/etc/shadow | |
269 | } | |
270 | ||
271 | cleanup() { | |
272 | [ -d $dlcache -a -d $rtcache ] || return 0 | |
273 | # lock, so we won't purge while someone is creating a repository | |
274 | ( | |
275 | if ! flock -n 200 ; then | |
276 | echo "Cache repository is busy." | |
277 | return 1 | |
278 | fi | |
279 | echo "Purging the download cache..." | |
280 | rm -rf --one-file-system $dlcache $rtcache || return 1 | |
281 | echo "Done." | |
282 | return 0 | |
420dfb59 | 283 | ) 200> @LOCALSTATEDIR@/lock/subsys/lxc-plamo |
cab79123 KY |
284 | } |
285 | ||
286 | usage() { | |
287 | cat <<- EOF | |
288 | $prog [-h|--help] -p|--path=<path> -n|--name=<name> --rootfs=<rootfs> | |
289 | [--clean] [-r|--release=<release>] [-b|--bindhome=<user>] | |
290 | [-a|--arch=<arch>] | |
291 | release: $release | |
292 | bindhome: bind <user>'s home into the container | |
293 | arch: x86 or x86_64: defaults to host arch | |
294 | EOF | |
295 | } | |
296 | ||
297 | prog=`basename $0` | |
298 | path="" ; name="" ; rootfs="" | |
299 | clean=0 | |
300 | release=${release:-5.x} | |
301 | bindhome="" | |
302 | arch=`uname -m | sed 's/i.86/x86/'` ; hostarch=$arch | |
303 | sopts=hp:n:cr:b:a: | |
304 | lopts=help,path:,name:,rootfs:,clean,release:,bindhome:,arch: | |
305 | if ! options=`getopt -o $sopts -l $lopts -- "$@"` ; then | |
306 | usage | |
307 | exit 1 | |
308 | fi | |
309 | eval set -- "$options" | |
310 | while true ; do | |
311 | case "$1" in | |
312 | -h|--help) usage && exit 0 ;; | |
313 | -p|--path) path=$2 ; shift 2 ;; | |
314 | -n|--name) name=$2 ; shift 2 ;; | |
315 | --rootfs) rootfs=$2 ; shift 2 ;; | |
316 | -c|--clean) clean=1 ; shift 1 ;; | |
317 | -r|--release) release=$2 ; shift 2 ;; | |
318 | -b|--bindhome) bindhome=$2 ; shift 2 ;; | |
319 | -a|--arch) arch=$2 ; shift 2 ;; | |
320 | --) shift 1 ; break ;; | |
321 | *) break ;; | |
322 | esac | |
323 | done | |
324 | if [ $clean -eq 1 -a -z "$path" ] ; then | |
325 | cleanup || exit 1 | |
326 | exit 0 | |
327 | fi | |
328 | if [ $hostarch == "x86" -a $arch == "x86_64" ] ; then | |
329 | echo "Can't create x86_64 container on x86." | |
330 | exit 1 | |
331 | fi | |
cab79123 KY |
332 | if [ -z "$path" ] ; then |
333 | echo "'path' parameter is required." | |
334 | exit 1 | |
335 | fi | |
336 | if [ -z "$name" ] ; then | |
337 | echo "'name' parameter is required." | |
338 | exit 1 | |
339 | fi | |
340 | if [ `id -u` -ne 0 ] ; then | |
341 | echo "This script should be run as 'root'." | |
342 | exit 1 | |
343 | fi | |
344 | cache=@LOCALSTATEDIR@/cache/lxc | |
345 | ptcache=$cache/partial-${prog##*-}-$release-$arch | |
346 | dlcache=$cache/cache-${prog##*-}-$release-$arch | |
347 | rtcache=$cache/rootfs-${prog##*-}-$release-$arch | |
348 | if [ -z "$rootfs" ] ; then | |
349 | if grep -q "^lxc.rootfs" $path/config ; then | |
8c3a756e | 350 | rootfs=`awk -F= '/^lxc.rootfs =/{ print $2 }' $path/config` |
cab79123 KY |
351 | else |
352 | rootfs=$path/rootfs | |
353 | fi | |
354 | fi | |
355 | if ! install_plamo ; then | |
356 | echo "Failed to install plamo $release." | |
357 | exit 1 | |
358 | fi | |
359 | if ! configure_plamo ; then | |
360 | echo "Failed to configure plamo $release for a container." | |
361 | exit 1 | |
362 | fi | |
363 | if ! copy_configuration ; then | |
364 | echo "Failed to write configuration file." | |
365 | exit 1 | |
366 | fi | |
367 | post_process | |
368 | if [ -n "$bindhome" ] ; then | |
369 | do_bindhome | |
370 | fi | |
371 | if [ $clean -eq 1 ] ; then | |
372 | cleanup || exit 1 | |
373 | exit 0 | |
374 | fi |