OSDN Git Service

[update] : Supports setting of supported architecture for each channel.
[alterlinux/alterlinux.git] / build.sh
1 #!/usr/bin/env bash
2 #
3 # Yamada Hayao
4 # Twitter: @Hayao0819
5 # Email  : hayao@fascone.net
6 #
7 # (c) 2019-2020 Fascode Network.
8 #
9 # build.sh
10 #
11 # The main script that runs the build
12 #
13
14 set -e
15 # set -u
16 script_path="$(readlink -f ${0%/*})"
17
18 # alteriso settings
19 #
20 # Do not change this variable.
21 # To change the settings permanently, edit the config file.
22
23 arch=$(uname -m)
24
25 os_name="Alter Linux"
26 iso_name=alterlinux
27 iso_label="ALTER_$(date +%Y%m)"
28 iso_publisher='Fascode Network <https://fascode.net>'
29 iso_application="${os_name} Live/Rescue CD"
30 iso_version=$(date +%Y.%m.%d)
31 install_dir=alter
32 work_dir=work
33 out_dir=out
34 gpg_key=
35 mkalteriso_option="-v"
36
37 # AlterLinux additional settings
38 password='alter'
39 boot_splash=false
40 kernel='zen'
41 theme_name="alter-logo"
42 theme_pkg="plymouth-theme-alter-logo-git"
43 sfs_comp="zstd"
44 sfs_comp_opt=""
45 bash_debug=false
46 debug=false
47 rebuild=false
48 japanese=false
49 channel_name='xfce'
50 cleaning=false
51 username='alter'
52 mkalteriso="${script_path}/system/mkalteriso"
53 usershell="/bin/bash"
54 noconfirm=false
55 dependence=(
56     "alterlinux-keyring"
57 #   "archiso"
58     "arch-install-scripts"
59     "curl"
60     "dosfstools"
61     "git"
62     "libburn"
63     "libisofs"
64     "lz4"
65     "lzo"
66     "make"
67     "squashfs-tools"
68     "libisoburn"
69  #  "lynx"
70     "xz"
71     "zlib"
72     "zstd"
73 )
74
75
76 # Pacman configuration file used only when building
77 build_pacman_conf=${script_path}/system/pacman-${arch}.conf
78
79
80 # Load config file
81 [[ -f "${script_path}"/config ]] && source "${script_path}"/config
82
83
84 umask 0022
85
86
87 # Color echo
88 # usage: echo_color -b <backcolor> -t <textcolor> -d <decoration> [Text]
89 #
90 # Text Color
91 # 30 => Black
92 # 31 => Red
93 # 32 => Green
94 # 33 => Yellow
95 # 34 => Blue
96 # 35 => Magenta
97 # 36 => Cyan
98 # 37 => White
99 #
100 # Background color
101 # 40 => Black
102 # 41 => Red
103 # 42 => Green
104 # 43 => Yellow
105 # 44 => Blue
106 # 45 => Magenta
107 # 46 => Cyan
108 # 47 => White
109 #
110 # Text decoration
111 # You can specify multiple decorations with ;.
112 # 0 => All attributs off (ノーマル)
113 # 1 => Bold on (太字)
114 # 4 => Underscore (下線)
115 # 5 => Blink on (点滅)
116 # 7 => Reverse video on (色反転)
117 # 8 => Concealed on
118
119 echo_color() {
120     local backcolor
121     local textcolor
122     local decotypes
123     local echo_opts
124     local arg
125     local OPTIND
126     local OPT
127
128     echo_opts="-e"
129
130     while getopts 'b:t:d:n' arg; do
131         case "${arg}" in
132             b) backcolor="${OPTARG}" ;;
133             t) textcolor="${OPTARG}" ;;
134             d) decotypes="${OPTARG}" ;;
135             n) echo_opts="-n -e"     ;;
136         esac
137     done
138
139     shift $((OPTIND - 1))
140
141     echo ${echo_opts} "\e[$([[ -v backcolor ]] && echo -n "${backcolor}"; [[ -v textcolor ]] && echo -n ";${textcolor}"; [[ -v decotypes ]] && echo -n ";${decotypes}")m${@}\e[m"
142 }
143
144
145 # Show an INFO message
146 # $1: message string
147 _msg_info() {
148     local echo_opts="-e"
149     local arg
150     local OPTIND
151     local OPT
152     while getopts 'n' arg; do
153         case "${arg}" in
154             n) echo_opts="${echo_opts} -n" ;;
155         esac
156     done
157     shift $((OPTIND - 1))
158     echo ${echo_opts} "$( echo_color -t '36' '[build.sh]')    $( echo_color -t '32' 'Info') ${@}"
159 }
160
161
162 # Show an Warning message
163 # $1: message string
164 _msg_warn() {
165     local echo_opts="-e"
166     local arg
167     local OPTIND
168     local OPT
169     while getopts 'n' arg; do
170         case "${arg}" in
171             n) echo_opts="${echo_opts} -n" ;;
172         esac
173     done
174     shift $((OPTIND - 1))
175     echo ${echo_opts} "$( echo_color -t '36' '[build.sh]') $( echo_color -t '33' 'Warning') ${@}" >&2
176 }
177
178
179 # Show an debug message
180 # $1: message string
181 _msg_debug() {
182     local echo_opts="-e"
183     local arg
184     local OPTIND
185     local OPT
186     while getopts 'n' arg; do
187         case "${arg}" in
188             n) echo_opts="${echo_opts} -n" ;;
189         esac
190     done
191     shift $((OPTIND - 1))
192     if [[ ${debug} = true ]]; then
193         echo ${echo_opts} "$( echo_color -t '36' '[build.sh]')   $( echo_color -t '35' 'Debug') ${@}"
194     fi
195 }
196
197
198 # Show an ERROR message then exit with status
199 # $1: message string
200 # $2: exit code number (with 0 does not exit)
201 _msg_error() {
202     local echo_opts="-e"
203     local _error="$2"
204     local arg
205     local OPTIND
206     local OPT
207     local OPTARG
208     while getopts 'n' arg; do
209         case "${arg}" in
210             n) echo_opts="${echo_opts} -n" ;;
211         esac
212     done
213     shift $((OPTIND - 1))
214     echo ${echo_opts} "$( echo_color -t '36' '[build.sh]')   $( echo_color -t '31' 'Error') ${1}" >&2
215     if [[ -n "${_error}" ]]; then
216         exit ${_error}
217     fi
218 }
219
220
221 _usage () {
222     echo "usage ${0} [options] [channel]"
223     echo
224     echo " General options:"
225     echo "    -b                 Enable boot splash"
226     echo "                        Default: disable"
227     echo "    -c <comp_type>     Set SquashFS compression type (gzip, lzma, lzo, xz, zstd)"
228     echo "                        Default: ${sfs_comp}"
229     echo "    -g <gpg_key>       Set gpg key"
230     echo "                        Default: ${gpg_key}"
231     echo "    -j                 Enable Japanese mode."
232     echo "                        Default: disable"
233     echo "    -k <kernel>        Set special kernel type."
234     echo "                       core means normal linux kernel"
235     echo "                        Default: ${kernel}"
236     echo "    -l                 Enable post-build cleaning."
237     echo "                        Default: disable"
238     echo "    -o <out_dir>       Set the output directory"
239     echo "                        Default: ${out_dir}"
240     echo "    -p <password>      Set a live user password"
241     echo "                        Default: ${password}"
242     echo "    -t <options>       Set compressor-specific options."
243     echo "                        Default: empty"
244     echo "    -u <username>      Set user name."
245     echo "                        Default: ${username}"
246     echo "    -w <work_dir>      Set the working directory"
247     echo "                        Default: ${work_dir}"
248     echo "    -x                 Enable debug mode."
249     echo "                        Default: disable"
250     echo "    -h                 This help message and exit."
251     echo
252     echo "You can switch between installed packages, files included in images, etc. by channel."
253     echo
254     echo " Channel:"
255     for i in $(ls -l "${script_path}"/channels/ | awk '$1 ~ /d/ {print $9 }'); do
256         if [[ -n $(ls "${script_path}"/channels/${i}) ]]; then
257             if [[ ! ${i} = "share" ]]; then
258                 if [[ ! $(echo "${i}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
259                     if [[ ! -d "${script_path}/channels/${i}.add" ]]; then
260                         channel_list="${channel_list[@]} ${i}"
261                     fi
262                 else
263                     channel_list="${channel_list[@]} ${i}"
264                 fi
265             fi
266         fi
267     done
268     channel_list="${channel_list[@]} rebuild"
269     for _channel in ${channel_list[@]}; do
270         if [[ -f "${script_path}/channels/${_channel}/description.txt" ]]; then
271             description=$(cat "${script_path}/channels/${_channel}/description.txt")
272         elif [[ "${_channel}" = "rebuild" ]]; then
273             description="Rebuild using the settings of the previous build."
274         else
275             description="This channel does not have a description.txt."
276         fi
277         if [[ $(echo "${_channel}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
278             echo -ne "    $(echo ${_channel} | sed 's/\.[^\.]*$//')"
279             for i in $( seq 1 $(( 23 - ${#_channel} )) ); do
280                 echo -ne " "
281             done
282         else
283             echo -ne "    ${_channel}"
284             for i in $( seq 1 $(( 19 - ${#_channel} )) ); do
285                 echo -ne " "
286             done
287         fi
288         echo -ne "${description}\n"
289     done
290
291
292     exit "${1}"
293 }
294
295
296 # Check the value of a variable that can only be set to true or false.
297 check_bool() {
298     local 
299     case $(eval echo '$'${1}) in
300         true | false) : ;;
301                    *) _msg_error "The value ${boot_splash} set is invalid" "1";;
302     esac
303 }
304
305 check_bool boot_splash
306 check_bool debug
307 check_bool bash_debug
308 check_bool rebuild
309 check_bool japanese
310 check_bool cleaning
311 check_bool noconfirm
312
313
314 # Helper function to run make_*() only one time.
315 run_once() {
316     if [[ ! -e "${work_dir}/build.${1}_${arch}" ]]; then
317         _msg_debug "Running $1 ..."
318         "$1"
319         touch "${work_dir}/build.${1}_${arch}"
320     else
321         _msg_debug "Skipped because ${1} has already been executed."
322     fi
323 }
324
325
326 # rm helper
327 # Delete the file if it exists.
328 # For directories, rm -rf is used.
329 # If the file does not exist, skip it.
330 # remove <file> <file> ...
331 remove() {
332     local _list
333     local _file
334     _list=($(echo "$@"))
335     for _file in "${_list[@]}"; do
336         _msg_debug "Removeing ${_file}"
337         if [[ -f ${_file} ]]; then
338             rm -f "${_file}"
339         elif [[ -d ${_file} ]]; then
340             rm -rf "${_file}"
341         fi
342     done
343 }
344
345
346 # Preparation for build
347 prepare_build() {
348     # Check architecture for each channel
349     if [[ -z $(cat ${script_path}/channels/${channel_name}/architecture | grep -h -v ^'#' | grep -x "${arch}") ]]; then
350         _msg_error "${channel_name} channel does not support current architecture (${arch})." "1"
351     fi
352
353
354     # Create a working directory.
355     [[ ! -d "${work_dir}" ]] && mkdir -p "${work_dir}"
356
357
358     # Check work dir
359     if [[ -n $(ls -a "${work_dir}" 2> /dev/null | grep -xv ".." | grep -xv ".") ]] && [[ ! "${rebuild}" = true ]]; then
360         _msg_info "Deleting the contents of ${work_dir}..."
361         remove "${work_dir%/}"/*
362     fi
363
364
365     # Save build options
366     local save_var
367     save_var() {
368         local out_file="${work_dir}/build_options"
369         local i
370         echo "#!/usr/bin/env bash" > "${out_file}"
371         echo "# Build options are stored here." >> "${out_file}"
372         for i in ${@}; do
373             echo -n "${i}=" >> "${out_file}"
374             echo -n '"' >> "${out_file}"
375             eval echo -n '$'{${i}} >> "${out_file}"
376             echo '"' >> "${out_file}"
377         done
378     }
379     if [[ ${rebuild} = false ]]; then
380         # If there is pacman.conf for each channel, use that for building
381         if [[ -f "${script_path}/channels/${channel_name}/pacman-${arch}.conf" ]]; then
382             build_pacman_conf="${script_path}/channels/${channel_name}/pacman-${arch}.conf"
383         fi
384
385
386         # If there is config for each channel. load that.
387         if [[ -f "${script_path}/channels/${channel_name}/config" ]]; then
388             source "${script_path}/channels/${channel_name}/config"
389             _msg_debug "The settings have been overwritten by the ${script_path}/channels/${channel_name}/config."
390         fi
391         save_var \
392             arch \
393             os_name \
394             iso_name \
395             iso_label \
396             iso_publisher \
397             iso_application \
398             iso_version \
399             install_dir \
400             work_dir \
401             out_dir \
402             gpg_key \
403             mkalteriso_option \
404             password \
405             boot_splash \
406             kernel \
407             theme_name \
408             theme_pkg \
409             sfs_comp \
410             sfs_comp_opt \
411             debug \
412             japanese \
413             channel_name \
414             cleaning \
415             username mkalteriso \
416             usershell \
417             build_pacman_conf
418     else
419         # Load rebuild file
420         source "${work_dir}/build_options"
421
422         # Delete the lock file.
423         # remove "$(ls ${work_dir}/* | grep "build.make")"
424     fi
425
426
427     # Unmount
428     local mount
429     for mount in $(mount | awk '{print $3}' | grep $(realpath ${work_dir})); do
430         _msg_info "Unmounting ${mount}"
431         umount "${mount}"
432     done
433
434
435     # Generate iso file name.
436     if [[ "${japanese}" = true  ]]; then
437         if [[ $(echo "${channel_name}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
438             iso_filename="${iso_name}-$(echo ${channel_name} | sed 's/\.[^\.]*$//')-jp-${iso_version}-${arch}.iso"
439         else
440             iso_filename="${iso_name}-${channel_name}-jp-${iso_version}-${arch}.iso"
441         fi
442     else
443         if [[ $(echo "${channel_name}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
444             iso_filename="${iso_name}-$(echo ${channel_name} | sed 's/\.[^\.]*$//')-${iso_version}-${arch}.iso"
445         else
446             iso_filename="${iso_name}-${channel_name}-${iso_version}-${arch}.iso"
447         fi
448     fi
449
450
451     # Check packages
452     local installed_pkg
453     local installed_ver
454     local check_pkg
455     local check_failed=false
456
457     installed_pkg=($(pacman -Q | awk '{print $1}'))
458     installed_ver=($(pacman -Q | awk '{print $2}'))
459
460     check_pkg() {
461         local i
462         local ver
463         for i in $(seq 0 $(( ${#installed_pkg[@]} - 1 ))); do
464             if [[ "${installed_pkg[${i}]}" = ${1} ]]; then
465                 ver=$(pacman -Sp --print-format '%v' --config ${build_pacman_conf} ${1} 2> /dev/null)
466                 if [[ "${installed_ver[${i}]}" = "${ver}" ]]; then
467                     echo -n "installed"
468                     return 0
469                 elif [[ -z ${ver} ]]; then
470                     echo "norepo"
471                     return 0
472                 else
473                     echo -n "old"
474                     return 0
475                 fi
476             fi
477         done
478         echo -n "not"
479         return 0
480     }
481     echo
482     if [[ ${debug} = false ]]; then
483         _msg_info "Checking dependencies ..."
484     fi
485     for pkg in ${dependence[@]}; do
486         _msg_debug -n "Checking ${pkg} ..."
487         case $(check_pkg ${pkg}) in
488             "old") 
489                 [[ "${debug}" = true ]] && echo -ne " $(pacman -Q ${pkg} | awk '{print $2}')\n"
490                 _msg_warn "${pkg} is not the latest package."
491                 _msg_warn "Local: $(pacman -Q ${pkg} 2> /dev/null | awk '{print $2}') Latest: $(pacman -Sp --print-format '%v' --config ${build_pacman_conf} ${pkg} 2> /dev/null)"
492                 echo
493                 ;;
494             "not") _msg_error "${pkg} is not installed." ; check_failed=true ;;
495             "norepo") _msg_warn "${pkg} is not a repository package." ;;
496             "installed") [[ ${debug} = true ]] && echo -ne " $(pacman -Q ${pkg} | awk '{print $2}')\n" ;;
497         esac
498     done
499
500     if [[ "${check_failed}" = true ]]; then
501         exit 1
502     fi
503
504
505     # Load kernel module
506     if [[ -z $(lsmod | awk '{print $1}' | grep -x "loop") ]]; then
507         sudo modprobe loop
508     fi
509 }
510
511
512 # Show settings.
513 show_settings() {
514     echo
515     if [[ "${boot_splash}" = true ]]; then
516         _msg_info "Boot splash is enabled."
517         _msg_info "Theme is used ${theme_name}."
518     fi
519     _msg_info "Use the ${kernel} kernel."
520     _msg_info "Live username is ${username}."
521     _msg_info "Live user password is ${password}."
522     _msg_info "The compression method of squashfs is ${sfs_comp}."
523     if [[ $(echo "${channel_name}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
524         _msg_info "Use the $(echo ${channel_name} | sed 's/\.[^\.]*$//') channel."
525     else
526         _msg_info "Use the ${channel_name} channel."
527     fi
528     [[ "${japanese}" = true ]] && _msg_info "Japanese mode has been activated."
529     _msg_info "Build with architecture ${arch}."
530     echo
531     if [[ ${noconfirm} = false ]]; then
532         echo "Press Enter to continue or Ctrl + C to cancel."
533         read
534     else
535         :
536         #sleep 3
537     fi
538 }
539
540
541 # Setup custom pacman.conf with current cache directories.
542 make_pacman_conf() {
543     local _cache_dirs
544     _cache_dirs=($(pacman -v 2>&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g'))
545     sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${_cache_dirs[@]})|g" ${build_pacman_conf} > ${work_dir}/pacman.conf
546 }
547
548 # Base installation, plus needed packages (airootfs)
549 make_basefs() {
550     arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" init
551     # ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -p "haveged intel-ucode amd-ucode memtest86+ mkinitcpio-nfs-utils nbd zsh efitools" install
552     arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -p "bash haveged intel-ucode amd-ucode mkinitcpio-nfs-utils nbd efitools" install
553
554     # Install plymouth.
555     if [[ "${boot_splash}" = true ]]; then
556         if [[ -n "${theme_pkg}" ]]; then
557             arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -p "plymouth ${theme_pkg}" install
558         else
559             arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -p "plymouth" install
560         fi
561     fi
562
563     # Install kernel.
564     if [[ ! "${kernel}" = "core" ]]; then
565         arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -p "linux-${kernel} linux-${kernel}-headers broadcom-wl-dkms" install
566     else
567         arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -p "linux linux-headers broadcom-wl" install
568     fi
569 }
570
571 # Additional packages (airootfs)
572 make_packages() {
573     # インストールするパッケージのリストを読み込み、配列pkglistに代入します。
574     installpkglist() {
575         set +e
576         local _loadfilelist
577         local _pkg
578         local _file
579         local jplist
580         local excludefile
581         local excludelist
582         local _pkglist
583
584         #-- Detect package list to load --#
585         # Append the file in the share directory to the file to be read.
586
587         # Package list for Japanese
588         jplist="${script_path}/channels/share/packages.${arch}/jp.${arch}"
589
590         # Package list for non-Japanese
591         nojplist="${script_path}/channels/share/packages.${arch}/non-jp.${arch}"
592
593         if [[ "${japanese}" = true ]]; then
594             _loadfilelist=($(ls "${script_path}"/channels/share/packages.${arch}/*.${arch} | grep -xv "${nojplist}"))
595         else
596             _loadfilelist=($(ls "${script_path}"/channels/share/packages.${arch}/*.${arch} | grep -xv "${jplist}"))
597         fi
598
599
600         # Add the files for each channel to the list of files to read.
601
602         # Package list for Japanese
603         jplist="${script_path}/channels/${channel_name}/packages.${arch}/jp.${arch}"
604
605         # Package list for non-Japanese
606         nojplist="${script_path}/channels/${channel_name}/packages.${arch}/non-jp.${arch}"
607
608         if [[ "${japanese}" = true ]]; then
609             # If Japanese is enabled, add it to the list of files to read other than non-jp.
610             _loadfilelist=(${_loadfilelist[@]} $(ls "${script_path}"/channels/${channel_name}/packages.${arch}/*.${arch} | grep -xv "${nojplist}"))
611         else
612             # If Japanese is disabled, add it to the list of files to read other than jp.
613             _loadfilelist=(${_loadfilelist[@]} $(ls "${script_path}"/channels/${channel_name}/packages.${arch}/*.${arch} | grep -xv ${jplist}))
614         fi
615
616
617         #-- Read package list --#
618         # Read the file and remove comments starting with # and add it to the list of packages to install.
619         for _file in ${_loadfilelist[@]}; do
620             _msg_debug "Loaded package file ${_file}."
621             pkglist=( ${pkglist[@]} "$(grep -h -v ^'#' ${_file})" )
622         done
623         if [[ ${debug} = true ]]; then
624             sleep 3
625         fi
626
627         # Exclude packages from the share exclusion list
628         excludefile="${script_path}/channels/share/packages.${arch}/exclude"
629         if [[ -f "${excludefile}" ]]; then
630             excludelist=( $(grep -h -v ^'#' "${excludefile}") )
631
632             # 現在のpkglistをコピーする
633             _pkglist=(${pkglist[@]})
634             unset pkglist
635             for _pkg in ${_pkglist[@]}; do
636                 # もし変数_pkgの値が配列excludelistに含まれていなかったらpkglistに追加する
637                 if [[ ! $(printf '%s\n' "${excludelist[@]}" | grep -qx "${_pkg}"; echo -n ${?} ) = 0 ]]; then
638                     pkglist=(${pkglist[@]} "${_pkg}")
639                 fi
640             done
641         fi
642
643         if [[ -n "${excludelist[@]}" ]]; then
644             _msg_debug "The following packages have been removed from the installation list."
645             _msg_debug "Excluded packages: ${excludelist[@]}"
646         fi
647
648         # Exclude packages from the exclusion list for each channel
649         excludefile="${script_path}/channels/${channel_name}/packages.${arch}/exclude"
650         if [[ -f "${excludefile}" ]]; then
651             excludelist=( $(grep -h -v ^'#' "${excludefile}") )
652         
653             # 現在のpkglistをコピーする
654             _pkglist=(${pkglist[@]})
655             unset pkglist
656             for _pkg in ${_pkglist[@]}; do
657                 # もし変数_pkgの値が配列excludelistに含まれていなかったらpkglistに追加する
658                 if [[ ! $(printf '%s\n' "${excludelist[@]}" | grep -qx "${_pkg}"; echo -n ${?} ) = 0 ]]; then
659                     pkglist=(${pkglist[@]} "${_pkg}")
660                 fi
661             done
662         fi
663             
664         
665         # Sort the list of packages in abc order.
666         pkglist=(
667             "$(
668                 for _pkg in ${pkglist[@]}; do
669                     echo "${_pkg}"
670                 done \
671                 | sort
672             )"
673         )
674
675
676         #-- Debug code --#
677         #for _pkg in ${pkglist[@]}; do
678         #    echo -n "${_pkg} "
679         #done
680         # echo "${pkglist[@]}"
681
682
683         set -e
684     }
685
686     installpkglist    
687
688     # echo ${pkglist[@]}
689
690     # Create a list of packages to be finally installed as packages.list directly under the working directory.
691     echo "# The list of packages that is installed in live cd." > ${work_dir}/packages.list
692     echo "#" >> ${work_dir}/packages.list
693     echo >> ${work_dir}/packages.list
694     for _pkg in ${pkglist[@]}; do
695         echo ${_pkg} >> ${work_dir}/packages.list
696     done
697
698     # Install packages on airootfs
699     arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -p "${pkglist[@]}" install
700 }
701
702 # Customize installation (airootfs)
703 make_customize_airootfs() {
704     # Overwrite airootfs with customize_airootfs.
705     local copy_airootfs
706
707     copy_airootfs() {
708         local i 
709         for i in "${@}"; do
710             local _dir="${1%/}"
711             if [[ -d "${_dir}" ]]; then
712                 cp -af "${_dir}"/* "${work_dir}/${arch}/airootfs"
713             fi
714         done
715     }
716
717     copy_airootfs "${script_path}/channels/share/airootfs.share"
718     copy_airootfs "${script_path}/channels/share/airootfs.${arch}"
719     copy_airootfs "${script_path}/channels/${channel_name}/airootfs.share"
720     copy_airootfs "${script_path}/channels/${channel_name}/airootfs.${arch}"
721
722     # Replace /etc/mkinitcpio.conf if Plymouth is enabled.
723     if [[ "${boot_splash}" = true ]]; then
724         cp "${script_path}/mkinitcpio/mkinitcpio-plymouth.conf" "${work_dir}/${arch}/airootfs/etc/mkinitcpio.conf"
725     fi
726
727     # Code to use common pacman.conf in archiso.
728     # cp "${script_path}/pacman.conf" "${work_dir}/${arch}/airootfs/etc"
729     # cp "${build_pacman_conf}" "${work_dir}/${arch}/airootfs/etc"
730
731     # Get the optimal mirror list.
732     if [[ "${japanese}" = true ]]; then
733         # Use Japanese optimized mirror list when Japanese is enabled.
734         curl -o "${work_dir}/${arch}/airootfs/etc/pacman.d/mirrorlist" 'https://www.archlinux.org/mirrorlist/?country=JP&protocol=http&use_mirror_status=on'
735     else
736         curl -o "${work_dir}/${arch}/airootfs/etc/pacman.d/mirrorlist" 'https://www.archlinux.org/mirrorlist/?country=all&protocol=http&use_mirror_status=on'
737     fi
738
739     # lynx -dump -nolist 'https://wiki.archlinux.org/index.php/Installation_Guide?action=render' >> ${work_dir}/${arch}/airootfs/root/install.txt
740
741
742     # customize_airootfs.sh options
743     # -b            : Enable boot splash.
744     # -d            : Enable debug mode.
745     # -i <inst_dir> : Set install dir
746     # -j            : Enable Japanese.
747     # -k <kernel>   : Set kernel name.
748     # -o <os name>  : Set os name.
749     # -p <password> : Set password.
750     # -s <shell>    : Set user shell.
751     # -t            : Set plymouth theme.
752     # -u <username> : Set live user name.
753     # -x            : Enable bash debug mode.
754     # -r            : Enable rebuild.
755
756
757     # Generate options of customize_airootfs.sh.
758     local addition_options
759     local share_options
760     addition_options=
761     if [[ ${boot_splash} = true ]]; then
762         if [[ -z ${theme_name} ]]; then
763             addition_options="${addition_options} -b"
764         else
765             addition_options="${addition_options} -b -t ${theme_name}"
766         fi
767     fi
768     if [[ ${debug} = true ]]; then
769         addition_options="${addition_options} -d"
770     fi
771     if [[ ${bash_debug} = true ]]; then
772         addition_options="${addition_options} -x"
773     fi
774     if [[ ${japanese} = true ]]; then
775         addition_options="${addition_options} -j"
776     fi
777     if [[ ${rebuild} = true ]]; then
778         addition_options="${addition_options} -r"
779     fi
780
781     share_options="-p '${password}' -k '${kernel}' -u '${username}' -o '${os_name}' -i '${install_dir}' -s '${usershell}' -a '${arch}'"
782
783
784     # X permission
785     if [[ -f ${work_dir}/${arch}/airootfs/root/customize_airootfs.sh ]]; then
786         chmod 755 "${work_dir}/${arch}/airootfs/root/customize_airootfs.sh"
787     fi
788     if [[ -f "${work_dir}/${arch}/airootfs/root/customize_airootfs.sh" ]]; then
789         chmod 755 "${work_dir}/${arch}/airootfs/root/customize_airootfs.sh"
790     fi
791     if [[ -f "${work_dir}/${arch}/airootfs/root/customize_airootfs_${channel_name}.sh" ]]; then
792         chmod 755 "${work_dir}/${arch}/airootfs/root/customize_airootfs_${channel_name}.sh"
793     elif [[ -f "${work_dir}/${arch}/airootfs/root/customize_airootfs_$(echo ${channel_name} | sed 's/\.[^\.]*$//').sh" ]]; then
794         chmod 755 "${work_dir}/${arch}/airootfs/root/customize_airootfs_$(echo ${channel_name} | sed 's/\.[^\.]*$//').sh"
795     fi
796
797     # Execute customize_airootfs.sh.
798     if [[ -z ${addition_options} ]]; then
799         arch=${arch} ${mkalteriso} ${mkalteriso_option} \
800             -w "${work_dir}/${arch}" \
801             -C "${work_dir}/pacman.conf" \
802             -D "${install_dir}" \
803             -r "/root/customize_airootfs.sh ${share_options}" \
804             run
805         if [[ -f "${work_dir}/${arch}/airootfs/root/customize_airootfs_${channel_name}.sh" ]]; then
806             arch=${arch} ${mkalteriso} ${mkalteriso_option} \
807                 -w "${work_dir}/${arch}" \
808                 -C "${work_dir}/pacman.conf" \
809                 -D "${install_dir}" \
810                 -r "/root/customize_airootfs_${channel_name}.sh ${share_options}" \
811                 run
812         elif [[ -f "${work_dir}/${arch}/airootfs/root/customize_airootfs_$(echo ${channel_name} | sed 's/\.[^\.]*$//').sh" ]]; then
813             arch=${arch} ${mkalteriso} ${mkalteriso_option} \
814                 -w "${work_dir}/${arch}" \
815                 -C "${work_dir}/pacman.conf" \
816                 -D "${install_dir}" \
817                 -r "/root/customize_airootfs_$(echo ${channel_name} | sed 's/\.[^\.]*$//').sh ${share_options}" \
818                 run
819         fi
820     else
821         arch=${arch} ${mkalteriso} ${mkalteriso_option} \
822             -w "${work_dir}/${arch}" \
823             -C "${work_dir}/pacman.conf" \
824             -D "${install_dir}" \
825             -r "/root/customize_airootfs.sh ${share_options} ${addition_options}" \
826             run
827
828         if [[ -f "${work_dir}/${arch}/airootfs/root/customize_airootfs_${channel_name}.sh" ]]; then
829             arch=${arch} ${mkalteriso} ${mkalteriso_option} \
830                 -w "${work_dir}/${arch}" \
831                 -C "${work_dir}/pacman.conf" \
832                 -D "${install_dir}" \
833                 -r "/root/customize_airootfs_${channel_name}.sh ${share_options} ${addition_options}" \
834                 run
835         elif [[ -f "${work_dir}/${arch}/airootfs/root/customize_airootfs_$(echo ${channel_name} | sed 's/\.[^\.]*$//').sh" ]]; then
836             arch=${arch} ${mkalteriso} ${mkalteriso_option} \
837                 -w "${work_dir}/${arch}" \
838                 -C "${work_dir}/pacman.conf" \
839                 -D "${install_dir}" \
840                 -r "/root/customize_airootfs_$(echo ${channel_name} | sed 's/\.[^\.]*$//').sh ${share_options} ${addition_options}" \
841                 run
842         fi
843     fi
844
845
846     # Delete customize_airootfs.sh.
847     remove "${work_dir}/${arch}/airootfs/root/customize_airootfs.sh"
848     remove "${work_dir}/${arch}/airootfs/root/customize_airootfs_${channel_name}.sh"
849 }
850
851 # Copy mkinitcpio archiso hooks and build initramfs (airootfs)
852 make_setup_mkinitcpio() {
853     local _hook
854     mkdir -p "${work_dir}/${arch}/airootfs/etc/initcpio/hooks"
855     mkdir -p "${work_dir}/${arch}/airootfs/etc/initcpio/install"
856     for _hook in "archiso" "archiso_shutdown" "archiso_pxe_common" "archiso_pxe_nbd" "archiso_pxe_http" "archiso_pxe_nfs" "archiso_loop_mnt"; do
857         cp "${script_path}/system/initcpio/hooks/${_hook}" "${work_dir}/${arch}/airootfs/etc/initcpio/hooks"
858         cp "${script_path}/system/initcpio/install/${_hook}" "${work_dir}/${arch}/airootfs/etc/initcpio/install"
859     done
860     sed -i "s|/usr/lib/initcpio/|/etc/initcpio/|g" "${work_dir}/${arch}/airootfs/etc/initcpio/install/archiso_shutdown"
861     cp "${script_path}/system/initcpio/install/archiso_kms" "${work_dir}/${arch}/airootfs/etc/initcpio/install"
862     cp "${script_path}/system/initcpio/archiso_shutdown" "${work_dir}/${arch}/airootfs/etc/initcpio"
863     if [[ "${boot_splash}" = true ]]; then
864         cp "${script_path}/mkinitcpio/mkinitcpio-archiso-plymouth.conf" "${work_dir}/${arch}/airootfs/etc/mkinitcpio-archiso.conf"
865     else
866         cp "${script_path}/mkinitcpio/mkinitcpio-archiso.conf" "${work_dir}/${arch}/airootfs/etc/mkinitcpio-archiso.conf"
867     fi
868     gnupg_fd=
869     if [[ "${gpg_key}" ]]; then
870       gpg --export "${gpg_key}" >"${work_dir}/gpgkey"
871       exec 17<>$"{work_dir}/gpgkey"
872     fi
873
874     if [[ ! ${kernel} = "core" ]]; then
875         ARCHISO_GNUPG_FD=${gpg_key:+17} arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -r "mkinitcpio -c /etc/mkinitcpio-archiso.conf -k /boot/vmlinuz-linux-${kernel} -g /boot/archiso.img" run
876     else
877         ARCHISO_GNUPG_FD=${gpg_key:+17} arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}/${arch}" -C "${work_dir}/pacman.conf" -D "${install_dir}" -r 'mkinitcpio -c /etc/mkinitcpio-archiso.conf -k /boot/vmlinuz-linux -g /boot/archiso.img' run
878     fi
879
880     if [[ "${gpg_key}" ]]; then
881       exec 17<&-
882     fi
883 }
884
885 # Prepare kernel/initramfs ${install_dir}/boot/
886 make_boot() {
887     mkdir -p "${work_dir}/iso/${install_dir}/boot/${arch}"
888     cp "${work_dir}/${arch}/airootfs/boot/archiso.img" "${work_dir}/iso/${install_dir}/boot/${arch}/archiso.img"
889
890     if [[ ! "${kernel}" = "core" ]]; then
891         cp "${work_dir}/${arch}/airootfs/boot/vmlinuz-linux-${kernel}" "${work_dir}/iso/${install_dir}/boot/${arch}/vmlinuz-linux-${kernel}"
892     else
893         cp "${work_dir}/${arch}/airootfs/boot/vmlinuz-linux" "${work_dir}/iso/${install_dir}/boot/${arch}/vmlinuz"
894     fi
895 }
896
897 # Add other aditional/extra files to ${install_dir}/boot/
898 make_boot_extra() {
899     # In AlterLinux, memtest has been removed.
900     # cp "${work_dir}/${arch}/airootfs/boot/memtest86+/memtest.bin" "${work_dir}/iso/${install_dir}/boot/memtest"
901     # cp "${work_dir}/${arch}/airootfs/usr/share/licenses/common/GPL2/license.txt" "${work_dir}/iso/${install_dir}/boot/memtest.COPYING"
902     cp "${work_dir}/${arch}/airootfs/boot/intel-ucode.img" "${work_dir}/iso/${install_dir}/boot/intel_ucode.img"
903     cp "${work_dir}/${arch}/airootfs/usr/share/licenses/intel-ucode/LICENSE" "${work_dir}/iso/${install_dir}/boot/intel_ucode.LICENSE"
904     cp "${work_dir}/${arch}/airootfs/boot/amd-ucode.img" "${work_dir}/iso/${install_dir}/boot/amd_ucode.img"
905     cp "${work_dir}/${arch}/airootfs/usr/share/licenses/amd-ucode/LICENSE" "${work_dir}/iso/${install_dir}/boot/amd_ucode.LICENSE"
906 }
907
908 # Prepare /${install_dir}/boot/syslinux
909 make_syslinux() {
910     if [[ ! ${kernel} = "core" ]]; then
911         _uname_r="$(file -b ${work_dir}/${arch}/airootfs/boot/vmlinuz-linux-${kernel} | awk 'f{print;f=0} /version/{f=1}' RS=' ')"
912     else
913         _uname_r="$(file -b ${work_dir}/${arch}/airootfs/boot/vmlinuz-linux | awk 'f{print;f=0} /version/{f=1}' RS=' ')"
914     fi
915     mkdir -p "${work_dir}/iso/${install_dir}/boot/syslinux"
916
917     for _cfg in ${script_path}/syslinux/${arch}/*.cfg; do
918         sed "s|%ARCHISO_LABEL%|${iso_label}|g;
919              s|%OS_NAME%|${os_name}|g;
920              s|%INSTALL_DIR%|${install_dir}|g" "${_cfg}" > "${work_dir}/iso/${install_dir}/boot/syslinux/${_cfg##*/}"
921     done
922
923     if [[ ${boot_splash} = true ]]; then
924         sed "s|%ARCHISO_LABEL%|${iso_label}|g;
925              s|%OS_NAME%|${os_name}|g;
926              s|%INSTALL_DIR%|${install_dir}|g" \
927              "${script_path}/syslinux/${arch}/pxe-plymouth/archiso_pxe-${kernel}.cfg" > "${work_dir}/iso/${install_dir}/boot/syslinux/archiso_pxe.cfg"
928
929         sed "s|%ARCHISO_LABEL%|${iso_label}|g;
930              s|%OS_NAME%|${os_name}|g;
931              s|%INSTALL_DIR%|${install_dir}|g" \
932              "${script_path}/syslinux/${arch}/sys-plymouth/archiso_sys-${kernel}.cfg" > "${work_dir}/iso/${install_dir}/boot/syslinux/archiso_sys.cfg"
933     else
934         sed "s|%ARCHISO_LABEL%|${iso_label}|g;
935              s|%OS_NAME%|${os_name}|g;
936              s|%INSTALL_DIR%|${install_dir}|g" \
937              "${script_path}/syslinux/${arch}/pxe/archiso_pxe-${kernel}.cfg" > "${work_dir}/iso/${install_dir}/boot/syslinux/archiso_pxe.cfg"
938
939         sed "s|%ARCHISO_LABEL%|${iso_label}|g;
940              s|%OS_NAME%|${os_name}|g;
941              s|%INSTALL_DIR%|${install_dir}|g" \
942              "${script_path}/syslinux/${arch}/sys/archiso_sys-${kernel}.cfg" > "${work_dir}/iso/${install_dir}/boot/syslinux/archiso_sys.cfg"
943     fi
944
945     if [[ -f "${script_path}/channels/${channel_name}/splash.png" ]]; then
946         cp "${script_path}/channels/${channel_name}/splash.png" "${work_dir}/iso/${install_dir}/boot/syslinux"
947     else
948         cp "${script_path}/syslinux/${arch}/splash.png" "${work_dir}/iso/${install_dir}/boot/syslinux"
949     fi
950     cp "${work_dir}"/${arch}/airootfs/usr/lib/syslinux/bios/*.c32 "${work_dir}/iso/${install_dir}/boot/syslinux"
951     cp "${work_dir}/${arch}/airootfs/usr/lib/syslinux/bios/lpxelinux.0" "${work_dir}/iso/${install_dir}/boot/syslinux"
952     cp "${work_dir}/${arch}/airootfs/usr/lib/syslinux/bios/memdisk" "${work_dir}/iso/${install_dir}/boot/syslinux"
953     mkdir -p "${work_dir}/iso/${install_dir}/boot/syslinux/hdt"
954     gzip -c -9 "${work_dir}/${arch}/airootfs/usr/share/hwdata/pci.ids" > "${work_dir}/iso/${install_dir}/boot/syslinux/hdt/pciids.gz"
955     gzip -c -9 "${work_dir}/${arch}/airootfs/usr/lib/modules/${_uname_r}/modules.alias" > "${work_dir}/iso/${install_dir}/boot/syslinux/hdt/modalias.gz"
956 }
957
958 # Prepare /isolinux
959 make_isolinux() {
960     mkdir -p "${work_dir}/iso/isolinux"
961
962     sed "s|%INSTALL_DIR%|${install_dir}|g" \
963         "${script_path}/system/isolinux.cfg" > "${work_dir}/iso/isolinux/isolinux.cfg"
964     cp "${work_dir}/${arch}/airootfs/usr/lib/syslinux/bios/isolinux.bin" "${work_dir}/iso/isolinux/"
965     cp "${work_dir}/${arch}/airootfs/usr/lib/syslinux/bios/isohdpfx.bin" "${work_dir}/iso/isolinux/"
966     cp "${work_dir}/${arch}/airootfs/usr/lib/syslinux/bios/ldlinux.c32" "${work_dir}/iso/isolinux/"
967 }
968
969 # Prepare /EFI
970 make_efi() {
971     mkdir -p "${work_dir}/iso/EFI/boot"
972     cp "${work_dir}/${arch}/airootfs/usr/share/efitools/efi/HashTool.efi" "${work_dir}/iso/EFI/boot/"
973     if [[ "${arch}" = "x86_64" ]]; then
974         cp "${work_dir}/${arch}/airootfs/usr/share/efitools/efi/PreLoader.efi" "${work_dir}/iso/EFI/boot/bootx64.efi"
975         cp "${work_dir}/${arch}/airootfs/usr/lib/systemd/boot/efi/systemd-bootx64.efi" "${work_dir}/iso/EFI/boot/loader.efi"
976     fi
977
978     mkdir -p "${work_dir}/iso/loader/entries"
979     cp "${script_path}/efiboot/loader/loader.conf" "${work_dir}/iso/loader/"
980     cp "${script_path}/efiboot/loader/entries/uefi-shell-v2-${arch}.conf" "${work_dir}/iso/loader/entries/"
981     cp "${script_path}/efiboot/loader/entries/uefi-shell-v1-${arch}.conf" "${work_dir}/iso/loader/entries/"
982
983     sed "s|%ARCHISO_LABEL%|${iso_label}|g;
984          s|%OS_NAME%|${os_name}|g;
985          s|%INSTALL_DIR%|${install_dir}|g" \
986         "${script_path}/efiboot/loader/entries/usb/archiso-${arch}-usb-${kernel}.conf" > "${work_dir}/iso/loader/entries/archiso-${arch}.conf"
987
988     # EFI Shell 2.0 for UEFI 2.3+
989     curl -o "${work_dir}/iso/EFI/shellx64_v2.efi" "https://raw.githubusercontent.com/tianocore/edk2/UDK2018/ShellBinPkg/UefiShell/X64/Shell.efi"
990     # EFI Shell 1.0 for non UEFI 2.3+
991     curl -o "${work_dir}/iso/EFI/shellx64_v1.efi" "https://raw.githubusercontent.com/tianocore/edk2/UDK2018/EdkShellBinPkg/FullShell/X64/Shell_Full.efi"
992 }
993
994 # Prepare efiboot.img::/EFI for "El Torito" EFI boot mode
995 make_efiboot() {
996     mkdir -p "${work_dir}/iso/EFI/archiso"
997     truncate -s 64M "${work_dir}/iso/EFI/archiso/efiboot.img"
998     mkfs.fat -n ARCHISO_EFI "${work_dir}/iso/EFI/archiso/efiboot.img"
999
1000     mkdir -p "${work_dir}/efiboot"
1001     mount "${work_dir}/iso/EFI/archiso/efiboot.img" "${work_dir}/efiboot"
1002
1003     mkdir -p "${work_dir}/efiboot/EFI/archiso"
1004
1005     if [[ ! ${kernel} = "core" ]]; then
1006         cp "${work_dir}/iso/${install_dir}/boot/${arch}/vmlinuz-linux-${kernel}" "${work_dir}/efiboot/EFI/archiso/vmlinuz-linux-${kernel}.efi"
1007     else
1008         cp "${work_dir}/iso/${install_dir}/boot/${arch}/vmlinuz" "${work_dir}/efiboot/EFI/archiso/vmlinuz.efi"
1009     fi
1010
1011     cp "${work_dir}/iso/${install_dir}/boot/${arch}/archiso.img" "${work_dir}/efiboot/EFI/archiso/archiso.img"
1012
1013     cp "${work_dir}/iso/${install_dir}/boot/intel_ucode.img" "${work_dir}/efiboot/EFI/archiso/intel_ucode.img"
1014     cp "${work_dir}/iso/${install_dir}/boot/amd_ucode.img" "${work_dir}/efiboot/EFI/archiso/amd_ucode.img"
1015
1016     mkdir -p "${work_dir}/efiboot/EFI/boot"
1017     cp "${work_dir}/${arch}/airootfs/usr/share/efitools/efi/HashTool.efi" "${work_dir}/efiboot/EFI/boot/"
1018
1019     if [[ "${arch}" = "x86_64" ]]; then
1020         cp "${work_dir}/${arch}/airootfs/usr/share/efitools/efi/PreLoader.efi" "${work_dir}/efiboot/EFI/boot/bootx64.efi"
1021         cp "${work_dir}/${arch}/airootfs/usr/lib/systemd/boot/efi/systemd-bootx64.efi" "${work_dir}/efiboot/EFI/boot/loader.efi"
1022     fi
1023
1024     mkdir -p "${work_dir}/efiboot/loader/entries"
1025     cp "${script_path}/efiboot/loader/loader.conf" "${work_dir}/efiboot/loader/"
1026     cp "${script_path}/efiboot/loader/entries/uefi-shell-v2-${arch}.conf" "${work_dir}/efiboot/loader/entries/"
1027     cp "${script_path}/efiboot/loader/entries/uefi-shell-v1-${arch}.conf" "${work_dir}/efiboot/loader/entries/"
1028
1029     #${script_path}/efiboot/loader/entries/archiso-${arch}-cd.conf
1030
1031     sed "s|%ARCHISO_LABEL%|${iso_label}|g;
1032          s|%OS_NAME%|${os_name}|g;
1033          s|%INSTALL_DIR%|${install_dir}|g" \
1034         "${script_path}/efiboot/loader/entries/cd/archiso-${arch}-cd-${kernel}.conf" > "${work_dir}/efiboot/loader/entries/archiso-${arch}.conf"
1035
1036     cp "${work_dir}/iso/EFI/shellx64_v2.efi" "${work_dir}/efiboot/EFI/"
1037     cp "${work_dir}/iso/EFI/shellx64_v1.efi" "${work_dir}/efiboot/EFI/"
1038
1039     umount -d "${work_dir}/efiboot"
1040 }
1041
1042 # Build airootfs filesystem image
1043 make_prepare() {
1044     cp -a -l -f "${work_dir}/${arch}/airootfs" "${work_dir}"
1045     arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}" -D "${install_dir}" pkglist
1046     pacman -Q --sysroot "${work_dir}/airootfs" > "${work_dir}/packages-full.list"
1047     arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}" -D "${install_dir}" ${gpg_key:+-g ${gpg_key}} -c "${sfs_comp}" -t "${sfs_comp_opt}" prepare
1048     remove "${work_dir}/airootfs"
1049
1050     if [[ "${cleaning}" = true ]]; then
1051         remove "${work_dir}/${arch}/airootfs"
1052     fi
1053 }
1054
1055 # Build ISO
1056 make_iso() {
1057     arch=${arch} ${mkalteriso} ${mkalteriso_option} -w "${work_dir}" -D "${install_dir}" -L "${iso_label}" -P "${iso_publisher}" -A "${iso_application}" -o "${out_dir}" iso "${iso_filename}"
1058
1059     if [[ ${cleaning} = true ]]; then
1060         remove "$(ls ${work_dir}/* | grep "build.make")"
1061         remove "${work_dir}/pacman.conf"
1062         remove "${work_dir}/efiboot"
1063         remove "${work_dir}/iso"
1064         remove "${work_dir}/${arch}"
1065         remove "${work_dir}/packages.list"
1066         remove "${work_dir}/packages-full.list"
1067         remove "${work_dir}/build_options"
1068         if [[ -z $(ls $(realpath "${work_dir}")/* ) ]]; then
1069             remove ${work_dir}/*
1070         fi
1071     fi
1072     _msg_info "The password for the live user and root is ${password}."
1073 }
1074
1075
1076 # Parse options
1077 while getopts 'w:o:g:p:c:t:hbk:xs:jlu:d-:' arg; do
1078     case "${arg}" in
1079         p) password="${OPTARG}" ;;
1080         w) work_dir="${OPTARG}" ;;
1081         o) out_dir="${OPTARG}" ;;
1082         g) gpg_key="${OPTARG}" ;;
1083         c)
1084             # compression format check.
1085             if [[ ${OPTARG} = "gzip" ||  ${OPTARG} = "lzma" ||  ${OPTARG} = "lzo" ||  ${OPTARG} = "lz4" ||  ${OPTARG} = "xz" ||  ${OPTARG} = "zstd" ]]; then
1086                 sfs_comp="${OPTARG}"
1087             else
1088                 _msg_error "Invalid compressors ${arg}" "1"
1089             fi
1090             ;;
1091         t) sfs_comp_opt=${OPTARG} ;;
1092         b) boot_splash=true ;;
1093         k)
1094             if [[ -n $(cat ${script_path}/system/kernel_list | grep -h -v ^'#' | grep -x "${OPTARG}") ]]; then
1095                 kernel="${OPTARG}"
1096             else
1097                 _msg_error "Invalid kernel ${OPTARG}" "1"
1098             fi
1099             ;;
1100         s)
1101             if [[ -f "${OPTARG}" ]]; then
1102                 source "${OPTARG}"
1103             else
1104                 _msg_error "Invalid configuration file ${OPTARG}." "1"
1105             fi
1106             ;;
1107         x) 
1108             debug=true
1109             bash_debug=true
1110             ;;
1111         d) debug=true;;
1112         j) japanese=true ;;
1113         l) cleaning=true ;;
1114         u) username="${OPTARG}" ;;
1115         h) _usage 0 ;;
1116         -)
1117             case "${OPTARG}" in
1118                 help)_usage 0 ;;
1119                 noconfirm) noconfirm=true ;;
1120                 *)
1121                     _msg_error "Invalid argument '${OPTARG}'"
1122                     _usage 1
1123                     ;;
1124             esac
1125             ;;
1126         *)
1127            _msg_error "Invalid argument '${arg}'"
1128            _usage 1
1129            ;;
1130     esac
1131 done
1132
1133
1134 # Check root.
1135 if [[ ${EUID} -ne 0 ]]; then
1136     _msg_warn "This script must be run as root." >&2
1137     # echo "Use -h to display script details." >&2
1138     # _usage 1
1139     _msg_warn "Re-run 'sudo ${0} ${@}'"
1140     sudo ${0} ${@}
1141     exit 1
1142 fi
1143
1144
1145 # Show config message
1146 [[ -f "${script_path}"/config ]] && _msg_debug "The settings have been overwritten by the "${script_path}"/config."
1147
1148
1149 # Debug mode
1150 if [[ "${bash_debug}" = true ]]; then
1151     set -x
1152     set -v
1153     mkalteriso_option="${mkalteriso_option} -x"
1154 fi
1155
1156
1157 # Parse options
1158 set +e
1159
1160 shift $((OPTIND - 1))
1161
1162 if [[ -n "${1}" ]]; then
1163     channel_name="${1}"
1164
1165     # Channel list
1166     # check_channel <channel name>
1167     check_channel() {
1168         local channel_list
1169         local i
1170         channel_list=()
1171         for i in $(ls -l "${script_path}"/channels/ | awk '$1 ~ /d/ {print $9 }'); do
1172             if [[ -n $(ls "${script_path}"/channels/${i}) ]]; then
1173                 if [[ ! ${i} = "share" ]]; then
1174                     if [[ ! $(echo "${i}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
1175                         if [[ ! -d "${script_path}/channels/${i}.add" ]]; then
1176                             channel_list="${channel_list[@]} ${i}"
1177                         fi
1178                     else
1179                         channel_list="${channel_list[@]} ${i}"
1180                     fi
1181                 fi
1182             fi
1183         done
1184         for i in ${channel_list[@]}; do
1185             if [[ $(echo "${i}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
1186                 if [[ $(echo ${i} | sed 's/\.[^\.]*$//') = ${1} ]]; then
1187                     echo -n "true"
1188                     return 0
1189                 fi
1190             else
1191                 if [[ ${i} = ${1} ]]; then
1192                     echo -n "true"
1193                     return 0
1194                 fi
1195             fi
1196         done
1197         if [[ "${channel_name}" = "rebuild" ]]; then
1198             echo -n "true"
1199             return 0
1200         else
1201             echo -n "false"
1202             return 1
1203         fi
1204     }
1205
1206     if [[ $(check_channel "${channel_name}") = false ]]; then
1207         _msg_error "Invalid channel ${channel_name}" "1"
1208     fi
1209
1210     if [[ -d "${script_path}"/channels/${channel_name}.add ]]; then
1211         channel_name="${channel_name}.add"
1212     elif [[ ${channel_name} = rebuild ]]; then
1213         if [[ -f "${work_dir}/build_options" ]]; then
1214             if [[ ! $(( OPTIND - 1 )) = 0 ]]; then
1215                 if [[ $(( OPTIND - 1 )) = 1 ]] && [[ ${debug} = true ]]; then
1216                     rebuild=true
1217                 else
1218                     _msg_error "Options cannot be specified for the rebuild channel.All options will use the previous settings." "1"
1219                 fi
1220             else
1221                 rebuild=true
1222             fi
1223         else
1224             _msg_error "The previous build information is not in the working directory." "1"
1225         fi
1226     fi
1227
1228     _msg_debug "channel path is ${script_path}/channels/${channel_name}"
1229 fi
1230
1231 set -e
1232
1233
1234 prepare_build
1235 show_settings
1236 run_once make_pacman_conf
1237 run_once make_basefs
1238 run_once make_packages
1239 run_once make_customize_airootfs
1240 run_once make_setup_mkinitcpio
1241 run_once make_boot
1242 run_once make_boot_extra
1243 run_once make_syslinux
1244 run_once make_isolinux
1245 run_once make_efi
1246 run_once make_efiboot
1247 run_once make_prepare
1248 run_once make_iso