]>
Commit | Line | Data |
---|---|---|
eb960fea DL |
1 | #!/bin/bash |
2 | ||
3 | # | |
4 | # lxc: linux Container library | |
5 | ||
6 | # Authors: | |
7 | # Daniel Lezcano <daniel.lezcano@free.fr> | |
8 | ||
9 | # This library is free software; you can redistribute it and/or | |
10 | # modify it under the terms of the GNU Lesser General Public | |
11 | # License as published by the Free Software Foundation; either | |
12 | # version 2.1 of the License, or (at your option) any later version. | |
13 | ||
14 | # This library is distributed in the hope that it will be useful, | |
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | # Lesser General Public License for more details. | |
18 | ||
19 | # You should have received a copy of the GNU Lesser General Public | |
20 | # License along with this library; if not, write to the Free Software | |
21 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | ||
23 | install_busybox() | |
24 | { | |
25 | rootfs=$1 | |
26 | name=$2 | |
27 | res=0 | |
28 | tree="\ | |
29 | $rootfs/dev \ | |
30 | $rootfs/home \ | |
31 | $rootfs/root \ | |
32 | $rootfs/etc \ | |
33 | $rootfs/etc/init.d \ | |
34 | $rootfs/bin \ | |
35 | $rootfs/sbin \ | |
36 | $rootfs/proc \ | |
37 | $rootfs/mnt \ | |
38 | $rootfs/tmp \ | |
39 | $rootfs/var/log \ | |
40 | $rootfs/usr/share/udhcpc \ | |
41 | $rootfs/dev/shm" | |
42 | ||
43 | mkdir -p $tree || return 1 | |
44 | chmod 755 $tree || return 1 | |
45 | ||
46 | pushd $rootfs/dev > /dev/null || return 1 | |
47 | ||
48 | # minimal devices needed for busybox | |
49 | mknod tty c 5 0 || res=1 | |
50 | mknod console c 5 1 || res=1 | |
51 | chmod 666 tty console || res=1 | |
52 | mknod tty0 c 4 0 || res=1 | |
53 | mknod tty1 c 4 0 || res=1 | |
54 | mknod tty5 c 4 0 || res=1 | |
55 | chmod 666 tty0 || res=1 | |
56 | mknod ram0 b 1 0 || res=1 | |
57 | chmod 600 ram0 || res=1 | |
58 | mknod null c 1 3 || res=1 | |
59 | chmod 666 null || res=1 | |
60 | ||
61 | popd > /dev/null | |
62 | ||
63 | # root user defined | |
64 | cat <<EOF >> $rootfs/etc/passwd | |
65 | root:x:0:0:root:/root:/bin/sh | |
66 | EOF | |
67 | ||
68 | cat <<EOF >> $rootfs/etc/group | |
69 | root:x:0:root | |
70 | EOF | |
71 | ||
72 | # empty password | |
73 | cat <<EOF >> $rootfs/etc/shadow | |
74 | root:\$1\$NJJLsV0P\$Y/esfSXDNR88G/bZFzgWY1:14595:0:99999:7::: | |
75 | EOF | |
76 | ||
77 | echo "empty password for root, don't forget to change it !" | |
78 | ||
79 | # mount everything | |
80 | cat <<EOF >> $rootfs/etc/init.d/rcS | |
81 | #!/bin/sh | |
82 | syslogd | |
83 | mount -a | |
84 | udhcpc | |
85 | EOF | |
86 | ||
87 | # executable | |
88 | chmod 744 $rootfs/etc/init.d/rcS || return 1 | |
89 | ||
90 | # mount points | |
91 | cat <<EOF >> $rootfs/etc/fstab | |
92 | proc /proc proc defaults 0 0 | |
93 | shm /dev/shm tmpfs defaults 0 0 | |
94 | EOF | |
95 | ||
96 | # writable and readable for other | |
97 | chmod 644 $rootfs/etc/fstab || return 1 | |
98 | ||
99 | # launch rcS first then make a console available | |
100 | # and propose a shell on the tty, the last one is | |
101 | # not needed | |
102 | cat <<EOF >> $rootfs/etc/inittab | |
103 | ::sysinit:/etc/init.d/rcS | |
104 | ::respawn:/bin/getty -L tty1 115200 vt100 | |
105 | ::askfirst:/bin/sh | |
106 | EOF | |
107 | # writable and readable for other | |
108 | chmod 644 $rootfs/etc/inittab || return 1 | |
109 | ||
110 | cat <<EOF >> $rootfs/usr/share/udhcpc/default.script | |
111 | #!/bin/sh | |
112 | ||
113 | case "\$1" in | |
114 | deconfig) | |
115 | ip addr flush dev \$interface | |
116 | ;; | |
117 | ||
118 | renew|bound) | |
119 | ||
120 | # flush all the routes | |
121 | if [ -n "\$router" ]; then | |
122 | ip route del default 2> /dev/null | |
123 | fi | |
124 | ||
125 | # check broadcast | |
126 | if [ -n "\$broadcast" ]; then | |
127 | broadcast="broadcast \$broadcast" | |
128 | fi | |
129 | ||
130 | # add a new ip address | |
131 | ip addr add \$ip/\$mask \$broadcast dev \$interface | |
132 | ||
133 | if [ -n "\$router" ]; then | |
134 | ip route add default via \$router dev \$interface | |
135 | fi | |
136 | ||
137 | [ -n "\$domain" ] && echo search \$domain > /etc/resolv.conf | |
138 | for i in \$dns ; do | |
139 | echo nameserver \$i >> /etc/resolv.conf | |
140 | done | |
141 | ;; | |
142 | esac | |
143 | exit 0 | |
144 | EOF | |
145 | ||
146 | chmod 744 $rootfs/usr/share/udhcpc/default.script | |
147 | ||
148 | return $res | |
149 | } | |
150 | ||
151 | configure_busybox() | |
152 | { | |
153 | rootfs=$1 | |
154 | ||
155 | functions="\ | |
156 | [ [[ addgroup adduser adjtimex ar arp arping ash awk basename brctl bunzip2 bzcat bzip2 cal cat catv chattr chgrp chmod chown chpasswd chpst chroot chrt chvt cksum clear cmp comm cp cpio crond crontab cryptpw cut date dc dd deallocvt delgroup deluser df dhcprelay diff dirname dmesg dnsd dos2unix du dumpkmap dumpleases echo ed egrep eject env envdir envuidgid ether-wake expand expr fakeidentd false fbset fdformat fdisk fetchmail fgrep find findfs fold free freeramdisk fsck fsck.minix ftpget ftpput fuser getopt getty grep gunzip gzip halt hdparm head hexdump hostid hostname httpd hwclock id ifconfig ifdown ifenslave ifup inetd init insmod install ip ipaddr ipcalc ipcrm ipcs iplink iproute iprule iptunnel kbd_mode kill killall killall5 klogd last length less linux32 linux64 linuxrc ln loadfont loadkmap logger login logname logread losetup lpd lpq lpr ls lsattr lsmod lzmacat makedevs md5sum mdev mesg microcom mkdir mkfifo mkfs.minix mknod mkswap mktemp modprobe more mount mountpoint msh mt mv nameif nc netstat nice nmeter nohup nslookup od openvt passwd patch pgrep pidof ping ping6 pipe_progress pivot_root pkill poweroff printenv printf ps pscan pwd raidautorun rdate readahead readlink readprofile realpath reboot renice reset resize rm rmdir rmmod route rpm rpm2cpio run-parts runlevel runsv runsvdir rx script sed sendmail seq setarch setconsole setkeycodes setlogcons setsid setuidgid sh sha1sum slattach sleep softlimit sort split start-stop-daemon stat strings stty su sulogin sum sv svlogd swapoff swapon switch_root sync sysctl syslogd tac tail tar taskset tcpsvd tee telnet telnetd test tftp tftpd time top touch tr traceroute true tty ttysize udhcpc udhcpd udpsvd umount uname uncompress unexpand uniq unix2dos unlzma unzip uptime usleep uudecode uuencode vconfig vi vlock watch watchdog wc wget which who whoami xargs yes zcat zcip" | |
157 | ||
158 | type busybox | |
159 | if [ $? -ne 0 ]; then | |
160 | echo "busybox executable is not accessible" | |
161 | return 1 | |
162 | fi | |
163 | ||
164 | # copy busybox in the rootfs | |
165 | cp $(which busybox) $rootfs/bin | |
166 | if [ $? -ne 0 ]; then | |
167 | echo "failed to copy busybox in the rootfs" | |
168 | return 1 | |
169 | fi | |
170 | ||
171 | # do hardlink to busybox for the different commands | |
172 | for i in $functions; do ln $rootfs/bin/busybox $rootfs/bin/$i; done | |
173 | ||
174 | # relink /sbin/init | |
175 | ln $rootfs/bin/busybox $rootfs/sbin/init | |
176 | ||
177 | # passwd exec must be setuid | |
178 | chmod +s $rootfs/bin/passwd | |
179 | ||
180 | return 0 | |
181 | } | |
182 | ||
183 | copy_configuration() | |
184 | { | |
185 | path=$1 | |
186 | rootfs=$2 | |
187 | name=$3 | |
188 | ||
189 | cat <<EOF >> $path/config | |
190 | lxc.utsname = $name | |
191 | lxc.tty = 1 | |
192 | lxc.rootfs = $rootfs | |
193 | lxc.cgroup.devices.deny = a | |
194 | # /dev/null and zero | |
195 | lxc.cgroup.devices.allow = c 1:3 rwm | |
196 | lxc.cgroup.devices.allow = c 1:5 rwm | |
197 | # consoles | |
198 | lxc.cgroup.devices.allow = c 5:1 rwm | |
199 | lxc.cgroup.devices.allow = c 5:0 rwm | |
200 | lxc.cgroup.devices.allow = c 4:0 rwm | |
201 | lxc.cgroup.devices.allow = c 4:1 rwm | |
202 | # /dev/{,u}random | |
203 | lxc.cgroup.devices.allow = c 1:9 rwm | |
204 | lxc.cgroup.devices.allow = c 1:8 rwm | |
205 | lxc.cgroup.devices.allow = c 136:* rwm | |
206 | lxc.cgroup.devices.allow = c 5:2 rwm | |
207 | # rtc | |
208 | lxc.cgroup.devices.allow = c 254:0 rwm | |
209 | EOF | |
210 | } | |
211 | ||
212 | usage() | |
213 | { | |
214 | cat <<EOF | |
215 | $1 -h|--help -p|--path=<path> | |
216 | EOF | |
217 | return 0 | |
218 | } | |
219 | ||
220 | options=$(getopt -o hp:n: -l help,path:,name: -- "$@") | |
221 | if [ $? -ne 0 ]; then | |
222 | usage $(basename $0) | |
223 | exit 1 | |
224 | fi | |
225 | eval set -- "$options" | |
226 | ||
227 | while true | |
228 | do | |
229 | case "$1" in | |
230 | -h|--help) usage $0 && exit 0;; | |
231 | -p|--path) path=$2; shift 2;; | |
232 | -n|--name) name=$2; shift 2;; | |
233 | --) shift 1; break ;; | |
234 | *) break ;; | |
235 | esac | |
236 | done | |
237 | ||
238 | if [ "$(id -u)" != "0" ]; then | |
239 | echo "This script should be run as 'root'" | |
240 | exit 1 | |
241 | fi | |
242 | ||
243 | if [ -z "$path" ]; then | |
244 | echo "'path' parameter is required" | |
245 | exit 1 | |
246 | fi | |
247 | ||
248 | rootfs=$path/rootfs | |
249 | ||
250 | install_busybox $rootfs $name | |
251 | if [ $? -ne 0 ]; then | |
252 | echo "failed to install busybox's rootfs" | |
253 | exit 1 | |
254 | fi | |
255 | ||
256 | configure_busybox $rootfs | |
257 | if [ $? -ne 0 ]; then | |
258 | echo "failed to configure busybox template" | |
259 | exit 1 | |
260 | fi | |
261 | ||
262 | copy_configuration $path $rootfs $name | |
263 | if [ $? -ne 0 ]; then | |
264 | echo "failed to write configuration file" | |
265 | exit 1 | |
266 | fi | |
267 |