OSDN Git Service

add ubuntuになる問題の修正
[alterlinux/LUBS.git] / lubs
diff --git a/lubs b/lubs
index d21bcf1..034c400 100755 (executable)
--- a/lubs
+++ b/lubs
@@ -6,6 +6,8 @@ set -e
 export LANG=C
 
 script_path=$(readlink -f ${0%/*})
+
+cache_dir="${script_path}/cache"
 channels_dir="${script_path}/channels"
 isolinux_dir="${script_path}/isolinux"
 
@@ -26,13 +28,35 @@ iso_filename="${iso_name}-${iso_version}-${arch}.iso"
 channel_name="serene"
 
 debug=false
+cache_only=false
+
+
+start_time="$(date +%s)"
+
+_msg_common() {
+    if [[ "${debug}" = true ]]; then
+        local _current_time="$(date +%s)"
+        local _time
+
+        _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 <message>
 _msg_info() {
     local _msg="${@}"
-    "${script_path}/echo_color"  -t 36 "[LUBS Core]" /! -t 32 " INFO:" "/#" -t 0 "${_msg}"
+    echo "$(_msg_common)  $("${script_path}/echo_color" -t 2 "Info:") ${_msg}"
 }
 
 # Show an debug message
@@ -40,7 +64,7 @@ _msg_info() {
 _msg_debug() {
     if [[ "${debug}" = true ]]; then
         local _msg="${@}"
-        "${script_path}/echo_color"  -t 36 "[LUBS Core]" /! -t 35 "Debug:" "/#" -t 0 "${_msg}"
+        echo "$(_msg_common)  $("${script_path}/echo_color" -t 3 "Debug:") ${_msg}"
     fi
 }
 
@@ -49,15 +73,25 @@ _msg_debug() {
 _msg_error() {
     local _msg="${1}"
     local _error=${2}
-    "${script_path}/echo_color" -t 36 "[LUBS Core]" /! -t 31 "ERROR:" "/#" -t 0 "${_msg}" >&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
+        [[ "${1}" == debug ]] && _msg_debug "Unmounting ${mount}" || _msg_info "Unmounting ${mount}"
+        umount -fl "${mount}"
+    done
+}
+
 # Helper function to run make_*() only one time.
 run_once() {
     local name
+    umount_chroot
 
     if [[ "run_bootfiles" == "$1" ]]; then
         name="$2"
@@ -80,7 +114,13 @@ run_once() {
 }
 
 run_cmd() {
-    "${script_path}/lubs-chroot" "${work_dir}/airootfs" "${@}"
+    for mount in "dev" "dev/pts" "proc" "sys" "run/systemd/resolve/stub-resolv.conf"; do
+        _msg_debug "Mounting  ${work_dir}/airootfs/${mount}"
+        [[ "${mount}" == "run/systemd/resolve/stub-resolv.conf" ]] && mount --bind /etc/resolv.conf "${work_dir}/airootfs/${mount}" || mount --bind /${mount} "${work_dir}/airootfs/${mount}"
+    done
+
+    chroot "${work_dir}/airootfs" "${@}"
+    umount_chroot debug
 }
 
 run_bootfiles() {
@@ -132,6 +172,29 @@ _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_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
 }
 
 
@@ -143,28 +206,45 @@ prepare_build() {
     [[ ! -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
+        _msg_error "This codename (${channel_name}) is not supported on this channel (${codename})."
+    fi
 
 }
 
 
 make_basefs() {
-    if [[ ! -d "${cache_dir}/${codename}" ]]; then
-        _msg_info "Installing Ubuntu to '${cache_dir}/${codename}'..."
-        mkdir -p "${cache_dir}/${codename}"
-        debootstrap --arch=${arch} --include=linux-image-generic  --verbose --merged-usr "${codename}" "${cache_dir}/${codename}" ${mirror}
-        _msg_info "${codename} installed successfully!"
-    else
+    local debootstrap_status
+    statusfile="${cache_dir}/${codename}/status"
+
+    debootstrap_status() {
+        if [[ ! -d "$(dirname ${statusfile})" ]]; then
+            mkdir -p "$(dirname ${statusfile})"
+        fi
+        echo "${1}" > "${statusfile}"
+    }
+
+    if [[ -f "${statusfile}" ]] && [[ $(cat "${statusfile}" 2> /dev/null) = "Done" ]]; then
         _msg_info "${codename} cache is found."
+    else
+        remove "${cache_dir}/${codename}"
+        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}
+        _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}' to '${work_dir}/airootfs'..."
-    rsync  -au "${cache_dir}/${codename}/" "${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"
     echo 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH}' >> "${work_dir}/airootfs/etc/bash.bashrc"
     run_cmd apt-get update
     # run_cmd apt-get upgrade
@@ -174,19 +254,42 @@ make_sourcelist() {
     cp ${script_path}/source.list.d/${codename}/* ${work_dir}/airootfs/etc/apt
     run_cmd apt-get update
 
-    if [[ -f "${channels_dir}/${channel_name}/${channel_name}.list" ]] && [[ -f "${channels_dir}/${channel_name}/${channel_name}-list_key" ]]; then
-        source ${channels_dir}/${channel_name}/${channel_name}-list_key
+    if [[ -n $(find ${channels_dir}/*/repo -type f) ]]; then
+        _apt_install gnupg
 
-        if [[ ! -f "${cache_dir}/${channel_name}.key" ]]; then
-            wget -q -O ${cache_dir}/${channel_name}.key "${url}"
-        fi
+        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})
+                fi
+
+                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
 
-        _apt_install gnupg
-        cp ${cache_dir}/${channel_name}.key ${work_dir}/airootfs/${channel_name}.key
-        run_cmd apt-key add ${channel_name}.key
-        cp ${channels_dir}/${channel_name}/${channel_name}.list ${work_dir}/airootfs/etc/apt/sources.list.d
         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
+                run_cmd add-apt-repository --yes "${_ppa}"
+            done
+        fi
+    done
 }
 
 make_systemd() {
@@ -195,18 +298,35 @@ make_systemd() {
     run_cmd ln -fs /etc/machine-id /var/lib/dbus/machine-id
 }
 
-make_packages() {
-    remove "${work_dir}/airootfs/installpkglist"
+make_apt_packages() {
+    remove "${work_dir}/airootfs/aptpkglist"
 
     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/aptpkglist"))" ]]; then
+        run_cmd env -i bash -c 'DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends --yes install $(echo $(<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 $(<installpkglist))'
+    remove "${work_dir}/airootfs/aptpkglist"
+}
+
+make_snap_packages() {
+    remove "${work_dir}/airootfs/snappkglist"
+
+    if [[ -f "${channels_dir}/share/snap-packages.${arch}" ]]; then
+        grep -h -v ^'#' "${channels_dir}/share/snap-packages.${arch}" | grep -v "^$" >> "${work_dir}/airootfs/snappkglist"
+    fi
+    if [[ -f "${channels_dir}/${channel_name}/snap-packages.${arch}" ]]; then
+        grep -h -v ^'#' "${channels_dir}/${channel_name}/snap-packages.${arch}" | grep -v "^$" >> "${work_dir}/airootfs/snappkglist"
     fi
+    if [[ -n "$(echo $(<"${work_dir}/airootfs/snappkglist"))" ]]; then
+        _apt_install snapd
+        run_cmd env -i bash -c 'snap install $(echo $(<snappkglist))'
+    fi
+    remove "${work_dir}/airootfs/snappkglist"
 }
 
 make_config() {
@@ -257,8 +377,9 @@ make_clean() {
 }
 
 make_bootfiles() {
-    run_cmd update-initramfs -c -k all
+    run_cmd env -i bash -c 'update-initramfs -c -k all'
     _apt_install memtest86+
+    [[ -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
@@ -321,6 +442,7 @@ make_isolinux() {
         --modules="linux16 linux normal iso9660 biosdisk search" \
         --locales="" \
         --fonts="" \
+        --themes="" \
         "boot/grub/grub.cfg=isolinux/grub.cfg"
     cat /usr/lib/grub/i386-pc/cdboot.img isolinux/core.img > isolinux/bios.img
 }
@@ -371,7 +493,7 @@ make_checksum() {
 # 参考記事:https://0e0.pw/ci83 https://0e0.pw/VJlg
 
 _opt_short="w:o:ha:-:m:c:d"
-_opt_long="help,arch:,codename:,debug,help,mirror:,out:,work"
+_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
@@ -418,8 +540,6 @@ while :; do
             if [[ -z ${2} ]]; then
                 _msg_error "Please specify the out dir."
                 exit 1
-            else
-                out_dir="${2}"
             fi
             shift 2
             ;;
@@ -432,6 +552,10 @@ while :; do
             fi
             shift 2
             ;;
+        --cache-only)
+            cache_only=true
+            shift 1
+            ;;
         --)
             shift
             break
@@ -443,15 +567,44 @@ while :; do
     esac
 done
 
-cache_dir="${work_dir}/cache"
 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_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_snap_packages
 run_once make_config
 run_once make_customize_airootfs
 run_once make_clean