OSDN Git Service

[update] : Added message.
[alterlinux/alterlinux.git] / wizard.sh
1 #!/usr/bin/env bash
2
3 set -e
4
5 nobuild=false
6
7 while getopts 'xn' arg; do
8     case "${arg}" in
9         n)
10             nobuild=true
11             echo "シミュレーションモードを有効化しました"
12             ;;
13         x)
14             set -x 
15             echo "デバッグモードを有効化しました"
16             ;;
17     esac
18 done
19
20
21 script_path="$(readlink -f ${0%/*})"
22
23
24 function check_files () {
25     if [[ ! -f "${script_path}/build.sh" ]]; then
26         echo "${script_path}/build.shが見つかりませんでした。" >&2
27         exit 1
28     fi
29     if [[ ! -f "${script_path}/keyring.sh" ]]; then
30         echo "${script_path}/keyring.shが見つかりませんでした。" >&2
31         exit 1
32     fi
33 }
34
35
36 function install_dependencies () {
37     local checkpkg
38     local dependence
39     local pkg
40     local installed_pkg
41     local installed_ver
42     local check_pkg
43
44     dependence=("git" "make" "arch-install-scripts" "squashfs-tools" "libisoburn" "dosfstools" "lynx" "archiso" "bash" "base")
45     installed_pkg=($(pacman -Q | awk '{print $1}'))
46     installed_ver=($(pacman -Q | awk '{print $2}'))
47
48     check_pkg() {
49         local i
50         for i in $(seq 1 ${#installed_pkg[@]}); do
51             if [[ ${installed_pkg[${i}]} = ${1} ]]; then
52                 if [[ ${installed_ver[${i}]} = $(pacman -Sp --print-format '%v' ${1}) ]]; then
53                     echo -n "true"
54                     return 0
55                 else
56                     echo -n "false"
57                     return 0
58                 fi
59             fi
60         done
61         echo -n "false"
62         return 0
63     }
64
65     for pkg in ${dependence[@]}; do
66         echo "依存パッケージ ${pkg} を確認しています..."
67         if [[ $(check_pkg ${pkg}) = false ]]; then
68             install=(${install[@]} ${pkg})
69         fi
70     done
71
72     if [[ -n "${install[@]}" ]]; then
73         sudo pacman -Sy
74         sudo pacman -S --needed ${install[@]}
75     fi
76             
77 }
78
79
80 function run_add_key_script () {
81     local yn
82     echo -n "AlterLinuxの鍵を追加しますか? (y/N) : "
83     read yn
84     if ${nobuild}; then
85         echo "${yn}が入力されました。シミュレーションモードが有効化されているためスキップします。"
86     else
87         case ${yn} in
88             y | Y | yes | Yes | YES ) sudo "${script_path}/keyring.sh" --alter-add   ;;
89             n | N | no  | No  | NO  ) return 0                                       ;;
90             *                       ) run_add_key_script                             ;;
91         esac
92     fi
93 }
94
95
96 function remove_dependencies () {
97     if [[ -n "${install[@]}" ]]; then
98         sudo pacman -Rsn ${install[@]}
99     fi
100 }
101
102
103 function enable_plymouth () {
104     local yn
105     echo -n "Plymouthを有効化しますか?[no](y/N) : "
106     read yn
107     case ${yn} in
108         y | Y | yes | Yes | YES ) plymouth=true   ;;
109         n | N | no  | No  | NO  ) plymouth=false  ;;
110         *                       ) enable_plymouth ;;
111     esac
112 }
113
114
115 function enable_japanese () {
116     local yn
117     echo -n "日本語を有効化しますか?[no](y/N) : "
118     read yn
119     case ${yn} in
120         y | Y | yes | Yes | YES ) japanese=true   ;;
121         n | N | no  | No  | NO  ) japanese=false  ;;
122         *                       ) enable_japanese ;;
123     esac
124 }
125
126
127 function select_comp_type () {
128     local yn
129     local details
130     local ask_comp_type
131     echo -n "圧縮方式を設定しますか?[zstd](y/N) : "
132     read yn
133     case ${yn} in
134         y | Y | yes | Yes | YES ) details=true               ;;
135         n | N | no  | No  | NO  ) details=false              ;;
136         *                       ) select_comp_type; return 0 ;;
137     esac
138
139     function ask_comp_type () {
140         echo "圧縮方式を以下の番号から選択してください "
141         echo
142         echo "1: gzip"
143         echo "2: lzma"
144         echo "3: lzo"
145         echo "4: lz4"
146         echo "5: xz"
147         echo "6: zstd (default)"
148         echo -n ": "
149
150         read yn
151
152         case ${yn} in
153             1    ) comp_type="gzip" ;;
154             2    ) comp_type="lzma" ;;
155             3    ) comp_type="lzo"  ;;
156             4    ) comp_type="lz4"  ;;
157             5    ) comp_type="xz"   ;;
158             6    ) comp_type="zstd" ;;
159             gzip ) comp_type="gzip" ;;
160             lzma ) comp_type="lzma" ;;
161             lzo  ) comp_type="lzo"  ;;
162             lz4  ) comp_type="lz4"  ;;
163             xz   ) comp_type="xz"   ;;
164             zstd ) comp_type="zstd" ;;
165             *    ) ask_comp_type    ;;
166         esac
167     }
168
169     if [[ ${details} = true ]]; then
170         ask_comp_type
171     else
172         comp_type="zstd"
173     fi
174
175     return 0
176 }
177
178
179 function set_comp_option () {
180     local ask_comp_option
181     ask_comp_option() {
182         local gzip
183         local lzo
184         local lz4
185         local xz
186         local zstd
187         comp_option=""
188
189         function gzip () {
190             local comp_level
191             function comp_level () {
192                 local level
193                 echo -n "gzipの圧縮レベルを入力してください。 (1~22) : "
194                 read level
195                 if [[ ${level} -lt 23 && ${level} -ge 4 ]]; then
196                     comp_option="-Xcompression-level ${level}"
197                 else
198                     comp_level
199                 fi
200             }
201             local window_size
202             function window_size () {
203                 local window
204                 echo -n "gzipのウィンドウサイズを入力してください。 (1~15) : "
205                 read window
206                 if [[ ${window} -lt 16 && ${window} -ge 4 ]]; then
207                     comp_option="${comp_option} -Xwindow-size ${window}"
208                 else
209                     window_size
210                 fi
211             }
212
213         }
214
215         function lz4 () {
216             local yn
217             echo -n "高圧縮モードを有効化しますか? (y/N) : "
218             read yn
219             case ${yn} in
220                 y | Y | yes | Yes | YES ) comp_option="-Xhc" ;;
221                 n | N | no  | No  | NO  ) :                  ;;
222                 *                       ) lz4                ;;
223             esac
224         }
225
226         function zstd () {
227             local level
228             echo -n "zstdの圧縮レベルを入力してください。 (1~22) : "
229             read level
230             if [[ ${level} -lt 23 && ${level} -ge 4 ]]; then
231                 comp_option="-Xcompression-level ${level}"
232             else
233                 zstd
234             fi
235         }
236
237         function lzo () {
238             echo "現在lzoは詳細プションのウィザードがサポートされていません。" >&2
239         }
240
241         function xz () {
242             echo "現在xzは詳細プションのウィザードがサポートされていません。" >&2
243         }
244
245         case ${comp_type} in
246             gzip ) gzip ;;
247             zstd ) zstd ;;
248             lz4  ) lz4  ;;
249             lzo  ) lzo  ;;
250             xz   ) xz   ;;
251             *    ) :    ;;
252         esac
253     }
254
255     # lzmaには詳細なオプションはありません。
256     if [[ ! ${comp_type} = "lzma" ]]; then
257         local yn
258         local details
259         echo -n "圧縮の詳細を設定しますか? (y/N) : "
260         read yn
261         case ${yn} in
262             y | Y | yes | Yes | YES ) details=true              ;;
263             n | N | no  | No  | NO  ) details=false             ;;
264             *                       ) set_comp_option; return 0 ;;
265         esac
266         if [[ ${details} = true ]]; then
267             ask_comp_option
268             return 0
269         else
270             return 0
271         fi
272     fi
273 }
274
275
276 function set_username () {
277     local details
278     local ask_comp_type
279     echo -n "デフォルトではないユーザー名を設定しますか? (y/N) : "
280     read yn
281     case ${yn} in
282         y | Y | yes | Yes | YES ) details=true           ;;
283         n | N | no  | No  | NO  ) details=false          ;;
284         *                       ) set_username; return 0 ;;
285     esac
286
287     function ask_username () {
288         echo -n "ユーザー名を入力してください : "
289         read username
290         if [[ -z ${username} ]]; then
291             ask_username
292         fi
293     }
294
295     if [[ ${details} = true ]]; then
296         ask_username
297     fi
298
299     return 0
300 }
301
302
303 function set_password () {
304     local details
305     local ask_comp_type
306     echo -n "デフォルトではないパスワードを設定しますか? (y/N) : "
307     read yn
308     case ${yn} in
309         y | Y | yes | Yes | YES ) details=true           ;;
310         n | N | no  | No  | NO  ) details=false          ;;
311         *                       ) set_password; return 0 ;;
312     esac
313
314     function ask_password () {
315         echo -n "パスワードを入力してください : "
316         read -s password
317         echo
318         echo -n "もう一度入力してください : "
319         read -s confirm
320         if [[ ! $password = $confirm ]]; then
321             echo
322             echo "同じパスワードが入力されませんでした。"
323             ask_password
324         elif [[ -z $password || -z $confirm ]]; then
325             echo
326             echo "パスワードを入力してください。"
327             ask_password
328         fi
329         echo
330         unset confirm
331     }
332
333     if [[ ${details} = true ]]; then
334         ask_password
335     fi
336
337     return 0
338 }
339
340
341 function select_kernel () {
342     set +e
343     local do_you_want_to_select_kernel
344
345     function do_you_want_to_select_kernel () {
346         set +e
347         local yn
348         echo -n "デフォルト(zen)以外のカーネルを使用しますか? (y/N) : "
349         read yn
350         case ${yn} in
351             y | Y | yes | Yes | YES ) return 0                               ;;
352             n | N | no  | No  | NO  ) return 1                               ;;
353             *                       ) do_you_want_to_select_kernel; return 0 ;;
354         esac
355
356     }
357
358     local what_kernel
359
360     function what_kernel () {
361         echo "使用するカーネルを以下の番号から選択してください "
362         echo
363         echo "1: linux"
364         echo "2: linux-lts"
365         echo "3: linux-zen"
366         echo "4: linux-ck"
367         echo "5: linux-rt"
368         echo "6: linux-rt-lts"
369         echo "7: linux-lqx"
370         echo "8: linux-xanmod"
371         echo "9: linux-xanmod-lts"
372         echo -n ": "
373
374         read yn
375
376         case ${yn} in
377             1                ) kernel="core"       ;;
378             2                ) kernel="lts"        ;;
379             3                ) kernel="zen"        ;;
380             4                ) kernel="ck"         ;;
381             5                ) kernel="rt"         ;;
382             6                ) kernel="rt-lts"     ;;
383             7                ) kernel="lqx"        ;;
384             8                ) kernel="xanmod"     ;;
385             9                ) kernel="xanmod-lts" ;;
386             linux            ) kernel="kernel"     ;;
387             linux-lts        ) kernel="lts"        ;;
388             linux-zen        ) kernel="zen"        ;;
389             linux-ck         ) kernel="ck"         ;;
390             linux-rt         ) kernel="rt"         ;;
391             linux-rt-lts     ) kernel="rt-lts"     ;;
392             linux-lqx        ) kernel="lqx"        ;;
393             linux-xanmod     ) kernel="xanmod"     ;;
394             linux-xanmod-lts ) kernel="xanmod-lts" ;;
395
396             core             ) kernel="core"       ;;
397             lts              ) kernel="lts"        ;;
398             zen              ) kernel="zen"        ;;
399             ck               ) kernel="ck"         ;;
400             rt               ) kernel="rt"         ;;
401             rt-lts           ) kernel="rt-lts"     ;;
402             lqx              ) kernel="lqx"        ;;
403             xanmod           ) kernel="xanmod"     ;;
404             xanmod-lts       ) kernel="xanmod-lts" ;;
405             *                ) what_kernel         ;;
406         esac
407     }
408
409     do_you_want_to_select_kernel
410     exit_code=$?
411     if [[ ${exit_code} = 0 ]]; then
412         what_kernel
413     fi
414     set -e
415 }
416
417
418 # チャンネルの指定
419 function select_channel () {
420     local ask_channel
421
422     echo -n "デフォルト(xfce)以外のチャンネルを使用しますか? (y/N) : "
423     read yn
424     case ${yn} in
425         y | Y | yes | Yes | YES ) details=true             ;;
426         n | N | no  | No  | NO  ) details=false            ;;
427         *                       ) select_channel; return 0 ;;
428     esac
429
430     function ask_channel () {
431         local i
432         local count
433         local _channel
434         local channel_list
435         local description
436
437         # チャンネルの一覧を生成
438         for i in $(ls -l "${script_path}"/channels/ | awk '$1 ~ /d/ {print $9 }'); do
439             if [[ -n $(ls "${script_path}"/channels/${i}) ]]; then
440                 if [[ ! ${i} = "share" ]]; then
441                         channel_list=(${channel_list[@]} ${i})
442                 fi
443             fi
444         done
445         echo "チャンネルを以下の番号から選択してください "
446         count=1
447         for _channel in ${channel_list[@]}; do
448             if [[ -f "${script_path}/channels/${_channel}/description.txt" ]]; then
449                 description=$(cat "${script_path}/channels/${_channel}/description.txt")
450             else
451                 description="This channel does not have a description.txt."
452             fi
453             if [[ $(echo "${_channel}" | sed 's/^.*\.\([^\.]*\)$/\1/') = "add" ]]; then
454                 echo -ne "${count}    $(echo ${_channel} | sed 's/\.[^\.]*$//')"
455                 for i in $( seq 1 $(( 23 - ${#_channel} )) ); do
456                     echo -ne " "
457                 done
458             else
459                 echo -ne "${count}    ${_channel}"
460                 for i in $( seq 1 $(( 19 - ${#_channel} )) ); do
461                     echo -ne " "
462                 done
463             fi
464             echo -ne "${description}\n"
465             count=$(( count + 1 ))
466         done
467         echo -n ":"
468         read channel
469
470         # 数字かどうか判定する
471         set +e
472         expr "${channel}" + 1 >/dev/null 2>&1
473         if [[ ${?} -lt 2 ]]; then
474             set -e
475             # 数字である
476             channel=$(( channel - 1 ))
477             if [[ -z "${channel_list[${channel}]}" ]]; then
478                 ask_channel
479                 return 0
480             else
481                 channel="${channel_list[${channel}]}"
482             fi
483         else
484             set -e
485             # 数字ではない
486             if [[ ! $(printf '%s\n' "${channel_list[@]}" | grep -qx "${channel}.add"; echo -n ${?} ) -eq 0 ]]; then
487                 if [[ ! $(printf '%s\n' "${channel_list[@]}" | grep -qx "${channel}"; echo -n ${?} ) -eq 0 ]]; then
488                     ask_channel
489                     return 0
490                 fi
491             fi
492         fi
493     }
494
495     if [[ ${details} = true ]]; then
496         ask_channel
497     fi
498     # echo ${channel}
499     return 0
500 }
501
502
503 # イメージファイルの所有者
504 function set_iso_owner () {
505     local owner
506     local user_check
507     function user_check () {
508     if [[ $(getent passwd $1 > /dev/null ; printf $?) = 0 ]]; then
509         if [[ -z $1 ]]; then
510             echo -n "false"
511         fi
512         echo -n "true"
513     else
514         echo -n "false"
515     fi
516     }
517
518     echo -n "イメージファイルの所有者を入力してください。: "
519     read owner
520     if [[ $(user_check ${owner}) = false ]]; then
521         echo "ユーザーが存在しません。"
522         set_iso_owner
523         return 0
524     elif  [[ -z "${owner}" ]]; then
525         echo "ユーザー名を入力して下さい。"
526         set_iso_owner
527         return 0
528     elif [[ "${owner}" = root ]]; then
529         echo "所有者の変更を行いません。"
530         return 0
531     fi
532 }
533
534
535 # イメージファイルの作成先
536 function set_out_dir () {
537     echo "イメージファイルの作成先を入力して下さい。"
538     echo "デフォルトは ${script_path}/out です。"
539     echo -n ": "
540     read out_dir
541     if [[ -z "${out_dir}" ]]; then
542         out_dir=out
543     else
544         if [[ ! -d "${out_dir}" ]]; then
545             echo "存在しているディレクトリを指定して下さい"
546             set_out_dir
547             return 0
548         elif [[ "${out_dir}" = / ]] || [[ "${out_dir}" = /home ]]; then
549             echo "そのディレクトリは使用できません。"
550             set_out_dir
551             return 0
552         elif [[ -n "$(ls ${out_dir})" ]]; then
553             echo "ディレクトリは空ではありません。"
554             set_out_dir
555             return 0
556         fi
557     fi
558 }
559
560
561 # 最終的なbuild.shのオプションを生成
562 function generate_argument () {
563     if [[ ${japanese} = true ]]; then
564         argument="${argument} -j"
565     fi
566     if [[ ${plymouth} = true ]]; then
567         argument="${argument} -b"
568     fi
569     if [[ -n ${comp_type} ]]; then
570         argument="${argument} -c ${comp_type}"
571     fi
572     if [[ -n ${kernel} ]]; then
573         argument="${argument} -k ${kernel}"
574     fi
575     if [[ -n "${username}" ]]; then
576         argument="${argument} -u '${username}'"
577     fi
578     if [[ -n ${password} ]]; then
579         argument="${argument} -p '${password}'"
580     fi
581     if [[ -n ${out_dir} ]]; then
582         argument="${argument} -o '${out_dir}'"
583     fi
584     argument="${argument} ${channel}"
585 }
586
587 # 上の質問の関数を実行
588 function ask () {
589     enable_japanese
590     enable_plymouth
591     select_kernel
592     select_comp_type
593     set_comp_option
594     set_username
595     set_password
596     select_channel
597     set_iso_owner
598     # set_out_dir
599     lastcheck
600 }
601
602 # ビルド設定の確認
603 function lastcheck () {
604     echo "以下の設定でビルドを開始します。"
605     echo
606     [[ -n "${japanese}"    ]] && echo "           Japanese : ${japanese}"
607     [[ -n "${plymouth}"    ]] && echo "           Plymouth : ${plymouth}"
608     [[ -n "${kernel}"      ]] && echo "             kernel : ${kernel}"
609     [[ -n "${comp_type}"   ]] && echo " Compression method : ${comp_type}"
610     [[ -n "${comp_option}" ]] && echo "Compression options : ${comp_option}"
611     [[ -n "${username}"    ]] && echo "           Username : ${username}"
612     [[ -n "${password}"    ]] && echo "           Password : ${password}"
613     [[ -n "${channel}"     ]] && echo "            Channel : ${channel}"
614     echo
615     echo -n "この設定で続行します。よろしいですか? (y/N) : "
616     local yn
617     read yn
618     case ${yn} in
619         y | Y | yes | Yes | YES ) :         ;;
620         n | N | no  | No  | NO  ) ask       ;;
621         *                       ) lastcheck ;;
622     esac
623 }
624
625 function start_build () {
626     if [[ ${nobuild} = true ]]; then
627         echo "${argument}"
628     else
629         # build.shの引数を表示(デバッグ用)
630         # echo ${argument}
631         sudo ./build.sh ${argument}
632         sudo rm -rf work/
633     fi
634 }
635
636
637 remove_work_dir() {
638     if [[ -d "${script_path}/work/" ]]; then
639         sudo rm -rf "${script_path}/work/"
640     fi
641 }
642
643
644 change_iso_permission() {
645     if [[ -n "${owner}" ]]; then
646         chown -R "${owner}" "${script_path}/out/"
647         chmod -R 750 "${script_path}/out/"
648     fi
649 }
650
651 # 関数を実行
652 check_files
653 install_dependencies
654 run_add_key_script
655 ask
656 generate_argument
657 start_build
658 remove_dependencies
659 remove_work_dir
660 change_iso_permission