X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=lubs;h=de6870fd25b5cfbe62c5abc1740f81903bd082f2;hb=73c22c8de89f6f0887ef0df81bb53381da165b6e;hp=e809d9b1039f2be6f75fdcfd234720cfe64f67ae;hpb=7c1fcc76706c7d5f8e4d029c91f7641c7cc3a6c6;p=alterlinux%2FLUBS.git diff --git a/lubs b/lubs index e809d9b..de6870f 100755 --- a/lubs +++ b/lubs @@ -1,18 +1,32 @@ #!/usr/bin/env bash +# SPDX-License-Identifier: GPL-3.0 +# +# mk-linux419 +# Twitter: @fascoder_4 +# Email : m.k419sabuaka@gmail.com +# +# Yamada Hayao +# Twitter: @Hayao0819 +# Email : hayao@fascode.net +# +# (c) 2019-2020 Fascode Network. +# +# lubs +# set -e # set -u export LANG=C -script_path=$(readlink -f ${0%/*}) +script_path=$(readlink -f "${0%/*}") cache_dir="${script_path}/cache" channels_dir="${script_path}/channels" -isolinux_dir="${script_path}/isolinux" +nfb_dir="${script_path}/nfb" codename="focal" -mirror="http://ftp.jaist.ac.jp/pub/Linux/ubuntu/" +mirror="http://linux.yz.yamagata-u.ac.jp/ubuntu/" os_name="Ubuntu" iso_name="ubuntu" @@ -27,69 +41,106 @@ iso_filename="${iso_name}-${iso_version}-${arch}.iso" channel_name="serene" +username="liveuser" +usershell="/bin/bash" + debug=false cache_only=false +start_time="$(date +%s)" + +_msg_common() { + if [[ "${debug}" = true ]]; then + local _current_time + local _time + _current_time="$(date +%s)" + _time="$(("${_current_time}"-"${start_time}"))" + + if [[ "${_time}" -ge 3600 ]]; then + echo "[$(date -d @${_time} +%H:%M.%S)]$("${script_path}/echo_color" -t 6 "[LUBS Core]")" + elif [[ "${_time}" -ge 60 ]]; then + echo "[00:$(date -d @${_time} +%M.%S)]$("${script_path}/echo_color" -t 6 "[LUBS Core]")" + else + echo "[00:00.$(date -d @${_time} +%S)] $("${script_path}/echo_color" -t 6 "[LUBS Core]")" + fi + else + "${script_path}/echo_color" -t 6 "[LUBS Core]" + fi +} + # Show an INFO message # _msg_info _msg_info() { - local _msg="${@}" - echo "$("${script_path}/echo_color" -t 6 "[LUBS Core]") $("${script_path}/echo_color" -t 2 "Info:") ${_msg}" + local _msg + _msg="${@}" + echo "$(_msg_common) $("${script_path}/echo_color" -t 2 "Info:") ${_msg}" } # Show an debug message # _msg_debug _msg_debug() { if [[ "${debug}" = true ]]; then - local _msg="${@}" - echo "$("${script_path}/echo_color" -t 6 "[LUBS Core]") $("${script_path}/echo_color" -t 3 "Debug:") ${_msg}" + local _msg + _msg="${@}" + echo "$(_msg_common) $("${script_path}/echo_color" -t 3 "Debug:") ${_msg}" fi } # Show an ERROR message then exit with status # _msg_error _msg_error() { - local _msg="${1}" - local _error=${2} - echo "$("${script_path}/echo_color" -t 6 "[LUBS Core]") $("${script_path}/echo_color" -t 1 "Error:") ${_msg}" + local _msg + local _error + _msg="${1}" + _error=${2} + echo "$(_msg_common) $("${script_path}/echo_color" -t 1 "Error:") ${_msg}" + if [[ ! ${_error} = 0 ]]; then exit ${_error} fi } +# Unmount chroot dir +umount_chroot () { + local mount + + for mount in $(mount | awk '{print $3}' | grep "$(realpath "${work_dir}")" | sort -r); do + _msg_info "Unmounting ${mount}" + umount -fl "${mount}" + done +} + # Helper function to run make_*() only one time. run_once() { local name - - if [[ "run_bootfiles" == "$1" ]]; then - name="$2" - else - name="$1" - fi + umount_chroot + name="$1" if [[ ! -e "${work_dir}/build.${name}" ]]; then _msg_info "$(echo $name | sed "s@_@ @g") is starting." - - if [[ "run_bootfiles" == "$1" ]]; then - "$1" "$2" - else - "$1" - fi - + "${1}" _msg_info "$(echo $name | sed "s@_@ @g") was done!" touch "${work_dir}/build.${name}" fi } run_cmd() { - arch-chroot "${work_dir}/airootfs" "${@}" -} + local mount -run_bootfiles() { - cd "${bootfiles_dir}" - "$1" - cd - > /dev/null + for mount in "dev" "dev/pts" "proc" "sys" "run/systemd/resolve/stub-resolv.conf"; do + if [[ "${mount}" == "run/systemd/resolve/stub-resolv.conf" ]]; then + mount --bind /etc/resolv.conf "${work_dir}/airootfs/${mount}" + else + mount --bind /${mount} "${work_dir}/airootfs/${mount}" + fi + done + + chroot "${work_dir}/airootfs" "${@}" + + for mount in $(mount | awk '{print $3}' | grep "$(realpath "${work_dir}")" | sort -r); do + umount -fl "${mount}" + done } _apt_install() { @@ -105,8 +156,10 @@ remove() { local _list local _file _list=($(echo "$@")) + for _file in "${_list[@]}"; do _msg_debug "Removeing ${_file}" + if [[ -f ${_file} ]]; then rm -f "${_file}" elif [[ -d ${_file} ]]; then @@ -135,6 +188,35 @@ _usage () { echo " -d | --debug " echo " -h | --help This help message and exit" echo + echo "You can switch between installed packages, files included in images, etc. by channel." + echo + echo " Channel:" + + local _channel + local channel_list + local description + + for _channel in $(ls -l "${channels_dir}" | awk '$1 ~ /d/ {print $9 }'); do + if [[ -n $(ls "${channels_dir}/${_channel}") ]] && [[ ! "${_channel}" = "share" ]]; then + channel_list+=( "${_channel}" ) + fi + done + + for _channel in ${channel_list[@]}; do + if [[ -f "${channels_dir}/${_channel}/description.txt" ]]; then + description=$(cat "${channels_dir}/${_channel}/description.txt") + else + description="This channel does not have a description.txt." + fi + + echo -ne " ${_channel}" + + for i in $( seq 1 $(( 23 - ${#_channel} )) ); do + echo -ne " " + done + + echo -ne "${description}\n" + done } @@ -142,15 +224,10 @@ prepare_build() { if [[ ${EUID} -ne 0 ]]; then _msg_error "This script must be run as root." 1 fi - + [[ ! -d "${work_dir}" ]] && mkdir -p "${work_dir}" [[ ! -d "${out_dir}" ]] && mkdir -p "${out_dir}" - - local mount - for mount in $(mount | awk '{print $3}' | grep $(realpath ${work_dir}) | sort -r); do - _msg_info "Unmounting ${mount}" - umount "${mount}" - done + umount_chroot # Check codename if [[ -z $(grep -h -v ^'#' ${channels_dir}/${channel_name}/codename.${arch} | grep -x ${codename}) ]]; then @@ -178,14 +255,15 @@ make_basefs() { debootstrap_status "Running" _msg_info "Installing Ubuntu to '${cache_dir}/${codename}/airootfs'..." mkdir -p "${cache_dir}/${codename}/airootfs" - debootstrap --arch=${arch} --include=linux-image-generic --verbose --merged-usr "${codename}" "${cache_dir}/${codename}/airootfs" ${mirror} + debootstrap --arch="${arch}" --verbose --merged-usr "${codename}" "${cache_dir}/${codename}/airootfs" "${mirror}" _msg_info "${codename} installed successfully!" debootstrap_status "Done" fi + if [[ "${cache_only}" = true ]]; then exit 0 fi - + rm -rf "${work_dir}/airootfs" && mkdir -p "${work_dir}/airootfs" _msg_info "copy base files from '${cache_dir}/${codename}/airootfs' to '${work_dir}/airootfs'..." rsync -au "${cache_dir}/${codename}/airootfs/" "${work_dir}/airootfs" @@ -196,37 +274,37 @@ make_basefs() { make_sourcelist() { cp ${script_path}/source.list.d/${codename}/* ${work_dir}/airootfs/etc/apt + sed -i "s@http://archive.ubuntu.com/ubuntu/@${mirror}@g" ${work_dir}/airootfs/etc/apt/sources.list run_cmd apt-get update if [[ -n $(find ${channels_dir}/*/repo -type f) ]]; then _apt_install gnupg - for repo in $(find ${channels_dir}/*/repo -name *.list); do - key="$(dirname $repo)/$(basename $repo | sed "s/list/key/")" - - if [[ -f "$key" ]]; then - if $(file $key | grep -q "PGP/GPG key"); then - cp $key ${work_dir}/airootfs/$(basename $key) + for repo in $(find ${channels_dir}/*/repo -name '*.list'); do + key="$(dirname ${repo})/$(basename ${repo} | sed "s/list/key/")" + + if [[ -f "${key}" ]]; then + if file ${key} | grep -q "PGP/GPG key"; then + cp "${key}" "${work_dir}/airootfs/$(basename ${key})" else - wget -q -O ${work_dir}/airootfs/$(basename $key) $(cat $key) + wget -q -O "${work_dir}/airootfs/$(basename ${key})" "$(cat ${key})" fi - run_cmd apt-key add $(basename $key) - rm ${work_dir}/airootfs/$(basename $key) - cp $repo ${work_dir}/airootfs/etc/apt/sources.list.d + run_cmd apt-key add "$(basename ${key})" + rm "${work_dir}/airootfs/$(basename ${key})" + cp "${repo}" "${work_dir}/airootfs/etc/apt/sources.list.d" fi done - run_cmd apt-get update fi - + # PPA local PPA_FILELIST local _PPA_FILE local _ppa - PPA_FILELIST=("${channels_dir}/share/ppa_list.${arch}" "${channels_dir}/${channel_name}/ppa_list.${arch}") _apt_install software-properties-common + for _PPA_FILE in ${PPA_FILELIST[@]}; do if [[ -f "${_PPA_FILE}" ]]; then for _ppa in $(grep -h -v ^'#' ${_PPA_FILE}); do @@ -238,22 +316,28 @@ make_sourcelist() { make_systemd() { _apt_install systemd-sysv - run_cmd dbus-uuidgen > /etc/machine-id - run_cmd ln -fs /etc/machine-id /var/lib/dbus/machine-id + run_cmd dbus-uuidgen --ensure=/etc/machine-id + run_cmd ln -sf /etc/machine-id /var/lib/dbus/machine-id } -make_packages() { - remove "${work_dir}/airootfs/installpkglist" +make_apt_packages() { + remove "${work_dir}/airootfs/aptpkglist" + _apt_install initramfs-tools + run_cmd env -i bash -c 'DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade --yes' if [[ -f "${channels_dir}/share/packages.${arch}" ]]; then - grep -h -v ^'#' "${channels_dir}/share/packages.${arch}" | grep -v "^$" >> "${work_dir}/airootfs/installpkglist" + grep -h -v ^'#' "${channels_dir}/share/packages.${arch}" | grep -v "^$" >> "${work_dir}/airootfs/aptpkglist" fi + if [[ -f "${channels_dir}/${channel_name}/packages.${arch}" ]]; then - grep -h -v ^'#' "${channels_dir}/${channel_name}/packages.${arch}" | grep -v "^$" >> "${work_dir}/airootfs/installpkglist" + grep -h -v ^'#' "${channels_dir}/${channel_name}/packages.${arch}" | grep -v "^$" >> "${work_dir}/airootfs/aptpkglist" fi - if [[ -n "$(echo $(<"${work_dir}/airootfs/installpkglist"))" ]]; then - run_cmd env -i bash -c 'DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends --yes install $(echo $( "${work_dir}/airootfs/etc/casper.conf" + chmod 755 "${work_dir}"/airootfs/usr/share/initramfs-tools/scripts/casper-bottom/*adduser "${work_dir}"/airootfs/usr/share/initramfs-tools/scripts/casper-bottom/*autologin + run_cmd env -i bash -c 'mkinitramfs -o /boot/initrd.img-`uname -r` `uname -r`' } make_clean() { + sed -i "s@${mirror}@http://archive.ubuntu.com/ubuntu/@g" ${work_dir}/airootfs/etc/apt/sources.list + run_cmd apt-get update run_cmd apt-get clean run_cmd apt-get --yes autoremove run_cmd rm -rf "/tmp/* ~/.bash_history" } -make_bootfiles() { - run_cmd update-initramfs -c -k all - _apt_install memtest86+ +make_squashfs() { + # prepare [[ -d "${bootfiles_dir}" ]] && rm -r "${bootfiles_dir}" - mkdir -p ${bootfiles_dir}/{casper,isolinux,install} - cp ${work_dir}/airootfs/boot/vmlinuz-*-*-generic ${bootfiles_dir}/casper/vmlinuz - cp ${work_dir}/airootfs/boot/initrd.img-*-*-generic ${bootfiles_dir}/casper/initrd - cp ${work_dir}/airootfs/boot/memtest86+.bin ${bootfiles_dir}/install/memtest86+ + mkdir -p "${bootfiles_dir}"/{casper,isolinux,install} - if [[ ! -f "${cache_dir}/memtest86-usb.zip" ]]; then - wget -O ${cache_dir}/memtest86-usb.zip https://www.memtest86.com/downloads/memtest86-usb.zip - fi - - (unzip -p ${cache_dir}/memtest86-usb.zip memtest86-usb.img > ${bootfiles_dir}/install/memtest86) + # make squashfs + mksquashfs "${work_dir}/airootfs" "${bootfiles_dir}/casper/filesystem.squashfs" } -make_grubcfg() { +make_nfb() { + # prepare touch "${bootfiles_dir}/ubuntu" - cp ${isolinux_dir}/grub.cfg ${bootfiles_dir}/isolinux/grub.cfg -} - -make_manifest() { - run_cmd dpkg-query -W --showformat='${Package} ${Version}\n' | tee ${bootfiles_dir}/casper/filesystem.manifest - cp -v ${bootfiles_dir}/casper/filesystem.manifest "${bootfiles_dir}/casper/filesystem.manifest-desktop" - sed -i '/ubiquity/d' "${bootfiles_dir}/casper/filesystem.manifest-desktop" - sed -i '/casper/d' "${bootfiles_dir}/casper/filesystem.manifest-desktop" - sed -i '/discover/d' "${bootfiles_dir}/casper/filesystem.manifest-desktop" - sed -i '/laptop-detect/d' "${bootfiles_dir}/casper/filesystem.manifest-desktop" - sed -i '/os-prober/d' "${bootfiles_dir}/casper/filesystem.manifest-desktop" -} + sed "s|%OS_NAME%|${os_name}|g" "${nfb_dir}/README.diskdefines" > "${bootfiles_dir}/README.diskdefines" + + # casper setup + cp "${work_dir}/airootfs/boot/vmlinuz" "${bootfiles_dir}/casper/vmlinuz" + cp "${work_dir}/airootfs/boot/initrd.img" "${bootfiles_dir}/casper/initrd" + run_cmd dpkg-query -W --showformat='${Package} ${Version}\n' > ${bootfiles_dir}/casper/filesystem.manifest + cp -v "${bootfiles_dir}/casper/filesystem.manifest" "${bootfiles_dir}/casper/filesystem.manifest-desktop" + sed -i '/casper/d;/discover/d;/laptop-detect/d;/os-prober/d;/ubiquity/d' "${bootfiles_dir}/casper/filesystem.manifest-desktop" + printf $(du -sx --block-size=1 "${work_dir}/airootfs" | cut -f1) > "${bootfiles_dir}/casper/filesystem.size" + + # isolinux setup + cp "${work_dir}"/airootfs/usr/lib/syslinux/modules/bios/*.c32 "${bootfiles_dir}/isolinux/" + cp "${work_dir}/airootfs/usr/lib/ISOLINUX/isolinux.bin" "${bootfiles_dir}/isolinux/" + cp "${work_dir}/airootfs/usr/lib/ISOLINUX/isohdpfx.bin" "${bootfiles_dir}/isolinux/" + sed "s|%OS_NAME%|${os_name}|g" "${nfb_dir}/grub.cfg" > "${bootfiles_dir}/isolinux/grub.cfg" + sed "s|%OS_NAME%|${os_name}|g" "${nfb_dir}/isolinux.cfg" > "${bootfiles_dir}/isolinux/isolinux.cfg" + + # memtest86+ setup + _apt_install memtest86+ + cp "${work_dir}/airootfs/boot/memtest86+.bin" "${bootfiles_dir}/install/memtest86+" -make_squashfs() { - mksquashfs "${work_dir}/airootfs" "${bootfiles_dir}/casper/filesystem.squashfs" - printf $(du -sx --block-size=1 "${work_dir}/airootfs" | cut -f1) > ${bootfiles_dir}/casper/filesystem.size -} + # memtest86 setup + if [[ ! -f "${cache_dir}/memtest86-usb.zip" ]]; then + wget -O "${cache_dir}/memtest86-usb.zip" "https://www.memtest86.com/downloads/memtest86-usb.zip" + bash -c "(unzip -p ${cache_dir}/memtest86-usb.zip memtest86-usb.img > ${cache_dir}/memtest86)" + fi -make_deifnes() { - cp ${isolinux_dir}/README.diskdefines ${bootfiles_dir}/README.diskdefines + cp "${cache_dir}/memtest86" "${bootfiles_dir}/install/memtest86" } -make_isolinux() { - if [[ "${arch}" = "amd64" ]]; then - local _arch="x86_64" - else - local _arch="${arch}" - fi +make_efi() { + # UEFI 32bit (ia32) grub-mkstandalone \ - --format=${_arch}-efi \ - --output=isolinux/bootx64.efi \ + --format=i386-efi \ + --output="${bootfiles_dir}/isolinux/bootia32.efi" \ --locales="" \ --fonts="" \ - "boot/grub/grub.cfg=isolinux/grub.cfg" - ( - cd isolinux && \ - dd if=/dev/zero of=efiboot.img bs=1M count=10 && \ - sudo mkfs.vfat efiboot.img && \ - LC_CTYPE=C mmd -i efiboot.img efi efi/boot && \ - LC_CTYPE=C mcopy -i efiboot.img ./bootx64.efi ::efi/boot/ - ) + "boot/grub/grub.cfg=${bootfiles_dir}/isolinux/grub.cfg" + + # UEFI 64bit (x64) grub-mkstandalone \ - --format=i386-pc \ - --output=isolinux/core.img \ - --install-modules="linux16 linux normal iso9660 biosdisk memdisk search tar ls" \ - --modules="linux16 linux normal iso9660 biosdisk search" \ + --format=x86_64-efi \ + --output="${bootfiles_dir}/isolinux/bootx64.efi" \ --locales="" \ --fonts="" \ - "boot/grub/grub.cfg=isolinux/grub.cfg" - cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > isolinux/bios.img -} - -make_md5sum() { - /bin/bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v "\./md5sum.txt" > md5sum.txt)" + "boot/grub/grub.cfg=${bootfiles_dir}/isolinux/grub.cfg" + + # create efiboot.img + truncate -s 50M "${bootfiles_dir}/isolinux/efiboot.img" + mkfs.fat -F 16 -f 1 -r 112 "${bootfiles_dir}/isolinux/efiboot.img" + mount "${bootfiles_dir}/isolinux/efiboot.img" "${bootfiles_dir}/mnt" + mkdir -p "${bootfiles_dir}/mnt/efi/boot" + cp "${bootfiles_dir}/isolinux/bootia32.efi" "${bootfiles_dir}/mnt/efi/boot/" + cp "${bootfiles_dir}/isolinux/bootx64.efi" "${bootfiles_dir}/mnt/efi/boot/" + umount -d "${bootfiles_dir}/mnt" + rm -r "${bootfiles_dir}/mnt" } make_iso() { + cd "${bootfiles_dir}" + + # create checksum (using at booting) + bash -c "(find . -type f -print0 | xargs -0 md5sum | grep -v "\./md5sum.txt" > md5sum.txt)" + + # create iso xorriso \ -as mkisofs \ -iso-level 3 \ @@ -386,26 +457,28 @@ make_iso() { -appid "${iso_application}" \ -publisher "${iso_publisher}" \ -preparer "prepared by LUBS" \ - -eltorito-boot boot/grub/bios.img \ - -no-emul-boot \ - -boot-load-size 4 \ - -boot-info-table \ - --eltorito-catalog boot/grub/boot.cat \ - --grub2-boot-info \ - --grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \ + -eltorito-boot isolinux/isolinux.bin \ + -no-emul-boot \ + -boot-load-size 4 \ + -boot-info-table \ -eltorito-alt-boot \ - -e EFI/efiboot.img \ - -no-emul-boot \ - -append_partition 2 0xef isolinux/efiboot.img \ + -eltorito-platform efi \ + -eltorito-boot EFI/efiboot.img \ + -no-emul-boot \ + -isohybrid-mbr "${bootfiles_dir}/isolinux/isohdpfx.bin" \ + -isohybrid-gpt-basdat \ + -eltorito-catalog isolinux/boot.cat \ -output "${out_dir}/${iso_filename}" \ -graft-points \ "." \ - /boot/grub/bios.img=isolinux/bios.img \ - /EFI/efiboot.img=isolinux/efiboot.img + "/isolinux/isolinux.bin=isolinux/isolinux.bin" \ + "/EFI/efiboot.img=isolinux/efiboot.img" + + cd - > /dev/null } make_checksum() { - cd ${out_dir} + cd "${out_dir}" _msg_info "Creating md5 checksum ..." md5sum "${iso_filename}" > "${iso_filename}.md5" @@ -421,10 +494,13 @@ make_checksum() { _opt_short="w:o:ha:-:m:c:d" _opt_long="help,arch:,codename:,debug,help,mirror:,out:,work,cache-only" OPT=$(getopt -o ${_opt_short} -l ${_opt_long} -- "${@}") + if [[ ${?} != 0 ]]; then exit 1 fi + eval set -- "${OPT}" + while :; do case ${1} in -a | --arch) @@ -460,14 +536,17 @@ while :; do else mirror="${2}" fi + shift 2 ;; -o | --out) if [[ -z ${2} ]]; then _msg_error "Please specify the out dir." - exit 1Do not use cache if interrupted on the way -Change cache structure + exit 1 + else + out_dir="${2}" fi + shift 2 ;; -w | --work) @@ -477,6 +556,7 @@ Change cache structure else work_dir="${2}" fi + shift 2 ;; --cache-only) @@ -495,22 +575,50 @@ Change cache structure done bootfiles_dir="${work_dir}/bootfiles" +trap umount_chroot 0 2 15 + +if [[ -n "${1}" ]]; then + channel_name="${1}" + + check_channel() { + local channel_list + local i + channel_list=() + + for _channel in $(ls -l "${channels_dir}" | awk '$1 ~ /d/ {print $9 }'); do + if [[ -n $(ls "${channels_dir}/${_channel}") ]] && [[ ! "${_channel}" = "share" ]]; then + channel_list+=( "${_channel}" ) + fi + done + + for i in ${channel_list[@]}; do + if [[ "${i}" = "${channel_name}" ]]; then + echo -n "true" + return 0 + fi + done + + echo -n "false" + return 1 + } + + if [[ $(check_channel ${channel_name}) = false ]]; then + _msg_error "Invalid channel ${channel_name}" + exit 1 + fi +fi prepare_build run_once make_basefs run_once make_sourcelist run_once make_systemd -run_once make_packages +run_once make_apt_packages run_once make_config -run_once make_customize_airootfs +run_once make_add_user run_once make_clean -run_once make_bootfiles -run_once make_grubcfg -run_once make_manifest run_once make_squashfs -run_once make_deifnes -run_once run_bootfiles make_isolinux -run_once run_bootfiles make_md5sum -run_once run_bootfiles make_iso +run_once make_nfb +run_once make_efi +run_once make_iso run_once make_checksum