]> git.proxmox.com Git - mirror_lxc.git/blob - templates/lxc-plamo.in
lxc-oci: rely on jq instead of sed to transform values
[mirror_lxc.git] / templates / lxc-plamo.in
1 #!/bin/bash -eu
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 # Detect use under userns (unsupported)
32 for arg in "$@"; do
33 [ "$arg" = "--" ] && break
34 if [ "$arg" = "--mapped-uid" -o "$arg" = "--mapped-gid" ]; then
35 echo "This template can't be used for unprivileged containers." 1>&2
36 echo "You may want to try the \"download\" template instead." 1>&2
37 exit 1
38 fi
39 done
40
41 # Make sure the usual locations are in PATH
42 export PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
43
44 [ -r /etc/default/lxc ] && . /etc/default/lxc
45
46 DLSCHEME=${DLSCHEME:-"http"}
47 MIRRORSRV=${MIRRORSRV:-"repository.plamolinux.org"}
48 MIRRORPATH=${MIRRORPATH:-"/pub/linux/Plamo"}
49 CATEGORIES=${CATEGORIES-"00_base 01_minimum"}
50 EXTRACTGRS=${EXTRACTGRS-""}
51 IGNOREPKGS=${IGNOREPKGS-"grub kernel lilo linux_firmware microcode_ctl
52 cpufreqd cpufrequtils gpm ntp kmod"}
53 ADDONPKGS=${ADDONPKGS-"`echo contrib/Hamradio/{morse,qrq}`"}
54
55 download_plamo() {
56 # check the mini plamo was not already downloaded
57 if ! mkdir -p $ptcache ; then
58 echo "Failed to create '$ptcache' directory."
59 return 1
60 fi
61 # download a mini plamo into a cache
62 echo "Downloading Plamo-$release minimal..."
63 cd $ptcache
64 case $DLSCHEME in http) depth=2 ;; ftp) depth=3 ;; esac
65 rej=${IGNOREPKGS%% *} ; [ -n "$rej" ] && rej="$rej-*"
66 if [ `echo $IGNOREPKGS | wc -w` -gt 1 ] ; then
67 for p in ${IGNOREPKGS#* } ; do rej="$rej,$p-*" ; done
68 fi
69 for i in $CATEGORIES ; do
70 wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \
71 -I $MIRRORPATH/Plamo-$release/$arch/plamo/$i \
72 -X $MIRRORPATH/Plamo-$release/$arch/plamo/$i/old \
73 $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/plamo/$i
74 if [ $? -ne 0 ] ; then
75 echo "Failed to download the rootfs, aborting."
76 return 1
77 fi
78 done
79 for i in $EXTRACTGRS ; do
80 wget -nv -e robots=off -r -l $depth -nd -A .tgz,.txz -R "$rej" \
81 -I $MIRRORPATH/Plamo-$release/$arch/contrib/$i \
82 -X $MIRRORPATH/Plamo-$release/$arch/contrib/$i/old \
83 $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/contrib/$i
84 if [ $? -ne 0 ] ; then
85 echo "Failed to download the rootfs, aborting."
86 return 1
87 fi
88 done
89 for p in $ADDONPKGS ; do
90 wget -nv -e robots=off -r -l $depth -nd -A "`basename $p`-*" \
91 -I $MIRRORPATH/Plamo-$release/$arch/`dirname $p` \
92 -X $MIRRORPATH/Plamo-$release/$arch/`dirname $p`/old \
93 $DLSCHEME://$MIRRORSRV$MIRRORPATH/Plamo-$release/$arch/`dirname $p`
94 if [ $? -ne 0 ] ; then
95 echo "Failed to download the rootfs, aborting."
96 return 1
97 fi
98 done
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 9 ; 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
126 # install "installpkg" command temporarily with static linked tar
127 # command into the lxc cache directory to keep the original uid/
128 # gid of files/directories.
129 echo "Installing 'installpkg' command into $dlcache/sbin..."
130 ( cd $dlcache ; tar xpJf hdsetup-*.txz ; rm -rf tmp usr var )
131 sed -i "/ldconfig/!s@/sbin@$dlcache&@g" $dlcache/sbin/installpkg*
132 PATH=$dlcache/sbin:$PATH
133 echo "Installing packages to $rtcache..."
134 if [ ! -d $rtcache ] ; then
135 mkdir -p $rtcache
136 for p in `ls -cr $dlcache/*.t?z` ; do
137 installpkg -root $rtcache -priority ADD $p
138 done
139 fi
140 echo "Copy $rtcache to $rootfs..."
141 if ! copy_plamo ; then
142 echo "Failed to copy rootfs."
143 return 1
144 fi
145 return 0
146 ) 9> @LOCALSTATEDIR@/lock/subsys/lxc-plamo
147 }
148
149 configure_plamo() {
150 # suppress log level output for udev
151 sed -i 's/="err"/=0/' $rootfs/etc/udev/udev.conf
152 # /etc/fstab
153 cat <<- "EOF" > $rootfs/etc/fstab
154 none /proc proc defaults 0 0
155 none /sys sysfs defaults 0 0
156 none /dev tmpfs defaults 0 0
157 none /tmp tmpfs defaults 0 0
158 none /dev/pts devpts gid=5,mode=620 0 0
159 none /proc/bus/usb usbfs noauto 0 0
160 none /var/lib/nfs/rpc_pipefs rpc_pipefs defaults 0 0
161 EOF
162 # /etc/inittab
163 cat <<- "EOF" | patch $rootfs/etc/inittab
164 32,33c32,33
165 < # What to do when power fails (shutdown to single user).
166 < pf::powerfail:/sbin/shutdown -f +5 "THE POWER IS FAILING"
167 ---
168 > # What to do when power fails (shutdown).
169 > pf::powerfail:/sbin/shutdown -h +0 "THE POWER IS FAILING"
170 47a48
171 > 1:1235:respawn:/sbin/agetty 38400 console
172 52,53d52
173 < c5:1235:respawn:/sbin/agetty 38400 tty5 linux
174 < c6:12345:respawn:/sbin/agetty 38400 tty6 linux
175 EOF
176 # set the hostname
177 echo "$name" > $rootfs/etc/HOSTNAME
178 # set minimal hosts
179 echo "127.0.0.1 localhost $name" > $rootfs/etc/hosts
180 # configure the network using the dhcp
181 echo "DHCP" > $rootfs/var/run/inet1-scheme
182 # localtime (JST)
183 ln -s ../usr/share/zoneinfo/Asia/Tokyo $rootfs/etc/localtime
184 # disable pam_loginuid.so in /etc/pam.d/login (for libvirt's lxc driver)
185 sed -i '/pam_loginuid/s/^/#/' $rootfs/etc/pam.d/login
186 # glibc configure
187 mv $rootfs/etc/ld.so.conf{.new,}
188 chroot $rootfs ldconfig
189
190 # delete unnecessary process from rc.S
191 ed - $rootfs/etc/rc.d/rc.S <<- "EOF"
192 /^mount -w -n -t proc/;/^mkdir \/dev\/shm/-1d
193 /^mknod \/dev\/null/;/^# Clean \/etc\/mtab/-2d
194 /^# copy the rules/;/^# Set the hostname/-1d
195 /^# Check the integrity/;/^# Clean up temporary/-1d
196 w
197 EOF
198
199 # delete unnecessary process from rc.M
200 ed - $rootfs/etc/rc.d/rc.M <<- "EOF"
201 /^# Screen blanks/;/^# Initialize ip6tables/-1d
202 /^# Initialize sysctl/;/^echo "Starting services/-1d
203 /^sync/;/^# All done/-1d
204 w
205 EOF
206
207 # delete unnecessary process from rc.6
208 ed - $rootfs/etc/rc.d/rc.6 <<- "EOF"
209 /^# Save system time/;/^# Unmount any remote filesystems/-1d
210 /^# Turn off swap/;/^# See if this is a powerfail situation/-1d
211 w
212 EOF
213
214 # /etc/rc.d/rc.inet1.tradnet
215 head -n-93 $rootfs/sbin/netconfig.tradnet > /tmp/netconfig.rconly
216 cat <<- EOF >> /tmp/netconfig.rconly
217 PCMCIA=n
218 RC=$rootfs/etc/rc.d/rc.inet1.tradnet
219 IFCONFIG=sbin/ifconfig
220 ROUTE=sbin/route
221 INET1SCHEME=var/run/inet1-scheme
222 IPADDR=127.0.0.1
223 NETWORK=127.0.0.0
224 DHCPCD=usr/sbin/dhclient
225 LOOPBACK=y
226 make_config_file
227 EOF
228 rm -f $rootfs/etc/rc.d/rc.inet1.tradnet
229 sh /tmp/netconfig.rconly
230 rm -f /tmp/netconfig.rconly
231 sed -i '/cmdline/s/if/& false \&\&/' $rootfs/etc/rc.d/rc.inet1.tradnet
232 # /etc/rc.d/rc.inet2
233 sed -i '/rpc.mountd/s/^/#/' $rootfs/etc/rc.d/rc.inet2
234 sed -i '/modprobe/s/^/#/' $rootfs/etc/rc.d/rc.inet2
235 # configure to start only the minimum of service
236 chmod 644 $rootfs/etc/rc.d/init.d/saslauthd
237 chmod 644 $rootfs/etc/rc.d/init.d/open-iscsi
238 rm -f $rootfs/etc/rc.d/init.d/postfix
239 rm -f $rootfs/var/log/initpkg/shadow
240 return 0
241 }
242
243 copy_configuration() {
244 ret=0
245 cat <<- EOF >> $path/config || let ret++
246 lxc.uts.name = $name
247 lxc.arch = $arch
248 EOF
249 if [ -f "@LXCTEMPLATECONFIG@/plamo.common.conf" ] ; then
250 cat <<- "EOF" >> $path/config || let ret++
251
252 lxc.include = @LXCTEMPLATECONFIG@/plamo.common.conf
253 EOF
254 fi
255 if [ $ret -ne 0 ] ; then
256 echo "Failed to add configuration."
257 return 1
258 fi
259 return 0
260 }
261
262 post_process() {
263 # nothing do in Plamo Linux
264 true
265 }
266
267 do_bindhome() {
268 # bind-mount the user's path into the container's /home
269 h=`getent passwd $bindhome | cut -d: -f6`
270 mkdir -p $rootfs/$h
271 echo "lxc.mount.entry = $h $rootfs/$h none bind 0 0" >> $path/config
272 # copy /etc/passwd, /etc/shadow, and /etc/group entries into container
273 if ! pwd=`getent passwd $bindhome` ; then
274 echo "Warning: failed to copy password entry for $bindhome."
275 else
276 echo $pwd >> $rootfs/etc/passwd
277 fi
278 echo `getent shadow $bindhome` >> $rootfs/etc/shadow
279 }
280
281 cleanup() {
282 [ -d $dlcache -a -d $rtcache ] || return 0
283 # lock, so we won't purge while someone is creating a repository
284 (
285 if ! flock -n 9 ; then
286 echo "Cache repository is busy."
287 return 1
288 fi
289 echo "Purging the download cache..."
290 rm -rf --one-file-system $dlcache $rtcache || return 1
291 echo "Done."
292 return 0
293 ) 9> @LOCALSTATEDIR@/lock/subsys/lxc-plamo
294 }
295
296 usage() {
297 cat <<- EOF
298 $prog [-h|--help] -p|--path=<path> -n|--name=<name> --rootfs=<rootfs>
299 [-c|--clean] [-r|--release=<release>] [-a|--arch=<arch>]
300 [-b|--bindhome=<user>]
301 release: $release
302 arch: x86 or x86_64: defaults to host arch
303 bindhome: bind <user>'s home into the container
304 EOF
305 }
306
307 prog=`basename $0`
308 path="" ; name="" ; rootfs=""
309 clean=0
310 release=${release:-6.x}
311 arch=`uname -m | sed 's/i.86/x86/'` ; hostarch=$arch
312 bindhome=""
313 sopts=hp:n:cr:a:b:
314 lopts=help,path:,name:,rootfs:,clean,release:,arch:,bindhome:
315 if ! options=`getopt -o $sopts -l $lopts -- "$@"` ; then
316 usage
317 exit 1
318 fi
319 eval set -- "$options"
320 while true ; do
321 case "$1" in
322 -h|--help) usage && exit 0 ;;
323 -p|--path) path=$2 ; shift 2 ;;
324 -n|--name) name=$2 ; shift 2 ;;
325 --rootfs) rootfs=$2 ; shift 2 ;;
326 -c|--clean) clean=1 ; shift 1 ;;
327 -r|--release) release=$2 ; shift 2 ;;
328 -a|--arch) arch=$2 ; shift 2 ;;
329 -b|--bindhome) bindhome=$2 ; shift 2 ;;
330 --) shift 1 ; break ;;
331 *) break ;;
332 esac
333 done
334 if [ $clean -eq 1 -a -z "$path" ] ; then
335 cleanup || exit 1
336 exit 0
337 fi
338 if [ $hostarch == "x86" -a $arch == "x86_64" ] ; then
339 echo "Can't create x86_64 container on x86."
340 exit 1
341 fi
342 if [ -z "$path" ] ; then
343 echo "'path' parameter is required."
344 exit 1
345 fi
346 if [ -z "$name" ] ; then
347 echo "'name' parameter is required."
348 exit 1
349 fi
350 if [ `id -u` -ne 0 ] ; then
351 echo "This script should be run as 'root'."
352 exit 1
353 fi
354 cache="${LXC_CACHE_PATH:-@LOCALSTATEDIR@/cache/lxc}"
355 ptcache=$cache/partial-${prog##*-}-$release-$arch
356 dlcache=$cache/cache-${prog##*-}-$release-$arch
357 rtcache=$cache/rootfs-${prog##*-}-$release-$arch
358 if [ -z "$rootfs" ] ; then
359 if grep -q "^lxc.rootfs.path" $path/config ; then
360 rootfs=`awk -F= '/^lxc.rootfs.path =/{ print $2 }' $path/config`
361 else
362 rootfs=$path/rootfs
363 fi
364 fi
365 if ! install_plamo ; then
366 echo "Failed to install plamo $release."
367 exit 1
368 fi
369 if ! configure_plamo ; then
370 echo "Failed to configure plamo $release for a container."
371 exit 1
372 fi
373 if ! copy_configuration ; then
374 echo "Failed to write configuration file."
375 exit 1
376 fi
377 post_process
378 if [ -n "$bindhome" ] ; then
379 do_bindhome
380 fi
381 if [ $clean -eq 1 ] ; then
382 cleanup || exit 1
383 exit 0
384 fi