OSDN Git Service

[update] : create channels dir
[alterlinux/LUBS.git] / lubs
1 #!/usr/bin/env bash
2
3 set -e -u
4
5 export LANG=C
6
7
8 arch=amd64
9 work_dir="work"
10 cache_dir="${work_dir}/cache"
11 out_dir="${work_dir}/out"
12 script_path=$(readlink -f ${0%/*})
13 channels_dir="${script_path}/channels"
14 codename="focal"
15 mirror="http://ftp.jaist.ac.jp/pub/Linux/ubuntu/"
16
17 os_name="Ubuntu"
18 iso_name="ubuntu"
19 iso_label="${os_name}_${codename}_${arch}"
20 iso_publisher='Fascode Network <https://fascode.net>'
21 iso_application="${os_name} Live/Rescue CD"
22 iso_version="${codename}-$(date +%Y.%m.%d)"
23 iso_filename="${iso_name}-${iso_version}-${arch}.iso"
24
25
26 # Show an INFO message
27 # _msg_info <message>
28 _msg_info () {
29     local _msg="${@}"
30     "${script_path}/echo_color"  -t 36 "[LUBS Core]" /! -t 32 "INFO:" "/#${_msg}"
31 }
32
33 # Show an ERROR message then exit with status
34 # _msg_error <message> <exit code>
35 _msg_error() {
36     local _msg="${1}"
37     local _error=${2}
38     "${script_path}/echo_color" -t 36 "[LUBS Core]" /! -t 31 "ERROR:" "/#${_msg}" >&2
39     if [[ ! ${_error} = 0 ]]; then
40         exit ${_error}
41     fi
42 }
43
44 _msg_start () {
45     _msg_info "make ${1} is starting."
46 }
47
48 _msg_end () {
49     _msg_info "make ${1} was done!"
50 }
51
52 # Helper function to run make_*() only one time.
53 run_once() {
54     local name
55     if [[ "run_out" == "$1" ]]; then
56         name="$2"
57     else
58         name="$1"
59     fi
60
61     if [[ ! -e "${work_dir}/build.${name}" ]]; then
62         if [[ "run_out" == "$1" ]]; then
63             "$1" "$2"
64         else
65             "$1"
66         fi
67
68         touch "${work_dir}/build.${name}"
69     fi
70 }
71
72 run_cmd () {
73     "${script_path}/lubs-chroot" "${work_dir}/airootfs" ${@}
74 }
75
76 run_out () {
77     cd "${out_dir}"
78     "$1"
79     cd - > /dev/null
80 }
81
82 _apt_install () {
83     run_cmd apt-get --yes install ${@}
84 }
85
86
87
88
89 prepare_build () {
90     if [[ ${EUID} -ne 0 ]]; then
91         _msg_error "This script must be run as root." 1
92     fi
93     
94     [[ ! -d "${work_dir}" ]] && mkdir -p "${work_dir}"
95
96     local mount
97     for mount in $(mount | awk '{print $3}' | grep $(realpath ${work_dir}) | sort -r); do
98         _msg_info "Unmounting ${mount}"
99         umount "${mount}"
100     done
101
102 }
103
104
105 make_basefs () {
106     local job_name
107     job_name="basefs"
108     _msg_start "${job_name}"
109
110     if [[ ! -d "${cache_dir}/${codename}" ]]; then
111         _msg_info "Installing Ubuntu to '${cache_dir}/${codename}'..."
112         mkdir -p "${cache_dir}/${codename}"
113         debootstrap --arch=${arch} --include=linux-image-generic  --verbose --merged-usr "${codename}" "${cache_dir}/${codename}" ${mirror}
114         _msg_info "${codename} installed successfully!"
115     else
116         _msg_info "${codename} cache is found."
117     fi
118     
119     rm -rf "${work_dir}/airootfs" && mkdir -p "${work_dir}/airootfs"
120     _msg_info "copy base files from '${cache_dir}/${codename}' to '${work_dir}/airootfs'..."
121     rsync  -au "${cache_dir}/${codename}/" "${work_dir}/airootfs"
122     echo 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH}' >> "${work_dir}/airootfs/etc/bash.bashrc"
123     run_cmd apt-get update
124     # run_cmd apt-get upgrade
125
126     _msg_end "${job_name}"
127 }
128
129 make_sourcelist () {
130     local job_name
131     job_name="sourcelist"
132     _msg_start "${job_name}"
133
134     cp ${script_path}/source.list.d/${codename}/* ${work_dir}/airootfs/etc/apt
135
136     _msg_end "${job_name}"
137 }
138
139 make_systemd() {
140     local job_name
141     job_name="systemd"
142     _msg_start "${job_name}"
143
144     _apt_install systemd-sysv
145     run_cmd dbus-uuidgen > /etc/machine-id
146     run_cmd ln -fs /etc/machine-id /var/lib/dbus/machine-id
147
148     _msg_end "${job_name}"
149 }
150
151 make_packages () {
152     local job_name
153     job_name="packages"
154     _msg_start "${job_name}"
155
156     run_cmd apt-get update
157     installpkglist=($(grep -h -v ^'#' ${script_path}/packages.x86_64))
158     run_cmd sudo -i apt-get --yes install ${installpkglist[@]}
159
160     _msg_end "${job_name}"
161 }
162
163 make_config() {
164     local job_name
165     job_name="config"
166     _msg_start "${job_name}"
167
168     # Locales
169     run_cmd env -i bash -c 'DEBIAN_FRONTEND=noninteractive LANG=en_US.UTF-8 LC_ALL=C LANGUAGE=en_US.UTF-8 dpkg-reconfigure locales'
170
171     # resolvconf
172     run_cmd env -i bash -c 'DEBIAN_FRONTEND=noninteractive dpkg-reconfigure resolvconf'
173
174     # NetworkManager
175     cp ${channels_dir}/share/airootfs/etc/NetworkManager/NetworkManager.conf ${work_dir}/airootfs/etc/NetworkManager/NetworkManager.conf
176
177     # Timezone
178     #run_cmd echo -ne "UTC" > '/etc/timezone'
179     #run_cmd dpkg-reconfigure -f noninteractive tzdata
180
181     run_cmd env -i bash -c 'DEBIAN_FRONTEND=noninteractive dpkg-reconfigure network-manager'
182     run_cmd truncate -s 0 /etc/machine-id
183
184     _msg_end "${job_name}"
185 }
186
187 make_customize_airootfs() {
188     local job_name
189     job_name="customize airootfs"
190     _msg_start "${job_name}"
191
192     # Overwrite airootfs with customize_airootfs.
193     cp -af "${channels_dir}/share/airootfs" "${work_dir}"
194
195     if [[ -f "${work_dir}/airootfs/root/customize_airootfs.sh" ]]; then
196         chmod 755 "${work_dir}/airootfs/root/customize_airootfs.sh"
197         run_cmd "/root/customize_airootfs.sh"
198     fi
199
200     _msg_end "${job_name}"
201 }
202
203 make_clean() {
204     local job_name
205     job_name="clean"
206     _msg_start "${job_name}"
207
208     run_cmd apt-get clean
209     run_cmd apt-get --yes autoremove
210     run_cmd rm -rf "/tmp/* ~/.bash_history"
211
212     _msg_end "${job_name}"
213 }
214
215 make_bootfiles() {
216     local job_name
217     job_name="boot files"
218     _msg_start "${job_name}"
219
220     run_cmd update-initramfs -c -k all
221     _apt_install memtest86+
222     mkdir -p ${out_dir}/{casper,isolinux,install}
223     cp ${work_dir}/airootfs/boot/vmlinuz-*-*-generic ${out_dir}/casper/vmlinuz
224     cp ${work_dir}/airootfs/boot/initrd.img-*-*-generic ${out_dir}/casper/initrd
225     cp ${work_dir}/airootfs/boot/memtest86+.bin ${out_dir}/install/memtest86+
226
227     if [[ ! -f "${cache_dir}/memtest86-usb.zip" ]]; then
228         wget -O ${cache_dir}/memtest86-usb.zip https://www.memtest86.com/downloads/memtest86-usb.zip
229     fi
230
231     (unzip -p ${cache_dir}/memtest86-usb.zip memtest86-usb.img > ${out_dir}/install/memtest86)
232
233     _msg_end "${job_name}"
234 }
235
236 make_grubcfg() {
237 local job_name
238 job_name="grubcfg"
239 _msg_start "${job_name}"
240
241 touch "${out_dir}/ubuntu"
242 cat <<EOF > ${out_dir}/isolinux/grub.cfg
243
244 search --set=root --file /ubuntu
245
246 insmod all_video
247
248 set default="0"
249 set timeout=30
250
251 menuentry "Try Ubuntu FS without installing" {
252    linux /casper/vmlinuz boot=casper quiet splash ---
253    initrd /casper/initrd
254 }
255
256 menuentry "Install Ubuntu FS" {
257    linux /casper/vmlinuz boot=casper only-ubiquity quiet splash ---
258    initrd /casper/initrd
259 }
260
261 menuentry "Check disc for defects" {
262    linux /casper/vmlinuz boot=casper integrity-check quiet splash ---
263    initrd /casper/initrd
264 }
265
266 menuentry "Test memory Memtest86+ (BIOS)" {
267    linux16 /install/memtest86+
268 }
269
270 menuentry "Test memory Memtest86 (UEFI, long load time)" {
271    insmod part_gpt
272    insmod search_fs_uuid
273    insmod chain
274    loopback loop /install/memtest86
275    chainloader (loop,gpt1)/efi/boot/BOOTX64.efi
276 }
277 EOF
278
279 _msg_end "${job_name}"
280 }
281
282 make_manifest() {
283     local job_name
284     job_name="manifest"
285     _msg_start "${job_name}"
286
287     run_cmd dpkg-query -W --showformat='${Package} ${Version}\n' | tee ${out_dir}/casper/filesystem.manifest
288     cp -v ${out_dir}/casper/filesystem.manifest "${out_dir}/casper/filesystem.manifest-desktop"
289     sed -i '/ubiquity/d' "${out_dir}/casper/filesystem.manifest-desktop"
290     sed -i '/casper/d' "${out_dir}/casper/filesystem.manifest-desktop"
291     sed -i '/discover/d' "${out_dir}/casper/filesystem.manifest-desktop"
292     sed -i '/laptop-detect/d' "${out_dir}/casper/filesystem.manifest-desktop"
293     sed -i '/os-prober/d' "${out_dir}/casper/filesystem.manifest-desktop"
294
295     _msg_end "${job_name}"
296 }
297
298 make_squashfs() {
299     local job_name
300     job_name="squashfs"
301     _msg_start "${job_name}"
302
303     mksquashfs "${work_dir}/airootfs" "${out_dir}/casper/filesystem.squashfs"
304     printf $(du -sx --block-size=1 "${work_dir}/airootfs" | cut -f1) > ${out_dir}/casper/filesystem.size
305
306     _msg_end "${job_name}"
307 }
308
309 make_deifnes() {
310 local job_name
311 job_name="defines"
312 _msg_start "${job_name}"
313
314 cat <<EOF > ${out_dir}/README.diskdefines
315 #define DISKNAME  Ubuntu from scratch
316 #define TYPE  binary
317 #define TYPEbinary  1
318 #define ARCH  amd64
319 #define ARCHamd64  1
320 #define DISKNUM  1
321 #define DISKNUM1  1
322 #define TOTALNUM  0
323 #define TOTALNUM0  1
324 EOF
325
326 _msg_end "${job_name}"
327 }
328
329 make_isolinux() {
330     local job_name
331     job_name="isolinux"
332     _msg_start "${job_name}"
333
334     grub-mkstandalone \
335         --format=x86_64-efi \
336         --output=isolinux/bootx64.efi \
337         --locales="" \
338         --fonts="" \
339         "boot/grub/grub.cfg=isolinux/grub.cfg"
340     (
341         cd isolinux && \
342         dd if=/dev/zero of=efiboot.img bs=1M count=10 && \
343         sudo mkfs.vfat efiboot.img && \
344         LC_CTYPE=C mmd -i efiboot.img efi efi/boot && \
345         LC_CTYPE=C mcopy -i efiboot.img ./bootx64.efi ::efi/boot/
346     )
347     grub-mkstandalone \
348         --format=i386-pc \
349         --output=isolinux/core.img \
350         --install-modules="linux16 linux normal iso9660 biosdisk memdisk search tar ls" \
351         --modules="linux16 linux normal iso9660 biosdisk search" \
352         --locales="" \
353         --fonts="" \
354         "boot/grub/grub.cfg=isolinux/grub.cfg"
355     cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > isolinux/bios.img
356
357     _msg_end "${job_name}"
358 }
359
360 make_md5sum() {
361     local job_name
362     job_name="md5sum"
363     _msg_start "${job_name}"
364
365     /bin/bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v "\./md5sum.txt" > md5sum.txt)"
366
367     _msg_end "${job_name}"
368 }
369
370 make_iso() {
371     local job_name
372     job_name="iso"
373     _msg_start "${job_name}"
374
375     xorriso \
376         -as mkisofs \
377         -iso-level 3 \
378         -full-iso9660-filenames \
379         -volid "${iso_label}" \
380         -appid "${iso_application}" \
381         -publisher "${iso_publisher}" \
382         -preparer "prepared by LUBS" \
383         -eltorito-boot boot/grub/bios.img \
384         -no-emul-boot \
385         -boot-load-size 4 \
386         -boot-info-table \
387         --eltorito-catalog boot/grub/boot.cat \
388         --grub2-boot-info \
389         --grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \
390         -eltorito-alt-boot \
391         -e EFI/efiboot.img \
392         -no-emul-boot \
393         -append_partition 2 0xef isolinux/efiboot.img \
394         -output "../${iso_filename}" \
395         -graft-points \
396             "." \
397             /boot/grub/bios.img=isolinux/bios.img \
398             /EFI/efiboot.img=isolinux/efiboot.img
399     
400     _msg_end "${job_name}"
401 }
402
403 prepare_build
404 run_once make_basefs
405 run_once make_sourcelist
406 run_once make_systemd
407 run_once make_packages
408 run_once make_config
409 run_once make_customize_airootfs
410 run_once make_clean
411 run_once make_bootfiles
412 run_once make_grubcfg
413 run_once make_manifest
414 run_once make_squashfs
415 run_once make_deifnes
416 run_once run_out make_isolinux
417 run_once run_out make_md5sum
418 run_once run_out make_iso