Bump to next branch

Host: Ubuntu 21.04
This commit is contained in:
orangepi-xunlong
2022-03-07 16:26:01 +08:00
parent 812e231da2
commit 206214916c
615 changed files with 61837 additions and 2426 deletions

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) Authors: http://www.armbian.com/authors
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
@@ -8,9 +8,11 @@
# Functions:
# unset_all
# pack_upload
# build_main
# array_contains
# check_hash
# build_all

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
@@ -8,12 +8,16 @@
# Functions:
# create_chroot
# chroot_prepare_distccd
# chroot_build_packages
# chroot_installpackages_local
# chroot_installpackages
# create_chroot <target_dir> <release> <arch>
#
create_chroot()
@@ -27,34 +31,60 @@ create_chroot()
apt_mirror['stretch']="$DEBIAN_MIRROR"
apt_mirror['buster']="$DEBIAN_MIRROR"
apt_mirror['bullseye']="$DEBIAN_MIRROR"
apt_mirror['bookworm']="$DEBIAN_MIRROR"
apt_mirror['xenial']="$UBUNTU_MIRROR"
apt_mirror['bionic']="$UBUNTU_MIRROR"
apt_mirror['focal']="$UBUNTU_MIRROR"
apt_mirror['eoan']="$UBUNTU_MIRROR"
apt_mirror['hirsute']="$UBUNTU_MIRROR"
apt_mirror['impish']="$UBUNTU_MIRROR"
components['stretch']='main,contrib'
apt_mirror['jammy']="$UBUNTU_MIRROR"
components['buster']='main,contrib'
components['bullseye']='main,contrib'
components['bookworm']='main,contrib'
components['sid']='main,contrib'
components['xenial']='main,universe,multiverse'
components['bionic']='main,universe,multiverse'
components['focal']='main,universe,multiverse'
components['eoan']='main,universe,multiverse'
components['hirsute']='main,universe,multiverse'
components['impish']='main,universe,multiverse'
components['jammy']='main,universe,multiverse'
display_alert "Creating build chroot" "$release/$arch" "info"
local includes="ccache,locales,git,ca-certificates,devscripts,libfile-fcntllock-perl,debhelper,rsync,python3,distcc"
local includes="ccache,locales,git,ca-certificates,devscripts,libfile-fcntllock-perl,debhelper,rsync,python3,distcc,apt-utils"
# perhaps a temporally workaround
[[ $release == buster || $release == bullseye || $release == focal || $release == eoan ]] && includes=${includes}",perl-openssl-defaults,libnet-ssleay-perl"
case $release in
buster|bullseye|focal|hirsute|sid|bookworm)
includes=${includes}",perl-openssl-defaults,libnet-ssleay-perl"
;;
esac
if [[ $NO_APT_CACHER != yes ]]; then
local mirror_addr="http://localhost:3142/${apt_mirror[${release}]}"
else
local mirror_addr="http://${apt_mirror[${release}]}"
fi
debootstrap --variant=buildd --components="${components[${release}]}" --arch="${arch}" --foreign --include="${includes}" "${release}" "${target_dir}" "${mirror_addr}"
[[ $? -ne 0 || ! -f "${target_dir}"/debootstrap/debootstrap ]] && exit_with_error "Create chroot first stage failed"
mkdir -p "${target_dir}"
cd "${target_dir}"
debootstrap --variant=buildd \
--components="${components[${release}]}" \
--arch="${arch}" $DEBOOTSTRAP_OPTION \
--foreign \
--include="${includes}" "${release}" "${target_dir}" "${mirror_addr}"
[[ $? -ne 0 || ! -f "${target_dir}"/debootstrap/debootstrap ]] && \
exit_with_error "Create chroot first stage failed"
cp /usr/bin/${qemu_binary[$arch]} "${target_dir}"/usr/bin/
[[ ! -f "${target_dir}"/usr/share/keyrings/debian-archive-keyring.gpg ]] && \
mkdir -p "${target_dir}"/usr/share/keyrings/ && \
cp /usr/share/keyrings/debian-archive-keyring.gpg "${target_dir}"/usr/share/keyrings/
chroot "${target_dir}" /bin/bash -c "/debootstrap/debootstrap --second-stage"
[[ $? -ne 0 || ! -f "${target_dir}"/bin/bash ]] && exit_with_error "Create chroot second stage failed"
create_sources_list "$release" "${target_dir}"
[[ $NO_APT_CACHER != yes ]] && \
echo 'Acquire::http { Proxy "http://localhost:3142"; };' > "${target_dir}"/etc/apt/apt.conf.d/02proxy
@@ -62,8 +92,10 @@ create_chroot()
APT::Install-Recommends "0";
APT::Install-Suggests "0";
EOF
[[ -f "${target_dir}"/etc/locale.gen ]] && sed -i "s/^# en_US.UTF-8/en_US.UTF-8/" "${target_dir}"/etc/locale.gen
[[ -f "${target_dir}"/etc/locale.gen ]] && \
sed -i "s/^# en_US.UTF-8/en_US.UTF-8/" "${target_dir}"/etc/locale.gen
chroot "${target_dir}" /bin/bash -c "locale-gen; update-locale LANG=en_US:en LC_ALL=en_US.UTF-8"
printf '#!/bin/sh\nexit 101' > "${target_dir}"/usr/sbin/policy-rc.d
chmod 755 "${target_dir}"/usr/sbin/policy-rc.d
rm "${target_dir}"/etc/resolv.conf 2>/dev/null
@@ -76,7 +108,17 @@ create_chroot()
mkdir -p "${target_dir}"/var/lock
fi
chroot "${target_dir}" /bin/bash -c "/usr/sbin/update-ccache-symlinks"
[[ $release == focal ]] && chroot "${target_dir}" /bin/bash -c "ln -s /usr/bin/python3 /usr/bin/python"
display_alert "Upgrading packages in" "${target_dir}" "info"
chroot "${target_dir}" /bin/bash -c "apt-get -q update; apt-get -q -y upgrade; apt-get clean"
date +%s >"$target_dir/root/.update-timestamp"
case $release in
bullseye|focal|hirsute|sid|bookworm)
chroot "${target_dir}" /bin/bash -c "apt-get install python-is-python3"
;;
esac
touch "${target_dir}"/root/.debootstrap-complete
display_alert "Debootstrap complete" "${release}/${arch}" "info"
} #############################################################################
@@ -93,16 +135,19 @@ chroot_prepare_distccd()
gcc_version['stretch']='6.3'
gcc_version['buster']='8.3'
gcc_version['bullseye']='9.2'
gcc_version['bookworm']='10.2'
gcc_version['xenial']='5.4'
gcc_version['bionic']='5.4'
gcc_version['focal']='9.2'
gcc_version['eoan']='9.2'
gcc_version['jammy']='10.2'
gcc_version['hirsute']='10.2'
gcc_version['sid']='10.2'
gcc_type['armhf']='arm-linux-gnueabihf-'
gcc_type['arm64']='aarch64-linux-gnu-'
rm -f "${dest}"/cmdlist
mkdir -p "${dest}"
#local toolchain_path=$(find_toolchain "${gcc_type[$arch]}" "== ${gcc_version[$release]}")
local toolchain_path
#local toolchain_path=$(find_toolchain "${gcc_type[${arch}]}" "== ${gcc_version[${release}]}")
toolchain_path=${toolchain}
ln -sf "${toolchain_path}/${gcc_type[${arch}]}gcc" "${dest}"/cc
echo "${dest}/cc" >> "${dest}"/cmdlist
@@ -131,7 +176,7 @@ chroot_build_packages()
target_arch="${ARCH}"
else
# only make packages for recent releases. There are no changes on older
target_release="stretch bionic buster bullseye eoan focal"
target_release="stretch bionic buster bullseye bookworm focal hirsute jammy sid"
target_arch="armhf arm64"
fi
@@ -140,7 +185,7 @@ chroot_build_packages()
display_alert "Starting package building process" "$release/$arch" "info"
local target_dir
target_dir="${DEST}/buildpkg/${release}-${arch}-v${CHROOT_CACHE_VERSION}"
target_dir="${EXTER}/cache/buildpkg/${release}-${arch}-v${CHROOT_CACHE_VERSION}"
local distcc_bindaddr="127.0.0.2"
[[ ! -f "${target_dir}"/root/.debootstrap-complete ]] && create_chroot "${target_dir}" "${release}" "${arch}"
@@ -169,7 +214,7 @@ chroot_build_packages()
# check build condition
if [[ $(type -t package_checkbuild) == function ]] && ! package_checkbuild; then
display_alert "Skipping building $package_name for" "$release/$arch" >/dev/null 2>&1
display_alert "Skipping building $package_name for" "$release/$arch"
continue
fi
@@ -189,7 +234,7 @@ chroot_build_packages()
needs_building=yes
fi
if [[ $needs_building == no ]]; then
display_alert "Packages are up to date" "$package_name $release/$arch" "info" >/dev/null 2>&1
display_alert "Packages are up to date" "$package_name $release/$arch" "info"
continue
fi
display_alert "Building packages" "$package_name $release/$arch" "ext"
@@ -197,72 +242,18 @@ chroot_build_packages()
[[ -v $dist_builddeps_name ]] && package_builddeps="${package_builddeps} ${!dist_builddeps_name}"
# create build script
cat <<-EOF > "${target_dir}"/root/build.sh
#!/bin/bash
export PATH="/usr/lib/ccache:\$PATH"
export HOME="/root"
export DEBIAN_FRONTEND="noninteractive"
export DEB_BUILD_OPTIONS="nocheck noautodbgsym"
export CCACHE_TEMPDIR="/tmp"
# distcc is disabled to prevent compilation issues due to different host and cross toolchain configurations
#export CCACHE_PREFIX="distcc"
# uncomment for debug
#export CCACHE_RECACHE="true"
#export CCACHE_DISABLE="true"
export DISTCC_HOSTS="$distcc_bindaddr"
export DEBFULLNAME="$MAINTAINER"
export DEBEMAIL="$MAINTAINERMAIL"
$(declare -f display_alert)
cd /root/build
if [[ -n "${package_builddeps}" ]]; then
# can be replaced with mk-build-deps
deps=()
installed=\$(dpkg-query -W -f '\${db:Status-Abbrev}|\${binary:Package}\n' '*' 2>/dev/null | grep '^ii' | awk -F '|' '{print \$2}' | cut -d ':' -f 1)
for packet in $package_builddeps; do grep -q -x -e "\$packet" <<< "\$installed" || deps+=("\$packet"); done
if [[ \${#deps[@]} -gt 0 ]]; then
display_alert "Installing build dependencies"
apt-get -y -q update
apt-get -y -q --no-install-recommends --show-progress -o DPKG::Progress-Fancy=1 install "\${deps[@]}"
fi
fi
display_alert "Copying sources"
rsync -aq /root/sources/"${package_name}" /root/build/
cd /root/build/"${package_name}"
# copy overlay / "debianization" files
[[ -d "/root/overlay/${package_name}/" ]] && rsync -aq /root/overlay/"${package_name}" /root/build/
# set upstream version
[[ -n "${package_upstream_version}" ]] && debchange --preserve --newversion "${package_upstream_version}" "Import from upstream"
# set local version
# debchange -l~orangepi${REVISION}-${builddate}+ "New Orange Pi release"
debchange -l~orangepi${REVISION}+ "New Orange Pi release"
display_alert "Building package"
dpkg-buildpackage -b -uc -us -j2
if [[ \$? -eq 0 ]]; then
cd /root/build
# install in chroot if other libraries depend on them
if [[ -n "$package_install_chroot" ]]; then
display_alert "Installing packages"
for p in $package_install_chroot; do
dpkg -i \${p}_*.deb
done
fi
display_alert "Done building" "$package_name $release/$arch" "ext"
ls *.deb 2>/dev/null
mv *.deb /root 2>/dev/null
exit 0
else
display_alert "Failed building" "$package_name $release/$arch" "err"
exit 2
fi
EOF
chmod +x "${target_dir}"/root/build.sh
create_build_script
fetch_from_repo "$package_repo" "${EXTER}/cache/sources/extra/$package_name" "$package_ref"
eval systemd-nspawn -a -q --capability=CAP_MKNOD -D $target_dir --tmpfs=/root/build --tmpfs=/tmp:mode=777 --bind-ro $EXTER/packages/extras-buildpkgs/:/root/overlay \
--bind-ro $EXTER/cache/sources/extra/:/root/sources /bin/bash -c "/root/build.sh" 2>&1 \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/buildpkg.log'}
eval systemd-nspawn -a -q \
--capability=CAP_MKNOD -D "${target_dir}" \
--tmpfs=/root/build \
--tmpfs=/tmp:mode=777 \
--bind-ro "${EXTER}"/packages/extras-buildpkgs/:/root/overlay \
--bind-ro "${EXTER}"/cache/sources/extra/:/root/sources /bin/bash -c "/root/build.sh" 2>&1 \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/buildpkg.log'}
if [[ ${PIPESTATUS[0]} -eq 2 ]]; then
failed+=("$package_name:$release/$arch")
else
@@ -288,6 +279,92 @@ chroot_build_packages()
fi
} #############################################################################
# create build script
create_build_script ()
{
cat <<-EOF > "${target_dir}"/root/build.sh
#!/bin/bash
export PATH="/usr/lib/ccache:\$PATH"
export HOME="/root"
export DEBIAN_FRONTEND="noninteractive"
export DEB_BUILD_OPTIONS="nocheck noautodbgsym"
export CCACHE_TEMPDIR="/tmp"
# distcc is disabled to prevent compilation issues due
# to different host and cross toolchain configurations
#export CCACHE_PREFIX="distcc"
# uncomment for debug
#export CCACHE_RECACHE="true"
#export CCACHE_DISABLE="true"
export DISTCC_HOSTS="$distcc_bindaddr"
export DEBFULLNAME="$MAINTAINER"
export DEBEMAIL="$MAINTAINERMAIL"
$(declare -f display_alert)
cd /root/build
if [[ -n "${package_builddeps}" ]]; then
# can be replaced with mk-build-deps
deps=()
installed=\$(
dpkg-query -W -f '\${db:Status-Abbrev}|\${binary:Package}\n' '*' 2>/dev/null | \
grep '^ii' | \
awk -F '|' '{print \$2}' | \
cut -d ':' -f 1
)
for packet in $package_builddeps
do
grep -q -x -e "\$packet" <<< "\$installed" || deps+=("\$packet")
done
if [[ \${#deps[@]} -gt 0 ]]; then
display_alert "Installing build dependencies"
apt-get -y -q update
apt-get -y -q \
--no-install-recommends \
--show-progress \
-o DPKG::Progress-Fancy=1 install "\${deps[@]}"
fi
fi
display_alert "Copying sources"
rsync -aq /root/sources/"${package_name}" /root/build/
cd /root/build/"${package_name}"
# copy overlay / "debianization" files
[[ -d "/root/overlay/${package_name}/" ]] && rsync -aq /root/overlay/"${package_name}" /root/build/
# set upstream version
[[ -n "${package_upstream_version}" ]] && debchange --preserve --newversion "${package_upstream_version}" "Import from upstream"
# set local version
# debchange -l~orangepi${REVISION}-${builddate}+ "Custom $VENDOR release"
debchange -l~orangepi"${REVISION}"+ "Custom $VENDOR release"
display_alert "Building package"
dpkg-buildpackage -b -us -j2
if [[ \$? -eq 0 ]]; then
cd /root/build
# install in chroot if other libraries depend on them
if [[ -n "$package_install_chroot" ]]; then
display_alert "Installing packages"
for p in $package_install_chroot; do
dpkg -i \${p}_*.deb
done
fi
display_alert "Done building" "$package_name $release/$arch" "ext"
ls *.deb 2>/dev/null
mv *.deb /root 2>/dev/null
exit 0
else
display_alert "Failed building" "$package_name $release/$arch" "err"
exit 2
fi
EOF
chmod +x "${target_dir}"/root/build.sh
}
# chroot_installpackages_local
#
chroot_installpackages_local()
@@ -295,42 +372,34 @@ chroot_installpackages_local()
local conf=$EXTER/config/aptly-temp.conf
rm -rf /tmp/aptly-temp/
mkdir -p /tmp/aptly-temp/
echo -e "\n\t== Starting chroot_installpackages_local process ==\n" >>$DEST/debug/install.log
aptly -config=$conf repo create temp >> "${DEST}"/debug/install.log 2>&1
aptly -config="${conf}" repo create temp >> "${DEST}"/${LOG_SUBPATH}/install.log
# NOTE: this works recursively
if [[ $EXTERNAL_NEW == prebuilt ]]; then
aptly -config=$conf repo add temp ${DEB_ORANGEPI}/extra/${RELEASE}-desktop/ >> "${DEST}"/debug/install.log 2>&1
aptly -config=$conf repo add temp ${DEB_ORANGEPI}/extra/${RELEASE}-utils/ >> "${DEST}"/debug/install.log 2>&1
aptly -config="${conf}" repo add temp "${DEB_ORANGEPI}/extra/${RELEASE}-desktop/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
aptly -config="${conf}" repo add temp "${DEB_ORANGEPI}/extra/${RELEASE}-utils/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
else
aptly -config=$conf repo add temp ${DEB_STORAGE}/extra/${RELEASE}-desktop/ >> "${DEST}"/debug/install.log 2>&1
aptly -config=$conf repo add temp ${DEB_STORAGE}/extra/${RELEASE}-utils/ >> "${DEST}"/debug/install.log 2>&1
aptly -config="${conf}" repo add temp "${DEB_STORAGE}/extra/${RELEASE}-desktop/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
aptly -config="${conf}" repo add temp "${DEB_STORAGE}/extra/${RELEASE}-utils/" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
fi
# -gpg-key="925644A6"
aptly -keyring="$EXTER/packages/extras-buildpkgs/buildpkg-public.gpg" -secret-keyring="$EXTER/packages/extras-buildpkgs/buildpkg.gpg" -batch=true -config=$conf \
-gpg-key="925644A6" -passphrase="testkey1234" -component=temp -distribution=$RELEASE publish repo temp >> "${DEST}"/debug/install.log 2>&1
aptly -config=$conf -listen=":8189" serve >> "${DEST}"/debug/install.log 2>&1 &
[[ ! -d /root/.gnupg ]] && mkdir -p /root/.gnupg
aptly -keyring="$EXTER/packages/extras-buildpkgs/buildpkg-public.gpg" -secret-keyring="$EXTER/packages/extras-buildpkgs/buildpkg.gpg" -batch=true -config="${conf}" \
-gpg-key="925644A6" -passphrase="testkey1234" -component=temp -distribution="${RELEASE}" publish repo temp >> "${DEST}"/${LOG_SUBPATH}/install.log
#aptly -config="${conf}" -listen=":8189" serve &
aptly -config="${conf}" -listen=":8189" serve >> "${DEST}"/debug/install.log 2>&1 &
local aptly_pid=$!
cp $EXTER/packages/extras-buildpkgs/buildpkg.key $SDCARD/tmp/buildpkg.key
cat <<-'EOF' > $SDCARD/etc/apt/preferences.d/90-orangepi-temp.pref
cp $EXTER/packages/extras-buildpkgs/buildpkg.key "${SDCARD}"/tmp/buildpkg.key
cat <<-'EOF' > "${SDCARD}"/etc/apt/preferences.d/90-orangepi-temp.pref
Package: *
Pin: origin "localhost"
Pin-Priority: 550
EOF
cat <<-EOF > "${SDCARD}"/etc/apt/sources.list.d/orangepi-temp.list
deb http://localhost:8189/ $RELEASE temp
EOF
chroot_installpackages
echo -e "\n\t== Finished chroot_installpackages_local process ==\n" >>$DEST/debug/install.log
kill "${aptly_pid}"
kill "${aptly_pid}" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
} #############################################################################
# chroot_installpackages
@@ -338,37 +407,32 @@ chroot_installpackages_local()
chroot_installpackages()
{
local install_list=""
for plugin in "${EXTER}"/packages/extras-buildpkgs/*.conf; do
source "$plugin"
source "${plugin}"
if [[ $(type -t package_checkinstall) == function ]] && package_checkinstall; then
install_list="$install_list $package_install_target"
fi
unset package_install_target package_checkinstall
done
if [[ -n $PACKAGE_LIST_RM ]]; then
install_list=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${install_list} ")
install_list="$(echo ${install_list})"
fi
display_alert "Installing extras-buildpkgs" "$install_list"
[[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
display_alert "Installing additional packages" "${install_list}"
cat <<-EOF > "${SDCARD}"/tmp/install.sh
#!/bin/bash
apt-key add /tmp/buildpkg.key
apt-get $apt_extra -q update
apt-get -q $apt_extra --show-progress -o DPKG::Progress-Fancy=1 install -y $install_list
apt-get -q ${apt_extra} --show-progress -o DPKG::Progress-Fancy=1 install -y ${install_list}
apt-get clean
apt-key del "925644A6"
rm /etc/apt/sources.list.d/orangepi-temp.list
rm /etc/apt/preferences.d/90-orangepi-temp.pref
rm /tmp/buildpkg.key
rm /etc/apt/sources.list.d/orangepi-temp.list 2>/dev/null
rm /etc/apt/preferences.d/90-orangepi-temp.pref 2>/dev/null
rm /tmp/buildpkg.key 2>/dev/null
rm -- "\$0"
EOF
chmod +x "${SDCARD}"/tmp/install.sh
chroot "${SDCARD}" /bin/bash -c "/tmp/install.sh" >> "${DEST}"/debug/install.log 2>&1
chroot "${SDCARD}" /bin/bash -c "/tmp/install.sh" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
} #############################################################################

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
@@ -8,6 +8,7 @@
# Functions:
# compile_atf
# compile_uboot
# compile_kernel
@@ -22,6 +23,9 @@
# userpatch_create
# overlayfs_wrapper
compile_atf()
{
if [[ $CLEAN_LEVEL == *make* ]]; then
@@ -39,6 +43,9 @@ compile_atf()
display_alert "Compiling ATF" "" "info"
# build aarch64
if [[ $(dpkg --print-architecture) == amd64 ]]; then
local toolchain
toolchain=$(find_toolchain "$ATF_COMPILER" "$ATF_USE_GCC")
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${ATF_COMPILER}gcc $ATF_USE_GCC"
@@ -51,6 +58,9 @@ compile_atf()
[[ -z $toolchain2 ]] && exit_with_error "Could not find required toolchain" "${toolchain2_type}gcc $toolchain2_ver"
fi
# build aarch64
fi
display_alert "Compiler version" "${ATF_COMPILER}gcc $(eval env PATH="${toolchain}:${PATH}" "${ATF_COMPILER}gcc" -dumpversion)" "info"
local target_make target_patchdir target_files
@@ -63,13 +73,13 @@ compile_atf()
# create patch for manual source changes
[[ $CREATE_PATCHES == yes ]] && userpatch_create "atf"
echo -e "\n\t== atf ==\n" >> "${DEST}"/debug/compilation.log
echo -e "\n\t== atf ==\n" >> "${DEST}"/${LOG_SUBPATH}/compilation.log
# ENABLE_BACKTRACE="0" has been added to workaround a regression in ATF.
# Check: https://github.com/armbian/build/issues/1157
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${toolchain2}:${PATH}" \
'make ENABLE_BACKTRACE="0" $target_make $CTHREADS \
CROSS_COMPILE="$CCACHE $ATF_COMPILER"' 2>> "${DEST}"/debug/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
CROSS_COMPILE="$CCACHE $ATF_COMPILER"' 2>> "${DEST}"/${LOG_SUBPATH}/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Compiling ATF..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
@@ -77,8 +87,9 @@ compile_atf()
[[ $(type -t atf_custom_postprocess) == function ]] && atf_custom_postprocess
local atftempdir=$SRC/.tmp/atf-${LINUXFAMILY}-${BOARD}-${BRANCH}
mkdir -p "${atftempdir}"
atftempdir=$(mktemp -d)
chmod 700 ${atftempdir}
trap "rm -rf \"${atftempdir}\" ; exit 0" 0 1 2 3 15
# copy files to temp directory
for f in $target_files; do
@@ -121,10 +132,13 @@ compile_uboot()
# read uboot version
local version hash
version=$(grab_version "$ubootdir")
hash=$(git --git-dir="$ubootdir"/.git rev-parse HEAD)
hash=$(improved_git --git-dir="$ubootdir"/.git rev-parse HEAD)
display_alert "Compiling u-boot" "v$version" "info"
# build aarch64
if [[ $(dpkg --print-architecture) == amd64 ]]; then
local toolchain
toolchain=$(find_toolchain "$UBOOT_COMPILER" "$UBOOT_USE_GCC")
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${UBOOT_COMPILER}gcc $UBOOT_USE_GCC"
@@ -137,13 +151,19 @@ compile_uboot()
[[ -z $toolchain2 ]] && exit_with_error "Could not find required toolchain" "${toolchain2_type}gcc $toolchain2_ver"
fi
# build aarch64
fi
display_alert "Compiler version" "${UBOOT_COMPILER}gcc $(eval env PATH="${toolchain}:${toolchain2}:${PATH}" "${UBOOT_COMPILER}gcc" -dumpversion)" "info"
[[ -n $toolchain2 ]] && display_alert "Additional compiler version" "${toolchain2_type}gcc $(eval env PATH="${toolchain}:${toolchain2}:${PATH}" "${toolchain2_type}gcc" -dumpversion)" "info"
# create directory structure for the .deb package
uboottempdir=$(mktemp -d)
chmod 700 ${uboottempdir}
trap "rm -rf \"${uboottempdir}\" ; exit 0" 0 1 2 3 15
local uboot_name=${CHOSEN_UBOOT}_${REVISION}_${ARCH}
rm -rf $SRC/.tmp/{$uboot_name,packout}
mkdir -p $SRC/.tmp/$uboot_name/usr/lib/{u-boot,$uboot_name} $SRC/.tmp/$uboot_name/DEBIAN $SRC/.tmp/packout
rm -rf $uboottempdir/$uboot_name
mkdir -p $uboottempdir/$uboot_name/usr/lib/{u-boot,$uboot_name} $uboottempdir/$uboot_name/DEBIAN
# process compilation for one or multiple targets
while read -r target; do
@@ -152,9 +172,13 @@ compile_uboot()
target_patchdir=$(cut -d';' -f2 <<< "${target}")
target_files=$(cut -d';' -f3 <<< "${target}")
# needed for multiple targets and for calling compile_uboot directly
#display_alert "Checking out to clean sources"
#improved_git checkout -f -q HEAD
if [[ $CLEAN_LEVEL == *make* ]]; then
display_alert "Cleaning" "$BOOTSOURCEDIR" "info"
(cd "$BOOTSOURCEDIR"; make clean > /dev/null 2>&1)
(cd "${BOOTSOURCEDIR}"; make clean > /dev/null 2>&1)
fi
advanced_patch "u-boot" "$BOOTPATCHDIR" "$BOARD" "$target_patchdir" "$BRANCH" "${LINUXFAMILY}-${BOARD}-${BRANCH}"
@@ -163,15 +187,15 @@ compile_uboot()
[[ $CREATE_PATCHES == yes ]] && userpatch_create "u-boot"
if [[ -n $ATFSOURCE ]]; then
local atftempdir=$SRC/.tmp/atf-${LINUXFAMILY}-${BOARD}-${BRANCH}
cp -Rv "${atftempdir}"/*.bin .
rm -rf "${atftempdir}"
fi
echo -e "\n\t== u-boot ==\n" >> "${DEST}"/debug/compilation.log
echo -e "\n\t== u-boot make $BOOTCONFIG ==\n" >> "${DEST}"/${LOG_SUBPATH}/compilation.log
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${toolchain2}:${PATH}" \
'make $CTHREADS $BOOTCONFIG \
CROSS_COMPILE="$CCACHE $UBOOT_COMPILER"' 2>> "${DEST}"/debug/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
CROSS_COMPILE="$CCACHE $UBOOT_COMPILER"' 2>> "${DEST}"/${LOG_SUBPATH}/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/compilation.log'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
if [[ "${version}" != 2014.07 ]]; then
@@ -207,14 +231,15 @@ compile_uboot()
cross_compile="CROSS_COMPILE=$CCACHE $UBOOT_COMPILER";
[[ -n $UBOOT_TOOLCHAIN2 ]] && cross_compile="ORANGEPI=foe"; # empty parameter is not allowed
echo -e "\n\t== u-boot make $target_make ==\n" >> "${DEST}"/${LOG_SUBPATH}/compilation.log
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${toolchain2}:${PATH}" \
'make $target_make $CTHREADS \
"${cross_compile}"' 2>>"${DEST}"/debug/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a "${DEST}"/debug/compilation.log'} \
"${cross_compile}"' 2>>"${DEST}"/${LOG_SUBPATH}/compilation.log \
${PROGRESS_LOG_TO_FILE:+' | tee -a "${DEST}"/${LOG_SUBPATH}/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Compiling u-boot..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "U-boot compilation failed"
[[ ${EVALPIPE[0]} -ne 0 ]] && exit_with_error "U-boot compilation failed"
[[ $(type -t uboot_custom_postprocess) == function ]] && uboot_custom_postprocess
@@ -231,9 +256,9 @@ compile_uboot()
fi
[[ ! -f $f_src ]] && exit_with_error "U-boot file not found" "$(basename "${f_src}")"
if [[ "${version}" =~ 2014.07|2011.09 ]]; then
cp "${f_src}" "${SRC}/.tmp/packout/${f_dst}"
cp "${f_src}" "$uboottempdir/packout/${f_dst}"
else
cp "${f_src}" "${SRC}/.tmp/${uboot_name}/usr/lib/${uboot_name}/${f_dst}"
cp "${f_src}" "$uboottempdir/${uboot_name}/usr/lib/${uboot_name}/${f_dst}"
fi
done
done <<< "$UBOOT_TARGET_MAP"
@@ -247,14 +272,14 @@ compile_uboot()
fi
else
pack_uboot
cp ${SRC}/.tmp/packout/{boot0_sdcard.fex,boot_package.fex} "${SRC}/.tmp/${uboot_name}/usr/lib/${uboot_name}/"
cp ${SRC}/.tmp/packout/dts/${BOARD}-u-boot.dts "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/"
cp $uboottempdir/packout/{boot0_sdcard.fex,boot_package.fex} "${SRC}/.tmp/${uboot_name}/usr/lib/${uboot_name}/"
cp $uboottempdir/packout/dts/${BOARD}-u-boot.dts "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/"
fi
cd "${ubootdir}" || exit
fi
# declare -f on non-defined function does not do anything
cat <<-EOF > "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/platform_install.sh"
cat <<-EOF > "$uboottempdir/${uboot_name}/usr/lib/u-boot/platform_install.sh"
DIR=/usr/lib/$uboot_name
$(declare -f write_uboot_platform)
$(declare -f write_uboot_platform_mtd)
@@ -262,7 +287,7 @@ compile_uboot()
EOF
# set up control file
cat <<-EOF > "${SRC}/.tmp/${uboot_name}/DEBIAN/control"
cat <<-EOF > "$uboottempdir/${uboot_name}/DEBIAN/control"
Package: linux-u-boot-${BOARD}-${BRANCH}
Version: $REVISION
Architecture: $ARCH
@@ -278,20 +303,62 @@ compile_uboot()
# copy config file to the package
# useful for FEL boot with overlayfs_wrapper
[[ -f .config && -n $BOOTCONFIG ]] && cp .config "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/${BOOTCONFIG}"
[[ -f .config && -n $BOOTCONFIG ]] && cp .config "$uboottempdir/${uboot_name}/usr/lib/u-boot/${BOOTCONFIG}"
# copy license files from typical locations
[[ -f COPYING ]] && cp COPYING "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/LICENSE"
[[ -f Licenses/README ]] && cp Licenses/README "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/LICENSE"
[[ -n $atftempdir && -f $atftempdir/license.md ]] && cp "${atftempdir}/license.md" "${SRC}/.tmp/${uboot_name}/usr/lib/u-boot/LICENSE.atf"
[[ -f COPYING ]] && cp COPYING "$uboottempdir/${uboot_name}/usr/lib/u-boot/LICENSE"
[[ -f Licenses/README ]] && cp Licenses/README "$uboottempdir/${uboot_name}/usr/lib/u-boot/LICENSE"
[[ -n $atftempdir && -f $atftempdir/license.md ]] && cp "${atftempdir}/license.md" "$uboottempdir/${uboot_name}/usr/lib/u-boot/LICENSE.atf"
display_alert "Building deb" "${uboot_name}.deb" "info"
fakeroot dpkg-deb -b "${SRC}/.tmp/${uboot_name}" "${SRC}/.tmp/${uboot_name}.deb" >> "${DEST}"/debug/output.log 2>&1
rm -rf "${SRC}/.tmp/${uboot_name}"
fakeroot dpkg-deb -b "$uboottempdir/${uboot_name}" "$uboottempdir/${uboot_name}.deb" >> "${DEST}"/${LOG_SUBPATH}/output.log 2>&1
rm -rf "$uboottempdir/${uboot_name}"
[[ -n $atftempdir ]] && rm -rf "${atftempdir}"
[[ ! -f $SRC/.tmp/${uboot_name}.deb ]] && exit_with_error "Building u-boot package failed"
[[ ! -f $uboottempdir/${uboot_name}.deb ]] && exit_with_error "Building u-boot package failed"
mv "${SRC}/.tmp/${uboot_name}.deb" "${DEB_STORAGE}/u-boot/"
rsync --remove-source-files -rq "$uboottempdir/${uboot_name}.deb" "${DEB_STORAGE}/u-boot/"
rm -rf "$uboottempdir"
}
create_linux-source_package ()
{
ts=$(date +%s)
local sources_pkg_dir tmp_src_dir
tmp_src_dir=$(mktemp -d)
trap "rm -rf \"${tmp_src_dir}\" ; exit 0" 0 1 2 3 15
sources_pkg_dir=${tmp_src_dir}/${CHOSEN_KSRC}_${REVISION}_all
mkdir -p "${sources_pkg_dir}"/usr/src/ \
"${sources_pkg_dir}"/usr/share/doc/linux-source-${version}-${LINUXFAMILY} \
"${sources_pkg_dir}"/DEBIAN
cp "${EXTER}/config/kernel/${LINUXCONFIG}.config" "default_${LINUXCONFIG}.config"
xz < .config > "${sources_pkg_dir}/usr/src/${LINUXCONFIG}_${version}_${REVISION}_config.xz"
display_alert "Compressing sources for the linux-source package"
tar cp --directory="$kerneldir" --exclude='.git' --owner=root . \
| pv -p -b -r -s "$(du -sb "$kerneldir" --exclude=='.git' | cut -f1)" \
| pixz -4 > "${sources_pkg_dir}/usr/src/linux-source-${version}-${LINUXFAMILY}.tar.xz"
cp COPYING "${sources_pkg_dir}/usr/share/doc/linux-source-${version}-${LINUXFAMILY}/LICENSE"
cat <<-EOF > "${sources_pkg_dir}"/DEBIAN/control
Package: linux-source-${version}-${BRANCH}-${LINUXFAMILY}
Version: ${version}-${BRANCH}-${LINUXFAMILY}+${REVISION}
Architecture: all
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Section: kernel
Priority: optional
Depends: binutils, coreutils
Provides: linux-source, linux-source-${version}-${LINUXFAMILY}
Recommends: gcc, make
Description: This package provides the source code for the Linux kernel $version
EOF
fakeroot dpkg-deb -b -Z${DEB_COMPRESS} -z0 "${sources_pkg_dir}" "${sources_pkg_dir}.deb"
rsync --remove-source-files -rq "${sources_pkg_dir}.deb" "${DEB_STORAGE}/"
te=$(date +%s)
display_alert "Make the linux-source package" "$(($te - $ts)) sec." "info"
rm -rf "${tmp_src_dir}"
}
compile_kernel()
@@ -309,9 +376,6 @@ compile_kernel()
fi
cd "${kerneldir}" || exit
if ! grep -qoE '^-rc[[:digit:]]+' <(grep "^EXTRAVERSION" Makefile | head -1 | awk '{print $(NF)}'); then
sed -i 's/EXTRAVERSION = .*/EXTRAVERSION = /' Makefile
fi
rm -f localversion
# read kernel version
@@ -319,60 +383,69 @@ compile_kernel()
version=$(grab_version "$kerneldir")
# read kernel git hash
hash=$(git --git-dir="$kerneldir"/.git rev-parse HEAD)
hash=$(improved_git --git-dir="$kerneldir"/.git rev-parse HEAD)
# Apply a series of patches if a series file exists
if test -f "${EXTER}"/patch/kernel/${KERNELPATCHDIR}/series.conf; then
display_alert "series.conf file visible. Apply"
series_conf="${SRC}"/patch/kernel/${KERNELPATCHDIR}/series.conf
# apply_patch_series <target dir> <full path to series file>
apply_patch_series "${kerneldir}" "$series_conf"
fi
# build 3rd party drivers
# compilation_prepare
advanced_patch "kernel" "$KERNELPATCHDIR" "$BOARD" "" "$BRANCH" "$LINUXFAMILY-$BRANCH"
# create patch for manual source changes in debug mode
[[ $CREATE_PATCHES == yes ]] && userpatch_create "kernel"
# create patch for manual source changes in debug mode
[[ $CREATE_PATCHES == yes ]] && userpatch_create "kernel"
# re-read kernel version after patching
local version
version=$(grab_version "$kerneldir")
# create linux-source package - with already patched sources
local sources_pkg_dir=$SRC/.tmp/${CHOSEN_KSRC}_${REVISION}_all
rm -rf "${sources_pkg_dir}"
mkdir -p "${sources_pkg_dir}"/usr/src/ "${sources_pkg_dir}/usr/share/doc/linux-source-${version}-${LINUXFAMILY}" "${sources_pkg_dir}"/DEBIAN $SRC/.tmp/gpu_modules_${LINUXFAMILY}
if [[ $BUILD_KSRC == yes ]]; then
display_alert "Cleaning" "$LINUXSOURCEDIR" "info"
(cd $LINUXSOURCEDIR; make ARCH=$ARCHITECTURE clean >/dev/null 2>&1)
display_alert "Compressing sources for the linux-source package"
tar cp --directory="$kerneldir" --exclude='./.git/' --owner=root . \
| pv -p -b -r -s "$(du -sb "$kerneldir" --exclude=='./.git/' | cut -f1)" \
| pixz -4 > "${sources_pkg_dir}/usr/src/linux-source-${version}-${LINUXFAMILY}.tar.xz"
cp COPYING "${sources_pkg_dir}/usr/share/doc/linux-source-${version}-${LINUXFAMILY}/LICENSE"
fi
# re-read kernel version after patching
local version
version=$(grab_version "$kerneldir")
display_alert "Compiling $BRANCH kernel" "$version" "info"
local toolchain
toolchain=$(find_toolchain "$KERNEL_COMPILER" "$KERNEL_USE_GCC")
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${KERNEL_COMPILER}gcc $KERNEL_USE_GCC"
# compare with the architecture of the current Debian node
# if it matches we use the system compiler
if $(dpkg-architecture -e "${ARCH}"); then
display_alert "Native compilation"
elif [[ $(dpkg --print-architecture) == amd64 ]]; then
local toolchain
toolchain=$(find_toolchain "$KERNEL_COMPILER" "$KERNEL_USE_GCC")
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${KERNEL_COMPILER}gcc $KERNEL_USE_GCC"
else
exit_with_error "Architecture [$ARCH] is not supported"
fi
display_alert "Compiler version" "${KERNEL_COMPILER}gcc $(eval env PATH="${toolchain}:${PATH}" "${KERNEL_COMPILER}gcc" -dumpversion)" "info"
# copy kernel config
if [[ $KERNEL_KEEP_CONFIG == yes && -f "${DEST}"/config/$LINUXCONFIG.config ]]; then
display_alert "Using previous kernel config" "${DEST}/config/$LINUXCONFIG.config" "info"
cp "${DEST}/config/${LINUXCONFIG}.config" .config
cp -p "${DEST}/config/${LINUXCONFIG}.config" .config
else
if [[ -f $USERPATCHES_PATH/$LINUXCONFIG.config ]]; then
display_alert "Using kernel config provided by user" "userpatches/$LINUXCONFIG.config" "info"
cp "${USERPATCHES_PATH}/${LINUXCONFIG}.config" .config
cp -p "${USERPATCHES_PATH}/${LINUXCONFIG}.config" .config
else
display_alert "Using kernel config file" "config/kernel/$LINUXCONFIG.config" "info"
cp "${EXTER}/config/kernel/${LINUXCONFIG}.config" .config
display_alert "Using kernel config file" "${EXTER}/config/kernel/$LINUXCONFIG.config" "info"
cp -p "${EXTER}/config/kernel/${LINUXCONFIG}.config" .config
fi
fi
call_extension_method "custom_kernel_config" << 'CUSTOM_KERNEL_CONFIG'
*Kernel .config is in place, still clean from git version*
Called after ${LINUXCONFIG}.config is put in place (.config).
Before any olddefconfig any Kconfig make is called.
A good place to customize the .config directly.
CUSTOM_KERNEL_CONFIG
# hack for deb builder. To pack what's missing in headers pack.
cp $EXTER/patch/misc/headers-debian-byteshift.patch /tmp
cp "$EXTER"/patch/misc/headers-debian-byteshift.patch /tmp
if [[ $KERNEL_CONFIGURE != yes ]]; then
if [[ $BRANCH == legacy ]]; then
@@ -403,16 +476,20 @@ compile_kernel()
fi
fi
xz < .config > "${sources_pkg_dir}/usr/src/${LINUXCONFIG}_${version}_${REVISION}_config.xz"
# create linux-source package - with already patched sources
# We will build this package first and clear the memory.
if [[ $BUILD_KSRC != no ]]; then
create_linux-source_package
fi
echo -e "\n\t== kernel ==\n" >> "${DEST}"/debug/compilation.log
echo -e "\n\t== kernel ==\n" >> "${DEST}"/${LOG_SUBPATH}/compilation.log
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make $CTHREADS ARCH=$ARCHITECTURE \
CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" \
$SRC_LOADADDR \
LOCALVERSION="-$LINUXFAMILY" \
$KERNEL_IMAGE_TYPE modules dtbs 2>>$DEST/debug/compilation.log' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
$KERNEL_IMAGE_TYPE ${KERNEL_EXTRA_TARGETS:-modules dtbs} 2>>$DEST/${LOG_SUBPATH}/compilation.log' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" \
--progressbox "Compiling kernel..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
@@ -435,52 +512,61 @@ compile_kernel()
display_alert "Creating packages"
# produce deb packages: image, headers, firmware, dtb
echo -e "\n\t== deb packages: image, headers, firmware, dtb ==\n" >> "${DEST}"/debug/compilation.log
echo -e "\n\t== deb packages: image, headers, firmware, dtb ==\n" >> "${DEST}"/${LOG_SUBPATH}/compilation.log
eval CCACHE_BASEDIR="$(pwd)" env PATH="${toolchain}:${PATH}" \
'make -j1 $kernel_packing \
'make $CTHREADS $kernel_packing \
KDEB_PKGVERSION=$REVISION \
KDEB_COMPRESS=${DEB_COMPRESS} \
BRANCH=$BRANCH \
LOCALVERSION="-${LINUXFAMILY}" \
KBUILD_DEBARCH=$ARCH \
ARCH=$ARCHITECTURE \
DEBFULLNAME="$MAINTAINER" \
DEBEMAIL="$MAINTAINERMAIL" \
CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" 2>>$DEST/debug/compilation.log' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/compilation.log'} \
CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" 2>>$DEST/${LOG_SUBPATH}/compilation.log' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/compilation.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Creating kernel packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
cat <<-EOF > "${sources_pkg_dir}"/DEBIAN/control
Package: linux-source-${version}-${BRANCH}-${LINUXFAMILY}
Version: ${version}-${BRANCH}-${LINUXFAMILY}+${REVISION}
Architecture: all
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Section: kernel
Priority: optional
Depends: binutils, coreutils
Provides: linux-source, linux-source-${version}-${LINUXFAMILY}
Recommends: gcc, make
Description: This package provides the source code for the Linux kernel $version
EOF
if [[ $BUILD_KSRC == yes ]]; then
fakeroot dpkg-deb -z0 -b "${sources_pkg_dir}" "${sources_pkg_dir}.deb"
mv "${sources_pkg_dir}.deb" "${DEB_STORAGE}/"
fi
rm -rf "${sources_pkg_dir}"
cd .. || exit
# remove firmare image packages here - easier than patching ~40 packaging scripts at once
rm -f linux-firmware-image-*.deb
mv ./*.deb "${DEB_STORAGE}/" || exit_with_error "Failed moving kernel DEBs"
# store git hash to the file
echo "${hash}" > "${EXTER}/cache/hash/linux-image-${BRANCH}-${LINUXFAMILY}.githash"
[[ -z ${KERNELPATCHDIR} ]] && KERNELPATCHDIR=$LINUXFAMILY-$BRANCH
[[ -z ${LINUXCONFIG} ]] && LINUXCONFIG=linux-$LINUXFAMILY-$BRANCH
hash_watch_1=$(find "${EXTER}/patch/kernel/${KERNELPATCHDIR}" -maxdepth 1 -printf '%s %P\n' 2> /dev/null | sort)
hash_watch_2=$(cat "${EXTER}/config/kernel/${LINUXCONFIG}.config")
echo "${hash_watch_1}${hash_watch_2}" | git hash-object --stdin >> "${EXTER}/cache/hash/linux-image-${BRANCH}-${LINUXFAMILY}.githash"
rsync --remove-source-files -rq ./*.deb "${DEB_STORAGE}/" || exit_with_error "Failed moving kernel DEBs"
# store git hash to the file and create a change log
#HASHTARGET="${EXTER}/cache/hash"$([[ ${BETA} == yes ]] && echo "-beta")"/linux-image-${BRANCH}-${LINUXFAMILY}"
#OLDHASHTARGET=$(head -1 "${HASHTARGET}.githash" 2>/dev/null)
# check if OLDHASHTARGET commit exists otherwise use oldest
#if [[ -z ${KERNEL_VERSION_LEVEL} ]]; then
# git -C ${kerneldir} cat-file -t ${OLDHASHTARGET} >/dev/null 2>&1
# [[ $? -ne 0 ]] && OLDHASHTARGET=$(git -C ${kerneldir} show HEAD~199 --pretty=format:"%H" --no-patch)
# else
# git -C ${kerneldir} cat-file -t ${OLDHASHTARGET} >/dev/null 2>&1
# [[ $? -ne 0 ]] && OLDHASHTARGET=$(git -C ${kerneldir} rev-list --max-parents=0 HEAD)
#fi
#[[ -z ${KERNELPATCHDIR} ]] && KERNELPATCHDIR=$LINUXFAMILY-$BRANCH
#[[ -z ${LINUXCONFIG} ]] && LINUXCONFIG=linux-$LINUXFAMILY-$BRANCH
# calculate URL
#if [[ "$KERNELSOURCE" == *"github.com"* ]]; then
# URL="${KERNELSOURCE/git:/https:}/commit/${HASH}"
#elif [[ "$KERNELSOURCE" == *"kernel.org"* ]]; then
# URL="${KERNELSOURCE/git:/https:}/commit/?h=$(echo $KERNELBRANCH | cut -d":" -f2)&id=${HASH}"
#else
# URL="${KERNELSOURCE}/+/$HASH"
#fi
# create change log
#git --no-pager -C ${kerneldir} log --abbrev-commit --oneline --no-patch --no-merges --date-order --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:'%C(black bold)%ad%Creset%C(auto) | %s | <%an> | <a href='$URL'%H>%H</a>' ${OLDHASHTARGET}..${hash} > "${HASHTARGET}.gitlog"
#echo "${hash}" > "${HASHTARGET}.githash"
#hash_watch_1=$(LC_COLLATE=C find -L "${EXTER}/patch/kernel/${KERNELPATCHDIR}"/ -name '*.patch' -mindepth 1 -maxdepth 1 -printf '%s %P\n' 2> /dev/null | LC_COLLATE=C sort -n)
#hash_watch_2=$(cat "${EXTER}/config/kernel/${LINUXCONFIG}.config")
#echo "${hash_watch_1}${hash_watch_2}" | improved_git hash-object --stdin >> "${HASHTARGET}.githash"
}
@@ -488,39 +574,32 @@ compile_kernel()
compile_firmware()
{
display_alert "Merging and packaging linux firmware" "@host" "info"
if [[ $USE_MAINLINE_GOOGLE_MIRROR == yes ]]; then
plugin_repo="https://kernel.googlesource.com/pub/scm/linux/kernel/git/firmware/linux-firmware.git"
else
plugin_repo="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git"
[[ $DOWNLOAD_MIRROR == china ]] && plugin_repo="${GIT_SERVER}/linux-firmware.git"
fi
local plugin_dir="orangepi-firmware${FULL}"
[[ -d "${EXTER}/cache/sources/${plugin_dir}" ]] && rm -rf "${EXTER}/cache/sources/${plugin_dir}"
mkdir -p "${EXTER}/cache/sources/${plugin_dir}/lib/firmware"
display_alert "Merging and packaging linux firmware" "@host" "info"
[[ $IGNORE_UPDATES != yes ]] && fetch_from_repo "${GIT_SERVER}/firmware" "${EXTER}/cache/sources/orangepi-firmware-git" "branch:master"
local firmwaretempdir plugin_dir
if [[ -n $FULL ]]; then
[[ $IGNORE_UPDATES != yes ]] && fetch_from_repo "$plugin_repo" "${EXTER}/cache/sources/linux-firmware-git" "branch:master"
# cp : create hardlinks
#cp -alf "${EXTER}"/cache/sources/linux-firmware-git/* "${EXTER}/cache/sources/${plugin_dir}/lib/firmware/"
fi
# overlay our firmware
# cp : create hardlinks
if [[ -n $FULL ]]; then
cp -alf "${EXTER}"/cache/sources/linux-firmware-git/* "${EXTER}/cache/sources/${plugin_dir}/lib/firmware/"
else
cp -alf "${EXTER}"/cache/sources/orangepi-firmware-git/* "${EXTER}/cache/sources/${plugin_dir}/lib/firmware/"
firmwaretempdir=$(mktemp -d)
chmod 700 ${firmwaretempdir}
trap "rm -rf \"${firmwaretempdir}\" ; exit 0" 0 1 2 3 15
plugin_dir="orangepi-firmware${FULL}"
mkdir -p "${firmwaretempdir}/${plugin_dir}/lib/firmware"
[[ $IGNORE_UPDATES != yes ]] && fetch_from_repo "https://github.com/orangepi-xunlong/firmware" "${EXTER}/cache/sources/orangepi-firmware-git" "branch:master"
if [[ -n $FULL ]]; then
[[ $IGNORE_UPDATES != yes ]] && fetch_from_repo "$MAINLINE_FIRMWARE_SOURCE" "${EXTER}/cache/sources/linux-firmware-git" "branch:master"
# cp : create hardlinks
cp -af --reflink=auto "${EXTER}"/cache/sources/linux-firmware-git/* "${firmwaretempdir}/${plugin_dir}/lib/firmware/"
fi
# overlay our firmware
# cp : create hardlinks
cp -af --reflink=auto "${EXTER}"/cache/sources/orangepi-firmware-git/* "${firmwaretempdir}/${plugin_dir}/lib/firmware/"
# cleanup what's not needed for sure
rm -rf "${EXTER}/cache/sources/${plugin_dir}"/lib/firmware/{amdgpu,amd-ucode,radeon,nvidia,matrox,.git}
cd "${EXTER}/cache/sources/${plugin_dir}" || exit
# cleanup what's not needed for sure
rm -rf "${firmwaretempdir}/${plugin_dir}"/lib/firmware/{amdgpu,amd-ucode,radeon,nvidia,matrox,.git}
cd "${firmwaretempdir}/${plugin_dir}" || exit
# set up control file
mkdir -p DEBIAN
# set up control file
mkdir -p DEBIAN
cat <<-END > DEBIAN/control
Package: orangepi-firmware${FULL}
Version: $REVISION
@@ -533,12 +612,95 @@ compile_firmware()
Description: Linux firmware${FULL}
END
cd "${EXTER}"/cache/sources || exit
# pack
mv "orangepi-firmware${FULL}" "orangepi-firmware${FULL}_${REVISION}_all"
fakeroot dpkg -b "orangepi-firmware${FULL}_${REVISION}_all" >> "${DEST}"/debug/install.log 2>&1
mv "orangepi-firmware${FULL}_${REVISION}_all" "orangepi-firmware${FULL}"
mv "orangepi-firmware${FULL}_${REVISION}_all.deb" "${DEB_STORAGE}/"
cd "${firmwaretempdir}" || exit
# pack
mv "orangepi-firmware${FULL}" "orangepi-firmware${FULL}_${REVISION}_all"
display_alert "Building firmware package" "orangepi-firmware${FULL}_${REVISION}_all" "info"
fakeroot dpkg -b "orangepi-firmware${FULL}_${REVISION}_all" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
mv "orangepi-firmware${FULL}_${REVISION}_all" "orangepi-firmware${FULL}"
rsync -rq "orangepi-firmware${FULL}_${REVISION}_all.deb" "${DEB_STORAGE}/"
# remove temp directory
rm -rf "${firmwaretempdir}"
}
compile_orangepi-zsh()
{
local tmp_dir orangepi_zsh_dir
tmp_dir=$(mktemp -d)
chmod 700 ${tmp_dir}
trap "rm -rf \"${tmp_dir}\" ; exit 0" 0 1 2 3 15
orangepi_zsh_dir=orangepi-zsh_${REVISION}_all
display_alert "Building deb" "orangepi-zsh" "info"
[[ $IGNORE_UPDATES != yes ]] && fetch_from_repo "https://github.com/robbyrussell/oh-my-zsh" "${EXTER}/cache/sources/oh-my-zsh" "branch:master"
[[ $IGNORE_UPDATES != yes ]] && fetch_from_repo "https://github.com/mroth/evalcache" "${EXTER}/cache/sources/evalcache" "branch:master"
mkdir -p "${tmp_dir}/${orangepi_zsh_dir}"/{DEBIAN,etc/skel/,etc/oh-my-zsh/,/etc/skel/.oh-my-zsh/cache}
# set up control file
cat <<-END > "${tmp_dir}/${orangepi_zsh_dir}"/DEBIAN/control
Package: orangepi-zsh
Version: $REVISION
Architecture: all
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Depends: zsh, tmux
Section: utils
Priority: optional
Description: Orange Pi improved ZShell
END
# set up post install script
cat <<-END > "${tmp_dir}/${orangepi_zsh_dir}"/DEBIAN/postinst
#!/bin/sh
# copy cache directory if not there yet
awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$6"/.oh-my-zsh"}' /etc/passwd | xargs -i sh -c 'test ! -d {} && cp -R --attributes-only /etc/skel/.oh-my-zsh {}'
awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$6"/.zshrc"}' /etc/passwd | xargs -i sh -c 'test ! -f {} && cp -R /etc/skel/.zshrc {}'
# fix owner permissions in home directory
awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$1":"\$3" "\$6"/.oh-my-zsh"}' /etc/passwd | xargs -n2 chown -R
awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$1":"\$3" "\$6"/.zshrc"}' /etc/passwd | xargs -n2 chown -R
# add support for bash profile
! grep emulate /etc/zsh/zprofile >/dev/null && echo "emulate sh -c 'source /etc/profile'" >> /etc/zsh/zprofile
exit 0
END
cp -R "${EXTER}"/cache/sources/oh-my-zsh "${tmp_dir}/${orangepi_zsh_dir}"/etc/
cp -R "${EXTER}"/cache/sources/evalcache "${tmp_dir}/${orangepi_zsh_dir}"/etc/oh-my-zsh/plugins
cp "${tmp_dir}/${orangepi_zsh_dir}"/etc/oh-my-zsh/templates/zshrc.zsh-template "${tmp_dir}/${orangepi_zsh_dir}"/etc/skel/.zshrc
chmod -R g-w,o-w "${tmp_dir}/${orangepi_zsh_dir}"/etc/oh-my-zsh/
# we have common settings
sed -i "s/^export ZSH=.*/export ZSH=\/etc\/oh-my-zsh/" "${tmp_dir}/${orangepi_zsh_dir}"/etc/skel/.zshrc
# user cache
sed -i "/^export ZSH=.*/a export ZSH_CACHE_DIR=~\/.oh-my-zsh\/cache" "${tmp_dir}/${orangepi_zsh_dir}"/etc/skel/.zshrc
# define theme
sed -i 's/^ZSH_THEME=.*/ZSH_THEME="mrtazz"/' "${tmp_dir}/${orangepi_zsh_dir}"/etc/skel/.zshrc
# disable prompt while update
sed -i 's/# DISABLE_UPDATE_PROMPT="true"/DISABLE_UPDATE_PROMPT="true"/g' "${tmp_dir}/${orangepi_zsh_dir}"/etc/skel/.zshrc
# disable auto update since we provide update via package
sed -i 's/# DISABLE_AUTO_UPDATE="true"/DISABLE_AUTO_UPDATE="true"/g' "${tmp_dir}/${orangepi_zsh_dir}"/etc/skel/.zshrc
# define default plugins
sed -i 's/^plugins=.*/plugins=(evalcache git git-extras debian tmux screen history extract colorize web-search docker)/' "${tmp_dir}/${orangepi_zsh_dir}"/etc/skel/.zshrc
chmod 755 "${tmp_dir}/${orangepi_zsh_dir}"/DEBIAN/postinst
fakeroot dpkg-deb -b -Z${DEB_COMPRESS} "${tmp_dir}/${orangepi_zsh_dir}" >> "${DEST}"/${LOG_SUBPATH}/output.log 2>&1
rsync --remove-source-files -rq "${tmp_dir}/${orangepi_zsh_dir}.deb" "${DEB_STORAGE}/"
rm -rf "${tmp_dir}"
}
@@ -581,7 +743,7 @@ compile_orangepi-config()
ln -sf /usr/sbin/softy "${tmpdir}"/usr/bin/softy
fakeroot dpkg -b "${tmpdir}" >/dev/null
mv "${tmpdir}.deb" "${DEB_STORAGE}/"
rsync --remove-source-files -rq "${tmpdir}.deb" "${DEB_STORAGE}/"
rm -rf "${tmpdir}"
}
@@ -593,13 +755,13 @@ compile_sunxi_tools()
# Compile and install only if git commit hash changed
cd $EXTER/cache/sources/sunxi-tools || exit
# need to check if /usr/local/bin/sunxi-fexc to detect new Docker containers with old cached sources
if [[ ! -f .commit_id || $(git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/sunxi-fexc ]]; then
if [[ ! -f .commit_id || $(improved_git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/sunxi-fexc ]]; then
display_alert "Compiling" "sunxi-tools" "info"
make -s clean >/dev/null
make -s tools >/dev/null
mkdir -p /usr/local/bin/
make install-tools >/dev/null 2>&1
git rev-parse @ 2>/dev/null > .commit_id
improved_git rev-parse @ 2>/dev/null > .commit_id
fi
}
@@ -608,12 +770,12 @@ install_rkbin_tools()
# install only if git commit hash changed
cd "${EXTER}"/cache/sources/rkbin-tools || exit
# need to check if /usr/local/bin/sunxi-fexc to detect new Docker containers with old cached sources
if [[ ! -f .commit_id || $(git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/loaderimage ]]; then
if [[ ! -f .commit_id || $(improved_git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/loaderimage ]]; then
display_alert "Installing" "rkbin-tools" "info"
mkdir -p /usr/local/bin/
install -m 755 tools/loaderimage /usr/local/bin/
install -m 755 tools/trust_merger /usr/local/bin/
git rev-parse @ 2>/dev/null > .commit_id
improved_git rev-parse @ 2>/dev/null > .commit_id
fi
}
@@ -633,6 +795,7 @@ grab_version()
#
find_toolchain()
{
[[ "${SKIP_EXTERNAL_TOOLCHAINS}" == "yes" ]] && { echo "/usr/bin"; return; }
local compiler=$1
local expression=$2
local dist=10
@@ -661,12 +824,12 @@ find_toolchain()
done
echo "$toolchain"
# logging a stack of used compilers.
if [[ -f "${DEST}"/debug/compiler.log ]]; then
if ! grep -q "$toolchain" "${DEST}"/debug/compiler.log; then
echo "$toolchain" >> "${DEST}"/debug/compiler.log;
if [[ -f "${DEST}"/${LOG_SUBPATH}/compiler.log ]]; then
if ! grep -q "$toolchain" "${DEST}"/${LOG_SUBPATH}/compiler.log; then
echo "$toolchain" >> "${DEST}"/${LOG_SUBPATH}/compiler.log;
fi
else
echo "$toolchain" >> "${DEST}"/debug/compiler.log;
echo "$toolchain" >> "${DEST}"/${LOG_SUBPATH}/compiler.log;
fi
}
@@ -761,8 +924,8 @@ process_patch_file()
# detect and remove files which patch will create
lsdiff -s --strip=1 "${patch}" | grep '^+' | awk '{print $2}' | xargs -I % sh -c 'rm -f %'
echo "Processing file $patch" >> "${DEST}"/debug/patching.log
patch --batch --silent -p1 -N < "${patch}" >> "${DEST}"/debug/patching.log 2>&1
echo "Processing file $patch" >> "${DEST}"/${LOG_SUBPATH}/patching.log
patch --batch --silent -p1 -N < "${patch}" >> "${DEST}"/${LOG_SUBPATH}/patching.log 2>&1
if [[ $? -ne 0 ]]; then
display_alert "* $status $(basename "${patch}")" "failed" "wrn"
@@ -770,7 +933,7 @@ process_patch_file()
else
display_alert "* $status $(basename "${patch}")" "" "info"
fi
echo >> "${DEST}"/debug/patching.log
echo >> "${DEST}"/${LOG_SUBPATH}/patching.log
}
userpatch_create()
@@ -805,7 +968,7 @@ userpatch_create()
read -e -p "Patch description: " -i "$COMMIT_MESSAGE" COMMIT_MESSAGE
[[ -z "$COMMIT_MESSAGE" ]] && COMMIT_MESSAGE="Patching something"
git commit -s -m "$COMMIT_MESSAGE"
git format-patch -1 HEAD --stdout --signature="Created with Armbian build tools https://github.com/armbian/build" > "${patch}"
git format-patch -1 HEAD --stdout --signature="Created with orangepi build tools https://github.com/orangepi-xunlong/build" > "${patch}"
PATCHFILE=$(git format-patch -1 HEAD)
rm $PATCHFILE # delete the actual file
# create a symlink to have a nice name ready
@@ -838,44 +1001,34 @@ userpatch_create()
#
overlayfs_wrapper()
{
local operation="$1"
if [[ $operation == wrap ]]; then
local srcdir="$2"
local description="$3"
mkdir -p /tmp/overlay_components/ /tmp/orangepi_build/
local tempdir workdir mergeddir
tempdir=$(mktemp -d --tmpdir="/tmp/overlay_components/")
workdir=$(mktemp -d --tmpdir="/tmp/overlay_components/")
mergeddir=$(mktemp -d --suffix="_$description" --tmpdir="/tmp/orangepi_build/")
mount -t overlay overlay -o lowerdir="$srcdir",upperdir="$tempdir",workdir="$workdir" "$mergeddir"
# this is executed in a subshell, so use temp files to pass extra data outside
echo "$tempdir" >> /tmp/.overlayfs_wrapper_cleanup
echo "$mergeddir" >> /tmp/.overlayfs_wrapper_umount
echo "$mergeddir" >> /tmp/.overlayfs_wrapper_cleanup
echo "$mergeddir"
return
fi
if [[ $operation == cleanup ]]; then
if [[ -f /tmp/.overlayfs_wrapper_umount ]]; then
for dir in $(</tmp/.overlayfs_wrapper_umount); do
[[ $dir == /tmp/* ]] && umount -l "$dir" > /dev/null 2>&1
done
fi
if [[ -f /tmp/.overlayfs_wrapper_cleanup ]]; then
for dir in $(</tmp/.overlayfs_wrapper_cleanup); do
[[ $dir == /tmp/* ]] && rm -rf "$dir"
done
fi
rm -f /tmp/.overlayfs_wrapper_umount /tmp/.overlayfs_wrapper_cleanup
fi
local operation="$1"
if [[ $operation == wrap ]]; then
local srcdir="$2"
local description="$3"
mkdir -p /tmp/overlay_components/ /tmp/orangepi_build/
local tempdir workdir mergeddir
tempdir=$(mktemp -d --tmpdir="/tmp/overlay_components/")
workdir=$(mktemp -d --tmpdir="/tmp/overlay_components/")
mergeddir=$(mktemp -d --suffix="_$description" --tmpdir="/tmp/orangepi_build/")
mount -t overlay overlay -o lowerdir="$srcdir",upperdir="$tempdir",workdir="$workdir" "$mergeddir"
# this is executed in a subshell, so use temp files to pass extra data outside
echo "$tempdir" >> /tmp/.overlayfs_wrapper_cleanup
echo "$mergeddir" >> /tmp/.overlayfs_wrapper_umount
echo "$mergeddir" >> /tmp/.overlayfs_wrapper_cleanup
echo "$mergeddir"
return
fi
if [[ $operation == cleanup ]]; then
if [[ -f /tmp/.overlayfs_wrapper_umount ]]; then
for dir in $(</tmp/.overlayfs_wrapper_umount); do
[[ $dir == /tmp/* ]] && umount -l "$dir" > /dev/null 2>&1
done
fi
if [[ -f /tmp/.overlayfs_wrapper_cleanup ]]; then
for dir in $(</tmp/.overlayfs_wrapper_cleanup); do
[[ $dir == /tmp/* ]] && rm -rf "$dir"
done
fi
rm -f /tmp/.overlayfs_wrapper_umount /tmp/.overlayfs_wrapper_cleanup
fi
}

View File

@@ -1,30 +1,34 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
[[ -z $VENDOR ]] && VENDOR="Orange Pi"
[[ -z $ROOTPWD ]] && ROOTPWD="orangepi" # Must be changed @first login
[[ -z $OPI_USERNAME ]] && OPI_USERNAME="orangepi"
[[ -z $OPI_PWD ]] && OPI_PWD="orangepi"
[[ -z $MAINTAINER ]] && MAINTAINER="Orange Pi" # deb signature
[[ -z $MAINTAINERMAIL ]] && MAINTAINERMAIL="leeboby@aliyun.com" # deb signature
[[ -z $DEB_COMPRESS ]] && DEB_COMPRESS="xz" # compress .debs with XZ by default. Use 'none' for faster/larger builds
TZDATA=$(cat /etc/timezone) # Timezone for target is taken from host or defined here.
USEALLCORES=yes # Use all CPU cores for compiling
EXIT_PATCHING_ERROR="" # exit patching if failed
HOSTRELEASE=$(cat /etc/os-release | grep VERSION_CODENAME | cut -d"=" -f2)
[[ -z $HOSTRELEASE ]] && HOSTRELEASE=$(cut -d'/' -f1 /etc/debian_version)
[[ -z $EXIT_PATCHING_ERROR ]] && EXIT_PATCHING_ERROR="" # exit patching if failed
[[ -z $HOST ]] && HOST="$BOARD" # set hostname to the board
[[ -z $CHINA_DOWNLOAD_MIRROR ]] && CHINA_DOWNLOAD_MIRROR=tsinghua
cd "${SRC}" || exit
ROOTFSCACHE_VERSION=38
CHROOT_CACHE_VERSION=7
[[ -z "${ROOTFSCACHE_VERSION}" ]] && ROOTFSCACHE_VERSION=11
[[ -z "${CHROOT_CACHE_VERSION}" ]] && CHROOT_CACHE_VERSION=7
cd ${SRC}/scripts
BUILD_REPOSITORY_URL=$(git remote get-url $(git remote 2>/dev/null) 2>/dev/null)
BUILD_REPOSITORY_COMMIT=$(git describe --match=d_e_a_d_b_e_e_f --always --dirty 2>/dev/null)
ROOTFS_CACHE_MAX=42 # max number of rootfs cache, older ones will be cleaned up
BUILD_REPOSITORY_URL=$(improved_git remote get-url $(improved_git remote 2>/dev/null | grep origin) 2>/dev/null)
BUILD_REPOSITORY_COMMIT=$(improved_git describe --match=d_e_a_d_b_e_e_f --always --dirty 2>/dev/null)
ROOTFS_CACHE_MAX=200 # max number of rootfs cache, older ones will be cleaned up
DEB_STORAGE=$DEST/debs
DEB_ORANGEPI=$EXTER/cache/debs
@@ -32,7 +36,7 @@ DEB_ORANGEPI=$EXTER/cache/debs
# TODO: fixed name can't be used for parallel image building
ROOT_MAPPER="orangepi-root"
[[ -z $ROOTFS_TYPE ]] && ROOTFS_TYPE=ext4 # default rootfs type is ext4
[[ "ext4 f2fs btrfs nfs fel" != *$ROOTFS_TYPE* ]] && exit_with_error "Unknown rootfs type" "$ROOTFS_TYPE"
[[ "ext4 f2fs btrfs xfs nfs fel" != *$ROOTFS_TYPE* ]] && exit_with_error "Unknown rootfs type" "$ROOTFS_TYPE"
[[ -z $BTRFS_COMPRESSION ]] && BTRFS_COMPRESSION=zlib # default btrfs filesystem compression method is zlib
[[ ! $BTRFS_COMPRESSION =~ zlib|lzo|zstd|none ]] && exit_with_error "Unknown btrfs compression method" "$BTRFS_COMPRESSION"
@@ -50,22 +54,75 @@ fi
# small SD card with kernel, boot script and .dtb/.bin files
[[ $ROOTFS_TYPE == nfs ]] && FIXED_IMAGE_SIZE=64
# Since we are having too many options for mirror management,
# then here is yet another mirror related option.
# Respecting user's override in case a mirror is unreachable.
case $REGIONAL_MIRROR in
china)
[[ -z $USE_MAINLINE_GOOGLE_MIRROR ]] && [[ -z $MAINLINE_MIRROR ]] && MAINLINE_MIRROR=tuna
[[ -z $USE_GITHUB_UBOOT_MIRROR ]] && [[ -z $UBOOT_MIRROR ]] && UBOOT_MIRROR=gitee
[[ -z $GITHUB_MIRROR ]] && GITHUB_MIRROR=fastgit
[[ -z $DOWNLOAD_MIRROR ]] && DOWNLOAD_MIRROR=china
;;
*)
;;
esac
# used by multiple sources - reduce code duplication
[[ $USE_MAINLINE_GOOGLE_MIRROR == yes ]] && MAINLINE_MIRROR=google
case $MAINLINE_MIRROR in
google) MAINLINE_KERNEL_SOURCE='https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable' ;;
tuna) MAINLINE_KERNEL_SOURCE='https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git' ;;
*) MAINLINE_KERNEL_SOURCE='git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git' ;;
google)
MAINLINE_KERNEL_SOURCE='https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable'
MAINLINE_FIRMWARE_SOURCE='https://kernel.googlesource.com/pub/scm/linux/kernel/git/firmware/linux-firmware.git'
;;
tuna)
MAINLINE_KERNEL_SOURCE='https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git'
MAINLINE_FIRMWARE_SOURCE='https://mirrors.tuna.tsinghua.edu.cn/git/linux-firmware.git'
;;
bfsu)
MAINLINE_KERNEL_SOURCE='https://mirrors.bfsu.edu.cn/git/linux-stable.git'
MAINLINE_FIRMWARE_SOURCE='https://mirrors.bfsu.edu.cn/git/linux-firmware.git'
;;
*)
MAINLINE_KERNEL_SOURCE='git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git'
MAINLINE_FIRMWARE_SOURCE='git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git'
;;
esac
MAINLINE_KERNEL_DIR="$SRC/kernel"
if [[ $USE_GITHUB_UBOOT_MIRROR == yes ]]; then
MAINLINE_UBOOT_SOURCE='https://github.com/RobertCNelson/u-boot'
else
MAINLINE_UBOOT_SOURCE='https://github.com/orangepi-xunlong/u-boot-orangepi.git'
fi
[[ $USE_GITHUB_UBOOT_MIRROR == yes ]] && UBOOT_MIRROR=github
case $UBOOT_MIRROR in
gitee)
MAINLINE_UBOOT_SOURCE='https://github.com/orangepi-xunlong/u-boot-orangepi.git'
;;
github)
MAINLINE_UBOOT_SOURCE='https://github.com/orangepi-xunlong/u-boot-orangepi.git'
;;
*)
MAINLINE_UBOOT_SOURCE='https://source.denx.de/u-boot/u-boot.git'
;;
esac
MAINLINE_UBOOT_DIR="$SRC/u-boot"
case $GITHUB_MIRROR in
fastgit)
GITHUB_SOURCE='https://hub.fastgit.org/'
;;
gitclone)
GITHUB_SOURCE='https://gitclone.com/github.com/'
;;
cnpmjs)
GITHUB_SOURCE='https://github.com.cnpmjs.org/'
;;
*)
GITHUB_SOURCE='https://github.com/'
;;
esac
# Let's set default data if not defined in board configuration above
[[ -z $OFFSET ]] && OFFSET=4 # offset to 1st partition (we use 4MiB boundaries by default)
ARCH=armhf
@@ -81,24 +138,17 @@ ATF_COMPILE=yes
[[ -z $CRYPTROOT_PARAMETERS ]] && CRYPTROOT_PARAMETERS="--pbkdf pbkdf2"
[[ -z $WIREGUARD ]] && WIREGUARD="no"
[[ -z $EXTRAWIFI ]] && EXTRAWIFI="yes"
[[ -z $SKIP_BOOTSPLASH ]] && SKIP_BOOTSPLASH="no"
[[ -z $AUFS ]] && AUFS="yes"
[[ -z $IMAGE_PARTITION_TABLE ]] && IMAGE_PARTITION_TABLE="msdos"
[[ -z $EXTRA_BSP_NAME ]] && EXTRA_BSP_NAME=""
[[ -z $EXTRA_ROOTFS_MIB_SIZE ]] && EXTRA_ROOTFS_MIB_SIZE=0
[[ -z $BUILD_KSRC ]] && BUILD_KSRC="no"
# single ext4 partition is the default and preferred configuration
#BOOTFS_TYPE=''
#BOOTFS_TYPE="fat"
[[ $BOOTFS_TYPE == fat && $ARCHITECTURE == arm ]] && BOOTSCRIPT="boot-sunxi-fat.cmd:boot.cmd"
[[ $BOOTFS_TYPE == fat && $ARCHITECTURE == arm64 ]] && BOOTSCRIPT='boot-sun50i-next-fat.cmd:boot.cmd'
# set unique mounting directory
SDCARD="${SRC}/.tmp/rootfs-${BRANCH}-${BOARD}-${RELEASE}-${BUILD_DESKTOP}-${BUILD_MINIMAL}"
MOUNT="${SRC}/.tmp/mount-${BRANCH}-${BOARD}-${RELEASE}-${BUILD_DESKTOP}-${BUILD_MINIMAL}"
DESTIMG="${SRC}/.tmp/image-${BRANCH}-${BOARD}-${RELEASE}-${BUILD_DESKTOP}-${BUILD_MINIMAL}"
[[ ! -f ${EXTER}/config/sources/families/$LINUXFAMILY.conf ]] && \
exit_with_error "Sources configuration not found" "$LINUXFAMILY"
exit_with_error "Sources configuration not found" "$LINUXFAMILY"
source "${EXTER}/config/sources/families/${LINUXFAMILY}.conf"
@@ -110,11 +160,252 @@ fi
# load architecture defaults
source "${EXTER}/config/sources/${ARCH}.conf"
## Extensions: at this point we've sourced all the config files that will be used,
## and (hopefully) not yet invoked any extension methods. So this is the perfect
## place to initialize the extension manager. It will create functions
## like the 'post_family_config' that is invoked below.
initialize_extension_manager
call_extension_method "post_family_config" "config_tweaks_post_family_config" << 'POST_FAMILY_CONFIG'
*give the config a chance to override the family/arch defaults*
This hook is called after the family configuration (`sources/families/xxx.conf`) is sourced.
Since the family can override values from the user configuration and the board configuration,
it is often used to in turn override those.
POST_FAMILY_CONFIG
# Myy : Menu configuration for choosing desktop configurations
show_menu() {
provided_title=$1
provided_backtitle=$2
provided_menuname=$3
# Myy : I don't know why there's a TTY_Y - 8...
#echo "Provided title : $provided_title"
#echo "Provided backtitle : $provided_backtitle"
#echo "Provided menuname : $provided_menuname"
#echo "Provided options : " "${@:4}"
#echo "TTY X: $TTY_X Y: $TTY_Y"
whiptail --title "${provided_title}" --backtitle "${provided_backtitle}" --notags \
--menu "${provided_menuname}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
"${@:4}" \
3>&1 1>&2 2>&3
}
# Myy : FIXME Factorize
show_select_menu() {
provided_title=$1
provided_backtitle=$2
provided_menuname=$3
#dialog --stdout --title "${provided_title}" --backtitle "${provided_backtitle}" \
#--checklist "${provided_menuname}" $TTY_Y $TTY_X $((TTY_Y - 8)) "${@:4}"
#whiptail --separate-output --title "${provided_title}" --backtitle "${provided_backtitle}" \
# --checklist "${provided_menuname}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
# "${@:4}" \
# 3>&1 1>&2 2>&3
whiptail --title "${provided_title}" --backtitle "${provided_backtitle}" \
--checklist "${provided_menuname}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
"${@:4}" \
3>&1 1>&2 2>&3
}
# Myy : Once we got a list of selected groups, parse the PACKAGE_LIST inside configuration.sh
DESKTOP_ELEMENTS_DIR="${EXTER}/config/desktop/${RELEASE}"
DESKTOP_CONFIGS_DIR="${DESKTOP_ELEMENTS_DIR}/environments"
DESKTOP_CONFIG_PREFIX="config_"
DESKTOP_APPGROUPS_DIR="${DESKTOP_ELEMENTS_DIR}/appgroups"
desktop_element_available_for_arch() {
local desktop_element_path="${1}"
local targeted_arch="${2}"
local arch_limitation_file="${1}/only_for"
echo "Checking if ${desktop_element_path} is available for ${targeted_arch} in ${arch_limitation_file}" >> "${DEST}"/${LOG_SUBPATH}/output.log
if [[ -f "${arch_limitation_file}" ]]; then
grep -- "${targeted_arch}" "${arch_limitation_file}"
return $?
else
return 0
fi
}
desktop_element_supported() {
local desktop_element_path="${1}"
local support_level_filepath="${desktop_element_path}/support"
if [[ -f "${support_level_filepath}" ]]; then
local support_level="$(cat "${support_level_filepath}")"
if [[ "${support_level}" != "supported" && "${EXPERT}" != "yes" ]]; then
return 65
fi
desktop_element_available_for_arch "${desktop_element_path}" "${ARCH}"
if [[ $? -ne 0 ]]; then
return 66
fi
else
return 64
fi
return 0
}
if [[ $BUILD_DESKTOP == "yes" && -z $DESKTOP_ENVIRONMENT ]]; then
desktop_environments_prepare_menu() {
for desktop_env_dir in "${DESKTOP_CONFIGS_DIR}/"*; do
local desktop_env_name=$(basename ${desktop_env_dir})
local expert_infos=""
[[ "${EXPERT}" == "yes" ]] && expert_infos="[$(cat "${desktop_env_dir}/support" 2> /dev/null)]"
desktop_element_supported "${desktop_env_dir}" "${ARCH}" && options+=("${desktop_env_name}" "${desktop_env_name^} desktop environment ${expert_infos}")
done
}
options=()
desktop_environments_prepare_menu
if [[ "${options[0]}" == "" ]]; then
exit_with_error "No desktop environment seems to be available for your board ${BOARD} (ARCH : ${ARCH} - EXPERT : ${EXPERT})"
fi
DESKTOP_ENVIRONMENT=$(show_menu "Choose a desktop environment" "$backtitle" "Select the default desktop environment to bundle with this image" "${options[@]}")
unset options
if [[ -z "${DESKTOP_ENVIRONMENT}" ]]; then
exit_with_error "No desktop environment selected..."
fi
fi
if [[ $BUILD_DESKTOP == "yes" ]]; then
# Expected environment variables :
# - options
# - ARCH
desktop_environment_check_if_valid() {
local error_msg=""
desktop_element_supported "${DESKTOP_ENVIRONMENT_DIRPATH}" "${ARCH}"
local retval=$?
if [[ ${retval} == 0 ]]; then
return
elif [[ ${retval} == 64 ]]; then
error_msg+="Either the desktop environment ${DESKTOP_ENVIRONMENT} does not exist "
error_msg+="or the file ${DESKTOP_ENVIRONMENT_DIRPATH}/support is missing"
elif [[ ${retval} == 65 ]]; then
error_msg+="Only experts can build an image with the desktop environment \"${DESKTOP_ENVIRONMENT}\", since the Armbian team won't offer any support for it (EXPERT=${EXPERT})"
elif [[ ${retval} == 66 ]]; then
error_msg+="The desktop environment \"${DESKTOP_ENVIRONMENT}\" has no packages for your targeted board architecture (BOARD=${BOARD} ARCH=${ARCH}). "
error_msg+="The supported boards architectures are : "
error_msg+="$(cat "${DESKTOP_ENVIRONMENT_DIRPATH}/only_for")"
fi
# supress error when cache is rebuilding
[[ -n "$ROOT_FS_CREATE_ONLY" ]] && exit 0
exit_with_error "${error_msg}"
}
DESKTOP_ENVIRONMENT_DIRPATH="${DESKTOP_CONFIGS_DIR}/${DESKTOP_ENVIRONMENT}"
desktop_environment_check_if_valid
fi
if [[ $BUILD_DESKTOP == "yes" && -z $DESKTOP_ENVIRONMENT_CONFIG_NAME ]]; then
# FIXME Check for empty folders, just in case the current maintainer
# messed up
# Note, we could also ignore it and don't show anything in the previous
# menu, but that hides information and make debugging harder, which I
# don't like. Adding desktop environments as a maintainer is not a
# trivial nor common task.
options=()
for configuration in "${DESKTOP_ENVIRONMENT_DIRPATH}/${DESKTOP_CONFIG_PREFIX}"*; do
config_filename=$(basename ${configuration})
config_name=${config_filename#"${DESKTOP_CONFIG_PREFIX}"}
options+=("${config_filename}" "${config_name} configuration")
done
DESKTOP_ENVIRONMENT_CONFIG_NAME=$(show_menu "Choose the desktop environment config" "$backtitle" "Select the configuration for this environment.\nThese are sourced from ${desktop_environment_config_dir}" "${options[@]}")
unset options
if [[ -z $DESKTOP_ENVIRONMENT_CONFIG_NAME ]]; then
exit_with_error "No desktop configuration selected... Do you really want a desktop environment ?"
fi
fi
if [[ $BUILD_DESKTOP == "yes" ]]; then
DESKTOP_ENVIRONMENT_PACKAGE_LIST_DIRPATH="${DESKTOP_ENVIRONMENT_DIRPATH}/${DESKTOP_ENVIRONMENT_CONFIG_NAME}"
DESKTOP_ENVIRONMENT_PACKAGE_LIST_FILEPATH="${DESKTOP_ENVIRONMENT_PACKAGE_LIST_DIRPATH}/packages"
fi
# "-z ${VAR+x}" allows to check for unset variable
# Technically, someone might want to build a desktop with no additional
# appgroups.
if [[ $BUILD_DESKTOP == "yes" && -z ${DESKTOP_APPGROUPS_SELECTED+x} ]]; then
options=()
for appgroup_path in "${DESKTOP_APPGROUPS_DIR}/"*; do
appgroup="$(basename "${appgroup_path}")"
options+=("${appgroup}" "${appgroup^}" off)
done
DESKTOP_APPGROUPS_SELECTED=$(\
show_select_menu \
"Choose desktop softwares to add" \
"$backtitle" \
"Select which kind of softwares you'd like to add to your build" \
"${options[@]}")
DESKTOP_APPGROUPS_SELECTED=${DESKTOP_APPGROUPS_SELECTED//\"/}
unset options
fi
#exit_with_error 'Testing'
# Expected variables
# - aggregated_content
# - potential_paths
# - separator
# Write to variables :
# - aggregated_content
aggregate_content() {
LOG_OUTPUT_FILE="${SRC}/output/${LOG_SUBPATH}/potential-paths.log"
echo -e "Potential paths :" >> "${LOG_OUTPUT_FILE}"
show_checklist_variables potential_paths
for filepath in ${potential_paths}; do
if [[ -f "${filepath}" ]]; then
echo -e "${filepath/"$EXTER"\//} yes" >> "${LOG_OUTPUT_FILE}"
aggregated_content+=$(cat "${filepath}")
aggregated_content+="${separator}"
# else
# echo -e "${filepath/"$EXTER"\//} no\n" >> "${LOG_OUTPUT_FILE}"
fi
done
echo "" >> "${LOG_OUTPUT_FILE}"
unset LOG_OUTPUT_FILE
}
# set unique mounting directory
MOUNT_UUID=$(uuidgen)
SDCARD="${SRC}/.tmp/rootfs-${MOUNT_UUID}"
MOUNT="${SRC}/.tmp/mount-${MOUNT_UUID}"
DESTIMG="${SRC}/.tmp/image-${MOUNT_UUID}"
# dropbear needs to be configured differently
[[ $CRYPTROOT_ENABLE == yes && $RELEASE == xenial ]] && exit_with_error "Encrypted rootfs is not supported in Xenial"
[[ $RELEASE == stretch && $CAN_BUILD_STRETCH != yes ]] && exit_with_error "Building Debian Stretch images with selected kernel is not supported"
[[ $RELEASE == bionic && $CAN_BUILD_STRETCH != yes ]] && exit_with_error "Building Ubuntu Bionic images with selected kernel is not supported"
[[ $RELEASE == bionic && $(lsb_release -sc) == xenial ]] && exit_with_error "Building Ubuntu Bionic images requires a Bionic build host. Please upgrade your host or select a different target OS"
[[ $RELEASE == hirsute && $HOSTRELEASE == focal ]] && exit_with_error "Building Ubuntu Hirsute images requires Hirsute build host. Please upgrade your host or select a different target OS"
[[ -n $ATFSOURCE && -z $ATF_USE_GCC ]] && exit_with_error "Error in configuration: ATF_USE_GCC is unset"
[[ -z $UBOOT_USE_GCC ]] && exit_with_error "Error in configuration: UBOOT_USE_GCC is unset"
@@ -127,174 +418,221 @@ BOOTCONFIG_VAR_NAME=BOOTCONFIG_${BRANCH^^}
[[ -z $ATFPATCHDIR ]] && ATFPATCHDIR="atf-$LINUXFAMILY"
[[ -z $KERNELPATCHDIR ]] && KERNELPATCHDIR="$LINUXFAMILY-$BRANCH"
if [[ $RELEASE == xenial || $RELEASE == bionic || $RELEASE == focal || $RELEASE == eoan ]]; then
if [[ "$RELEASE" =~ ^(xenial|bionic|focal|hirsute|impish|jammy)$ ]]; then
DISTRIBUTION="Ubuntu"
else
DISTRIBUTION="Debian"
fi
# Base system dependencies. Since adding MINIMAL_IMAGE we rely on "variant=minbase" which has very basic package set
DEBOOTSTRAP_LIST="locales gnupg ifupdown apt-utils apt-transport-https ca-certificates bzip2 console-setup cpio cron \
dbus init initramfs-tools iputils-ping isc-dhcp-client kmod less libpam-systemd \
linux-base logrotate netbase netcat-openbsd rsyslog systemd sudo ucf udev whiptail \
wireless-regdb crda dmsetup rsync tzdata"
CLI_CONFIG_PATH="${EXTER}/config/cli/${RELEASE}"
DEBOOTSTRAP_CONFIG_PATH="${CLI_CONFIG_PATH}/debootstrap"
[[ $BUILD_DESKTOP == yes ]] && DEBOOTSTRAP_LIST+=" libgtk2.0-bin"
# tab cleanup is mandatory
DEBOOTSTRAP_LIST=$(echo $DEBOOTSTRAP_LIST | sed -e 's,\\[trn],,g')
# For minimal build different set of packages is needed
# Essential packages for minimal build
PACKAGE_LIST="bc cpufrequtils device-tree-compiler fping fake-hwclock psmisc chrony parted dialog \
ncurses-term sysfsutils toilet figlet u-boot-tools usbutils openssh-server \
nocache debconf-utils python3-apt"
# Non-essential packages for minimal build
PACKAGE_LIST_ADDITIONAL="network-manager wireless-tools lsof htop mmc-utils wget nano sysstat net-tools resolvconf iozone3 jq libcrack2 cracklib-runtime curl"
[[ $RELEASE == xenial ]] && PACKAGE_LIST_ADDITIONAL="network-manager wireless-tools lsof htop wget nano sysstat net-tools resolvconf iozone3 jq libcrack2 cracklib-runtime curl"
if [[ "$BUILD_MINIMAL" != "yes" ]]; then
# Essential packages
PACKAGE_LIST="$PACKAGE_LIST bridge-utils build-essential fbset \
iw wpasupplicant sudo linux-base crda \
wireless-regdb unattended-upgrades \
console-setup unicode-data initramfs-tools \
ca-certificates expect iptables automake html2text \
bison flex libwrap0-dev libssl-dev libnl-3-dev libnl-genl-3-dev keyboard-configuration"
# Non-essential packages
PACKAGE_LIST_ADDITIONAL="$PACKAGE_LIST_ADDITIONAL alsa-utils btrfs-progs dosfstools iotop stress screen \
ntfs-3g vim pciutils evtest pv libfuse2 libdigest-sha-perl \
libproc-processtable-perl aptitude dnsutils f3 haveged hdparm rfkill vlan bash-completion \
hostapd git ethtool unzip ifenslave libpam-systemd iperf3 \
software-properties-common libnss-myhostname f2fs-tools avahi-autoipd iputils-arping qrencode sunxi-tools"
if [[ $? != 0 ]]; then
exit_with_error "The desktop environment ${DESKTOP_ENVIRONMENT} is not available for your architecture ${ARCH}"
fi
AGGREGATION_SEARCH_ROOT_ABSOLUTE_DIRS="
${EXTER}/config
${EXTER}/config/optional/_any_board/_config
${EXTER}/config/optional/architectures/${ARCH}/_config
${EXTER}/config/optional/families/${LINUXFAMILY}/_config
${EXTER}/config/optional/boards/${BOARD}/_config
${USERPATCHES_PATH}
"
DEBOOTSTRAP_SEARCH_RELATIVE_DIRS="
cli/_all_distributions/debootstrap
cli/${RELEASE}/debootstrap
"
CLI_SEARCH_RELATIVE_DIRS="
cli/_all_distributions/main
cli/${RELEASE}/main
"
PACKAGES_SEARCH_ROOT_ABSOLUTE_DIRS="
${EXTER}/packages
${EXTER}/config/optional/_any_board/_packages
${EXTER}/config/optional/architectures/${ARCH}/_packages
${EXTER}/config/optional/families/${LINUXFAMILY}/_packages
${EXTER}/config/optional/boards/${BOARD}/_packages
"
DESKTOP_ENVIRONMENTS_SEARCH_RELATIVE_DIRS="
desktop/_all_distributions/environments/_all_environments
desktop/_all_distributions/environments/${DESKTOP_ENVIRONMENT}
desktop/_all_distributions/environments/${DESKTOP_ENVIRONMENT}/${DESKTOP_ENVIRONMENT_CONFIG_NAME}
desktop/${RELEASE}/environments/_all_environments
desktop/${RELEASE}/environments/${DESKTOP_ENVIRONMENT}
desktop/${RELEASE}/environments/${DESKTOP_ENVIRONMENT}/${DESKTOP_ENVIRONMENT_CONFIG_NAME}
"
DESKTOP_APPGROUPS_SEARCH_RELATIVE_DIRS="
desktop/_all_distributions/appgroups
desktop/_all_distributions/environments/${DESKTOP_ENVIRONMENT}/appgroups
desktop/${RELEASE}/appgroups
desktop/${RELEASE}/environments/${DESKTOP_ENVIRONMENT}/appgroups
"
get_all_potential_paths() {
local root_dirs="${AGGREGATION_SEARCH_ROOT_ABSOLUTE_DIRS}"
local rel_dirs="${1}"
local sub_dirs="${2}"
local looked_up_subpath="${3}"
for root_dir in ${root_dirs}; do
for rel_dir in ${rel_dirs}; do
for sub_dir in ${sub_dirs}; do
potential_paths+="${root_dir}/${rel_dir}/${sub_dir}/${looked_up_subpath} "
done
done
done
# for ppath in ${potential_paths}; do
# echo "Checking for ${ppath}"
# if [[ -f "${ppath}" ]]; then
# echo "OK !|"
# else
# echo "Nope|"
# fi
# done
}
# Environment variables expected :
# - aggregated_content
# Arguments :
# 1. File to look up in each directory
# 2. The separator to add between each concatenated file
# 3. Relative directories paths added to ${3}
# 4. Relative directories paths added to ${4}
#
# The function will basically generate a list of potential paths by
# generating all the potential paths combinations leading to the
# looked up file
# ${AGGREGATION_SEARCH_ROOT_ABSOLUTE_DIRS}/${3}/${4}/${1}
# Then it will concatenate the content of all the available files
# into ${aggregated_content}
#
# TODO :
# ${4} could be removed by just adding the appropriate paths to ${3}
# dynamically for each case
# (debootstrap, cli, desktop environments, desktop appgroups, ...)
aggregate_all_root_rel_sub() {
local separator="${2}"
local potential_paths=""
get_all_potential_paths "${3}" "${4}" "${1}"
aggregate_content
}
aggregate_all_debootstrap() {
local sub_dirs_to_check=". "
if [[ ! -z "${SELECTED_CONFIGURATION+x}" ]]; then
sub_dirs_to_check+="config_${SELECTED_CONFIGURATION}"
fi
aggregate_all_root_rel_sub "${1}" "${2}" "${DEBOOTSTRAP_SEARCH_RELATIVE_DIRS}" "${sub_dirs_to_check}"
}
aggregate_all_cli() {
local sub_dirs_to_check=". "
if [[ ! -z "${SELECTED_CONFIGURATION+x}" ]]; then
sub_dirs_to_check+="config_${SELECTED_CONFIGURATION}"
fi
aggregate_all_root_rel_sub "${1}" "${2}" "${CLI_SEARCH_RELATIVE_DIRS}" "${sub_dirs_to_check}"
}
aggregate_all_desktop() {
aggregate_all_root_rel_sub "${1}" "${2}" "${DESKTOP_ENVIRONMENTS_SEARCH_RELATIVE_DIRS}" "."
aggregate_all_root_rel_sub "${1}" "${2}" "${DESKTOP_APPGROUPS_SEARCH_RELATIVE_DIRS}" "${DESKTOP_APPGROUPS_SELECTED}"
}
one_line() {
local aggregate_func_name="${1}"
local aggregated_content=""
shift 1
$aggregate_func_name "${@}"
cleanup_list aggregated_content
}
DEBOOTSTRAP_LIST="$(one_line aggregate_all_debootstrap "packages" " ")"
DEBOOTSTRAP_COMPONENTS="$(one_line aggregate_all_debootstrap "components" " ")"
DEBOOTSTRAP_COMPONENTS="${DEBOOTSTRAP_COMPONENTS// /,}"
PACKAGE_LIST="$(one_line aggregate_all_cli "packages" " ")"
PACKAGE_LIST_ADDITIONAL="$(one_line aggregate_all_cli "packages.additional" " ")"
LOG_OUTPUT_FILE="$SRC/output/${LOG_SUBPATH}/debootstrap-list.log"
show_checklist_variables "DEBOOTSTRAP_LIST DEBOOTSTRAP_COMPONENTS PACKAGE_LIST PACKAGE_LIST_ADDITIONAL PACKAGE_LIST_UNINSTALL"
# Dependent desktop packages
PACKAGE_LIST_DESKTOP="xserver-xorg xserver-xorg-video-fbdev gvfs-backends gvfs-fuse xfonts-base xinit \
x11-xserver-utils xfce4 lxtask xfce4-terminal thunar-volman gtk2-engines gtk2-engines-murrine gtk2-engines-pixbuf \
libgtk2.0-bin network-manager-gnome xfce4-notifyd gnome-keyring gcr libgck-1-0 p11-kit pasystray pavucontrol \
pulseaudio pavumeter bluez bluez-tools pulseaudio-module-bluetooth blueman libpam-gnome-keyring \
libgl1-mesa-dri policykit-1 profile-sync-daemon gnome-orca numix-gtk-theme synaptic apt-xapian-index lightdm lightdm-gtk-greeter"
# Recommended desktop packages
PACKAGE_LIST_DESKTOP_RECOMMENDS="galculator hexchat xfce4-screenshooter network-manager-openvpn-gnome mpv fbi \
cups-pk-helper cups geany atril xarchiver"
# Full desktop packages
PACKAGE_LIST_DESKTOP_FULL="libreoffice libreoffice-style-tango meld remmina kazam avahi-daemon transmission"
# Packages installed before desktop.
PACKAGE_LIST_PREDEPENDS=""
# Release specific packages
case $RELEASE in
xenial)
# Dependent desktop packages
PACKAGE_LIST_DESKTOP="xserver-xorg xserver-xorg-video-fbdev gvfs-backends gvfs-fuse xfonts-base xinit \
x11-xserver-utils xfce4 lxtask xfce4-terminal thunar-volman gtk2-engines gtk2-engines-murrine gtk2-engines-pixbuf \
libgtk2.0-bin network-manager-gnome xfce4-notifyd gnome-keyring gcr libgck-1-0 p11-kit pasystray pavucontrol \
pulseaudio pavumeter bluez bluez-tools pulseaudio-module-bluetooth blueman libpam-gnome-keyring \
libgl1-mesa-dri policykit-1 gnome-orca numix-gtk-theme synaptic apt-xapian-index lightdm lightdm-gtk-greeter xfce4-power-manager"
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" btrfs-tools"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db sysbench command-not-found"
PACKAGE_LIST_DESKTOP+=" paman libgcr-3-common gcj-jre-headless paprefs libgnome2-perl \
pulseaudio-module-gconf onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium-browser language-selector-gnome system-config-printer-common \
system-config-printer-gnome leafpad mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
stretch)
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" rng-tools"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr sysbench command-not-found"
PACKAGE_LIST_DESKTOP+=" paman libgcr-3-common gcj-jre-headless paprefs dbus-x11 libgnome2-perl pulseaudio-module-gconf onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium system-config-printer-common system-config-printer leafpad mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
bionic)
DEBOOTSTRAP_COMPONENTS="main,universe"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher command-not-found"
PACKAGE_LIST_DESKTOP+=" xserver-xorg-input-all paprefs dbus-x11 libgnome2-perl pulseaudio-module-gconf onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium-browser system-config-printer-common system-config-printer \
language-selector-gnome leafpad mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
buster)
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher command-not-found"
PACKAGE_LIST_DESKTOP+=" paprefs dbus-x11 numix-icon-theme onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" chromium system-config-printer-common system-config-printer mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
;;
bullseye)
DEBOOTSTRAP_COMPONENTS="main"
DEBOOTSTRAP_LIST+=" haveged fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher command-not-found"
PACKAGE_LIST_DESKTOP+=" paprefs dbus-x11 numix-icon-theme"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" firefox-esr system-config-printer-common system-config-printer"
PACKAGE_LIST_DESKTOP_FULL+=""
;;
focal)
DEBOOTSTRAP_COMPONENTS="main,universe"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher"
PACKAGE_LIST_DESKTOP+=" xserver-xorg-input-all paprefs dbus-x11 pulseaudio-module-gsettings onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" firefox system-config-printer-common system-config-printer \
language-selector-gnome viewnior"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
PACKAGE_LIST_PREDEPENDS="policykit-1-gnome notification-daemon"
;;
eoan)
DEBOOTSTRAP_COMPONENTS="main,universe"
DEBOOTSTRAP_LIST+=" rng-tools fdisk"
[[ -z $BUILD_MINIMAL || $BUILD_MINIMAL == no ]] && PACKAGE_LIST_RELEASE="man-db kbd net-tools gnupg2 dirmngr networkd-dispatcher"
PACKAGE_LIST_DESKTOP+=" xserver-xorg-input-all paprefs dbus-x11 pulseaudio-module-gsettings onboard"
PACKAGE_LIST_DESKTOP_RECOMMENDS+=" firefox system-config-printer-common system-config-printer \
language-selector-gnome mirage"
PACKAGE_LIST_DESKTOP_FULL+=" thunderbird"
PACKAGE_LIST_PREDEPENDS="policykit-1-gnome notification-daemon"
;;
esac
# Myy : Sources packages from file here
# Myy : FIXME Rename aggregate_all to aggregate_all_desktop
if [[ $BUILD_DESKTOP == "yes" ]]; then
PACKAGE_LIST_DESKTOP+="$(one_line aggregate_all_desktop "packages" " ")"
echo -e "\nGroups selected ${DESKTOP_APPGROUPS_SELECTED} -> PACKAGES :" >> "${LOG_OUTPUT_FILE}"
show_checklist_variables PACKAGE_LIST_DESKTOP
fi
unset LOG_OUTPUT_FILE
DEBIAN_MIRROR='deb.debian.org/debian'
DEBIAN_SECURTY='security.debian.org/'
UBUNTU_MIRROR='ports.ubuntu.com/'
if [[ $DOWNLOAD_MIRROR == china ]] ; then
DEBIAN_MIRROR='mirrors.tuna.tsinghua.edu.cn/debian'
DEBIAN_SECURTY='mirrors.tuna.tsinghua.edu.cn/debian-security'
UBUNTU_MIRROR='mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/'
if [[ $DOWNLOAD_MIRROR == "china" ]] ; then
if [[ ${CHINA_DOWNLOAD_MIRROR} == tsinghua ]]; then
DEBIAN_MIRROR='mirrors.tuna.tsinghua.edu.cn/debian'
DEBIAN_SECURTY='mirrors.tuna.tsinghua.edu.cn/debian-security'
UBUNTU_MIRROR='mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/'
fi
if [[ ${CHINA_DOWNLOAD_MIRROR} == huawai ]]; then
DEBIAN_MIRROR='repo.huaweicloud.com/debian'
DEBIAN_SECURTY='repo.huaweicloud.com/debian-security'
UBUNTU_MIRROR='repo.huaweicloud.com/ubuntu-ports/'
fi
fi
# For user override
if [[ $DOWNLOAD_MIRROR == "bfsu" ]] ; then
DEBIAN_MIRROR='mirrors.bfsu.edu.cn/debian'
DEBIAN_SECURTY='mirrors.bfsu.edu.cn/debian-security'
UBUNTU_MIRROR='mirrors.bfsu.edu.cn/ubuntu-ports/'
fi
if [[ "${ARCH}" == "amd64" ]]; then
UBUNTU_MIRROR='archive.ubuntu.com/ubuntu' # ports are only for non-amd64, of course.
fi
# don't use mirrors that throws garbage on 404
if [[ -z ${ARMBIAN_MIRROR} ]]; then
while true; do
ARMBIAN_MIRROR=$(wget -SO- -T 1 -t 1 https://redirect.armbian.com 2>&1 | egrep -i "Location" | awk '{print $2}' | head -1)
[[ ${ARMBIAN_MIRROR} != *armbian.hosthatch* ]] && break
done
fi
# For (late) user override.
# Notice: it is too late to define hook functions or add extensions in lib.config, since the extension initialization already ran by now.
# in case the user tries to use them in lib.config, hopefully they'll be detected as "wishful hooking" and the user will be wrn'ed.
if [[ -f $USERPATCHES_PATH/lib.config ]]; then
display_alert "Using user configuration override" "$USERPATCHES_PATH/lib.config" "info"
source "$USERPATCHES_PATH"/lib.config
fi
if [[ "$(type -t user_config)" == "function" ]]; then
display_alert "Invoke function with user override" "user_config" "info"
user_config
fi
call_extension_method "user_config" << 'USER_CONFIG'
*Invoke function with user override*
Allows for overriding configuration values set anywhere else.
It is called after sourcing the `lib.config` file if it exists,
but before assembling any package lists.
USER_CONFIG
call_extension_method "extension_prepare_config" << 'EXTENSION_PREPARE_CONFIG'
*allow extensions to prepare their own config, after user config is done*
Implementors should preserve variable values pre-set, but can default values an/or validate them.
This runs *after* user_config. Don't change anything not coming from other variables or meant to be configured by the user.
EXTENSION_PREPARE_CONFIG
# apt-cacher-ng mirror configurarion
if [[ $DISTRIBUTION == Ubuntu ]]; then
@@ -307,25 +645,75 @@ fi
# Build final package list after possible override
PACKAGE_LIST="$PACKAGE_LIST $PACKAGE_LIST_RELEASE $PACKAGE_LIST_ADDITIONAL"
[[ $BUILD_DESKTOP == yes ]] && PACKAGE_LIST="$PACKAGE_LIST $PACKAGE_LIST_DESKTOP $PACKAGE_LIST_DESKTOP_RECOMMENDS"
PACKAGE_MAIN_LIST="$(cleanup_list PACKAGE_LIST)"
[[ $BUILD_DESKTOP == yes ]] && PACKAGE_LIST="$PACKAGE_LIST $PACKAGE_LIST_DESKTOP"
PACKAGE_LIST="$(cleanup_list PACKAGE_LIST)"
# remove any packages defined in PACKAGE_LIST_RM in lib.config
aggregated_content="${PACKAGE_LIST_RM} "
aggregate_all_cli "packages.remove" " "
aggregate_all_desktop "packages.remove" " "
PACKAGE_LIST_RM="$(cleanup_list aggregated_content)"
unset aggregated_content
aggregated_content=""
aggregate_all_cli "packages.uninstall" " "
aggregate_all_desktop "packages.uninstall" " "
PACKAGE_LIST_UNINSTALL="$(cleanup_list aggregated_content)"
unset aggregated_content
if [[ -n $PACKAGE_LIST_RM ]]; then
PACKAGE_LIST=$(sed -r "s/\b($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\b//g" <<< "${PACKAGE_LIST}")
display_alert "Package remove list ${PACKAGE_LIST_RM}"
# Turns out that \b can be tricked by dashes.
# So if you remove mesa-utils but still want to install "mesa-utils-extra"
# a "\b(mesa-utils)\b" filter will convert "mesa-utils-extra" to "-extra".
# \W is not tricked by this but consumes the surrounding spaces, so we
# replace the occurence by one space, to avoid sticking the next word to
# the previous one after consuming the spaces.
DEBOOTSTRAP_LIST=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${DEBOOTSTRAP_LIST} ")
PACKAGE_LIST=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${PACKAGE_LIST} ")
PACKAGE_MAIN_LIST=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${PACKAGE_MAIN_LIST} ")
if [[ $BUILD_DESKTOP == "yes" ]]; then
PACKAGE_LIST_DESKTOP=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${PACKAGE_LIST_DESKTOP} ")
# Removing double spaces... AGAIN, since we might have used a sed on them
# Do not quote the variables. This would defeat the trick.
PACKAGE_LIST_DESKTOP="$(echo ${PACKAGE_LIST_DESKTOP})"
fi
# Removing double spaces... AGAIN, since we might have used a sed on them
# Do not quote the variables. This would defeat the trick.
DEBOOTSTRAP_LIST="$(echo ${DEBOOTSTRAP_LIST})"
PACKAGE_LIST="$(echo ${PACKAGE_LIST})"
PACKAGE_MAIN_LIST="$(echo ${PACKAGE_MAIN_LIST})"
fi
LOG_OUTPUT_FILE="$SRC/output/${LOG_SUBPATH}/debootstrap-list.log"
echo -e "\nVariables after manual configuration" >>$LOG_OUTPUT_FILE
show_checklist_variables "DEBOOTSTRAP_COMPONENTS DEBOOTSTRAP_LIST PACKAGE_LIST PACKAGE_MAIN_LIST"
unset LOG_OUTPUT_FILE
# Give the option to configure DNS server used in the chroot during the build process
[[ -z $NAMESERVER ]] && NAMESERVER="1.0.0.1" # default is cloudflare alternate
call_extension_method "post_aggregate_packages" "user_config_post_aggregate_packages" << 'POST_AGGREGATE_PACKAGES'
*For final user override, using a function, after all aggregations are done*
Called after aggregating all package lists, before the end of `compilation.sh`.
Packages will still be installed after this is called, so it is the last chance
to confirm or change any packages.
POST_AGGREGATE_PACKAGES
# debug
cat <<-EOF >> "${DEST}"/debug/output.log
cat <<-EOF >> "${DEST}"/${LOG_SUBPATH}/output.log
## BUILD SCRIPT ENVIRONMENT
Repository: $REPOSITORY_URL
Version: $REPOSITORY_COMMIT
Host OS: $(lsb_release -sc)
Host OS: $HOSTRELEASE
Host arch: $(dpkg --print-architecture)
Host system: $(uname -a)
Virtualization type: $(systemd-detect-virt)
@@ -347,6 +735,8 @@ Board: $BOARD
Branch: $BRANCH
Minimal: $BUILD_MINIMAL
Desktop: $BUILD_DESKTOP
Desktop Environment: $DESKTOP_ENVIRONMENT
Software groups: $DESKTOP_APPGROUPS_SELECTED
Kernel configuration:
Repository: $KERNELSOURCE
@@ -358,12 +748,9 @@ Repository: $BOOTSOURCE
Branch: $BOOTBRANCH
Config file: $BOOTCONFIG
Partitioning configuration:
Root partition type: $ROOTFS_TYPE
Boot partition type: ${BOOTFS_TYPE:-(none)}
User provided boot partition size: ${BOOTSIZE:-0}
Offset: $OFFSET
Partitioning configuration: $IMAGE_PARTITION_TABLE offset: $OFFSET
Boot partition type: ${BOOTFS_TYPE:-(none)} ${BOOTSIZE:+"(${BOOTSIZE} MB)"}
Root partition type: $ROOTFS_TYPE ${FIXED_IMAGE_SIZE:+"(${FIXED_IMAGE_SIZE} MB)"}
CPU configuration:
$CPUMIN - $CPUMAX with $GOVERNOR
CPU configuration: $CPUMIN - $CPUMAX with $GOVERNOR
EOF

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
@@ -8,6 +8,7 @@
# Functions:
# debootstrap_ng
# create_rootfs_cache
# prepare_partitions
@@ -16,11 +17,12 @@
# debootstrap_ng
#
debootstrap_ng()
{
display_alert "Starting rootfs and image building process for" "$BOARD $BRANCH $RELEASE" "info"
display_alert "Starting rootfs and image building process for" "${BRANCH} ${BOARD} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED:-null} ${DESKTOP_ENVIRONMENT:-null} ${BUILD_MINIMAL}" "info"
[[ $ROOTFS_TYPE != ext4 ]] && display_alert "Assuming $BOARD $BRANCH kernel supports $ROOTFS_TYPE" "" "wrn"
@@ -32,10 +34,9 @@ debootstrap_ng()
mkdir -p $SDCARD $MOUNT $DEST/images $EXTER/cache/rootfs
# stage: verify tmpfs configuration and mount
# default maximum size for tmpfs mount is 1/2 of available RAM
# CLI needs ~1.2GiB+ (Xenial CLI), Desktop - ~2.8GiB+ (Xenial Desktop w/o HW acceleration)
# calculate and set tmpfs mount to use 2/3 of available RAM
local phymem=$(( $(awk '/MemTotal/ {print $2}' /proc/meminfo) / 1024 * 2 / 3 )) # MiB
# CLI needs ~1.5GiB, desktop - ~3.5GiB
# calculate and set tmpfs mount to use 9/10 of available RAM+SWAP
local phymem=$(( (($(awk '/MemTotal/ {print $2}' /proc/meminfo) + $(awk '/SwapTotal/ {print $2}' /proc/meminfo))) / 1024 * 9 / 10 )) # MiB
if [[ $BUILD_DESKTOP == yes ]]; then local tmpfs_max_size=3500; else local tmpfs_max_size=1500; fi # MiB
if [[ $FORCE_USE_RAMDISK == no ]]; then local use_tmpfs=no
elif [[ $FORCE_USE_RAMDISK == yes || $phymem -gt $tmpfs_max_size ]]; then
@@ -48,6 +49,11 @@ debootstrap_ng()
# stage: prepare basic rootfs: unpack cache or create from scratch
create_rootfs_cache
call_extension_method "pre_install_distribution_specific" "config_pre_install_distribution_specific" << 'PRE_INSTALL_DISTRIBUTION_SPECIFIC'
*give config a chance to act before install_distribution_specific*
Called after `create_rootfs_cache` (_prepare basic rootfs: unpack cache or create from scratch_) but before `install_distribution_specific` (_install distribution and board specific applications_).
PRE_INSTALL_DISTRIBUTION_SPECIFIC
# stage: install kernel and u-boot packages
# install distribution and board specific applications
@@ -57,12 +63,19 @@ debootstrap_ng()
# install locally built packages or install pre-built packages from orangepi
[[ $EXTERNAL_NEW == compile || $EXTERNAL_NEW == prebuilt ]] && chroot_installpackages_local
## install from apt.armbian.com
#[[ $EXTERNAL_NEW == prebuilt ]] && chroot_installpackages "yes"
# stage: user customization script
# NOTE: installing too many packages may fill tmpfs mount
customize_image
# remove packages that are no longer needed. Since we have intrudoced uninstall feature, we might want to clean things that are no longer needed
display_alert "No longer needed packages" "purge" "info"
chroot $SDCARD /bin/bash -c "apt-get autoremove -y" >/dev/null 2>&1
# create list of installed packages for debug purposes
chroot $SDCARD /bin/bash -c "dpkg --get-selections" | grep -v deinstall | awk '{print $1}' | cut -f1 -d':' > $DEST/debug/installed-packages-${RELEASE}$([[ ${BUILD_MINIMAL} == yes ]] && echo "-minimal")$([[ ${BUILD_DESKTOP} == yes ]] && echo "-desktop").list 2>&1
chroot $SDCARD /bin/bash -c "dpkg --get-selections" | grep -v deinstall | awk '{print $1}' | cut -f1 -d':' > $DEST/${LOG_SUBPATH}/installed-packages-${RELEASE}$([[ ${BUILD_MINIMAL} == yes ]] && echo "-minimal")$([[ ${BUILD_DESKTOP} == yes ]] && echo "-desktop").list 2>&1
# clean up / prepare for making the image
umount_chroot "$SDCARD"
@@ -100,7 +113,10 @@ create_rootfs_cache()
{
local packages_hash=$(get_package_list_hash "$ROOTFSCACHE_VERSION")
local cache_type=$(if [[ ${BUILD_DESKTOP} == yes ]]; then echo "desktop"; elif [[ ${BUILD_MINIMAL} == yes ]]; then echo "minimal"; else echo "cli";fi)
local cache_type="cli"
[[ ${BUILD_DESKTOP} == yes ]] && local cache_type="xfce-desktop"
[[ -n ${DESKTOP_ENVIRONMENT} ]] && local cache_type="${DESKTOP_ENVIRONMENT}"
[[ ${BUILD_MINIMAL} == yes ]] && local cache_type="minimal"
local cache_name=${RELEASE}-${cache_type}-${ARCH}.$packages_hash.tar.lz4
local cache_fname=${EXTER}/cache/rootfs/${cache_name}
local display_name=${RELEASE}-${cache_type}-${ARCH}.${packages_hash:0:3}...${packages_hash:29}.tar.lz4
@@ -128,15 +144,23 @@ create_rootfs_cache()
# fancy progress bars
[[ -z $OUTPUT_DIALOG ]] && local apt_extra_progress="--show-progress -o DPKG::Progress-Fancy=1"
# Ok so for eval+PIPESTATUS.
# Try this on your bash shell:
# ONEVAR="testing" eval 'bash -c "echo value once $ONEVAR && false && echo value twice $ONEVAR"' '| grep value' '| grep value' ; echo ${PIPESTATUS[*]}
# Notice how PIPESTATUS has only one element. and it is always true, although we failed explicitly with false in the middle of the bash.
# That is because eval itself is considered a single command, no matter how many pipes you put in there, you'll get a single value, the return code of the LAST pipe.
# Lets export the value of the pipe inside eval so we know outside what happened:
# ONEVAR="testing" eval 'bash -e -c "echo value once $ONEVAR && false && echo value twice $ONEVAR"' '| grep value' '| grep value' ';EVALPIPE=(${PIPESTATUS[@]})' ; echo ${EVALPIPE[*]}
display_alert "Installing base system" "Stage 1/2" "info"
cd $SDCARD # this will prevent error sh: 0: getcwd() failed
eval 'debootstrap --variant=minbase --include=${DEBOOTSTRAP_LIST// /,} ${PACKAGE_LIST_EXCLUDE:+ --exclude=${PACKAGE_LIST_EXCLUDE// /,}} \
--arch=$ARCH --components=${DEBOOTSTRAP_COMPONENTS} --foreign $RELEASE $SDCARD/ $apt_mirror' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
--arch=$ARCH --components=${DEBOOTSTRAP_COMPONENTS} $DEBOOTSTRAP_OPTION --foreign $RELEASE $SDCARD/ $apt_mirror' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Debootstrap (stage 1/2)..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${PIPESTATUS[0]} -ne 0 || ! -f $SDCARD/debootstrap/debootstrap ]] && exit_with_error "Debootstrap base system first stage failed"
[[ ${EVALPIPE[0]} -ne 0 || ! -f $SDCARD/debootstrap/debootstrap ]] && exit_with_error "Debootstrap base system for ${BRANCH} ${BOARD} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL} first stage failed"
cp /usr/bin/$QEMU_BINARY $SDCARD/usr/bin/
@@ -144,19 +168,20 @@ create_rootfs_cache()
cp /usr/share/keyrings/*-archive-keyring.gpg $SDCARD/usr/share/keyrings/
display_alert "Installing base system" "Stage 2/2" "info"
eval 'chroot $SDCARD /bin/bash -c "/debootstrap/debootstrap --second-stage"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -e -c "/debootstrap/debootstrap --second-stage"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Debootstrap (stage 2/2)..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${PIPESTATUS[0]} -ne 0 || ! -f $SDCARD/bin/bash ]] && exit_with_error "Debootstrap base system second stage failed"
[[ ${EVALPIPE[0]} -ne 0 || ! -f $SDCARD/bin/bash ]] && exit_with_error "Debootstrap base system for ${BRANCH} ${BOARD} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL} second stage failed"
mount_chroot "$SDCARD"
display_alert "Diverting" "initctl/start-stop-daemon" "info"
# policy-rc.d script prevents starting or reloading services during image creation
printf '#!/bin/sh\nexit 101' > $SDCARD/usr/sbin/policy-rc.d
chroot $SDCARD /bin/bash -c "dpkg-divert --quiet --local --rename --add /sbin/initctl"
chroot $SDCARD /bin/bash -c "dpkg-divert --quiet --local --rename --add /sbin/start-stop-daemon"
LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "dpkg-divert --quiet --local --rename --add /sbin/initctl" &> /dev/null
LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "dpkg-divert --quiet --local --rename --add /sbin/start-stop-daemon" &> /dev/null
printf '#!/bin/sh\necho "Warning: Fake start-stop-daemon called, doing nothing"' > $SDCARD/sbin/start-stop-daemon
printf '#!/bin/sh\necho "Warning: Fake initctl called, doing nothing"' > $SDCARD/sbin/initctl
chmod 755 $SDCARD/usr/sbin/policy-rc.d
@@ -174,53 +199,114 @@ create_rootfs_cache()
if [[ -f $SDCARD/etc/default/console-setup ]]; then
sed -e 's/CHARMAP=.*/CHARMAP="UTF-8"/' -e 's/FONTSIZE=.*/FONTSIZE="8x16"/' \
-e 's/CODESET=.*/CODESET="guess"/' -i $SDCARD/etc/default/console-setup
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "setupcon --save"'
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "setupcon --save --force"'
fi
# stage: create apt-get sources list
create_sources_list "$RELEASE" "$SDCARD/"
# add armhf arhitecture to arm64
[[ $ARCH == arm64 ]] && eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "dpkg --add-architecture armhf"'
# add armhf arhitecture to arm64, unless configured not to do so.
if [[ "a${ARMHF_ARCH}" != "askip" ]]; then
[[ $ARCH == arm64 ]] && eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "dpkg --add-architecture armhf"'
fi
# this should fix resolvconf installation failure in some cases
chroot $SDCARD /bin/bash -c 'echo "resolvconf resolvconf/linkify-resolvconf boolean false" | debconf-set-selections'
# stage: update packages list
display_alert "Updating package list" "$RELEASE" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "apt-get -q -y $apt_extra update"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -e -c "apt-get -q -y $apt_extra update"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Updating package lists..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
#[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Updating package lists failed"
[[ ${EVALPIPE[0]} -ne 0 ]] && display_alert "Updating package lists" "failed" "wrn"
# stage: upgrade base packages from xxx-updates and xxx-backports repository branches
display_alert "Upgrading base packages" "Orange Pi" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -y -q \
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -e -c "DEBIAN_FRONTEND=noninteractive apt-get -y -q \
$apt_extra $apt_extra_progress upgrade"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Upgrading base packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Upgrading base packages failed"
# Myy: Dividing the desktop packages installation steps into multiple
# ones. We first install the "ADDITIONAL_PACKAGES" in order to get
# access to software-common-properties installation.
# THEN we add the APT sources and install the Desktop packages.
# TODO : Find a way to add APT sources WITHOUT software-common-properties
[[ ${EVALPIPE[0]} -ne 0 ]] && display_alert "Upgrading base packages" "failed" "wrn"
# stage: install additional packages
display_alert "Installing packages for" "Orange Pi" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -y -q \
$apt_extra $apt_extra_progress --no-install-recommends install $PACKAGE_LIST"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Installing Orange Pi system..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'}
display_alert "Installing the main packages for" "Orange Pi" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -e -c "DEBIAN_FRONTEND=noninteractive apt-get -y -q \
$apt_extra $apt_extra_progress --no-install-recommends install $PACKAGE_MAIN_LIST"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Installing Orange Pi main packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Installation of Orange Pi packages failed"
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Installation of Orange Pi main packages for ${BRANCH} ${BOARD} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL} failed"
if [[ $BUILD_DESKTOP == "yes" ]]; then
# FIXME Myy : Are we keeping this only for Desktop users,
# or should we extend this to CLI users too ?
# There might be some clunky boards that require Debian packages from
# specific repos...
display_alert "Adding apt sources for Desktop packages"
add_desktop_package_sources
local apt_desktop_install_flags=""
if [[ ! -z ${DESKTOP_APT_FLAGS_SELECTED+x} ]]; then
for flag in ${DESKTOP_APT_FLAGS_SELECTED}; do
apt_desktop_install_flags+=" --install-${flag}"
done
else
# Myy : Using the previous default option, if the variable isn't defined
# And ONLY if it's not defined !
apt_desktop_install_flags+=" --no-install-recommends"
fi
display_alert "Installing the desktop packages for" "Orange Pi" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -e -c "DEBIAN_FRONTEND=noninteractive apt-get -y -q \
$apt_extra $apt_extra_progress install ${apt_desktop_install_flags} $PACKAGE_LIST_DESKTOP"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Installing Orange Pi desktop packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${PIPESTATUS[0]} -ne 0 ]] && exit_with_error "Installation of Orange Pi desktop packages for ${BRANCH} ${BOARD} ${RELEASE} ${DESKTOP_APPGROUPS_SELECTED} ${DESKTOP_ENVIRONMENT} ${BUILD_MINIMAL} failed"
fi
# Remove packages from packages.uninstall
display_alert "Uninstall packages" "$PACKAGE_LIST_UNINSTALL" "info"
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -e -c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq \
$apt_extra $apt_extra_progress purge $PACKAGE_LIST_UNINSTALL"' \
${PROGRESS_LOG_TO_FILE:+' >> $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Removing packages.uninstall packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${EVALPIPE[0]} -ne 0 ]] && exit_with_error "Installation of Orange Pi packages failed"
# stage: purge residual packages
display_alert "Purging residual packages for" "Orange Pi" "info"
PURGINGPACKAGES=$(chroot $SDCARD /bin/bash -c "dpkg -l | grep \"^rc\" | awk '{print \$2}' | tr \"\n\" \" \"")
eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -e -c "DEBIAN_FRONTEND=noninteractive apt-get -y -q \
$apt_extra $apt_extra_progress remove --purge $PURGINGPACKAGES"' \
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/debootstrap.log'} \
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" --progressbox "Purging residual Orange Pi packages..." $TTY_Y $TTY_X'} \
${OUTPUT_VERYSILENT:+' >/dev/null 2>/dev/null'} ';EVALPIPE=(${PIPESTATUS[@]})'
[[ ${EVALPIPE[0]} -ne 0 ]] && exit_with_error "Purging of residual Orange Pi packages failed"
# stage: remove downloaded packages
chroot $SDCARD /bin/bash -c "apt clean"
chroot $SDCARD /bin/bash -c "apt-get -y autoremove; apt-get clean"
# DEBUG: print free space
#echo -e "\nFree space:"
#eval 'df -h' ${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'}
local freespace=$(LC_ALL=C df -h)
echo $freespace >> $DEST/${LOG_SUBPATH}/debootstrap.log
display_alert "Free SD cache" "$(echo -e "$freespace" | grep $SDCARD | awk '{print $5}')" "info"
display_alert "Mount point" "$(echo -e "$freespace" | grep $MOUNT | head -1 | awk '{print $5}')" "info"
# create list of installed packages for debug purposes
chroot $SDCARD /bin/bash -c "dpkg --get-selections" | grep -v deinstall | awk '{print $1}' | cut -f1 -d':' > ${cache_fname}.list 2>&1
@@ -228,7 +314,7 @@ create_rootfs_cache()
# creating xapian index that synaptic runs faster
if [[ $BUILD_DESKTOP == yes ]]; then
display_alert "Recreating Synaptic search index" "Please wait" "info"
chroot $SDCARD /bin/bash -c "/usr/sbin/update-apt-xapian-index -u"
chroot $SDCARD /bin/bash -c "[[ -f /usr/sbin/update-apt-xapian-index ]] && /usr/sbin/update-apt-xapian-index -u"
fi
# this is needed for the build process later since resolvconf generated file in /run is not saved
@@ -243,38 +329,31 @@ create_rootfs_cache()
umount_chroot "$SDCARD"
tar cp --xattrs --directory=$SDCARD/ --exclude='./dev/*' --exclude='./proc/*' --exclude='./run/*' --exclude='./tmp/*' \
--exclude='./sys/*' . | pv -p -b -r -s $(du -sb $SDCARD/ | cut -f1) -N "$display_name" | lz4 -c > $cache_fname
--exclude='./sys/*' --exclude='./home/*' --exclude='./root/*' . | pv -p -b -r -s $(du -sb $SDCARD/ | cut -f1) -N "$display_name" | lz4 -5 -c > $cache_fname
# sign rootfs cache archive that it can be used for web cache once. Internal purposes
if [[ -n $GPG_PASS ]]; then
echo $GPG_PASS | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes $cache_fname
if [[ -n "${GPG_PASS}" && "${SUDO_USER}" ]]; then
[[ -n ${SUDO_USER} ]] && sudo chown -R ${SUDO_USER}:${SUDO_USER} "${DEST}"/images/
echo "${GPG_PASS}" | sudo -H -u ${SUDO_USER} bash -c "gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes ${cache_fname}" || exit 1
fi
# needed for backend to keep current only
touch $cache_fname.current
fi
# used for internal purposes. Faster rootfs cache rebuilding
if [[ -n "$ROOT_FS_CREATE_ONLY" || $BUILD_OPT == rootfs ]]; then
[[ $use_tmpfs = yes ]] && umount $SDCARD
if [[ -n "$ROOT_FS_CREATE_ONLY" ]]; then
umount --lazy "$SDCARD"
rm -rf $SDCARD
if [[ -f "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid" ]];then
rm "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid"
fi
display_alert "Rootfs build done" "@host" "info"
display_alert "Target directory" "${EXTER}/cache/rootfs" "info"
display_alert "File name" "${cache_name}" "info"
end=$(date +%s)
runtime=$(((end-start)/60))
display_alert "Runtime" "$runtime min" "info"
display_alert "Repeat Build Options" "sudo ./build.sh ${BUILD_CONFIG} BOARD=${BOARD} BRANCH=${BRANCH} $([[ -n $BUILD_OPT ]] && echo "BUILD_OPT=${BUILD_OPT} ")$([[ -n $RELEASE ]] && echo "RELEASE=${RELEASE} ") $([[ -n $BUILD_MINIMAL ]] && echo "BUILD_MINIMAL=${BUILD_MINIMAL} ") $([[ -n $BUILD_DESKTOP ]] && echo "BUILD_DESKTOP=${BUILD_DESKTOP} ") $([[ -n $KERNEL_CONFIGURE ]] && echo "KERNEL_CONFIGURE=${KERNEL_CONFIGURE}") " "info"
# remove exit trap
trap - INT TERM EXIT
exit
exit
fi
mount_chroot "$SDCARD"
@@ -306,18 +385,23 @@ prepare_partitions()
parttype[fat]=fat16
parttype[f2fs]=ext4 # not a copy-paste error
parttype[btrfs]=btrfs
parttype[xfs]=xfs
# parttype[nfs] is empty
# metadata_csum and 64bit may need to be disabled explicitly when migrating to newer supported host OS releases
if [[ $(lsb_release -sc) =~ bionic|buster|bullseye|cosmic|eoan|focal ]]; then
mkopts[ext4]='-q -m 2 -O ^64bit,^metadata_csum'
elif [[ $(lsb_release -sc) == xenial ]]; then
mkopts[ext4]='-q -m 2'
# add -N number of inodes to keep mount from running out
# create bigger number for desktop builds
if [[ $BUILD_DESKTOP == yes ]]; then local node_number=4096; else local node_number=1024; fi
if [[ $HOSTRELEASE =~ bionic|buster|bullseye|bookworm|cosmic|focal|hirsute|impish|jammy|sid ]]; then
mkopts[ext4]="-q -m 2 -O ^64bit,^metadata_csum -N $((128*${node_number}))"
elif [[ $HOSTRELEASE == xenial ]]; then
mkopts[ext4]="-q -m 2 -N $((128*${node_number}))"
fi
mkopts[fat]='-n BOOT'
mkopts[ext2]='-q'
# mkopts[f2fs] is empty
mkopts[btrfs]='-m dup'
# mkopts[xfs] is empty
# mkopts[nfs] is empty
mkfs[ext4]=ext4
@@ -325,6 +409,7 @@ prepare_partitions()
mkfs[fat]=vfat
mkfs[f2fs]=f2fs
mkfs[btrfs]=btrfs
mkfs[xfs]=xfs
# mkfs[nfs] is empty
mountopts[ext4]=',commit=600,errors=remount-ro'
@@ -332,10 +417,21 @@ prepare_partitions()
# mountopts[fat] is empty
# mountopts[f2fs] is empty
mountopts[btrfs]=',commit=600'
# mountopts[xfs] is empty
# mountopts[nfs] is empty
# default BOOTSIZE to use if not specified
DEFAULT_BOOTSIZE=96 # MiB
DEFAULT_BOOTSIZE=256 # MiB
# size of UEFI partition. 0 for no UEFI. Don't mix UEFISIZE>0 and BOOTSIZE>0
UEFISIZE=${UEFISIZE:-0}
BIOSSIZE=${BIOSSIZE:-0}
UEFI_MOUNT_POINT=${UEFI_MOUNT_POINT:-/boot/efi}
UEFI_FS_LABEL="${UEFI_FS_LABEL:-armbiefi}"
call_extension_method "pre_prepare_partitions" "prepare_partitions_custom" <<'PRE_PREPARE_PARTITIONS'
*allow custom options for mkfs*
Good time to change stuff like mkfs opts, types etc.
PRE_PREPARE_PARTITIONS
# stage: determine partition configuration
if [[ -n $BOOTFS_TYPE ]]; then
@@ -361,6 +457,16 @@ prepare_partitions()
local bootpart=1
local rootpart=2
[[ -z $BOOTSIZE || $BOOTSIZE -le 8 ]] && BOOTSIZE=${DEFAULT_BOOTSIZE}
elif [[ $UEFISIZE -gt 0 ]]; then
if [[ "${IMAGE_PARTITION_TABLE}" == "gpt" ]]; then
# efi partition and ext4 root. some juggling is done by parted/sgdisk
local uefipart=15
local rootpart=1
else
# efi partition and ext4 root.
local uefipart=1
local rootpart=2
fi
else
# single partition ext4 root
local rootpart=1
@@ -368,8 +474,17 @@ prepare_partitions()
fi
# stage: calculate rootfs size
local rootfs_size=$(du -sm $SDCARD/ | cut -f1) # MiB
export rootfs_size=$(du -sm $SDCARD/ | cut -f1) # MiB
display_alert "Current rootfs size" "$rootfs_size MiB" "info"
call_extension_method "prepare_image_size" "config_prepare_image_size" << 'PREPARE_IMAGE_SIZE'
*allow dynamically determining the size based on the $rootfs_size*
Called after `${rootfs_size}` is known, but before `${FIXED_IMAGE_SIZE}` is taken into account.
A good spot to determine `FIXED_IMAGE_SIZE` based on `rootfs_size`.
UEFISIZE can be set to 0 for no UEFI partition, or to a size in MiB to include one.
Last chance to set `USE_HOOK_FOR_PARTITION`=yes and then implement create_partition_table hook_point.
PREPARE_IMAGE_SIZE
if [[ -n $FIXED_IMAGE_SIZE && $FIXED_IMAGE_SIZE =~ ^[0-9]+$ ]]; then
display_alert "Using user-defined image size" "$FIXED_IMAGE_SIZE MiB" "info"
local sdsize=$FIXED_IMAGE_SIZE
@@ -378,54 +493,91 @@ prepare_partitions()
exit_with_error "User defined image size is too small" "$sdsize <= $rootfs_size"
fi
else
local imagesize=$(( $rootfs_size + $OFFSET + $BOOTSIZE )) # MiB
case $ROOTFS_TYPE in
btrfs)
# Used for server images, currently no swap functionality, so disk space
if [[ $BTRFS_COMPRESSION == none ]]; then
local sdsize=$(bc -l <<< "scale=0; (($imagesize * 1.25) / 4 + 1) * 4")
else
# requirements are rather low since rootfs gets filled with compress-force=zlib
local sdsize=$(bc -l <<< "scale=0; (($imagesize * 0.8) / 4 + 1) * 4")
fi
;;
*)
# Hardcoded overhead +25% is needed for desktop images,
# for CLI it could be lower. Align the size up to 4MiB
if [[ $BUILD_DESKTOP == yes ]]; then
local sdsize=$(bc -l <<< "scale=0; ((($imagesize * 1.30) / 1 + 0) / 4 + 1) * 4")
else
local sdsize=$(bc -l <<< "scale=0; ((($imagesize * 1.25) / 1 + 0) / 4 + 1) * 4")
fi
;;
esac
local imagesize=$(( $rootfs_size + $OFFSET + $BOOTSIZE + $UEFISIZE + $EXTRA_ROOTFS_MIB_SIZE)) # MiB
# Hardcoded overhead +25% is needed for desktop images,
# for CLI it could be lower. Align the size up to 4MiB
if [[ $BUILD_DESKTOP == yes ]]; then
local sdsize=$(bc -l <<< "scale=0; ((($imagesize * 1.30) / 1 + 0) / 4 + 1) * 4")
else
local sdsize=$(bc -l <<< "scale=0; ((($imagesize * 1.25) / 1 + 0) / 4 + 1) * 4")
fi
fi
# stage: create blank image
display_alert "Creating blank image for rootfs" "$sdsize MiB" "info"
# truncate --size=${sdsize}M ${SDCARD}.raw # sometimes results in fs corruption, revert to previous know to work solution
dd if=/dev/zero bs=1M status=none count=$sdsize | pv -p -b -r -s $(( $sdsize * 1024 * 1024 )) -N "[ .... ] dd" | dd status=none of=${SDCARD}.raw
if [[ $FAST_CREATE_IMAGE == yes ]]; then
truncate --size=${sdsize}M ${SDCARD}.raw # sometimes results in fs corruption, revert to previous know to work solution
sync
else
dd if=/dev/zero bs=1M status=none count=$sdsize | pv -p -b -r -s $(( $sdsize * 1024 * 1024 )) -N "[ .... ] dd" | dd status=none of=${SDCARD}.raw
fi
# stage: calculate boot partition size
local bootstart=$(($OFFSET * 2048))
local rootstart=$(($bootstart + ($BOOTSIZE * 2048)))
local rootstart=$(($bootstart + ($BOOTSIZE * 2048) + ($UEFISIZE * 2048)))
local bootend=$(($rootstart - 1))
# stage: create partition table
display_alert "Creating partitions" "${bootfs:+/boot: $bootfs }root: $ROOTFS_TYPE" "info"
parted -s ${SDCARD}.raw -- mklabel ${IMAGE_PARTITION_TABLE}
if [[ $ROOTFS_TYPE == nfs ]]; then
if [[ "${USE_HOOK_FOR_PARTITION}" == "yes" ]]; then
call_extension_method "create_partition_table" <<- 'CREATE_PARTITION_TABLE'
*only called when USE_HOOK_FOR_PARTITION=yes to create the complete partition table*
Finally, we can get our own partition table. You have to partition ${SDCARD}.raw
yourself. Good luck.
CREATE_PARTITION_TABLE
elif [[ $ROOTFS_TYPE == nfs ]]; then
# single /boot partition
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s 100%
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s "100%"
elif [[ $UEFISIZE -gt 0 ]]; then
# uefi partition + root partition
if [[ "${IMAGE_PARTITION_TABLE}" == "gpt" ]]; then
if [[ ${BIOSSIZE} -gt 0 ]]; then
display_alert "Creating partitions" "BIOS+UEFI+rootfs" "info"
# UEFI + GPT automatically get a BIOS partition at 14, EFI at 15
local biosstart=$(($OFFSET * 2048))
local uefistart=$(($OFFSET * 2048 + ($BIOSSIZE * 2048)))
local rootstart=$(($uefistart + ($UEFISIZE * 2048) ))
local biosend=$(($uefistart - 1))
local uefiend=$(($rootstart - 1))
parted -s ${SDCARD}.raw -- mkpart bios fat32 ${biosstart}s ${biosend}s
parted -s ${SDCARD}.raw -- mkpart efi fat32 ${uefistart}s ${uefiend}s
parted -s ${SDCARD}.raw -- mkpart rootfs ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
# transpose so BIOS is in sda14; EFI is in sda15 and root in sda1; requires sgdisk, parted cant do numbers
sgdisk --transpose 1:14 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 1:14 FAILED"
sgdisk --transpose 2:15 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 2:15 FAILED"
sgdisk --transpose 3:1 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 3:1 FAILED"
# set the ESP (efi) flag on 15
parted -s ${SDCARD}.raw -- set 14 bios_grub on || echo "*** SETTING bios_grub ON 14 FAILED"
parted -s ${SDCARD}.raw -- set 15 esp on || echo "*** SETTING ESP ON 15 FAILED"
else
display_alert "Creating partitions" "UEFI+rootfs (no BIOS)" "info"
# Simple EFI + root partition on GPT, no BIOS.
parted -s ${SDCARD}.raw -- mkpart efi fat32 ${bootstart}s ${bootend}s
parted -s ${SDCARD}.raw -- mkpart rootfs ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
# transpose so EFI is in sda15 and root in sda1; requires sgdisk, parted cant do numbers
sgdisk --transpose 1:15 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 1:15 FAILED"
sgdisk --transpose 2:1 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 2:1 FAILED"
# set the ESP (efi) flag on 15
parted -s ${SDCARD}.raw -- set 15 esp on || echo "*** SETTING ESP ON 15 FAILED"
fi
else
parted -s ${SDCARD}.raw -- mkpart primary fat32 ${bootstart}s ${bootend}s
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
fi
elif [[ $BOOTSIZE == 0 ]]; then
# single root partition
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s 100%
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
else
# /boot partition + root partition
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s ${bootend}s
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s 100%
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
fi
call_extension_method "post_create_partitions" <<- 'POST_CREATE_PARTITIONS'
*called after all partitions are created, but not yet formatted*
POST_CREATE_PARTITIONS
# stage: mount image
# lock access to loop devices
exec {FD}>/var/lock/orangepi-debootstrap-losetup
@@ -436,7 +588,6 @@ prepare_partitions()
check_loop_device "$LOOP"
# NOTE: losetup -P option is not available in Trusty
losetup $LOOP ${SDCARD}.raw
# loop device was grabbed here, unlock
@@ -460,7 +611,7 @@ prepare_partitions()
check_loop_device "$rootdevice"
display_alert "Creating rootfs" "$ROOTFS_TYPE on $rootdevice"
mkfs.${mkfs[$ROOTFS_TYPE]} ${mkopts[$ROOTFS_TYPE]} $rootdevice
mkfs.${mkfs[$ROOTFS_TYPE]} ${mkopts[$ROOTFS_TYPE]} $rootdevice >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
[[ $ROOTFS_TYPE == ext4 ]] && tune2fs -o journal_data_writeback $rootdevice > /dev/null
if [[ $ROOTFS_TYPE == btrfs && $BTRFS_COMPRESSION != none ]]; then
local fscreateopt="-o compress-force=${BTRFS_COMPRESSION}"
@@ -474,19 +625,32 @@ prepare_partitions()
else
local rootfs="UUID=$(blkid -s UUID -o value $rootdevice)"
fi
echo "$rootfs / ${mkfs[$ROOTFS_TYPE]} defaults,noatime,nodiratime${mountopts[$ROOTFS_TYPE]} 0 1" >> $SDCARD/etc/fstab
echo "$rootfs / ${mkfs[$ROOTFS_TYPE]} defaults,noatime${mountopts[$ROOTFS_TYPE]} 0 1" >> $SDCARD/etc/fstab
fi
if [[ -n $bootpart ]]; then
display_alert "Creating /boot" "$bootfs"
display_alert "Creating /boot" "$bootfs on ${LOOP}p${bootpart}"
check_loop_device "${LOOP}p${bootpart}"
mkfs.${mkfs[$bootfs]} ${mkopts[$bootfs]} ${LOOP}p${bootpart}
mkfs.${mkfs[$bootfs]} ${mkopts[$bootfs]} ${LOOP}p${bootpart} >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
mkdir -p $MOUNT/boot/
mount ${LOOP}p${bootpart} $MOUNT/boot/
echo "UUID=$(blkid -s UUID -o value ${LOOP}p${bootpart}) /boot ${mkfs[$bootfs]} defaults${mountopts[$bootfs]} 0 2" >> $SDCARD/etc/fstab
fi
if [[ -n $uefipart ]]; then
display_alert "Creating EFI partition" "FAT32 ${UEFI_MOUNT_POINT} on ${LOOP}p${uefipart} label ${UEFI_FS_LABEL}"
check_loop_device "${LOOP}p${uefipart}"
mkfs.fat -F32 -n "${UEFI_FS_LABEL}" ${LOOP}p${uefipart} >>"${DEST}"/debug/install.log 2>&1
mkdir -p "${MOUNT}${UEFI_MOUNT_POINT}"
mount ${LOOP}p${uefipart} "${MOUNT}${UEFI_MOUNT_POINT}"
echo "UUID=$(blkid -s UUID -o value ${LOOP}p${uefipart}) ${UEFI_MOUNT_POINT} vfat defaults 0 2" >>$SDCARD/etc/fstab
fi
[[ $ROOTFS_TYPE == nfs ]] && echo "/dev/nfs / nfs defaults 0 0" >> $SDCARD/etc/fstab
echo "tmpfs /tmp tmpfs defaults,nosuid 0 0" >> $SDCARD/etc/fstab
call_extension_method "format_partitions" <<- 'FORMAT_PARTITIONS'
*if you created your own partitions, this would be a good time to format them*
The loop device is mounted, so ${LOOP}p1 is it's first partition etc.
FORMAT_PARTITIONS
# stage: adjust boot script or boot environment
if [[ -f $SDCARD/boot/orangepiEnv.txt ]]; then
if [[ $CRYPTROOT_ENABLE == yes ]]; then
@@ -520,13 +684,19 @@ prepare_partitions()
sed -i "s/console=.*/console=$DEFAULT_CONSOLE/" $SDCARD/boot/orangepiEnv.txt
else
echo "console=$DEFAULT_CONSOLE" >> $SDCARD/boot/orangepiEnv.txt
fi
fi
fi
# recompile .cmd to .scr if boot.cmd exists
[[ -f $SDCARD/boot/boot.cmd ]] && \
mkimage -C none -A arm -T script -d $SDCARD/boot/boot.cmd $SDCARD/boot/boot.scr > /dev/null 2>&1
# create extlinux config
if [[ -f $SDCARD/boot/extlinux/extlinux.conf ]]; then
echo " append root=$rootfs $SRC_CMDLINE $MAIN_CMDLINE" >> $SDCARD/boot/extlinux/extlinux.conf
[[ -f $SDCARD/boot/orangepiEnv.txt ]] && rm $SDCARD/boot/orangepiEnv.txt
fi
} #############################################################################
# update_initramfs
@@ -546,13 +716,26 @@ prepare_partitions()
update_initramfs()
{
local chroot_target=$1
update_initramfs_cmd="update-initramfs -uv -k ${VER}-${LINUXFAMILY}"
local target_dir=$(
find ${chroot_target}/lib/modules/ -maxdepth 1 -type d -name "*${VER}*"
)
if [ "$target_dir" != "" ]; then
update_initramfs_cmd="update-initramfs -uv -k $(basename $target_dir)"
else
exit_with_error "No kernel installed for the version" "${VER}"
fi
display_alert "Updating initramfs..." "$update_initramfs_cmd" ""
cp /usr/bin/$QEMU_BINARY $chroot_target/usr/bin/
mount_chroot "$chroot_target/"
chroot $chroot_target /bin/bash -c "$update_initramfs_cmd" >> $DEST/debug/install.log 2>&1
display_alert "Updated initramfs." "for details see: $DEST/debug/install.log" "ext"
chroot $chroot_target /bin/bash -c "$update_initramfs_cmd" >> $DEST/${LOG_SUBPATH}/install.log 2>&1 || {
display_alert "Updating initramfs FAILED, see:" "$DEST/${LOG_SUBPATH}/install.log" "err"
exit 23
}
display_alert "Updated initramfs." "for details see: $DEST/${LOG_SUBPATH}/install.log" "info"
display_alert "Re-enabling" "initramfs-tools hook for kernel"
chroot $chroot_target /bin/bash -c "chmod -v +x /etc/kernel/postinst.d/initramfs-tools" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
umount_chroot "$chroot_target/"
rm $chroot_target/usr/bin/$QEMU_BINARY
@@ -566,9 +749,7 @@ update_initramfs()
create_image()
{
# stage: create file name
local version="${BOARD^}_${REVISION}_${DISTRIBUTION,}_${RELEASE}_${IMAGETYPE}_linux"$(grab_version "$LINUXSOURCEDIR")""
[[ $BUILD_MINIMAL == yes ]] && version=${version}_minimal
local version="${BOARD^}_${REVISION}_${DISTRIBUTION,}_${RELEASE}_linux"$(grab_version "$LINUXSOURCEDIR")"${DESKTOP_ENVIRONMENT:+_$DESKTOP_ENVIRONMENT}_${SELECTED_CONFIGURATION}"
[[ $ROOTFS_TYPE == nfs ]] && version=${version}_nfsboot
destimg=$DEST/images/${version}
@@ -576,9 +757,16 @@ create_image()
mkdir -p $destimg
if [[ $ROOTFS_TYPE != nfs ]]; then
display_alert "Copying files to root directory"
rsync -aHWXh --exclude="/boot/*" --exclude="/dev/*" --exclude="/proc/*" --exclude="/run/*" --exclude="/tmp/*" \
--exclude="/sys/*" --info=progress2,stats1 $SDCARD/ $MOUNT/
display_alert "Copying files to" "/"
echo -e "\nCopying files to [/]" >>"${DEST}"/${LOG_SUBPATH}/install.log
rsync -aHWXh \
--exclude="/boot/*" \
--exclude="/dev/*" \
--exclude="/proc/*" \
--exclude="/run/*" \
--exclude="/tmp/*" \
--exclude="/sys/*" \
--info=progress0,stats1 $SDCARD/ $MOUNT/ >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
else
display_alert "Creating rootfs archive" "rootfs.tgz" "info"
tar cp --xattrs --directory=$SDCARD/ --exclude='./boot/*' --exclude='./dev/*' --exclude='./proc/*' --exclude='./run/*' --exclude='./tmp/*' \
@@ -586,21 +774,35 @@ create_image()
fi
# stage: rsync /boot
display_alert "Copying files to /boot directory"
display_alert "Copying files to" "/boot"
echo -e "\nCopying files to [/boot]" >>"${DEST}"/${LOG_SUBPATH}/install.log
if [[ $(findmnt --target $MOUNT/boot -o FSTYPE -n) == vfat ]]; then
# fat32
rsync -rLtWh --info=progress2,stats1 $SDCARD/boot $MOUNT
rsync -rLtWh \
--info=progress0,stats1 \
--log-file="${DEST}"/${LOG_SUBPATH}/install.log $SDCARD/boot $MOUNT
else
# ext4
rsync -aHWXh --info=progress2,stats1 $SDCARD/boot $MOUNT
rsync -aHWXh \
--info=progress0,stats1 \
--log-file="${DEST}"/${LOG_SUBPATH}/install.log $SDCARD/boot $MOUNT
fi
call_extension_method "pre_update_initramfs" "config_pre_update_initramfs" << 'PRE_UPDATE_INITRAMFS'
*allow config to hack into the initramfs create process*
Called after rsync has synced both `/root` and `/root` on the target, but before calling `update_initramfs`.
PRE_UPDATE_INITRAMFS
# stage: create final initramfs
[[ $ROOTFS_TYPE != nfs ]] && update_initramfs $MOUNT
[[ -n $KERNELSOURCE ]] && {
update_initramfs $MOUNT
}
# DEBUG: print free space
#display_alert "Free space:" "SD card" "info"
#eval 'df -h' ${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/debug/debootstrap.log'}
local freespace=$(LC_ALL=C df -h)
echo $freespace >> $DEST/${LOG_SUBPATH}/debootstrap.log
display_alert "Free SD cache" "$(echo -e "$freespace" | grep $SDCARD | awk '{print $5}')" "info"
display_alert "Mount point" "$(echo -e "$freespace" | grep $MOUNT | head -1 | awk '{print $5}')" "info"
# stage: write u-boot
write_uboot $LOOP
@@ -608,26 +810,43 @@ create_image()
# fix wrong / permissions
chmod 755 $MOUNT
# unmount /boot first, rootfs second, image file last
call_extension_method "pre_umount_final_image" "config_pre_umount_final_image" << 'PRE_UMOUNT_FINAL_IMAGE'
*allow config to hack into the image before the unmount*
Called before unmounting both `/root` and `/boot`.
PRE_UMOUNT_FINAL_IMAGE
# unmount /boot/efi first, then /boot, rootfs third, image file last
sync
[[ $UEFISIZE != 0 ]] && umount -l "${MOUNT}${UEFI_MOUNT_POINT}"
[[ $BOOTSIZE != 0 ]] && umount -l $MOUNT/boot
[[ $ROOTFS_TYPE != nfs ]] && umount -l $MOUNT
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose $ROOT_MAPPER
call_extension_method "post_umount_final_image" "config_post_umount_final_image" << 'POST_UMOUNT_FINAL_IMAGE'
*allow config to hack into the image after the unmount*
Called after unmounting both `/root` and `/boot`.
POST_UMOUNT_FINAL_IMAGE
# to make sure its unmounted
while grep -Eq '(${MOUNT}|${DESTIMG})' /proc/mounts
do
display_alert "Unmounting" "${MOUNT}" "info"
display_alert "Wait for unmount" "${MOUNT}" "info"
sleep 5
done
losetup -d $LOOP
rm -rf --one-file-system $DESTIMG $MOUNT
mv ${SDCARD}.raw $destimg/${version}.img
mkdir -p $DESTIMG
mv ${SDCARD}.raw $DESTIMG/${version}.img
FINALDEST=${destimg}
# custom post_build_image_modify hook to run before fingerprinting and compression
[[ $(type -t post_build_image_modify) == function ]] && display_alert "Custom Hook Detected" "post_build_image_modify" "info" && post_build_image_modify "${DESTIMG}/${version}.img"
if [[ $BUILD_ALL != yes ]]; then
if [[ $COMPRESS_OUTPUTIMAGE == "" || $COMPRESS_OUTPUTIMAGE == no ]]; then
COMPRESS_OUTPUTIMAGE="sha,gpg,img"
elif [[ $COMPRESS_OUTPUTIMAGE == yes ]]; then
@@ -635,76 +854,104 @@ create_image()
fi
if [[ $COMPRESS_OUTPUTIMAGE == *gz* ]]; then
display_alert "Compressing" "$destimg/${version}.img.gz" "info"
pigz -3 < $destimg/${version}.img > $destimg/${version}.img.gz
display_alert "Compressing" "${DESTIMG}/${version}.img.gz" "info"
pigz -3 < $DESTIMG/${version}.img > $DESTIMG/${version}.img.gz
compression_type=".gz"
fi
if [[ $COMPRESS_OUTPUTIMAGE == *xz* ]]; then
display_alert "Compressing" "$destimg/${version}.img.xz" "info"
pixz -3 < $destimg/${version}.img > $destimg/${version}.img.xz
display_alert "Compressing" "${DESTIMG}/${version}.img.xz" "info"
# compressing consumes a lot of memory we don't have. Waiting for previous packing job to finish helps to run a lot more builds in parallel
available_cpu=$(grep -c 'processor' /proc/cpuinfo)
[[ ${BUILD_ALL} == yes ]] && available_cpu=$(( $available_cpu * 30 / 100 )) # lets use 20% of resources in case of build-all
[[ ${available_cpu} -gt 8 ]] && available_cpu=8 # using more cpu cores for compressing is pointless
available_mem=$(LC_ALL=c free | grep Mem | awk '{print $4/$2 * 100.0}' | awk '{print int($1)}') # in percentage
# build optimisations when memory drops below 5%
if [[ ${BUILD_ALL} == yes && ( ${available_mem} -lt 15 || $(ps -uax | grep "pixz" | wc -l) -gt 4 )]]; then
while [[ $(ps -uax | grep "pixz" | wc -l) -gt 2 ]]
do echo -en "#"
sleep 20
done
fi
pixz -7 -p ${available_cpu} -f $(expr ${available_cpu} + 2) < $DESTIMG/${version}.img > ${DESTIMG}/${version}.img.xz
compression_type=".xz"
fi
if [[ $COMPRESS_OUTPUTIMAGE == *img* || $COMPRESS_OUTPUTIMAGE == *7z* ]]; then
compression_type=""
fi
if [[ $COMPRESS_OUTPUTIMAGE == *img* || $COMPRESS_OUTPUTIMAGE == *7z* ]]; then
# mv $DESTIMG/${version}.img ${FINALDEST}/${version}.img || exit 1
compression_type=""
fi
if [[ $COMPRESS_OUTPUTIMAGE == *sha* ]]; then
cd $destimg
cd ${DESTIMG}
display_alert "SHA256 calculating" "${version}.img${compression_type}" "info"
sha256sum -b ${version}.img${compression_type} > ${version}.img${compression_type}.sha
fi
if [[ $COMPRESS_OUTPUTIMAGE == *gpg* ]]; then
cd $destimg
cd ${DESTIMG}
if [[ -n $GPG_PASS ]]; then
display_alert "GPG signing" "${version}.img${compression_type}" "info"
echo $GPG_PASS | gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes $destimg/${version}.img${compression_type} || exit 1
[[ -n ${SUDO_USER} ]] && sudo chown -R ${SUDO_USER}:${SUDO_USER} "${DESTIMG}"/
echo "${GPG_PASS}" | sudo -H -u ${SUDO_USER} bash -c "gpg --passphrase-fd 0 --armor --detach-sign --pinentry-mode loopback --batch --yes ${DESTIMG}/${version}.img${compression_type}" || exit 1
else
display_alert "GPG signing skipped - no GPG_PASS" "${version}.img" "wrn"
fi
fi
#fingerprint_image "$destimg/${version}.img${compression_type}.txt" "${version}"
#fingerprint_image "${DESTIMG}/${version}.img${compression_type}.txt" "${version}"
if [[ $COMPRESS_OUTPUTIMAGE == *7z* ]]; then
display_alert "Compressing" "$destimg/${version}.7z" "info"
display_alert "Compressing" "${DESTIMG}/${version}.7z" "info"
7za a -t7z -bd -m0=lzma2 -mx=3 -mfb=64 -md=32m -ms=on \
$destimg/${version}.7z ${version}.key ${version}.img{,.sha,.txt} >/dev/null 2>&1
#find $destimg/ -type \
#f \( -name "${version}.img" -o -name "${version}.img.asc" -o -name "${version}.img.txt" -o -name "${version}.img.sha" \) -print0 \
#| xargs -0 rm >/dev/null 2>&1
${DESTIMG}/${version}.7z ${version}.key ${version}.img* >/dev/null 2>&1
find ${DESTIMG}/ -type \
f \( -name "${version}.img" -o -name "${version}.img.asc" -o -name "${version}.img.txt" -o -name "${version}.img.sha" \) -print0 \
>/dev/null 2>&1
fi
fi
display_alert "Done building" "$destimg/${version}.img" "info"
#display_alert "Done building" "${DESTIMG}/${version}.img" "info"
display_alert "Done building" "${FINALDEST}/${version}.img" "info"
# call custom post build hook
[[ $(type -t post_build_image) == function ]] && post_build_image "$destimg/${version}.img"
[[ $(type -t post_build_image) == function ]] && post_build_image "${DESTIMG}/${version}.img"
# move artefacts from temporally directory to its final destination
[[ -n $compression_type ]] && rm $DESTIMG/${version}.img
mv $DESTIMG/${version}* ${FINALDEST}
rm -rf $DESTIMG
# write image to SD card
if [[ $(lsblk "$CARD_DEVICE" 2>/dev/null) && -f $destimg/${version}.img ]]; then
if [[ $(lsblk "$CARD_DEVICE" 2>/dev/null) && -f ${FINALDEST}/${version}.img ]]; then
# make sha256sum if it does not exists. we need it for comparisson
if [[ -f "$destimg/${version}".img.sha ]]; then
local ifsha=$(cat $destimg/${version}.img.sha | awk '{print $1}')
if [[ -f "${FINALDEST}/${version}".img.sha ]]; then
local ifsha=$(cat ${FINALDEST}/${version}.img.sha | awk '{print $1}')
else
local ifsha=$(sha256sum -b "$destimg/${version}".img | awk '{print $1}')
local ifsha=$(sha256sum -b "${FINALDEST}/${version}".img | awk '{print $1}')
fi
display_alert "Writing image" "$CARD_DEVICE ${readsha}" "info"
# write to SD card
pv -p -b -r -c -N "[ .... ] dd" $destimg/${version}.img | dd of=$CARD_DEVICE bs=1M iflag=fullblock oflag=direct status=none
pv -p -b -r -c -N "[ .... ] dd" ${FINALDEST}/${version}.img | dd of=$CARD_DEVICE bs=1M iflag=fullblock oflag=direct status=none
# read and compare
display_alert "Verifying. Please wait!"
local ofsha=$(dd if=$CARD_DEVICE count=$(du -b $destimg/${version}.img | cut -f1) status=none iflag=count_bytes oflag=direct | sha256sum | awk '{print $1}')
if [[ $ifsha == $ofsha ]]; then
display_alert "Writing verified" "${version}.img" "info"
else
display_alert "Writing failed" "${version}.img" "err"
call_extension_method "post_write_sdcard" <<- 'POST_BUILD_IMAGE'
*run after writing img to sdcard*
After the image is written to `$CARD_DEVICE`, but before verifying it.
You can still set SKIP_VERIFY=yes to skip verification.
POST_BUILD_IMAGE
if [[ "${SKIP_VERIFY}" != "yes" ]]; then
# read and compare
display_alert "Verifying. Please wait!"
local ofsha=$(dd if=$CARD_DEVICE count=$(du -b ${FINALDEST}/${version}.img | cut -f1) status=none iflag=count_bytes oflag=direct | sha256sum | awk '{print $1}')
if [[ $ifsha == $ofsha ]]; then
display_alert "Writing verified" "${version}.img" "info"
else
display_alert "Writing failed" "${version}.img" "err"
fi
fi
elif [[ `systemd-detect-virt` == 'docker' && -n $CARD_DEVICE ]]; then
# display warning when we want to write sd card under Docker

View File

@@ -1,26 +1,53 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Functions:
# create_desktop_package
# install_ppa_prerequisites
# add_apt_sources
# add_desktop_package_sources
# desktop_postinstall
create_desktop_package ()
{
# join and cleanup package list
PACKAGE_LIST_DESKTOP+=" "${PACKAGE_LIST_DESKTOP_RECOMMENDS}
PACKAGE_LIST_DESKTOP=${PACKAGE_LIST_DESKTOP// /,};
PACKAGE_LIST_DESKTOP=${PACKAGE_LIST_DESKTOP//[[:space:]]/}
echo "Showing PACKAGE_LIST_DESKTOP before postprocessing" >> "${DEST}"/${LOG_SUBPATH}/output.log
# Use quotes to show leading and trailing spaces
echo "\"$PACKAGE_LIST_DESKTOP\"" >> "${DEST}"/${LOG_SUBPATH}/output.log
# Remove leading and trailing spaces with some bash monstruosity
# https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable#12973694
DEBIAN_RECOMMENDS="${PACKAGE_LIST_DESKTOP#"${PACKAGE_LIST_DESKTOP%%[![:space:]]*}"}"
DEBIAN_RECOMMENDS="${DEBIAN_RECOMMENDS%"${DEBIAN_RECOMMENDS##*[![:space:]]}"}"
# Replace whitespace characters by commas
DEBIAN_RECOMMENDS=${DEBIAN_RECOMMENDS// /,};
# Remove others 'spacing characters' (like tabs)
DEBIAN_RECOMMENDS=${DEBIAN_RECOMMENDS//[[:space:]]/}
echo "DEBIAN_RECOMMENDS : ${DEBIAN_RECOMMENDS}" >> "${DEST}"/${LOG_SUBPATH}/output.log
# Replace whitespace characters by commas
PACKAGE_LIST_PREDEPENDS=${PACKAGE_LIST_PREDEPENDS// /,};
# Remove others 'spacing characters' (like tabs)
PACKAGE_LIST_PREDEPENDS=${PACKAGE_LIST_PREDEPENDS//[[:space:]]/}
local destination=${SRC}/.tmp/${RELEASE}/${BOARD}/${CHOSEN_DESKTOP}_${REVISION}_all
local destination tmp_dir
tmp_dir=$(mktemp -d)
destination=${tmp_dir}/${BOARD}/${CHOSEN_DESKTOP}_${REVISION}_all
rm -rf "${destination}"
mkdir -p "${destination}"/DEBIAN
echo "${PACKAGE_LIST_PREDEPENDS}" >> "${DEST}"/${LOG_SUBPATH}/output.log
# set up control file
cat <<-EOF > "${destination}"/DEBIAN/control
Package: ${CHOSEN_DESKTOP}
@@ -30,109 +57,219 @@ create_desktop_package ()
Installed-Size: 1
Section: xorg
Priority: optional
Recommends: ${PACKAGE_LIST_DESKTOP//[:space:]+/,}
Provides: ${CHOSEN_DESKTOP}
Recommends: ${DEBIAN_RECOMMENDS//[:space:]+/,}, orangepi-bsp-desktop
Provides: ${CHOSEN_DESKTOP}, orangepi-${RELEASE}-desktop
Pre-Depends: ${PACKAGE_LIST_PREDEPENDS//[:space:]+/,}
Description: Orange Pi desktop for ${DISTRIBUTION} ${RELEASE}
EOF
cat <<-EOF > "${destination}"/DEBIAN/postinst
#!/bin/sh -e
# Recreating the DEBIAN/postinst file
echo "#!/bin/sh -e" > "${destination}/DEBIAN/postinst"
# overwrite stock chromium and firefox configuration
if [ -d /etc/chromium-browser/ ]; then ln -sf /etc/orangepi/chromium.conf /etc/chromium-browser/default; fi
if [ -d /etc/chromium.d/ ]; then ln -sf /etc/orangepi/chromium.conf /etc/chromium.d/chromium.conf; fi
cp -R /etc/orangepi/chromium /usr/share
# overwrite stock lightdm greeter configuration
if [ -d /etc/orangepi/lightdm ]; then cp -R /etc/orangepi/lightdm /etc/; fi
local aggregated_content=""
aggregate_all_desktop "debian/postinst" $'\n'
echo "${aggregated_content}" >> "${destination}/DEBIAN/postinst"
echo "exit 0" >> "${destination}/DEBIAN/postinst"
if [ -d /usr/lib/firefox-esr/ ]; then
ln -sf /etc/orangepi/firefox.conf /usr/lib/firefox-esr/mozilla.cfg
echo 'pref("general.config.obscure_value", 0);' > /usr/lib/firefox-esr/defaults/pref/local-settings.js
echo 'pref("general.config.filename", "mozilla.cfg");' >> /usr/lib/firefox-esr/defaults/pref/local-settings.js
fi
# Adjust menu
#if [ -f /etc/xdg/menus/xfce-applications.menu ]; then
#sed -i -n '/<Menuname>Settings<\/Menuname>/{p;:a;N;/<Filename>xfce4-session-logout.desktop<\/Filename>/!ba;s/.*\n/\
#\t<Separator\/>\n\t<Merge type="all"\/>\n <Separator\/>\n <Filename>orangepi-donate.desktop<\/Filename>\
#\n <Filename>orangepi-support.desktop<\/Filename>\n/};p' /etc/xdg/menus/xfce-applications.menu
#fi
# Hide few items
if [ -f /usr/share/applications/display-im6.q16.desktop ]; then mv /usr/share/applications/display-im6.q16.desktop /usr/share/applications/display-im6.q16.desktop.hidden; fi
if [ -f /usr/share/applications/display-im6.desktop ]]; then mv /usr/share/applications/display-im6.desktop /usr/share/applications/display-im6.desktop.hidden; fi
if [ -f /usr/share/applications/vim.desktop ]]; then mv /usr/share/applications/vim.desktop /usr/share/applications/vim.desktop.hidden; fi
if [ -f /usr/share/applications/libreoffice-startcenter.desktop ]]; then mv /usr/share/applications/libreoffice-startcenter.desktop /usr/share/applications/libreoffice-startcenter.desktop.hidden; fi
# Disable Pulseaudio timer scheduling which does not work with sndhdmi driver
if [ -f /etc/pulse/default.pa ]; then sed "s/load-module module-udev-detect$/& tsched=0/g" -i /etc/pulse/default.pa; fi
exit 0
EOF
chmod 755 "${destination}"/DEBIAN/postinst
# add loading desktop splash service
mkdir -p "${destination}"/etc/systemd/system/
cp "${EXTER}"/packages/blobs/desktop/desktop-splash/desktop-splash.service "${destination}"/etc/systemd/system/desktop-splash.service
#display_alert "Showing ${destination}/DEBIAN/postinst"
cat "${destination}/DEBIAN/postinst" >> "${DEST}"/${LOG_SUBPATH}/install.log
# OrangePi create_desktop_package scripts
unset aggregated_content
# install optimized browser configurations
mkdir -p "${destination}"/etc/orangepi
cp "${EXTER}"/packages/blobs/desktop/chromium.conf "${destination}"/etc/orangepi
cp "${EXTER}"/packages/blobs/desktop/firefox.conf "${destination}"/etc/orangepi
cp -R "${EXTER}"/packages/blobs/desktop/chromium "${destination}"/etc/orangepi
# install lightdm greeter
cp -R "${EXTER}"/packages/blobs/desktop/lightdm "${destination}"/etc/orangepi
local aggregated_content=""
aggregate_all_desktop "orangepi/create_desktop_package.sh" $'\n'
eval "${aggregated_content}"
[[ $? -ne 0 ]] && display_alert "create_desktop_package.sh exec error" "" "wrn"
# install default desktop settings
mkdir -p "${destination}"/etc/skel
cp -R "${EXTER}"/packages/blobs/desktop/skel/. "${destination}"/etc/skel
# using different icon pack. Workaround due to this bug https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=867779
if [[ ${RELEASE} == bionic || ${RELEASE} == stretch || ${RELEASE} == buster || ${RELEASE} == bullseye || ${RELEASE} == focal || ${RELEASE} == eoan ]]; then
sed -i 's/<property name="IconThemeName" type="string" value=".*$/<property name="IconThemeName" type="string" value="LoginIcons"\/>/g' \
"${destination}"/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xsettings.xml
fi
# install dedicated startup icons
mkdir -p "${destination}"/usr/share/pixmaps "${destination}"/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/
cp "${EXTER}/packages/blobs/desktop/icons/${DISTRIBUTION,,}.png" "${destination}"/usr/share/pixmaps
sed 's/xenial.png/'"${DISTRIBUTION,,}"'.png/' -i "${destination}"/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml
# install logo for login screen
cp "${EXTER}"/packages/blobs/desktop/icons/orangepi.png "${destination}"/usr/share/pixmaps
# install wallpapers
mkdir -p "${destination}"/usr/share/backgrounds/xfce/
cp "${EXTER}"/packages/blobs/desktop/wallpapers/orangepi*.jpg "${destination}"/usr/share/backgrounds/xfce/
# create board DEB file
display_alert "Building desktop package" "${CHOSEN_DESKTOP}_${REVISION}_all" "info"
fakeroot dpkg-deb -b "${destination}" "${destination}.deb" >/dev/null
mkdir -p "${DEB_STORAGE}/${RELEASE}"
mv "${destination}.deb" "${DEB_STORAGE}/${RELEASE}"
cd "${destination}"; cd ..
fakeroot dpkg-deb -b -Z${DEB_COMPRESS} "${destination}" "${DEB_STORAGE}/${RELEASE}/${CHOSEN_DESKTOP}_${REVISION}_all.deb" >/dev/null
# cleanup
rm -rf "${destination}"
rm -rf "${tmp_dir}"
unset aggregated_content
}
create_bsp_desktop_package ()
{
display_alert "Creating board support package for desktop" "${package_name}" "info"
local package_name="${BSP_DESKTOP_PACKAGE_FULLNAME}"
local destination tmp_dir
tmp_dir=$(mktemp -d)
destination=${tmp_dir}/${BOARD}/${BSP_DESKTOP_PACKAGE_FULLNAME}
rm -rf "${destination}"
mkdir -p "${destination}"/DEBIAN
copy_all_packages_files_for "bsp-desktop"
# set up control file
cat <<-EOF > "${destination}"/DEBIAN/control
Package: orangepi-bsp-desktop-${BOARD}
Version: $REVISION
Architecture: $ARCH
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
Installed-Size: 1
Section: xorg
Priority: optional
Provides: orangepi-bsp-desktop, orangepi-bsp-desktop-${BOARD}
Depends: ${BSP_CLI_PACKAGE_NAME}
Description: Orange Pi Board Specific Packages for desktop users using $ARCH ${BOARD} machines
EOF
# Recreating the DEBIAN/postinst file
echo "#!/bin/sh -e" > "${destination}/DEBIAN/postinst"
local aggregated_content=""
aggregate_all_desktop "debian/orangepi-bsp-desktop/postinst" $'\n'
echo "${aggregated_content}" >> "${destination}/DEBIAN/postinst"
echo "exit 0" >> "${destination}/DEBIAN/postinst"
chmod 755 "${destination}"/DEBIAN/postinst
# Orange Pi create_desktop_package scripts
unset aggregated_content
mkdir -p "${destination}"/etc/orangepi
local aggregated_content=""
aggregate_all_desktop "debian/orangepi-bsp-desktop/prepare.sh" $'\n'
eval "${aggregated_content}"
[[ $? -ne 0 ]] && display_alert "prepare.sh exec error" "" "wrn"
mkdir -p "${DEB_STORAGE}/${RELEASE}"
cd "${destination}"; cd ..
fakeroot dpkg-deb -b "${destination}" "${DEB_STORAGE}/${RELEASE}/${package_name}.deb" >/dev/null
# cleanup
rm -rf "${tmp_dir}"
unset aggregated_content
}
install_ppa_prerequisites() {
# Myy : So... The whole idea is that, a good bunch of external sources
# are PPA.
# Adding PPA without add-apt-repository is poorly conveninent since
# you need to reconstruct the URL by hand, and find the GPG key yourself.
# add-apt-repository does that automatically, and in a way that allows you
# to remove it cleanly through the same tool.
# Myy : TODO Try to find a way to install this package only when
# we encounter a PPA.
run_on_sdcard "DEBIAN_FRONTEND=noninteractive apt-get install -yqq software-properties-common"
}
add_apt_sources() {
local potential_paths=""
local sub_dirs_to_check=". "
if [[ ! -z "${SELECTED_CONFIGURATION+x}" ]]; then
sub_dirs_to_check+="config_${SELECTED_CONFIGURATION}"
fi
get_all_potential_paths "${DEBOOTSTRAP_SEARCH_RELATIVE_DIRS}" "${sub_dirs_to_check}" "sources/apt"
get_all_potential_paths "${CLI_SEARCH_RELATIVE_DIRS}" "${sub_dirs_to_check}" "sources/apt"
get_all_potential_paths "${DESKTOP_ENVIRONMENTS_SEARCH_RELATIVE_DIRS}" "." "sources/apt"
get_all_potential_paths "${DESKTOP_APPGROUPS_SEARCH_RELATIVE_DIRS}" "${DESKTOP_APPGROUPS_SELECTED}" "sources/apt"
display_alert "ADDING ADDITIONAL APT SOURCES"
for apt_sources_dirpath in ${potential_paths}; do
if [[ -d "${apt_sources_dirpath}" ]]; then
for apt_source_filepath in "${apt_sources_dirpath}/"*.source; do
local new_apt_source="$(cat "${apt_source_filepath}")"
display_alert "Adding APT Source ${new_apt_source}"
# -y -> Assumes yes to all queries
# -n -> Do not update package cache after adding
run_on_sdcard "add-apt-repository -y -n \"${new_apt_source}\""
display_alert "Return code : $?"
# temporally exception for jammy
[[ $RELEASE == "jammy" ]] && find "${SDCARD}/etc/apt/sources.list.d/." -type f \( -name "*.list" ! -name "armbian.list" \) -print0 | xargs -0 sed -i 's/jammy/hirsute/g'
local apt_source_gpg_filepath="${apt_source_filepath}.gpg"
# PPA provide GPG keys automatically, it seems.
# But other repositories (Docker for example) require the
# user to import GPG keys manually
# Myy : FIXME We need some automatic Git warnings when someone
# add a GPG key, since trusting the wrong keys could lead to
# serious issues.
if [[ -f "${apt_source_gpg_filepath}" ]]; then
display_alert "Adding GPG Key ${apt_source_gpg_filepath}"
local apt_source_gpg_filename="$(basename ${apt_source_gpg_filepath})"
cp "${apt_source_gpg_filepath}" "${SDCARD}/tmp/${apt_source_gpg_filename}"
run_on_sdcard "apt-key add \"/tmp/${apt_source_gpg_filename}\""
echo "APT Key returned : $?"
fi
done
fi
done
}
add_desktop_package_sources() {
# Myy : I see Snap and Flatpak coming up in the next releases
# so... let's prepare for that
add_apt_sources
run_on_sdcard "apt-get -y -q update"
ls -l "${SDCARD}/etc/apt/sources.list.d" >> "${DEST}"/${LOG_SUBPATH}/install.log
cat "${SDCARD}/etc/apt/sources.list" >> "${DEST}"/${LOG_SUBPATH}/install.log
}
desktop_postinstall ()
{
# disable display manager for first run
#chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload disable lightdm.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get update" >> "${DEST}"/debug/install.log 2>&1
if [[ ${FULL_DESKTOP} == yes ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FULL" >> "${DEST}"/debug/install.log 2>&1
fi
# disable display manager for the first run
#run_on_sdcard "systemctl --no-reload disable lightdm.service >/dev/null 2>&1"
#run_on_sdcard "systemctl --no-reload disable gdm3.service >/dev/null 2>&1"
# update packages index
run_on_sdcard "DEBIAN_FRONTEND=noninteractive apt-get update >/dev/null 2>&1"
# install per board packages
if [[ -n ${PACKAGE_LIST_DESKTOP_BOARD} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_BOARD" >> "${DEST}"/debug/install.log 2>&1
run_on_sdcard "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_BOARD"
fi
# install per family packages
if [[ -n ${PACKAGE_LIST_DESKTOP_FAMILY} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FAMILY" >> "${DEST}"/debug/install.log 2>&1
run_on_sdcard "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_DESKTOP_FAMILY"
fi
# Compile Turbo Frame buffer for sunxi
@@ -144,11 +281,20 @@ desktop_postinstall ()
echo "extraargs=cma=96M" >> "${SDCARD}"/boot/orangepiEnv.txt
fi
mkdir -p ${SDCARD}/etc/lightdm/lightdm.conf.d
cat <<-EOF > ${SDCARD}/etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
[Seat:*]
autologin-user=$OPI_USERNAME
autologin-user-timeout=0
user-session=xfce
EOF
if [[ -d ${SDCARD}/etc/lightdm ]]; then
mkdir -p ${SDCARD}/etc/lightdm/lightdm.conf.d
cat <<-EOF > ${SDCARD}/etc/lightdm/lightdm.conf.d/22-orangepi-autologin.conf
[Seat:*]
autologin-user=$OPI_USERNAME
autologin-user-timeout=0
user-session=xfce
EOF
fi
#mkdir -p /etc/gdm3
#cat <<-EOF > /etc/gdm3/custom.conf
#[daemon]
#AutomaticLoginEnable = true
#AutomaticLogin = $RealUserName
#EOF
}

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
@@ -8,11 +8,15 @@
# Functions:
# install_common
# install_rclocal
# install_distribution_specific
# post_debootstrap_tweaks
install_common()
{
display_alert "Applying common tweaks" "" "info"
@@ -21,11 +25,11 @@ install_common()
if [[ $CRYPTROOT_ENABLE == yes ]]; then
display_alert "Installing rootfs encryption related packages" "cryptsetup" "info"
chroot "${SDCARD}" /bin/bash -c "apt-get -y -qq --no-install-recommends install cryptsetup" \
>> "${DEST}"/debug/install.log 2>&1
>> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
if [[ $CRYPTROOT_SSH_UNLOCK == yes ]]; then
display_alert "Installing rootfs encryption related packages" "dropbear-initramfs" "info"
chroot "${SDCARD}" /bin/bash -c "apt-get -y -qq --no-install-recommends install dropbear-initramfs cryptsetup-initramfs" \
>> "${DEST}"/debug/install.log 2>&1
>> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
fi
fi
@@ -38,7 +42,7 @@ install_common()
# adjust initramfs dropbear configuration
# needs to be done before kernel installation, else it won't be in the initrd image
if [[ $CRYPTROOT_ENABLE == yes && $CRYPTROOT_SSH_UNLOCK == yes ]]; then
# Set the port of the dropbear ssh deamon in the initramfs to a different one if configured
# Set the port of the dropbear ssh daemon in the initramfs to a different one if configured
# this avoids the typical 'host key changed warning' - `WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!`
[[ -f "${SDCARD}"/etc/dropbear-initramfs/config ]] && \
sed -i 's/^#DROPBEAR_OPTIONS=/DROPBEAR_OPTIONS="-p '"${CRYPTROOT_SSH_UNLOCK_PORT}"'"/' \
@@ -52,13 +56,13 @@ install_common()
# this key should be changed by the user on first login
display_alert "Generating a new SSH key pair for dropbear (initramfs)" "" ""
ssh-keygen -t ecdsa -f "${SDCARD}"/etc/dropbear-initramfs/id_ecdsa \
-N '' -O force-command=cryptroot-unlock -C 'AUTOGENERATED_BY_ARMBIAN_BUILD' >> "${DEST}"/debug/install.log 2>&1
-N '' -O force-command=cryptroot-unlock -C 'AUTOGENERATED_BY_ARMBIAN_BUILD' >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
# /usr/share/initramfs-tools/hooks/dropbear will automatically add 'id_ecdsa.pub' to authorized_keys file
# during mkinitramfs of update-initramfs
#cat "${SDCARD}"/etc/dropbear-initramfs/id_ecdsa.pub > "${SDCARD}"/etc/dropbear-initramfs/authorized_keys
# The version of the Linux kernel
CRYPTROOT_SSH_UNLOCK_KEY_NAME="${BOARD^}_${REVISION}_${DISTRIBUTION,}_${RELEASE}_${IMAGETYPE}_linux"$(grab_version "$LINUXSOURCEDIR")"".key
CRYPTROOT_SSH_UNLOCK_KEY_NAME="${BOARD^}_${REVISION}_${DISTRIBUTION,}_${RELEASE}_${SELECTED_CONFIGURATION}_linux"$(grab_version "$LINUXSOURCEDIR")"".key
# copy dropbear ssh key to image output dir for convenience
cp "${SDCARD}"/etc/dropbear-initramfs/id_ecdsa "${DEST}/images/${CRYPTROOT_SSH_UNLOCK_KEY_NAME}"
display_alert "SSH private key for dropbear (initramfs) has been copied to:" \
@@ -83,7 +87,7 @@ install_common()
fi
# configure MIN / MAX speed for cpufrequtils
cat <<-EOF > "${SDCARD}"/etc/default/cpufrequtils
cat <<-EOF > "${SDCARD}"/etc/default/cpufrequtils
ENABLE=true
MIN_SPEED=$CPUMIN
MAX_SPEED=$CPUMAX
@@ -131,9 +135,9 @@ install_common()
#mkdir -p "${SDCARD}"/etc/systemd/system/serial-getty@.service.d/
#cat <<-EOF > "${SDCARD}"/etc/systemd/system/serial-getty@.service.d/override.conf
#[Service]
#ExecStartPre=/bin/sleep 6
#ExecStartPre=/bin/sh -c 'exec /bin/sleep 10'
#ExecStart=
#ExecStart=-/sbin/agetty --noclear --autologin root %I $TERM
#ExecStart=-/sbin/agetty --noissue --autologin root %I $TERM
#Type=idle
#EOF
#cp "${SDCARD}"/etc/systemd/system/serial-getty@.service.d/override.conf "${SDCARD}"/etc/systemd/system/getty@.service.d/override.conf
@@ -142,9 +146,9 @@ install_common()
#chroot "${SDCARD}" /bin/bash -c "chage -d 0 root"
# change console welcome text
echo -e "Orange Pi ${REVISION} ${RELEASE^} \\l \n" > "${SDCARD}"/etc/issue
echo "Orange Pi ${REVISION} ${RELEASE^}" > "${SDCARD}"/etc/issue.net
sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"Orange Pi $REVISION "${RELEASE^}"\"/" "${SDCARD}"/etc/os-release
echo -e "${VENDOR} ${REVISION} ${RELEASE^} \\l \n" > "${SDCARD}"/etc/issue
echo "${VENDOR} ${REVISION} ${RELEASE^}" > "${SDCARD}"/etc/issue.net
sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"${VENDOR} $REVISION "${RELEASE^}"\"/" "${SDCARD}"/etc/os-release
# enable few bash aliases enabled in Ubuntu by default to make it even
sed "s/#alias ll='ls -l'/alias ll='ls -l'/" -i "${SDCARD}"/etc/skel/.bashrc
@@ -164,42 +168,62 @@ install_common()
# NOTE: this needs to be executed before family_tweaks
local bootscript_src=${BOOTSCRIPT%%:*}
local bootscript_dst=${BOOTSCRIPT##*:}
cp "${EXTER}/config/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
if [[ -n $BOOTENV_FILE ]]; then
if [[ -f $USERPATCHES_PATH/bootenv/$BOOTENV_FILE ]]; then
cp "$USERPATCHES_PATH/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/orangepiEnv.txt
elif [[ -f $EXTER/config/bootenv/$BOOTENV_FILE ]]; then
cp "${EXTER}/config/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/orangepiEnv.txt
fi
fi
if [[ $ROOTFS_TYPE == nfs ]]; then
display_alert "Copying NFS boot script template"
if [[ -f $USERPATCHES_PATH/nfs-boot.cmd ]]; then
cp "$USERPATCHES_PATH"/nfs-boot.cmd "${SDCARD}"/boot/boot.cmd
else
cp "${EXTER}"/config/templates/nfs-boot.cmd.template "${SDCARD}"/boot/boot.cmd
if [[ -z $NFS_LOCAL_IP ]]; then
NFS_LOCAL_IP=$(ifconfig "${NET_IFNAME}" | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p')
# create extlinux config file
if [[ $SRC_EXTLINUX == yes ]]; then
mkdir -p $SDCARD/boot/extlinux
cat <<-EOF > "$SDCARD/boot/extlinux/extlinux.conf"
label ${VENDOR}
kernel /boot/$NAME_KERNEL
initrd /boot/$NAME_INITRD
EOF
if [[ -n $BOOT_FDT_FILE ]]; then
if [[ $BOOT_FDT_FILE != "none" ]]; then
echo " fdt /boot/dtb/$BOOT_FDT_FILE" >> "$SDCARD/boot/extlinux/extlinux.conf"
fi
sed -i "s#BRANCH#$BRANCH#" "${SDCARD}"/boot/boot.cmd
sed -i "s#NFS_LOCAL_IP#$NFS_LOCAL_IP#" "${SDCARD}"/boot/boot.cmd
sed -i "s#NFS_ROOTFS#$NFS_ROOTFS#" "${SDCARD}"/boot/boot.cmd
else
echo " fdtdir /boot/dtb/" >> "$SDCARD/boot/extlinux/extlinux.conf"
fi
else
if [[ "${BOOTCONFIG}" != "none" ]]; then
if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then
cp "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
else
cp "${EXTER}/config/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
fi
fi
if [[ -n $BOOTENV_FILE ]]; then
if [[ -f $USERPATCHES_PATH/bootenv/$BOOTENV_FILE ]]; then
cp "$USERPATCHES_PATH/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/orangepiEnv.txt
elif [[ -f $EXTER/config/bootenv/$BOOTENV_FILE ]]; then
cp "${EXTER}/config/bootenv/${BOOTENV_FILE}" "${SDCARD}"/boot/orangepiEnv.txt
fi
fi
# TODO: modify $bootscript_dst or orangepiEnv.txt to make NFS boot universal
# instead of copying sunxi-specific template
if [[ $ROOTFS_TYPE == nfs ]]; then
display_alert "Copying NFS boot script template"
if [[ -f $USERPATCHES_PATH/nfs-boot.cmd ]]; then
cp "$USERPATCHES_PATH"/nfs-boot.cmd "${SDCARD}"/boot/boot.cmd
else
cp "${EXTER}"/config/templates/nfs-boot.cmd.template "${SDCARD}"/boot/boot.cmd
fi
fi
[[ -n $OVERLAY_PREFIX && -f "${SDCARD}"/boot/orangepiEnv.txt && $BRANCH == current ]] && \
echo "overlay_prefix=$OVERLAY_PREFIX" >> "${SDCARD}"/boot/orangepiEnv.txt
[[ -n $DEFAULT_OVERLAYS && -f "${SDCARD}"/boot/orangepiEnv.txt && $BRANCH == current ]] && \
echo "overlays=${DEFAULT_OVERLAYS//,/ }" >> "${SDCARD}"/boot/orangepiEnv.txt
[[ -n $BOOT_FDT_FILE && -f "${SDCARD}"/boot/orangepiEnv.txt ]] && \
echo "fdtfile=${BOOT_FDT_FILE}" >> "${SDCARD}/boot/orangepiEnv.txt"
fi
[[ -n $OVERLAY_PREFIX && -f $SDCARD/boot/orangepiEnv.txt && $BRANCH == current ]] && \
echo "overlay_prefix=$OVERLAY_PREFIX" >> "${SDCARD}"/boot/orangepiEnv.txt
[[ -n $DEFAULT_OVERLAYS && -f $SDCARD/boot/orangepiEnv.txt && $BRANCH == current ]] && \
echo "overlays=${DEFAULT_OVERLAYS//,/ }" >> "${SDCARD}"/boot/orangepiEnv.txt
[[ -n $BOOT_FDT_FILE && -f $SDCARD/boot/orangepiEnv.txt ]] && \
echo "fdtfile=${BOOT_FDT_FILE}" >> "${SDCARD}/boot/orangepiEnv.txt"
# initial date for fake-hwclock
date -u '+%Y-%m-%d %H:%M:%S' > "${SDCARD}"/etc/fake-hwclock.data
@@ -207,7 +231,8 @@ install_common()
# set hostname in hosts file
cat <<-EOF > "${SDCARD}"/etc/hosts
127.0.0.1 localhost $HOST
127.0.0.1 localhost
127.0.1.1 $HOST
::1 localhost $HOST ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
@@ -215,81 +240,116 @@ install_common()
ff02::2 ip6-allrouters
EOF
cd $SRC
# Prepare and export caching-related params common to all apt calls below, to maximize apt-cacher-ng usage
export APT_EXTRA_DIST_PARAMS=""
[[ $NO_APT_CACHER != yes ]] && APT_EXTRA_DIST_PARAMS="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
display_alert "Cleaning" "package lists"
chroot "${SDCARD}" /bin/bash -c "apt-get clean"
display_alert "Updating" "package lists"
chroot "${SDCARD}" /bin/bash -c "apt-get update" >> "${DEST}"/debug/install.log 2>&1
chroot "${SDCARD}" /bin/bash -c "apt-get ${APT_EXTRA_DIST_PARAMS} update" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
display_alert "Temporarily disabling" "initramfs-tools hook for kernel"
chroot "${SDCARD}" /bin/bash -c "chmod -v -x /etc/kernel/postinst.d/initramfs-tools" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
# install family packages
if [[ -n ${PACKAGE_LIST_FAMILY} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_FAMILY" >> "${DEST}"/debug/install.log 2>&1
display_alert "Installing PACKAGE_LIST_FAMILY packages" "${PACKAGE_LIST_FAMILY}"
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq --no-install-recommends install $PACKAGE_LIST_FAMILY" >> "${DEST}"/${LOG_SUBPATH}/install.log
fi
# install family packages
# install board packages
if [[ -n ${PACKAGE_LIST_BOARD} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_BOARD" >> "${DEST}"/debug/install.log 2>&1
display_alert "Installing PACKAGE_LIST_BOARD packages" "${PACKAGE_LIST_BOARD}"
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq --no-install-recommends install $PACKAGE_LIST_BOARD" >> "${DEST}"/${LOG_SUBPATH}/install.log || { display_alert "Failed to install PACKAGE_LIST_BOARD" "${PACKAGE_LIST_BOARD}" "err"; exit 2; }
fi
# remove family packages
if [[ -n ${PACKAGE_LIST_FAMILY_REMOVE} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq remove --auto-remove $PACKAGE_LIST_FAMILY_REMOVE" >> "${DEST}"/debug/install.log 2>&1
fi
# remove board packages
if [[ -n ${PACKAGE_LIST_BOARD_REMOVE} ]]; then
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq remove --auto-remove $PACKAGE_LIST_BOARD_REMOVE" >> "${DEST}"/debug/install.log 2>&1
fi
# remove family packages
if [[ -n ${PACKAGE_LIST_FAMILY_REMOVE} ]]; then
display_alert "Removing PACKAGE_LIST_FAMILY_REMOVE packages" "${PACKAGE_LIST_FAMILY_REMOVE}"
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq remove --auto-remove $PACKAGE_LIST_FAMILY_REMOVE" >> "${DEST}"/${LOG_SUBPATH}/install.log
fi
# remove board packages
if [[ -n ${PACKAGE_LIST_BOARD_REMOVE} ]]; then
display_alert "Removing PACKAGE_LIST_BOARD_REMOVE packages" "${PACKAGE_LIST_BOARD_REMOVE}"
for PKG_REMOVE in ${PACKAGE_LIST_BOARD_REMOVE}; do
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq remove --auto-remove ${PKG_REMOVE}" >> "${DEST}"/${LOG_SUBPATH}/install.log
done
fi
# install u-boot
if [[ "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
UBOOT_VER=$(dpkg --info "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
install_deb_chroot "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb"
else
UBOOT_VER=$(dpkg --info "${DEB_ORANGEPI}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
install_deb_chroot "${DEB_ORANGEPI}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" "orangepi"
fi
# @TODO: add install_bootloader() extension method, refactor into u-boot extension
[[ "${BOOTCONFIG}" != "none" ]] && {
if [[ "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
UBOOT_VER=$(dpkg --info "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
install_deb_chroot "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb"
else
UBOOT_VER=$(dpkg --info "${DEB_ORANGEPI}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
install_deb_chroot "${DEB_ORANGEPI}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" "orangepi"
fi
}
call_extension_method "pre_install_kernel_debs" << 'PRE_INSTALL_KERNEL_DEBS'
*called before installing the Armbian-built kernel deb packages*
It is not too late to `unset KERNELSOURCE` here and avoid kernel install.
PRE_INSTALL_KERNEL_DEBS
# install kernel
if [[ "${REPOSITORY_INSTALL}" != *kernel* ]]; then
VER=$(dpkg --info "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
VER="${VER/-$LINUXFAMILY/}"
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb"
if [[ -f ${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb"
fi
if [[ $INSTALL_HEADERS == yes ]]; then
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb"
fi
else
VER=$(dpkg --info "${DEB_ORANGEPI}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
VER="${VER/-$LINUXFAMILY/}"
[[ -n $KERNELSOURCE ]] && {
if [[ "${REPOSITORY_INSTALL}" != *kernel* ]]; then
VER=$(dpkg --info "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | awk -F"-" '/Source:/{print $2}')
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" "orangepi"
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb"
if [[ -f ${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb"
fi
if [[ $INSTALL_HEADERS == yes ]]; then
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb"
fi
else
VER=$(dpkg --info "${DEB_ORANGEPI}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
VER="${VER/-$LINUXFAMILY/}"
if [[ -f ${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb" "orangepi"
fi
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" "orangepi"
if [[ $INSTALL_HEADERS == yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb" "orangepi"
if [[ -f ${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb" "orangepi"
fi
if [[ $INSTALL_HEADERS == yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb" "orangepi"
fi
fi
fi
}
call_extension_method "post_install_kernel_debs" << 'POST_INSTALL_KERNEL_DEBS'
*allow config to do more with the installed kernel/headers*
Called after packages, u-boot, kernel and headers installed in the chroot, but before the BSP is installed.
If `KERNELSOURCE` is (still?) unset after this, Armbian-built firmware will not be installed.
POST_INSTALL_KERNEL_DEBS
# install board support packages
if [[ "${REPOSITORY_INSTALL}" != *bsp* ]]; then
install_deb_chroot "${DEB_STORAGE}/$RELEASE/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}.deb"
install_deb_chroot "${DEB_STORAGE}/$RELEASE/${BSP_CLI_PACKAGE_FULLNAME}.deb" | tee "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
else
install_deb_chroot "${DEB_ORANGEPI}/$RELEASE/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}.deb" "orangepi"
install_deb_chroot "${DEB_ORANGEPI}/$RELEASE/${CHOSEN_ROOTFS}_${BSP_CLI_PACKAGE_FULLNAME}.deb" "orangepi"
fi
# install orangepi-desktop
if [[ "${REPOSITORY_INSTALL}" != *orangepi-desktop* ]]; then
if [[ $BUILD_DESKTOP == yes ]]; then
install_deb_chroot "${DEB_STORAGE}/$RELEASE/orangepi-${RELEASE}-desktop_${REVISION}_all.deb"
install_deb_chroot "${DEB_STORAGE}/${RELEASE}/${CHOSEN_DESKTOP}_${REVISION}_all.deb"
install_deb_chroot "${DEB_STORAGE}/${RELEASE}/${BSP_DESKTOP_PACKAGE_FULLNAME}.deb"
# install display manager and PACKAGE_LIST_DESKTOP_FULL packages if enabled per board
desktop_postinstall
fi
else
if [[ $BUILD_DESKTOP == yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/$RELEASE/orangepi-${RELEASE}-desktop_${REVISION}_all.deb" "orangepi"
install_deb_chroot "${CHOSEN_DESKTOP}" "orangepi"
# install display manager and PACKAGE_LIST_DESKTOP_FULL packages if enabled per board
desktop_postinstall
fi
@@ -307,13 +367,28 @@ install_common()
fi
# install orangepi-config
if [[ "${REPOSITORY_INSTALL}" != *orangepi-config* ]]; then
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "${DEB_STORAGE}/orangepi-config_${REVISION}_all.deb"
if [[ "${PACKAGE_LIST_RM}" != *orangepi-config* ]]; then
if [[ "${REPOSITORY_INSTALL}" != *orangepi-config* ]]; then
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "${DEB_STORAGE}/orangepi-config_${REVISION}_all.deb"
fi
else
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/orangepi-config_${REVISION}_all.deb" "orangepi"
fi
fi
else
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "${DEB_ORANGEPI}/orangepi-config_${REVISION}_all.deb" "orangepi"
fi
# install orangepi-zsh
if [[ "${PACKAGE_LIST_RM}" != *orangepi-zsh* ]]; then
if [[ "${REPOSITORY_INSTALL}" != *orangepi-zsh* ]]; then
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "${DEB_STORAGE}/orangepi-zsh_${REVISION}_all.deb"
fi
else
if [[ $BUILD_MINIMAL != yes ]]; then
install_deb_chroot "orangepi-zsh" "remote"
fi
fi
fi
@@ -333,7 +408,7 @@ install_common()
if [[ $BSPFREEZE == yes ]]; then
display_alert "Freezing Orange Pi packages" "$BOARD" "info"
chroot "${SDCARD}" /bin/bash -c "apt-mark hold ${CHOSEN_KERNEL} ${CHOSEN_KERNEL/image/headers} \
linux-u-boot-${BOARD}-${BRANCH} ${CHOSEN_KERNEL/image/dtb}" >> "${DEST}"/debug/install.log 2>&1
linux-u-boot-${BOARD}-${BRANCH} ${CHOSEN_KERNEL/image/dtb}" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
fi
# add orangepi user
@@ -366,6 +441,12 @@ install_common()
# execute $LINUXFAMILY-specific tweaks
[[ $(type -t family_tweaks) == function ]] && family_tweaks
call_extension_method "post_family_tweaks" << 'FAMILY_TWEAKS'
*customize the tweaks made by $LINUXFAMILY-specific family_tweaks*
It is run after packages are installed in the rootfs, but before enabling additional services.
It allows implementors access to the rootfs (`${SDCARD}`) in its pristine state after packages are installed.
FAMILY_TWEAKS
# enable additional services
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-firstrun.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable orangepi-firstrun-config.service >/dev/null 2>&1"
@@ -395,7 +476,13 @@ install_common()
chroot "${SDCARD}" /bin/bash -c "chown root:messagebus /usr/lib/dbus-1.0/dbus-daemon-launch-helper"
chroot "${SDCARD}" /bin/bash -c "chmod u+s /usr/lib/dbus-1.0/dbus-daemon-launch-helper"
sed -i "s/^#kernel.printk*/kernel.printk/" "${SDCARD}"/etc/sysctl.conf
# disable samba NetBIOS over IP name service requests since it hangs when no network is present at boot
chroot "${SDCARD}" /bin/bash -c "systemctl --quiet disable nmbd 2> /dev/null"
# disable low-level kernel messages for non betas
if [[ -z $BETA ]]; then
sed -i "s/^#kernel.printk*/kernel.printk/" "${SDCARD}"/etc/sysctl.conf
fi
# disable repeated messages due to xconsole not being installed.
[[ -f "${SDCARD}"/etc/rsyslog.d/50-default.conf ]] && \
@@ -413,6 +500,8 @@ install_common()
for i in $(echo "${SERIALCON:-'ttyS0'}" | sed "s/,/ /g")
do
IFS=':' read -r -a array <<< "$i"
[[ "${array[0]}" == "tty1" ]] && continue # Don't enable tty1 as serial console.
display_alert "Enabling serial console" "${array[0]}" "info"
# add serial console to secure tty list
[ -z "$(grep -w '^${array[0]}' "${SDCARD}"/etc/securetty 2> /dev/null)" ] && \
echo "${array[0]}" >> "${SDCARD}"/etc/securetty
@@ -423,10 +512,9 @@ install_common()
sed -i "s/--keep-baud 115200/--keep-baud ${array[1]},115200/" \
"${SDCARD}/lib/systemd/system/serial-getty@${array[0]}.service"
fi
display_alert "Enabling serial console" "${array[0]}" "info"
chroot "${SDCARD}" /bin/bash -c "systemctl daemon-reload" >> "${DEST}"/debug/install.log 2>&1
chroot "${SDCARD}" /bin/bash -c "systemctl daemon-reload" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable serial-getty@${array[0]}.service" \
>> "${DEST}"/debug/install.log 2>&1
>> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
if [[ "${array[0]}" == "ttyGS0" && $LINUXFAMILY == sun8i && $BRANCH == legacy ]]; then
mkdir -p "${SDCARD}"/etc/systemd/system/serial-getty@ttyGS0.service.d
cat <<-EOF > "${SDCARD}"/etc/systemd/system/serial-getty@ttyGS0.service.d/10-switch-role.conf
@@ -451,7 +539,7 @@ install_common()
cp "${SDCARD}"/etc/orangepi-release "${SDCARD}"/etc/orangepi-image-release
# DNS fix. package resolvconf is not available everywhere
if [ -d /etc/resolvconf/resolv.conf.d ]; then
if [ -d /etc/resolvconf/resolv.conf.d ] && [ -n "$NAMESERVER" ]; then
echo "nameserver $NAMESERVER" > "${SDCARD}"/etc/resolvconf/resolv.conf.d/head
fi
@@ -461,14 +549,55 @@ install_common()
# enable PubkeyAuthentication
sed -i 's/#\?PubkeyAuthentication .*/PubkeyAuthentication yes/' "${SDCARD}"/etc/ssh/sshd_config
# configure network manager
sed "s/managed=\(.*\)/managed=true/g" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
if [ -f "${SDCARD}"/etc/NetworkManager/NetworkManager.conf ]; then
# configure network manager
sed "s/managed=\(.*\)/managed=true/g" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
# remove network manager defaults to handle eth by default
rm -f "${SDCARD}"/usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf
# remove network manager defaults to handle eth by default
rm -f "${SDCARD}"/usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf
# most likely we don't need to wait for nm to get online
chroot "${SDCARD}" /bin/bash -c "systemctl disable NetworkManager-wait-online.service" >> "${DEST}"/debug/install.log 2>&1
# most likely we don't need to wait for nm to get online
chroot "${SDCARD}" /bin/bash -c "systemctl disable NetworkManager-wait-online.service" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
# Just regular DNS and maintain /etc/resolv.conf as a file
sed "/dns/d" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
sed "s/\[main\]/\[main\]\ndns=default\nrc-manager=file/g" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
if [[ -n $NM_IGNORE_DEVICES ]]; then
mkdir -p "${SDCARD}"/etc/NetworkManager/conf.d/
cat <<-EOF > "${SDCARD}"/etc/NetworkManager/conf.d/10-ignore-interfaces.conf
[keyfile]
unmanaged-devices=$NM_IGNORE_DEVICES
EOF
fi
elif [ -d "${SDCARD}"/etc/systemd/network ]; then
# configure networkd
rm "${SDCARD}"/etc/resolv.conf
ln -s /run/systemd/resolve/resolv.conf "${SDCARD}"/etc/resolv.conf
# enable services
chroot "${SDCARD}" /bin/bash -c "systemctl enable systemd-networkd.service systemd-resolved.service" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
if [ -e /etc/systemd/timesyncd.conf ]; then
chroot "${SDCARD}" /bin/bash -c "systemctl enable systemd-timesyncd.service" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
fi
umask 022
cat > "${SDCARD}"/etc/systemd/network/eth0.network <<- __EOF__
[Match]
Name=eth0
[Network]
#MACAddress=
DHCP=ipv4
LinkLocalAddressing=ipv4
#Address=192.168.1.100/24
#Gateway=192.168.1.1
#DNS=192.168.1.1
#Domains=example.com
NTP=0.pool.ntp.org 1.pool.ntp.org
__EOF__
fi
# avahi daemon defaults if exists
[[ -f "${SDCARD}"/usr/share/doc/avahi-daemon/examples/sftp-ssh.service ]] && \
@@ -476,28 +605,17 @@ install_common()
[[ -f "${SDCARD}"/usr/share/doc/avahi-daemon/examples/ssh.service ]] && \
cp "${SDCARD}"/usr/share/doc/avahi-daemon/examples/ssh.service "${SDCARD}"/etc/avahi/services/
# Just regular DNS and maintain /etc/resolv.conf as a file
sed "/dns/d" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
sed "s/\[main\]/\[main\]\ndns=default\nrc-manager=file/g" -i "${SDCARD}"/etc/NetworkManager/NetworkManager.conf
if [[ -n $NM_IGNORE_DEVICES ]]; then
mkdir -p "${SDCARD}"/etc/NetworkManager/conf.d/
cat <<-EOF > "${SDCARD}"/etc/NetworkManager/conf.d/10-ignore-interfaces.conf
[keyfile]
unmanaged-devices=$NM_IGNORE_DEVICES
EOF
fi
# nsswitch settings for sane DNS behavior: remove resolve, assure libnss-myhostname support
sed "s/hosts\:.*/hosts: files mymachines dns myhostname/g" -i "${SDCARD}"/etc/nsswitch.conf
# build logo in any case
#boot_logo
boot_logo
# disable MOTD for first boot - we want as clean 1st run as possible
chmod -x "${SDCARD}"/etc/update-motd.d/*
}
install_rclocal()
{
@@ -521,9 +639,6 @@ install_rclocal()
}
install_distribution_specific()
{
@@ -544,7 +659,7 @@ install_distribution_specific()
;;
stretch|buster)
stretch|buster|sid)
# remove doubled uname from motd
[[ -f "${SDCARD}"/etc/update-motd.d/10-uname ]] && rm "${SDCARD}"/etc/update-motd.d/10-uname
@@ -563,17 +678,33 @@ install_distribution_specific()
[[ $(grep -L "VERSION_ID=" "${SDCARD}"/etc/os-release) ]] && echo 'VERSION_ID="11"' >> "${SDCARD}"/etc/os-release
[[ $(grep -L "VERSION=" "${SDCARD}"/etc/os-release) ]] && echo 'VERSION="11 (bullseye)"' >> "${SDCARD}"/etc/os-release
;;
bookworm)
# remove doubled uname from motd
[[ -f "${SDCARD}"/etc/update-motd.d/10-uname ]] && rm "${SDCARD}"/etc/update-motd.d/10-uname
# rc.local is not existing but one might need it
install_rclocal
# fix missing versioning
[[ $(grep -L "VERSION_ID=" "${SDCARD}"/etc/os-release) ]] && echo 'VERSION_ID="12"' >> "${SDCARD}"/etc/os-release
[[ $(grep -L "VERSION=" "${SDCARD}"/etc/os-release) ]] && echo 'VERSION="11 (bookworm)"' >> "${SDCARD}"/etc/os-release
# remove security updates repository since it does not exists yet
sed '/security/ d' -i "${SDCARD}"/etc/apt/sources.list
;;
bionic|eoan|focal)
bionic|focal|hirsute|impish|jammy)
# by using default lz4 initrd compression leads to corruption, go back to proven method
sed -i "s/^COMPRESS=.*/COMPRESS=gzip/" "${SDCARD}"/etc/initramfs-tools/initramfs.conf
# remove doubled uname from motd
[[ -f "${SDCARD}"/etc/update-motd.d/10-uname ]] && rm "${SDCARD}"/etc/update-motd.d/10-uname
# cleanup motd services and related files
chroot "${SDCARD}" /bin/bash -c "systemctl disable motd-news.service >/dev/null 2>&1"
chroot "${SDCARD}" /bin/bash -c "systemctl disable motd-news.timer >/dev/null 2>&1"
rm -f "${SDCARD}"/etc/update-motd.d/{10-uname,10-help-text,50-motd-news,80-esm,80-livepatch,90-updates-available,91-release-upgrade,95-hwe-eol}
# remove motd news from motd.ubuntu.com
[[ -f "${SDCARD}"/etc/default/motd-news ]] && sed -i "s/^ENABLED=.*/ENABLED=0/" "${SDCARD}"/etc/default/motd-news
@@ -581,15 +712,23 @@ install_distribution_specific()
# rc.local is not existing but one might need it
install_rclocal
# Basic Netplan config. Let NetworkManager manage all devices on this system
if [ -d "${SDCARD}"/etc/NetworkManager ]; then
local RENDERER=NetworkManager
else
local RENDERER=networkd
fi
# Basic Netplan config. Let NetworkManager/networkd manage all devices on this system
[[ -d "${SDCARD}"/etc/netplan ]] && cat <<-EOF > "${SDCARD}"/etc/netplan/orangepi-default.yaml
network:
version: 2
renderer: NetworkManager
renderer: $RENDERER
EOF
# DNS fix
sed -i "s/#DNS=.*/DNS=$NAMESERVER/g" "${SDCARD}"/etc/systemd/resolved.conf
if [ -n "$NAMESERVER" ]; then
sed -i "s/#DNS=.*/DNS=$NAMESERVER/g" "${SDCARD}"/etc/systemd/resolved.conf
fi
# Journal service adjustements
sed -i "s/#Storage=.*/Storage=volatile/g" "${SDCARD}"/etc/systemd/journald.conf
@@ -607,6 +746,12 @@ install_distribution_specific()
esac
# use list modules INITRAMFS
if [ -f "${EXTER}"/config/modules/"${MODULES_INITRD}" ]; then
display_alert "Use file list modules INITRAMFS" "${MODULES_INITRD}"
sed -i "s/^MODULES=.*/MODULES=list/" "${SDCARD}"/etc/initramfs-tools/initramfs.conf
cat "${EXTER}"/config/modules/"${MODULES_INITRD}" >> "${SDCARD}"/etc/initramfs-tools/modules
fi
}
@@ -621,4 +766,10 @@ post_debootstrap_tweaks()
chroot "${SDCARD}" /bin/bash -c "dpkg-divert --quiet --local --rename --remove /sbin/start-stop-daemon"
rm -f "${SDCARD}"/usr/sbin/policy-rc.d "${SDCARD}/usr/bin/${QEMU_BINARY}"
call_extension_method "post_post_debootstrap_tweaks" "config_post_debootstrap_tweaks" << 'POST_POST_DEBOOTSTRAP_TWEAKS'
*run after removing diversions and qemu with chroot unmounted*
Last chance to touch the `${SDCARD}` filesystem before it is copied to the final media.
It is too late to run any chrooted commands, since the supporting filesystems are already unmounted.
POST_POST_DEBOOTSTRAP_TWEAKS
}

447
scripts/extensions.sh Executable file
View File

@@ -0,0 +1,447 @@
# global variables managing the state of the extension manager. treat as private.
declare -A extension_function_info # maps a function name to a string with KEY=VALUEs information about the defining extension
declare -i initialize_extension_manager_counter=0 # how many times has the extension manager initialized?
declare -A defined_hook_point_functions # keeps a map of hook point functions that were defined and their extension info
declare -A hook_point_function_trace_sources # keeps a map of hook point functions that were actually called and their source
declare -A hook_point_function_trace_lines # keeps a map of hook point functions that were actually called and their source
declare fragment_manager_cleanup_file # this is a file used to cleanup the manager's produced functions, for build_all_ng
# configuration.
export DEBUG_EXTENSION_CALLS=no # set to yes to log every hook function called to the main build log
export LOG_ENABLE_EXTENSION=yes # colorful logs with stacktrace when enable_extension is called.
# This is a helper function for calling hooks.
# It follows the pattern long used in the codebase for hook-like behaviour:
# [[ $(type -t name_of_hook_function) == function ]] && name_of_hook_function
# but with the following added behaviors:
# 1) it allows for many arguments, and will treat each as a hook point.
# this allows for easily kept backwards compatibility when renaming hooks, for example.
# 2) it will read the stdin and assume it's (Markdown) documentation for the hook point.
# combined with heredoc in the call site, it allows for "inline" documentation about the hook
# notice: this is not involved in how the hook functions came to be. read below for that.
call_extension_method() {
# First, consume the stdin and write metadata about the call.
write_hook_point_metadata "$@" || true
# @TODO: hack to handle stdin again, possibly with '< /dev/tty'
# Then a sanity check, hook points should only be invoked after the manager has initialized.
if [[ ${initialize_extension_manager_counter} -lt 1 ]]; then
display_alert "Extension problem" "Call to call_extension_method() (in ${BASH_SOURCE[1]- $(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")}) before extension manager is initialized." "err"
fi
# With DEBUG_EXTENSION_CALLS, log the hook call. Users might be wondering what/when is a good hook point to use, and this is visual aid.
[[ "${DEBUG_EXTENSION_CALLS}" == "yes" ]] &&
display_alert "--> Extension Method '${1}' being called from" "$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")" ""
# Then call the hooks, if they are defined.
for hook_name in "$@"; do
echo "-- Extension Method being called: ${hook_name}" >>"${EXTENSION_MANAGER_LOG_FILE}"
# shellcheck disable=SC2086
[[ $(type -t ${hook_name}) == function ]] && { ${hook_name}; }
done
}
# what this does is a lot of bash mumbo-jumbo to find all board-,family-,config- or user-defined hook points.
# the meat of this is 'compgen -A function', which is bash builtin that lists all defined functions.
# it will then compose a full hook point (function) that calls all the implementing hooks.
# this centralized function will then be called by the regular Armbian build system, which is oblivious to how
# it came to be. (although it is encouraged to call hook points via call_extension_method() above)
# to avoid hard coding the list of hook-points (eg: user_config, image_tweaks_pre_customize, etc) we use
# a marker in the function names, namely "__" (two underscores) to determine the hook point.
initialize_extension_manager() {
# before starting, auto-add extensions specified (eg, on the command-line) via the ENABLE_EXTENSIONS env var. Do it only once.
[[ ${initialize_extension_manager_counter} -lt 1 ]] && [[ "${ENABLE_EXTENSIONS}" != "" ]] && {
local auto_extension
for auto_extension in $(echo "${ENABLE_EXTENSIONS}" | tr "," " "); do
ENABLE_EXTENSION_TRACE_HINT="ENABLE_EXTENSIONS -> " enable_extension "${auto_extension}"
done
}
# This marks the manager as initialized, no more extensions are allowed to load after this.
export initialize_extension_manager_counter=$((initialize_extension_manager_counter + 1))
# Have a unique temporary dir, even if being built concurrently by build_all_ng.
export EXTENSION_MANAGER_TMP_DIR="${SRC}/.tmp/.extensions/${LOG_SUBPATH}"
mkdir -p "${EXTENSION_MANAGER_TMP_DIR}"
# Log destination.
export EXTENSION_MANAGER_LOG_FILE="${EXTENSION_MANAGER_TMP_DIR}/extensions.log"
echo -n "" >"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt"
# globally initialize the extensions log.
echo "-- lib/extensions.sh included. logs will be below, followed by the debug generated by the initialize_extension_manager() function." >"${EXTENSION_MANAGER_LOG_FILE}"
# log whats happening.
echo "-- initialize_extension_manager() called." >>"${EXTENSION_MANAGER_LOG_FILE}"
# this is the all-important separator.
local hook_extension_delimiter="__"
# list all defined functions. filter only the ones that have the delimiter. get only the part before the delimiter.
# sort them, and make them unique. the sorting is required for uniq to work, and does not affect the ordering of execution.
# get them on a single line, space separated.
local all_hook_points
all_hook_points="$(compgen -A function | grep "${hook_extension_delimiter}" | awk -F "${hook_extension_delimiter}" '{print $1}' | sort | uniq | xargs echo -n)"
declare -i hook_points_counter=0 hook_functions_counter=0 hook_point_functions_counter=0
# initialize the cleanups file.
fragment_manager_cleanup_file="${SRC}"/.tmp/extension_function_cleanup.sh
echo "# cleanups: " >"${fragment_manager_cleanup_file}"
local FUNCTION_SORT_OPTIONS="--general-numeric-sort --ignore-case" # --random-sort could be used to introduce chaos
local hook_point=""
# now loop over the hook_points.
for hook_point in ${all_hook_points}; do
echo "-- hook_point ${hook_point}" >>"${EXTENSION_MANAGER_LOG_FILE}"
# check if the hook point is already defined as a function.
# that can happen for example with user_config(), that can be implemented itself directly by a userpatches config.
# for now, just warn, but we could devise a way to actually integrate it in the call list.
# or: advise the user to rename their user_config() function to something like user_config__make_it_awesome()
local existing_hook_point_function
existing_hook_point_function="$(compgen -A function | grep "^${hook_point}\$")"
if [[ "${existing_hook_point_function}" == "${hook_point}" ]]; then
echo "--- hook_point_functions (final sorted realnames): ${hook_point_functions}" >>"${EXTENSION_MANAGER_LOG_FILE}"
display_alert "Extension conflict" "function ${hook_point} already defined! ignoring functions: $(compgen -A function | grep "^${hook_point}${hook_extension_delimiter}")" "wrn"
continue
fi
# for each hook_point, obtain the list of implementing functions.
# the sort order here is (very) relevant, since it determines final execution order.
# so the name of the functions actually determine the ordering.
local hook_point_functions hook_point_functions_pre_sort hook_point_functions_sorted_by_sort_id
# Sorting. Multiple extensions (or even the same extension twice) can implement the same hook point
# as long as they have different function names (the part after the double underscore __).
# the order those will be called depends on the name; eg:
# 'hook_point__033_be_awesome()' would be caller sooner than 'hook_point__799_be_even_more_awesome()'
# independent from where they were defined or in which order the extensions containing them were added.
# since requiring specific ordering could hamper portability, we reward extension authors who
# don't mind ordering for writing just: 'hook_point__be_just_awesome()' which is automatically rewritten
# as 'hook_point__500_be_just_awesome()'.
# extension authors who care about ordering can use the 3-digit number, and use the context variables
# HOOK_ORDER and HOOK_POINT_TOTAL_FUNCS to confirm in which order they're being run.
# gather the real names of the functions (after the delimiter).
hook_point_functions_pre_sort="$(compgen -A function | grep "^${hook_point}${hook_extension_delimiter}" | awk -F "${hook_extension_delimiter}" '{print $2}' | xargs echo -n)"
echo "--- hook_point_functions_pre_sort: ${hook_point_functions_pre_sort}" >>"${EXTENSION_MANAGER_LOG_FILE}"
# add "500_" to the names of function that do NOT start with a number.
# keep a reference from the new names to the old names (we'll sort on the new, but invoke the old)
declare -A hook_point_functions_sortname_to_realname
declare -A hook_point_functions_realname_to_sortname
for hook_point_function_realname in ${hook_point_functions_pre_sort}; do
local sort_id="${hook_point_function_realname}"
[[ ! $sort_id =~ ^[0-9] ]] && sort_id="500_${sort_id}"
hook_point_functions_sortname_to_realname[${sort_id}]="${hook_point_function_realname}"
hook_point_functions_realname_to_sortname[${hook_point_function_realname}]="${sort_id}"
done
# actually sort the sort_id's...
# shellcheck disable=SC2086
hook_point_functions_sorted_by_sort_id="$(echo "${hook_point_functions_realname_to_sortname[*]}" | tr " " "\n" | LC_ALL=C sort ${FUNCTION_SORT_OPTIONS} | xargs echo -n)"
echo "--- hook_point_functions_sorted_by_sort_id: ${hook_point_functions_sorted_by_sort_id}" >>"${EXTENSION_MANAGER_LOG_FILE}"
# then map back to the real names, keeping the order..
hook_point_functions=""
for hook_point_function_sortname in ${hook_point_functions_sorted_by_sort_id}; do
hook_point_functions="${hook_point_functions} ${hook_point_functions_sortname_to_realname[${hook_point_function_sortname}]}"
done
# shellcheck disable=SC2086
hook_point_functions="$(echo -n ${hook_point_functions})"
echo "--- hook_point_functions (final sorted realnames): ${hook_point_functions}" >>"${EXTENSION_MANAGER_LOG_FILE}"
hook_point_functions_counter=0
hook_points_counter=$((hook_points_counter + 1))
# determine the variables we'll pass to the hook function during execution.
# this helps the extension author create extensions that are portable between userpatches and official Armbian.
# shellcheck disable=SC2089
local common_function_vars="HOOK_POINT=\"${hook_point}\""
# loop over the functions for this hook_point (keep a total for the hook point and a grand running total)
for hook_point_function in ${hook_point_functions}; do
hook_point_functions_counter=$((hook_point_functions_counter + 1))
hook_functions_counter=$((hook_functions_counter + 1))
done
common_function_vars="${common_function_vars} HOOK_POINT_TOTAL_FUNCS=\"${hook_point_functions_counter}\""
echo "-- hook_point: ${hook_point} will run ${hook_point_functions_counter} functions: ${hook_point_functions}" >>"${EXTENSION_MANAGER_LOG_FILE}"
local temp_source_file_for_hook_point="${EXTENSION_MANAGER_TMP_DIR}/extension_function_definition.sh"
hook_point_functions_loop_counter=0
# prepare the cleanup for the function, so we can remove our mess at the end of the build.
cat <<-FUNCTION_CLEANUP_FOR_HOOK_POINT >>"${fragment_manager_cleanup_file}"
unset ${hook_point}
FUNCTION_CLEANUP_FOR_HOOK_POINT
# now compose a function definition. notice the heredoc. it will be written to tmp file, logged, then sourced.
# theres a lot of opportunities here, but for now I keep it simple:
# - execute functions in the order defined by ${hook_point_functions} above
# - define call-specific environment variables, to help extension authors to write portable extensions (eg: EXTENSION_DIR)
cat <<-FUNCTION_DEFINITION_HEADER >"${temp_source_file_for_hook_point}"
${hook_point}() {
echo "*** Extension-managed hook starting '${hook_point}': will run ${hook_point_functions_counter} functions: '${hook_point_functions}'" >>"\${EXTENSION_MANAGER_LOG_FILE}"
FUNCTION_DEFINITION_HEADER
for hook_point_function in ${hook_point_functions}; do
hook_point_functions_loop_counter=$((hook_point_functions_loop_counter + 1))
# store the full name in a hash, so we can track which were actually called later.
defined_hook_point_functions["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="DEFINED=yes ${extension_function_info["${hook_point}${hook_extension_delimiter}${hook_point_function}"]}"
# prepare the call context
local hook_point_function_variables="${common_function_vars}" # start with common vars... (eg: HOOK_POINT_TOTAL_FUNCS)
# add the contextual extension info for the function (eg, EXTENSION_DIR)
hook_point_function_variables="${hook_point_function_variables} ${extension_function_info["${hook_point}${hook_extension_delimiter}${hook_point_function}"]}"
# add the current execution counter, so the extension author can know in which order it is being actually called
hook_point_function_variables="${hook_point_function_variables} HOOK_ORDER=\"${hook_point_functions_loop_counter}\""
# add it to our (not the call site!) environment. if we export those in the call site, the stack is corrupted.
eval "${hook_point_function_variables}"
# output the call, passing arguments, and also logging the output to the extensions log.
# attention: don't pipe here (eg, capture output), otherwise hook function cant modify the environment (which is mostly the point)
# @TODO: better error handling. we have a good opportunity to 'set -e' here, and 'set +e' after, so that extension authors are encouraged to write error-free handling code
cat <<-FUNCTION_DEFINITION_CALLSITE >>"${temp_source_file_for_hook_point}"
hook_point_function_trace_sources["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_SOURCE[*]}"
hook_point_function_trace_lines["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_LINENO[*]}"
[[ "\${DEBUG_EXTENSION_CALLS}" == "yes" ]] && display_alert "---> Extension Method ${hook_point}" "${hook_point_functions_loop_counter}/${hook_point_functions_counter} (ext:${EXTENSION:-built-in}) ${hook_point_function}" ""
echo "*** *** Extension-managed hook starting ${hook_point_functions_loop_counter}/${hook_point_functions_counter} '${hook_point}${hook_extension_delimiter}${hook_point_function}':" >>"\${EXTENSION_MANAGER_LOG_FILE}"
${hook_point_function_variables} ${hook_point}${hook_extension_delimiter}${hook_point_function} "\$@"
echo "*** *** Extension-managed hook finished ${hook_point_functions_loop_counter}/${hook_point_functions_counter} '${hook_point}${hook_extension_delimiter}${hook_point_function}':" >>"\${EXTENSION_MANAGER_LOG_FILE}"
FUNCTION_DEFINITION_CALLSITE
# output the cleanup for the implementation as well.
cat <<-FUNCTION_CLEANUP_FOR_HOOK_POINT_IMPLEMENTATION >>"${fragment_manager_cleanup_file}"
unset ${hook_point}${hook_extension_delimiter}${hook_point_function}
FUNCTION_CLEANUP_FOR_HOOK_POINT_IMPLEMENTATION
# unset extension vars for the next loop.
unset EXTENSION EXTENSION_DIR EXTENSION_FILE EXTENSION_ADDED_BY
done
cat <<-FUNCTION_DEFINITION_FOOTER >>"${temp_source_file_for_hook_point}"
echo "*** Extension-managed hook ending '${hook_point}': completed." >>"\${EXTENSION_MANAGER_LOG_FILE}"
} # end ${hook_point}() function
FUNCTION_DEFINITION_FOOTER
# unsets, lest the next loop inherits them
unset hook_point_functions hook_point_functions_sortname_to_realname hook_point_functions_realname_to_sortname
# log what was produced in our own debug logfile
cat "${temp_source_file_for_hook_point}" >>"${EXTENSION_MANAGER_LOG_FILE}"
cat "${fragment_manager_cleanup_file}" >>"${EXTENSION_MANAGER_LOG_FILE}"
# source the generated function.
# shellcheck disable=SC1090
source "${temp_source_file_for_hook_point}"
rm -f "${temp_source_file_for_hook_point}"
done
# Dont show any output until we have more than 1 hook function (we implement one already, below)
[[ ${hook_functions_counter} -gt 0 ]] &&
display_alert "Extension manager" "processed ${hook_points_counter} Extension Methods calls and ${hook_functions_counter} Extension Method implementations" "info" | tee -a "${EXTENSION_MANAGER_LOG_FILE}"
}
cleanup_extension_manager() {
if [[ -f "${fragment_manager_cleanup_file}" ]]; then
display_alert "Cleaning up" "extension manager" "info"
# this will unset all the functions.
# shellcheck disable=SC1090 # dynamic source, thanks, shellcheck
source "${fragment_manager_cleanup_file}"
fi
# reset/unset the variables used
initialize_extension_manager_counter=0
unset extension_function_info defined_hook_point_functions hook_point_function_trace_sources hook_point_function_trace_lines fragment_manager_cleanup_file
}
# why not eat our own dog food?
# process everything that happened during extension related activities
# and write it to the log. also, move the log from the .tmp dir to its
# final location. this will make run_after_build() "hot" (eg, emit warnings)
run_after_build__999_finish_extension_manager() {
# export these maps, so the hook can access them and produce useful stuff.
export defined_hook_point_functions hook_point_function_trace_sources
# eat our own dog food, pt2.
call_extension_method "extension_metadata_ready" <<'EXTENSION_METADATA_READY'
*meta-Meta time!*
Implement this hook to work with/on the meta-data made available by the extension manager.
Interesting stuff to process:
- `"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt"` contains a list of all hook points called, in order.
- For each hook_point in the list, more files will have metadata about that hook point.
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.orig.md` contains the hook documentation at the call site (inline docs), hopefully in Markdown format.
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.compat` contains the compatibility names for the hooks.
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.exports` contains _exported_ environment variables.
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.vars` contains _all_ environment variables.
- `${defined_hook_point_functions}` is a map of _all_ the defined hook point functions and their extension information.
- `${hook_point_function_trace_sources}` is a map of all the hook point functions _that were really called during the build_ and their BASH_SOURCE information.
- `${hook_point_function_trace_lines}` is the same, but BASH_LINENO info.
After this hook is done, the `${EXTENSION_MANAGER_TMP_DIR}` will be removed.
EXTENSION_METADATA_READY
# Move temporary log file over to final destination, and start writing to it instead (although 999 is pretty late in the game)
mv "${EXTENSION_MANAGER_LOG_FILE}" "${DEST}/${LOG_SUBPATH:-debug}/extensions.log"
export EXTENSION_MANAGER_LOG_FILE="${DEST}/${LOG_SUBPATH:-debug}/extensions.log"
# Cleanup. Leave no trace...
[[ -d "${EXTENSION_MANAGER_TMP_DIR}" ]] && rm -rf "${EXTENSION_MANAGER_TMP_DIR}"
}
# This is called by call_extension_method(). To say the truth, this should be in an extension. But then it gets too meta for anyone's head.
write_hook_point_metadata() {
local main_hook_point_name="$1"
[[ ! -d "${EXTENSION_MANAGER_TMP_DIR}" ]] && mkdir -p "${EXTENSION_MANAGER_TMP_DIR}"
cat - >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.orig.md" # Write the hook point documentation received via stdin to a tmp file for later processing.
shift
echo -n "$@" >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.compat" # log the 2nd+ arguments too (those are the alternative/compatibility names), separate file.
compgen -A export >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.exports" # capture the exported env vars.
compgen -A variable >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.vars" # capture all env vars.
# add to the list of hook points called, in order.
echo "${main_hook_point_name}" >>"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt"
}
# Helper function, to get clean "stack traces" that do not include the hook/extension infrastructure code.
get_extension_hook_stracktrace() {
local sources_str="$1" # Give this ${BASH_SOURCE[*]} - expanded
local lines_str="$2" # And this # Give this ${BASH_LINENO[*]} - expanded
local sources lines index final_stack=""
IFS=' ' read -r -a sources <<<"${sources_str}"
IFS=' ' read -r -a lines <<<"${lines_str}"
for index in "${!sources[@]}"; do
local source="${sources[index]}" line="${lines[((index - 1))]}"
# skip extension infrastructure sources, these only pollute the trace and add no insight to users
[[ ${source} == */.tmp/extension_function_definition.sh ]] && continue
[[ ${source} == *lib/extensions.sh ]] && continue
[[ ${source} == */compile.sh ]] && continue
# relativize the source, otherwise too long to display
source="${source#"${SRC}/"}"
# remove 'lib/'. hope this is not too confusing.
source="${source#"lib/"}"
# add to the list
arrow="$([[ "$final_stack" != "" ]] && echo "-> ")"
final_stack="${source}:${line} ${arrow} ${final_stack} "
done
# output the result, no newline
# shellcheck disable=SC2086 # I wanna suppress double spacing, thanks
echo -n $final_stack
}
show_caller_full() {
local frame=0
while caller $frame; do
((frame++))
done
}
# can be called by board, family, config or user to make sure an extension is included.
# single argument is the extension name.
# will look for it in /userpatches/extensions first.
# if not found there will look in /extensions
# if not found will exit 17
declare -i enable_extension_recurse_counter=0
declare -a enable_extension_recurse_stack
enable_extension() {
local extension_name="$1"
local extension_dir extension_file extension_file_in_dir extension_floating_file
local stacktrace
# capture the stack leading to this, possibly with a hint in front.
stacktrace="${ENABLE_EXTENSION_TRACE_HINT}$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")"
# if LOG_ENABLE_EXTENSION, output useful stack, so user can figure out which extensions are being added where
[[ "${LOG_ENABLE_EXTENSION}" == "yes" ]] &&
display_alert "Extension being added" "${extension_name} :: added by ${stacktrace}" ""
# first a check, has the extension manager already initialized? then it is too late to enable_extension(). bail.
if [[ ${initialize_extension_manager_counter} -gt 0 ]]; then
display_alert "Extension problem" "already initialized -- too late to add '${extension_name}' (trace: ${stacktrace})" "err"
exit 2
fi
# check the counter. if recurring, add to the stack and return success
if [[ $enable_extension_recurse_counter -gt 1 ]]; then
enable_extension_recurse_stack+=("${extension_name}")
return 0
fi
# increment the counter
enable_extension_recurse_counter=$((enable_extension_recurse_counter + 1))
# there are many opportunities here. too many, actually. let userpatches override just some functions, etc.
for extension_base_path in "${SRC}/userpatches/extensions" "${EXTER}/extensions"; do
extension_dir="${extension_base_path}/${extension_name}"
extension_file_in_dir="${extension_dir}/${extension_name}.sh"
extension_floating_file="${extension_base_path}/${extension_name}.sh"
if [[ -d "${extension_dir}" ]] && [[ -f "${extension_file_in_dir}" ]]; then
extension_file="${extension_file_in_dir}"
break
elif [[ -f "${extension_floating_file}" ]]; then
extension_dir="${extension_base_path}" # this is misleading. only directory-based extensions should have this.
extension_file="${extension_floating_file}"
break
fi
done
# After that, we should either have extension_file and extension_dir, or throw.
if [[ ! -f "${extension_file}" ]]; then
echo "ERR: Extension problem -- cant find extension '${extension_name}' anywhere - called by ${BASH_SOURCE[1]}"
exit 17 # exit, forcibly. no way we can recover from this, and next extensions will get bogus errors as well.
fi
local before_function_list after_function_list new_function_list
# store a list of existing functions at this point, before sourcing the extension.
before_function_list="$(compgen -A function)"
# error handling during a 'source' call is quite insane in bash after 4.3.
# to be able to catch errors in sourced scripts the only way is to trap
declare -i extension_source_generated_error=0
trap 'extension_source_generated_error=1;' ERR
# source the file. extensions are not supposed to do anything except export variables and define functions, so nothing should happen here.
# there is no way to enforce it though, short of static analysis.
# we could punish the extension authors who violate it by removing some essential variables temporarily from the environment during this source, and restore them later.
# shellcheck disable=SC1090
source "${extension_file}"
# remove the trap we set.
trap - ERR
# decrement the recurse counter, so calls to this method are allowed again.
enable_extension_recurse_counter=$((enable_extension_recurse_counter - 1))
# test if it fell into the trap, and abort immediately with an error.
if [[ $extension_source_generated_error != 0 ]]; then
display_alert "Extension failed to load" "${extension_file}" "err"
exit 4
fi
# get a new list of functions after sourcing the extension
after_function_list="$(compgen -A function)"
# compare before and after, thus getting the functions defined by the extension.
# comm is oldskool. we like it. go "man comm" to understand -13 below
new_function_list="$(comm -13 <(echo "$before_function_list" | sort) <(echo "$after_function_list" | sort))"
# iterate over defined functions, store them in global associative array extension_function_info
for newly_defined_function in ${new_function_list}; do
extension_function_info["${newly_defined_function}"]="EXTENSION=\"${extension_name}\" EXTENSION_DIR=\"${extension_dir}\" EXTENSION_FILE=\"${extension_file}\" EXTENSION_ADDED_BY=\"${stacktrace}\""
done
# snapshot, then clear, the stack
local -a stack_snapshot=("${enable_extension_recurse_stack[@]}")
enable_extension_recurse_stack=()
# process the stacked snapshot, finally enabling the extensions
for stacked_extension in "${stack_snapshot[@]}"; do
ENABLE_EXTENSION_TRACE_HINT="RECURSE ${stacktrace} ->" enable_extension "${stacked_extension}"
done
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
@@ -8,14 +8,19 @@
# Functions:
# mount_chroot
# umount_chroot
# unmount_on_exit
# check_loop_device
# install_external_applications
# write_uboot
# copy_all_packages_files_for
# customize_image
# install_deb_chroot
# run_on_sdcard
# mount_chroot <target>
@@ -24,12 +29,17 @@
#
mount_chroot()
{
local target=$1
mount -t proc chproc "${target}"/proc
mount -t sysfs chsys "${target}"/sys
mount -t devtmpfs chdev "${target}"/dev || mount --bind /dev "${target}"/dev
mount -t devpts chpts "${target}"/dev/pts
} #############################################################################
}
# umount_chroot <target>
#
@@ -37,6 +47,7 @@ mount_chroot()
#
umount_chroot()
{
local target=$1
display_alert "Unmounting" "$target" "info"
while grep -Eq "${target}.*(dev|proc|sys)" /proc/mounts
@@ -46,13 +57,28 @@ umount_chroot()
umount -l "${target}"/sys >/dev/null 2>&1
sleep 5
done
} #############################################################################
}
# unmount_on_exit
#
unmount_on_exit()
{
trap - INT TERM EXIT
local stacktrace="$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")"
display_alert "unmount_on_exit() called!" "$stacktrace" "err"
if [[ "${ERROR_DEBUG_SHELL}" == "yes" ]]; then
ERROR_DEBUG_SHELL=no # dont do it twice
display_alert "MOUNT" "${MOUNT}" "err"
display_alert "SDCARD" "${SDCARD}" "err"
display_alert "ERROR_DEBUG_SHELL=yes, starting a shell." "ERROR_DEBUG_SHELL" "err"
bash < /dev/tty || true
fi
umount_chroot "${SDCARD}/"
umount -l "${SDCARD}"/tmp >/dev/null 2>&1
umount -l "${SDCARD}" >/dev/null 2>&1
@@ -61,18 +87,18 @@ unmount_on_exit()
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose "${ROOT_MAPPER}"
losetup -d "${LOOP}" >/dev/null 2>&1
rm -rf --one-file-system "${SDCARD}"
exit_with_error "debootstrap-ng was interrupted" || true # don't trigger again
}
if [[ -f "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid" ]];then
rm "/run/orangepi/${BOARD^}_${BRANCH}_${RELEASE}_${BUILD_DESKTOP}_${BUILD_MINIMAL}.pid"
fi
exit_with_error "debootstrap-ng was interrupted"
} #############################################################################
# check_loop_device <device_node>
#
check_loop_device()
{
local device=$1
if [[ ! -b $device ]]; then
if [[ $CONTAINER_COMPAT == yes && -b /tmp/$device ]]; then
@@ -82,62 +108,147 @@ check_loop_device()
exit_with_error "Device node $device does not exist"
fi
fi
} #############################################################################
}
# write_uboot <loopdev>
#
# writes u-boot to loop device
# Parameters:
# loopdev: loop device with mounted rootfs image
#
write_uboot()
{
local loop=$1
local loop=$1 revision
display_alert "Writing U-boot bootloader" "$loop" "info"
mkdir -p /tmp/u-boot/
dpkg -x "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" /tmp/u-boot/
write_uboot_platform "/tmp/u-boot/usr/lib/${CHOSEN_UBOOT}_${REVISION}_${ARCH}" "$loop"
TEMP_DIR=$(mktemp -d || exit 1)
chmod 700 ${TEMP_DIR}
revision=${REVISION}
if [[ -n $UPSTREM_VER ]]; then
revision=${UPSTREM_VER}
dpkg -x "${DEB_STORAGE}/u-boot/linux-u-boot-${BOARD}-${BRANCH}_${revision}_${ARCH}.deb" ${TEMP_DIR}/
else
dpkg -x "${DEB_STORAGE}/u-boot/${CHOSEN_UBOOT}_${revision}_${ARCH}.deb" ${TEMP_DIR}/
fi
# source platform install to read $DIR
source ${TEMP_DIR}/usr/lib/u-boot/platform_install.sh
write_uboot_platform "${TEMP_DIR}${DIR}" "$loop"
[[ $? -ne 0 ]] && exit_with_error "U-boot bootloader failed to install" "@host"
rm -r /tmp/u-boot/
sync
} #############################################################################
rm -rf ${TEMP_DIR}
}
# copy_all_packages_files_for <folder> to package
#
copy_all_packages_files_for()
{
local package_name="${1}"
for package_src_dir in ${PACKAGES_SEARCH_ROOT_ABSOLUTE_DIRS};
do
local package_dirpath="${package_src_dir}/${package_name}"
if [ -d "${package_dirpath}" ];
then
cp -r "${package_dirpath}/"* "${destination}/" 2> /dev/null
display_alert "Adding files from" "${package_dirpath}"
fi
done
}
customize_image()
{
# for users that need to prepare files at host
[[ -f $USERPATCHES_PATH/customize-image-host.sh ]] && source "$USERPATCHES_PATH"/customize-image-host.sh
call_extension_method "pre_customize_image" "image_tweaks_pre_customize" << 'PRE_CUSTOMIZE_IMAGE'
*run before customize-image.sh*
This hook is called after `customize-image-host.sh` is called, but before the overlay is mounted.
It thus can be used for the same purposes as `customize-image-host.sh`.
PRE_CUSTOMIZE_IMAGE
cp "$USERPATCHES_PATH"/customize-image.sh "${SDCARD}"/tmp/customize-image.sh
chmod +x "${SDCARD}"/tmp/customize-image.sh
mkdir -p "${SDCARD}"/tmp/overlay
# util-linux >= 2.27 required
mount -o bind,ro "$USERPATCHES_PATH"/overlay "${SDCARD}"/tmp/overlay
display_alert "Calling image customization script" "customize-image.sh" "info"
chroot "${SDCARD}" /bin/bash -c "/tmp/customize-image.sh $RELEASE $LINUXFAMILY $BOARD $BUILD_DESKTOP"
chroot "${SDCARD}" /bin/bash -c "/tmp/customize-image.sh $RELEASE $LINUXFAMILY $BOARD $BUILD_DESKTOP $ARCH"
CUSTOMIZE_IMAGE_RC=$?
umount -i "${SDCARD}"/tmp/overlay >/dev/null 2>&1
mountpoint -q "${SDCARD}"/tmp/overlay || rm -r "${SDCARD}"/tmp/overlay
if [[ $CUSTOMIZE_IMAGE_RC != 0 ]]; then
exit_with_error "customize-image.sh exited with error (rc: $CUSTOMIZE_IMAGE_RC)"
fi
} #############################################################################
call_extension_method "post_customize_image" "image_tweaks_post_customize" << 'POST_CUSTOMIZE_IMAGE'
*post customize-image.sh hook*
Run after the customize-image.sh script is run, and the overlay is unmounted.
POST_CUSTOMIZE_IMAGE
}
install_deb_chroot()
{
local package=$1
local type=$2
local name=$(basename "${package}")
cp "${package}" "${SDCARD}/root/${name}"
if [[ ${type} == "orangepi" ]]; then
display_alert "Installing form Orange Pi" "$name"
local variant=$2
local transfer=$3
local name
local desc
if [[ ${variant} != remote ]]; then
name="/root/"$(basename "${package}")
[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"
desc=""
else
display_alert "Installing" "$name"
name=$1
desc=" from repository"
fi
display_alert "Installing${desc}" "${name/\/root\//}"
[[ $NO_APT_CACHER != yes ]] && local apt_extra="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
LC_ALL=C LANG=C chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq \
$apt_extra --no-install-recommends install ./root/$name" >> "${DEST}"/debug/install.log 2>&1
# when building in bulk from remote, lets make sure we have up2date index
[[ $BUILD_ALL == yes && ${variant} == remote ]] && chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get $apt_extra -yqq update"
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq $apt_extra --no-install-recommends install $name" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
[[ $? -ne 0 ]] && exit_with_error "Installation of $name failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"
[[ ${variant} == remote && ${transfer} == yes ]] && rsync -rq "${SDCARD}"/var/cache/apt/archives/*.deb ${DEB_STORAGE}/
}
dpkg_install_deb_chroot()
{
local package=$1
local name
local desc
name="/root/"$(basename "${package}")
[[ ! -f "${SDCARD}${name}" ]] && cp "${package}" "${SDCARD}${name}"
display_alert "Installing${desc}" "${name/\/root\//}"
# when building in bulk from remote, lets make sure we have up2date index
chroot "${SDCARD}" /bin/bash -c "dpkg -i $name" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
[[ $? -ne 0 ]] && exit_with_error "Installation of $name failed" "${BOARD} ${RELEASE} ${BUILD_DESKTOP} ${LINUXFAMILY}"
}
run_on_sdcard()
{
# Lack of quotes allows for redirections and pipes easily.
chroot "${SDCARD}" /bin/bash -c "${@}" >> "${DEST}"/${LOG_SUBPATH}/install.log
rm -f "${SDCARD}/root/${name}"
}

View File

@@ -1,28 +1,48 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
#
# Main program
#
cleanup_list() {
local varname="${1}"
local list_to_clean="${!varname}"
list_to_clean="${list_to_clean#"${list_to_clean%%[![:space:]]*}"}"
list_to_clean="${list_to_clean%"${list_to_clean##*[![:space:]]}"}"
echo ${list_to_clean}
}
if [[ $(basename "$0") == main.sh ]]; then
echo "Please use build.sh to start the build process"
exit 255
fi
# default umask for root is 022 so parent directories won't be group writeable without this
# this is used instead of making the chmod in prepare_host() recursive
umask 002
# destination
DEST="${SRC}"/output
REVISION="2.1.8"
if [ -d "$CONFIG_PATH/output" ]; then
DEST="${CONFIG_PATH}"/output
else
DEST="${SRC}"/output
fi
REVISION="3.0.0"
[[ $DOWNLOAD_MIRROR == "china" ]] && NTP_SERVER="cn.pool.ntp.org"
@@ -38,15 +58,12 @@ fi
backtitle="Orange Pi building script, http://www.orangepi.org"
titlestr="Choose an option"
# if language not set, set to english
[[ -z $LANGUAGE ]] && export LANGUAGE="en_US:en"
# Warnings mitigation
[[ -z $LANGUAGE ]] && export LANGUAGE="en_US:en" # set to english if not set
[[ -z $CONSOLE_CHAR ]] && export CONSOLE_CHAR="UTF-8" # set console to UTF-8 if not set
# default console if not set
[[ -z $CONSOLE_CHAR ]] && export CONSOLE_CHAR="UTF-8"
# Libraries include
[[ -z $FORCE_CHECKOUT ]] && FORCE_CHECKOUT=yes
# Load libraries
# shellcheck source=debootstrap.sh
source "${SRC}"/scripts/debootstrap.sh # system specific install
# shellcheck source=image-helpers.sh
@@ -58,23 +75,28 @@ source "${SRC}"/scripts/desktop.sh # desktop specific install
# shellcheck source=compilation.sh
source "${SRC}"/scripts/compilation.sh # patching and compilation of kernel, uboot, ATF
# shellcheck source=compilation-prepare.sh
#source "${SRC}"/scripts/compilation-prepare.sh # kernel plugins - 3rd party drivers that are not upstreamed. Like WG, AUFS, various Wifi
#source "${SRC}"/scripts/compilation-prepare.sh # drivers that are not upstreamed
# shellcheck source=makeboarddeb.sh
source "${SRC}"/scripts/makeboarddeb.sh # create board support package
source "${SRC}"/scripts/makeboarddeb.sh # board support package
# shellcheck source=general.sh
source "${SRC}"/scripts/general.sh # general functions
# shellcheck source=chroot-buildpackages.sh
source "${SRC}"/scripts/chroot-buildpackages.sh # building packages in chroot
source "${SRC}"/scripts/chroot-buildpackages.sh # chroot packages building
# shellcheck source=pack.sh
source "${SRC}"/scripts/pack-uboot.sh
# set log path
LOG_SUBPATH=${LOG_SUBPATH:=debug}
# compress and remove old logs
mkdir -p "${DEST}"/debug
(cd "${DEST}"/debug && tar -czf logs-"$(<timestamp)".tgz ./*.log) > /dev/null 2>&1
rm -f "${DEST}"/debug/*.log > /dev/null 2>&1
date +"%d_%m_%Y-%H_%M_%S" > "${DEST}"/debug/timestamp
mkdir -p "${DEST}"/${LOG_SUBPATH}
(cd "${DEST}"/${LOG_SUBPATH} && tar -czf logs-"$(<timestamp)".tgz ./*.log) > /dev/null 2>&1
rm -f "${DEST}"/${LOG_SUBPATH}/*.log > /dev/null 2>&1
date +"%d_%m_%Y-%H_%M_%S" > "${DEST}"/${LOG_SUBPATH}/timestamp
# delete compressed logs older than 7 days
(cd "${DEST}"/debug && find . -name '*.tgz' -mtime +7 -delete) > /dev/null
(cd "${DEST}"/${LOG_SUBPATH} && find . -name '*.tgz' -mtime +7 -delete) > /dev/null
if [[ $PROGRESS_DISPLAY == none ]]; then
@@ -88,15 +110,19 @@ fi
if [[ $PROGRESS_LOG_TO_FILE != yes ]]; then unset PROGRESS_LOG_TO_FILE; fi
SHOW_WARNING=yes
if [[ $USE_CCACHE != no ]]; then
CCACHE=ccache
export PATH="/usr/lib/ccache:$PATH"
# private ccache directory to avoid permission issues when using build script with "sudo"
# see https://ccache.samba.org/manual.html#_sharing_a_cache for alternative solution
[[ $PRIVATE_CCACHE == yes ]] && export CCACHE_DIR=$DEST/cache/ccache
[[ $PRIVATE_CCACHE == yes ]] && export CCACHE_DIR=$EXTER/cache/ccache
else
@@ -104,19 +130,36 @@ else
fi
if [ "$OFFLINE_WORK" == "yes" ]; then
echo -e "\n"
display_alert "* " "You are working offline."
display_alert "* " "Sources, time and host will not be checked"
echo -e "\n"
sleep 3s
else
# we need dialog to display the menu in case not installed. Other stuff gets installed later
prepare_host_basic
if [[ -n $REPOSITORY_UPDATE ]]; then
# select stable/beta configuration
if [[ $BETA == yes ]]; then
DEB_STORAGE=$DEST/debs-beta
REPO_STORAGE=$DEST/repository-beta
REPO_CONFIG="aptly-beta.conf"
else
DEB_STORAGE=$DEST/debs
REPO_STORAGE=$DEST/repository
REPO_CONFIG="aptly.conf"
fi
# For user override
if [[ -f "${USERPATCHES_PATH}"/lib.config ]]; then
display_alert "Using user configuration override" "userpatches/lib.config" "info"
source "${USERPATCHES_PATH}"/lib.config
fi
repo-manipulate "$REPOSITORY_UPDATE"
exit
fi
# if BUILD_OPT, KERNEL_CONFIGURE, BOARD, BRANCH or RELEASE are not set, display selection menu
# if BUILD_OPT, KERNEL_CONFIGURE, BOARD, BRANCH or RELEASE are not set, display selection menu
if [[ -z $BUILD_OPT ]]; then
options+=("u-boot" "U-boot package")
@@ -132,35 +175,62 @@ if [[ -z $BUILD_OPT ]]; then
unset options
[[ -z $BUILD_OPT ]] && exit_with_error "No option selected"
[[ $BUILD_OPT == rootfs ]] && ROOT_FS_CREATE_ONLY="yes"
fi
if [[ ${BUILD_OPT} =~ kernel|image ]]; then
if [[ -z $KERNEL_CONFIGURE ]]; then
options+=("no" "Do not change the kernel configuration")
options+=("yes" "Show a kernel configuration menu before compilation")
menustr="Select the kernel configuration."
KERNEL_CONFIGURE=$(whiptail --title "${titlestr}" --backtitle "$backtitle" --notags \
--menu "${menustr}" $TTY_Y $TTY_X $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $KERNEL_CONFIGURE ]] && exit_with_error "No option selected"
fi
fi
if [[ -z $BOARD ]]; then
options+=("orangepir1" "Allwinner H2+ quad core 256MB RAM WiFi SPI 2xETH")
options+=("orangepizero" "Allwinner H2+ quad core 256MB/512MB RAM WiFi SPI")
options+=("orangepipc" "Allwinner H3 quad core 1GB RAM")
options+=("orangepipcplus" "Allwinner H3 quad core 1GB RAM WiFi eMMC")
options+=("orangepione" "Allwinner H3 quad core 512MB/1GB RAM")
options+=("orangepilite" "Allwinner H3 quad core 512MB/1GB RAM WiFi")
options+=("orangepiplus" "Allwinner H3 quad core 1GB/2GB RAM WiFi GBE eMMC")
options+=("orangepiplus2e" "Allwinner H3 quad core 2GB RAM WiFi GBE eMMC")
options+=("orangepizeroplus2h3" "Allwinner H3 quad core 512MB RAM WiFi/BT eMMC")
options+=("orangepipch5" "Allwinner H5 quad core 1GB RAM")
options+=("orangepipc2" "Allwinner H5 quad core 1GB RAM GBE SPI")
options+=("orangepioneh5" "Allwinner H5 quad core 512MB/1GB RAM")
options+=("orangepiprime" "Allwinner H5 quad core 2GB RAM GBE WiFi/BT")
options+=("orangepizeroplus" "Allwinner H5 quad core 512MB RAM GBE WiFi SPI")
options+=("orangepizeroplus2h5" "Allwinner H5 quad core 512MB RAM WiFi/BT eMMC")
options+=("orangepi3" "Allwinner H6 quad core 1GB/2GB RAM GBE WiFi/BT-AP6256 eMMC USB3")
options+=("orangepi3-lts" "Allwinner H6 quad core 2GB RAM GBE WiFi/BT-AW859A eMMC USB3")
options+=("orangepilite2" "Allwinner H6 quad core 1GB RAM WiFi/BT USB3")
options+=("orangepioneplus" "Allwinner H6 quad core 1GB RAM GBE")
options+=("orangepizero2" "Allwinner H616 quad core 512MB/1GB RAM WiFi/BT GBE SPI")
#options+=("orangepizero2-b" "Allwinner H616 quad core 1GB RAM WiFi/BT GBE SPI")
#options+=("orangepizero2-lts" "Allwinner H616 quad core 1.5GB RAM WiFi/BT GBE SPI")
options+=("orangepi4" "Rockchip RK3399 hexa core 4GB RAM GBE eMMc USB3 USB-C WiFi/BT")
options+=("orangepir1plus" "Rockchip RK3328 quad core 1GB RAM 2xGBE 8211E USB2 SPI")
options+=("orangepir1plus-lts" "Rockchip RK3328 quad core 1GB RAM 2xGBE YT8531C USB2 SPI")
#options+=("orangepir1" "Allwinner H2+ quad core 256MB RAM WiFi SPI 2xETH")
#options+=("orangepizero" "Allwinner H2+ quad core 256MB/512MB RAM WiFi SPI")
#options+=("orangepipc" "Allwinner H3 quad core 1GB RAM")
#options+=("orangepipcplus" "Allwinner H3 quad core 1GB RAM WiFi eMMC")
#options+=("orangepione" "Allwinner H3 quad core 512MB RAM")
#options+=("orangepilite" "Allwinner H3 quad core 512MB RAM WiFi")
#options+=("orangepiplus" "Allwinner H3 quad core 1GB/2GB RAM WiFi GBE eMMC")
#options+=("orangepiplus2e" "Allwinner H3 quad core 2GB RAM WiFi GBE eMMC")
#options+=("orangepizeroplus2h3" "Allwinner H3 quad core 512MB RAM WiFi/BT eMMC")
#options+=("orangepipch5" "Allwinner H5 quad core 1GB RAM")
#options+=("orangepipc2" "Allwinner H5 quad core 1GB RAM GBE SPI")
#options+=("orangepioneh5" "Allwinner H5 quad core 512MB/1GB RAM")
#options+=("orangepiprime" "Allwinner H5 quad core 2GB RAM GBE WiFi/BT")
#options+=("orangepizeroplus" "Allwinner H5 quad core 512MB RAM GBE WiFi SPI")
#options+=("orangepizeroplus2h5" "Allwinner H5 quad core 512MB RAM WiFi/BT eMMC")
#options+=("orangepi3" "Allwinner H6 quad core 1GB/2GB RAM GBE WiFi/BT eMMC USB3")
options+=("orangepi3-lts" "Allwinner H6 quad core 2GB RAM GBE WiFi/BT-AW859A eMMC USB3")
#options+=("orangepilite2" "Allwinner H6 quad core 1GB RAM WiFi/BT USB3")
#options+=("orangepioneplus" "Allwinner H6 quad core 1GB RAM GBE")
#options+=("orangepizero2" "Allwinner H616 quad core 512MB/1GB RAM WiFi/BT GBE SPI")
#options+=("orangepizero2-b" "Allwinner H616 quad core 512MB/1GB RAM WiFi/BT GBE SPI")
#options+=("orangepizero2-lts" "Allwinner H616 quad core 1.5GB RAM WiFi/BT GBE SPI")
#options+=("orangepi400" "Allwinner H616 quad core 4GB RAM WiFi/BT GBE eMMC VGA")
#options+=("orangepi4" "Rockchip RK3399 hexa core 4GB RAM GBE eMMC USB3 USB-C WiFi/BT")
#options+=("orangepi800" "Rockchip RK3399 hexa core 4GB RAM GBE eMMC USB3 USB-C WiFi/BT VGA")
options+=("orangepi4-lts" "Rockchip RK3399 hexa core 4GB RAM GBE eMMC USB3 USB-C WiFi/BT")
#options+=("orangepir1plus" "Rockchip RK3328 quad core 1GB RAM 2xGBE USB2 SPI")
menustr="Please choose a Board."
BOARD=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" \
@@ -181,147 +251,115 @@ LINUXFAMILY="${BOARDFAMILY}"
if [[ -z $BRANCH ]]; then
options=()
[[ $KERNEL_TARGET == *current* ]] && options+=("current" "Mainline")
[[ $KERNEL_TARGET == *legacy* ]] && options+=("legacy" "Old stable")
[[ $KERNEL_TARGET == *dev* && $EXPERT = yes ]] && options+=("dev" "\Z1Development version (@kernel.org)\Zn")
options=()
[[ $KERNEL_TARGET == *current* ]] && options+=("current" "Recommended. Come with best support")
[[ $KERNEL_TARGET == *legacy* ]] && options+=("legacy" "Old stable / Legacy")
[[ $KERNEL_TARGET == *edge* && $EXPERT = yes ]] && options+=("edge" "\Z1Bleeding edge from @kernel.org\Zn")
menustr="Select the target kernel branch\nExact kernel versions depend on selected board"
# do not display selection dialog if only one kernel branch is available
if [[ "${#options[@]}" == 2 ]]; then
BRANCH="${options[0]}"
else
menustr="Select the target kernel branch\nExact kernel versions depend on selected board"
# do not display selection dialog if only one kernel branch is available
if [[ "${#options[@]}" == 2 ]]; then
BRANCH="${options[0]}"
else
BRANCH=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
fi
unset options
[[ -z $BRANCH ]] && exit_with_error "No kernel branch selected"
fi
unset options
[[ -z $BRANCH ]] && exit_with_error "No kernel branch selected"
[[ $BRANCH == dev && $SHOW_WARNING == yes ]] && show_developer_warning
else
[[ $KERNEL_TARGET != *$BRANCH* ]] && exit_with_error "Kernel branch not defined for this board" "$BRANCH"
[[ $BRANCH == next ]] && KERNEL_TARGET="next"
# next = new legacy. Should stay for backward compatibility, but be removed from menu above
# or we left definitions in board configs and only remove menu
[[ $KERNEL_TARGET != *$BRANCH* ]] && exit_with_error "Kernel branch not defined for this board" "$BRANCH"
fi
if [[ ${BUILD_OPT} == image || ${BUILD_OPT} == kernel ]]; then
if [[ -z $KERNEL_CONFIGURE ]]; then
options+=("no" "Do not change the kernel configuration")
options+=("yes" "Show a kernel configuration menu before compilation")
if [[ $BUILD_OPT =~ rootfs|image && -z $RELEASE ]]; then
menustr="Select the kernel configuration."
KERNEL_CONFIGURE=$(whiptail --title "${titlestr}" --backtitle "$backtitle" --notags \
--menu "${menustr}" $TTY_Y $TTY_X $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
options=()
unset options
[[ -z $KERNEL_CONFIGURE ]] && exit_with_error "No option selected"
fi
distros_options
menustr="Select the target OS release package base"
RELEASE=$(whiptail --title "Choose a release package base" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
#echo "options : ${options}"
[[ -z $RELEASE ]] && exit_with_error "No release selected"
unset options
fi
# define distribution support status
declare -A distro_name
distro_name['stretch']="Debian 9 Stretch"
distro_name['buster']="Debian 10 Buster"
distro_name['bullseye']="Debian 11 Bullseye"
distro_name['xenial']="Ubuntu Xenial 16.04 LTS"
distro_name['bionic']="Ubuntu Bionic 18.04 LTS"
distro_name['focal']="Ubuntu Focal 20.04 LTS"
distro_name['eoan']="Ubuntu Eoan 19.10"
# don't show desktop option if we choose minimal build
[[ $BUILD_MINIMAL == yes ]] && BUILD_DESKTOP=no
if [[ ${BUILD_OPT} == image || ${BUILD_OPT} == rootfs ]]; then
if [[ $BUILD_OPT =~ rootfs|image && -z $BUILD_DESKTOP ]]; then
RELEASE_TARGET="stretch buster bullseye xenial bionic eoan focal"
# read distribution support status which is written to the orangepi-release file
set_distribution_status
if [[ -z $RELEASE ]]; then
options=()
options+=("no" "Image with console interface (server)")
options+=("yes" "Image with desktop environment")
if [[ $BRANCH == legacy ]]; then
if [[ $LINUXFAMILY == sun50iw9 || $LINUXFAMILY == sun50iw6 ]]; then
RELEASE_TARGET="buster bionic focal"
elif [[ $LINUXFAMILY == rk3399 ]]; then
RELEASE_TARGET="xenial bionic buster"
else
RELEASE_TARGET="xenial"
fi
elif [[ $BRANCH == current ]]; then
RELEASE_TARGET="buster bionic focal"
[[ $LINUXFAMILY == sun50iw6 ]] && RELEASE_TARGET="buster focal"
else
[[ -z $BRANCH ]] && exit_with_error "No kernel branch selected"
fi
distro_menu "stretch"
distro_menu "buster"
distro_menu "bullseye"
distro_menu "xenial"
distro_menu "bionic"
distro_menu "eoan"
distro_menu "focal"
menustr="Select the target OS release package base"
RELEASE=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $RELEASE ]] && exit_with_error "No option selected"
menustr="Select the target image type"
BUILD_DESKTOP=$(whiptail --title "Choose image type" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BUILD_DESKTOP ]] && exit_with_error "No option selected"
if [[ ${BUILD_DESKTOP} == "yes" ]]; then
BUILD_MINIMAL=no
SELECTED_CONFIGURATION="desktop"
fi
# don't show desktop option if we choose minimal build
[[ $BUILD_MINIMAL == yes ]] && BUILD_DESKTOP="no"
fi
if [[ -z $BUILD_DESKTOP ]]; then
if [[ $BUILD_OPT =~ rootfs|image && $BUILD_DESKTOP == no && -z $BUILD_MINIMAL ]]; then
options+=("no" "Image with console interface (server)")
options+=("yes" "Image with desktop environment")
menustr="Select the target image type."
BUILD_DESKTOP=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" --notags \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BUILD_DESKTOP ]] && exit_with_error "No option selected"
[[ $BUILD_DESKTOP == yes ]] && BUILD_MINIMAL="no"
options=()
options+=("no" "Standard image with console interface")
options+=("yes" "Minimal image with console interface")
menustr="Select the target image type"
BUILD_MINIMAL=$(whiptail --title "Choose image type" --backtitle "${backtitle}" \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BUILD_MINIMAL ]] && exit_with_error "No option selected"
if [[ $BUILD_MINIMAL == "yes" ]]; then
SELECTED_CONFIGURATION="cli_minimal"
else
SELECTED_CONFIGURATION="cli_standard"
fi
if [[ $BUILD_DESKTOP == "no" && -z $BUILD_MINIMAL ]]; then
options+=("no" "Standard image with console interface")
options+=("yes" "Minimal image with console interface")
menustr="Select the target image type."
BUILD_MINIMAL=$(whiptail --title "${titlestr}" --backtitle "${backtitle}" --notags \
--menu "${menustr}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
--cancel-button Exit --ok-button Select "${options[@]}" \
3>&1 1>&2 2>&3)
unset options
[[ -z $BUILD_MINIMAL ]] && exit_with_error "No option selected"
fi
fi
#prevent conflicting setup
[[ $BUILD_DESKTOP == yes ]] && BUILD_MINIMAL=no
[[ $BUILD_DESKTOP == yes ]] && IMAGETYPE="desktop"
[[ $BUILD_DESKTOP == no ]] && IMAGETYPE="server"
[[ $BUILD_MINIMAL == yes ]] && EXTERNAL_NEW=no
if [[ $BUILD_DESKTOP == "yes" ]]; then
BUILD_MINIMAL=no
SELECTED_CONFIGURATION="desktop"
elif [[ $BUILD_MINIMAL != "yes" || -z "${BUILD_MINIMAL}" ]]; then
BUILD_MINIMAL=no # Just in case BUILD_MINIMAL is not defined
BUILD_DESKTOP=no
SELECTED_CONFIGURATION="cli_standard"
elif [[ $BUILD_MINIMAL == "yes" ]]; then
BUILD_DESKTOP=no
SELECTED_CONFIGURATION="cli_minimal"
fi
#[[ ${KERNEL_CONFIGURE} == prebuilt ]] && [[ -z ${REPOSITORY_INSTALL} ]] && \
#REPOSITORY_INSTALL="u-boot,kernel,bsp,orangepi-zsh,orangepi-config,orangepi-firmware${BUILD_DESKTOP:+,orangepi-desktop}"
CONTAINER_COMPAT="no"
[[ -z $COMPRESS_OUTPUTIMAGE ]] && COMPRESS_OUTPUTIMAGE="yes"
#shellcheck source=configuration.sh
source "${SRC}"/scripts/configuration.sh
@@ -338,10 +376,17 @@ else
fi
if [[ $BUILD_ALL == yes && -n $GPG_PASS ]]; then
IMAGE_TYPE=stable
call_extension_method "post_determine_cthreads" "config_post_determine_cthreads" << 'POST_DETERMINE_CTHREADS'
*give config a chance modify CTHREADS programatically. A build server may work better with hyperthreads-1 for example.*
Called early, before any compilation work starts.
POST_DETERMINE_CTHREADS
if [[ $BETA == yes ]]; then
IMAGE_TYPE=nightly
elif [[ $BETA != "yes" && $BUILD_ALL == yes && -n $GPG_PASS ]]; then
IMAGE_TYPE=stable
else
IMAGE_TYPE=user-built
IMAGE_TYPE=user-built
fi
branch2dir() {
@@ -352,18 +397,15 @@ BOOTSOURCEDIR="${BOOTDIR}/$(branch2dir "${BOOTBRANCH}")"
LINUXSOURCEDIR="${KERNELDIR}/$(branch2dir "${KERNELBRANCH}")"
[[ -n $ATFSOURCE ]] && ATFSOURCEDIR="${ATFDIR}/$(branch2dir "${ATFBRANCH}")"
# The version of the Linux kernel
#VER=$(grab_version "$LINUXSOURCEDIR")
#KERNEL_NAME="linux${VER}"
BSP_CLI_PACKAGE_NAME="orangepi-bsp-cli-${BOARD}"
BSP_CLI_PACKAGE_FULLNAME="${BSP_CLI_PACKAGE_NAME}_${REVISION}_${ARCH}"
BSP_DESKTOP_PACKAGE_NAME="orangepi-bsp-desktop-${BOARD}"
BSP_DESKTOP_PACKAGE_FULLNAME="${BSP_DESKTOP_PACKAGE_NAME}_${REVISION}_${ARCH}"
# define package names
DEB_BRANCH=${BRANCH//default}
# if not empty, append hyphen
DEB_BRANCH=${DEB_BRANCH:+${DEB_BRANCH}-}
CHOSEN_UBOOT=linux-u-boot-${DEB_BRANCH}${BOARD}
CHOSEN_KERNEL=linux-image-${DEB_BRANCH}${LINUXFAMILY}
CHOSEN_ROOTFS=linux-${RELEASE}-root-${DEB_BRANCH}${BOARD}
CHOSEN_DESKTOP=orangepi-${RELEASE}-desktop
CHOSEN_UBOOT=linux-u-boot-${BRANCH}-${BOARD}
CHOSEN_KERNEL=linux-image-${BRANCH}-${LINUXFAMILY}
CHOSEN_ROOTFS=${BSP_CLI_PACKAGE_NAME}
CHOSEN_DESKTOP=orangepi-${RELEASE}-desktop-${DESKTOP_ENVIRONMENT}
CHOSEN_KSRC=linux-source-${BRANCH}-${LINUXFAMILY}
do_default() {
@@ -374,31 +416,50 @@ start=$(date +%s)
# The OFFLINE_WORK variable inside the function
prepare_host
[[ "${JUST_INIT}" == "yes" ]] && exit 0
[[ $CLEAN_LEVEL == *sources* ]] && cleaning "sources"
# fetch_from_repo <url> <dir> <ref> <subdir_flag>
# ignore updates help on building all images - for internal purposes
if [[ $IGNORE_UPDATES != yes ]]; then
display_alert "Downloading sources" "" "info"
if [[ ${IGNORE_UPDATES} != yes ]]; then
fetch_from_repo "$BOOTSOURCE" "$BOOTDIR" "$BOOTBRANCH" "yes"
fetch_from_repo "$KERNELSOURCE" "$KERNELDIR" "$KERNELBRANCH" "yes"
if [[ -n $ATFSOURCE ]]; then
fetch_from_repo "$ATFSOURCE" "${EXTER}/cache/sources/$ATFDIR" "$ATFBRANCH" "yes"
fi
fetch_from_repo "https://github.com/linux-sunxi/sunxi-tools" "${EXTER}/cache/sources/sunxi-tools" "branch:master"
fetch_from_repo "https://github.com/armbian/rkbin" "${EXTER}/cache/sources/rkbin-tools" "branch:master"
display_alert "Downloading sources" "" "info"
[[ $BUILD_OPT =~ u-boot|image ]] && fetch_from_repo "$BOOTSOURCE" "$BOOTDIR" "$BOOTBRANCH" "yes"
[[ $BUILD_OPT =~ kernel|image ]] && fetch_from_repo "$KERNELSOURCE" "$KERNELDIR" "$KERNELBRANCH" "yes"
if [[ -n ${ATFSOURCE} ]]; then
[[ ${BUILD_OPT} =~ u-boot|image ]] && fetch_from_repo "$ATFSOURCE" "${EXTER}/cache/sources/$ATFDIR" "$ATFBRANCH" "yes"
if [[ $BOARD == orangepi4 ]]; then
fetch_from_repo "https://github.com/orangepi-xunlong/rk3399_gst_xserver_libs.git" "${EXTER}/cache/sources/rk3399_gst_xserver_libs" "branch:main"
fi
if [[ ${BOARD} =~ orangepi4|orangepi4-lts|orangepi800 && $BRANCH == legacy ]]; then
[[ $BUILD_OPT =~ image ]] && fetch_from_repo "https://github.com/orangepi-xunlong/rk3399_gst_xserver_libs.git" "${EXTER}/cache/sources/rk3399_gst_xserver_libs" "branch:main"
fi
if [[ ${BOARD} =~ orangepi4|orangepi4-lts|orangepi800 && $RELEASE =~ focal|buster|bullseye|bookworm ]]; then
[[ ${BUILD_OPT} == image ]] && fetch_from_repo "https://github.com/orangepi-xunlong/rk-rootfs-build.git" "${EXTER}/cache/sources/rk-rootfs-build-${RELEASE}" "branch:rk-rootfs-build-${RELEASE}"
fi
call_extension_method "fetch_sources_tools" <<- 'FETCH_SOURCES_TOOLS'
*fetch host-side sources needed for tools and build*
Run early to fetch_from_repo or otherwise obtain sources for needed tools.
FETCH_SOURCES_TOOLS
call_extension_method "build_host_tools" <<- 'BUILD_HOST_TOOLS'
*build needed tools for the build, host-side*
After sources are fetched, build host-side tools needed for the build.
BUILD_HOST_TOOLS
fi
compile_sunxi_tools
install_rkbin_tools
for option in $(tr ',' ' ' <<< "$CLEAN_LEVEL"); do
[[ $option != sources ]] && cleaning "$option"
done
@@ -414,6 +475,7 @@ if [[ $BUILD_OPT == u-boot || $BUILD_OPT == image ]]; then
fi
if [[ $BUILD_OPT == "u-boot" ]]; then
unset BUILD_MINIMAL BUILD_DESKTOP COMPRESS_OUTPUTIMAGE
display_alert "U-boot build done" "@host" "info"
display_alert "Target directory" "${DEB_STORAGE}/u-boot" "info"
display_alert "File name" "${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" "info"
@@ -425,10 +487,12 @@ if [[ $BUILD_OPT == kernel || $BUILD_OPT == image ]]; then
if [[ ! -f ${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb ]]; then
KDEB_CHANGELOG_DIST=$RELEASE
[[ "${REPOSITORY_INSTALL}" != *kernel* ]] && compile_kernel
fi
if [[ $BUILD_OPT == "kernel" ]]; then
unset BUILD_MINIMAL BUILD_DESKTOP COMPRESS_OUTPUTIMAGE
display_alert "Kernel build done" "@host" "info"
display_alert "Target directory" "${DEB_STORAGE}/" "info"
display_alert "File name" "${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" "info"
@@ -442,25 +506,53 @@ if [[ $BUILD_OPT == rootfs || $BUILD_OPT == image ]]; then
[[ "${REPOSITORY_INSTALL}" != *orangepi-config* ]] && compile_orangepi-config
fi
if [[ ! -f ${DEB_STORAGE}/orangepi-firmware_${REVISION}_all.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *orangepi-firmware* ]] && compile_firmware
# Compile orangepi-zsh if packed .deb does not exist or use the one from repository
if [[ ! -f ${DEB_STORAGE}/orangepi-zsh_${REVISION}_all.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *orangepi-zsh* ]] && compile_orangepi-zsh
fi
# Compile orangepi-firmware if packed .deb does not exist or use the one from repository
if [[ "${REPOSITORY_INSTALL}" != *orangepi-firmware* ]]; then
if ! ls "${DEB_STORAGE}/orangepi-firmware_${REVISION}_all.deb" 1> /dev/null 2>&1; then
FULL=""
REPLACE="-full"
compile_firmware
fi
#if ! ls "${DEB_STORAGE}/orangepi-firmware-full_${REVISION}_all.deb" 1> /dev/null 2>&1; then
#FULL="-full"
#REPLACE=""
#compile_firmware
#fi
fi
overlayfs_wrapper "cleanup"
# create board support package
if [[ ! -f ${DEB_STORAGE}/$RELEASE/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *bsp* ]] && create_board_package
fi
[[ -n $RELEASE && ! -f ${DEB_STORAGE}/$RELEASE/${BSP_CLI_PACKAGE_FULLNAME}.deb ]] && create_board_package
# create desktop package
if [[ ! -f ${DEB_STORAGE}/$RELEASE/${CHOSEN_DESKTOP}_${REVISION}_all.deb ]]; then
[[ "${REPOSITORY_INSTALL}" != *orangepi-desktop* ]] && create_desktop_package
fi
#[[ -n $RELEASE && $DESKTOP_ENVIRONMENT && ! -f ${DEB_STORAGE}/$RELEASE/${CHOSEN_DESKTOP}_${REVISION}_all.deb ]] && create_desktop_package
#[[ -n $RELEASE && $DESKTOP_ENVIRONMENT && ! -f ${DEB_STORAGE}/${RELEASE}/${BSP_DESKTOP_PACKAGE_FULLNAME}.deb ]] && create_bsp_desktop_package
[[ -n $RELEASE && $DESKTOP_ENVIRONMENT ]] && create_desktop_package
[[ -n $RELEASE && $DESKTOP_ENVIRONMENT ]] && create_bsp_desktop_package
# build additional packages
[[ $EXTERNAL_NEW == compile ]] && chroot_build_packages
@@ -485,8 +577,13 @@ $([[ -n $BUILD_OPT ]] && echo "BUILD_OPT=${BUILD_OPT} ")\
$([[ -n $RELEASE ]] && echo "RELEASE=${RELEASE} ")\
$([[ -n $BUILD_MINIMAL ]] && echo "BUILD_MINIMAL=${BUILD_MINIMAL} ")\
$([[ -n $BUILD_DESKTOP ]] && echo "BUILD_DESKTOP=${BUILD_DESKTOP} ")\
$([[ -n $KERNEL_CONFIGURE ]] && echo "KERNEL_CONFIGURE=${KERNEL_CONFIGURE}")\
" "info"
$([[ -n $KERNEL_CONFIGURE ]] && echo "KERNEL_CONFIGURE=${KERNEL_CONFIGURE} ")\
$([[ -n $DESKTOP_ENVIRONMENT ]] && echo "DESKTOP_ENVIRONMENT=${DESKTOP_ENVIRONMENT} ")\
$([[ -n $DESKTOP_ENVIRONMENT_CONFIG_NAME ]] && echo "DESKTOP_ENVIRONMENT_CONFIG_NAME=${DESKTOP_ENVIRONMENT_CONFIG_NAME} ")\
$([[ -n $DESKTOP_APPGROUPS_SELECTED ]] && echo "DESKTOP_APPGROUPS_SELECTED=\"${DESKTOP_APPGROUPS_SELECTED}\" ")\
$([[ -n $DESKTOP_APT_FLAGS_SELECTED ]] && echo "DESKTOP_APT_FLAGS_SELECTED=\"${DESKTOP_APT_FLAGS_SELECTED}\" ")\
$([[ -n $COMPRESS_OUTPUTIMAGE ]] && echo "COMPRESS_OUTPUTIMAGE=${COMPRESS_OUTPUTIMAGE} ")\
" "ext"
} # end of do_default()

View File

@@ -1,39 +1,58 @@
#!/bin/bash
#
# Copyright (c) 2015 Igor Pecovnik, igor.pecovnik@gma**.com
# Copyright (c) 2021 Igor Pecovnik, igor.pecovnik@gma**.com
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.
# Create board support packages
#
# Functions:
# create_board_package
create_board_package()
{
display_alert "Creating board support package" "$BOARD $BRANCH" "info"
display_alert "Creating board support package for CLI" "$CHOSEN_ROOTFS" "info"
local destination=$SRC/.tmp/${RELEASE}/${CHOSEN_ROOTFS}_${REVISION}_${ARCH}
rm -rf "${destination}"
bsptempdir=$(mktemp -d)
chmod 700 ${bsptempdir}
trap "rm -rf \"${bsptempdir}\" ; exit 0" 0 1 2 3 15
local destination=${bsptempdir}/${RELEASE}/${BSP_CLI_PACKAGE_FULLNAME}
mkdir -p "${destination}"/DEBIAN
cd $destination
# copy general overlay from packages/bsp-cli
copy_all_packages_files_for "bsp-cli"
# install copy of boot script & environment file
local bootscript_src=${BOOTSCRIPT%%:*}
local bootscript_dst=${BOOTSCRIPT##*:}
mkdir -p "${destination}"/usr/share/orangepi/
cp "${EXTER}/config/bootscripts/${bootscript_src}" "${destination}/usr/share/orangepi/${bootscript_dst}"
[[ -n $BOOTENV_FILE && -f ${EXTER}/config/bootenv/$BOOTENV_FILE ]] && \
cp "${EXTER}/config/bootenv/${BOOTENV_FILE}" "${destination}"/usr/share/orangepi/orangepiEnv.txt
if [[ "${BOOTCONFIG}" != "none" ]]; then
# @TODO: add extension method bsp_prepare_bootloader(), refactor into u-boot extension
local bootscript_src=${BOOTSCRIPT%%:*}
local bootscript_dst=${BOOTSCRIPT##*:}
mkdir -p "${destination}"/usr/share/orangepi/
# add configuration for setting uboot environment from userspace with: fw_setenv fw_printenv
if [[ -n $UBOOT_FW_ENV ]]; then
UBOOT_FW_ENV=($(tr ',' ' ' <<< "$UBOOT_FW_ENV"))
mkdir -p "${destination}"/etc
echo "# Device to access offset env size" > "${destination}"/etc/fw_env.config
echo "/dev/mmcblk0 ${UBOOT_FW_ENV[0]} ${UBOOT_FW_ENV[1]}" >> "${destination}"/etc/fw_env.config
# create extlinux config file
if [[ $SRC_EXTLINUX != yes ]]; then
if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then
cp "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${destination}/usr/share/orangepi/${bootscript_dst}"
else
cp "${EXTER}/config/bootscripts/${bootscript_src}" "${destination}/usr/share/orangepi/${bootscript_dst}"
fi
[[ -n $BOOTENV_FILE && -f $SRC/config/bootenv/$BOOTENV_FILE ]] && \
cp "${EXTER}/config/bootenv/${BOOTENV_FILE}" "${destination}"/usr/share/orangepi/orangepiEnv.txt
fi
# add configuration for setting uboot environment from userspace with: fw_setenv fw_printenv
if [[ -n $UBOOT_FW_ENV ]]; then
UBOOT_FW_ENV=($(tr ',' ' ' <<< "$UBOOT_FW_ENV"))
mkdir -p "${destination}"/etc
echo "# Device to access offset env size" > "${destination}"/etc/fw_env.config
echo "/dev/mmcblk0 ${UBOOT_FW_ENV[0]} ${UBOOT_FW_ENV[1]}" >> "${destination}"/etc/fw_env.config
fi
fi
# Replaces: base-files is needed to replace /etc/update-motd.d/ files on Xenial
@@ -42,7 +61,7 @@ create_board_package()
# Depends: linux-base is needed for "linux-version" command in initrd cleanup script
# Depends: fping is needed for orangepimonitor to upload orangepi-hardware-monitor.log
cat <<-EOF > "${destination}"/DEBIAN/control
Package: linux-${RELEASE}-root-${DEB_BRANCH}${BOARD}
Package: ${BSP_CLI_PACKAGE_NAME}
Version: $REVISION
Architecture: $ARCH
Maintainer: $MAINTAINER <$MAINTAINERMAIL>
@@ -50,12 +69,12 @@ create_board_package()
Section: kernel
Priority: optional
Depends: bash, linux-base, u-boot-tools, initramfs-tools, lsb-release, fping
Provides: orangepi-bsp
Conflicts: orangepi-bsp
Provides: linux-${RELEASE}-root-legacy-$BOARD, linux-${RELEASE}-root-current-$BOARD, linux-${RELEASE}-root-edge-$BOARD
Suggests: orangepi-config
Replaces: zram-config, base-files, orangepi-tools-$RELEASE
Replaces: zram-config, base-files, orangepi-tools-$RELEASE, linux-${RELEASE}-root-legacy-$BOARD (<< $REVISION~), linux-${RELEASE}-root-current-$BOARD (<< $REVISION~), linux-${RELEASE}-root-edge-$BOARD (<< $REVISION~)
Breaks: linux-${RELEASE}-root-legacy-$BOARD (<< $REVISION~), linux-${RELEASE}-root-current-$BOARD (<< $REVISION~), linux-${RELEASE}-root-edge-$BOARD (<< $REVISION~)
Recommends: bsdutils, parted, util-linux, toilet
Description: OrangePi tweaks for $RELEASE on $BOARD ($BRANCH branch)
Description: OrangePi board support files for $BOARD
EOF
# set up pre install script
@@ -102,7 +121,6 @@ create_board_package()
[ -f "/etc/update-motd.d/99-point-to-faq" ] && rm /etc/update-motd.d/99-point-to-faq
[ -f "/etc/update-motd.d/80-esm" ] && rm /etc/update-motd.d/80-esm
[ -f "/etc/update-motd.d/80-livepatch" ] && rm /etc/update-motd.d/80-livepatch
[ -f "/etc/apt/apt.conf.d/50unattended-upgrades" ] && rm /etc/apt/apt.conf.d/50unattended-upgrades
[ -f "/etc/apt/apt.conf.d/02compress-indexes" ] && rm /etc/apt/apt.conf.d/02compress-indexes
[ -f "/etc/apt/apt.conf.d/02periodic" ] && rm /etc/apt/apt.conf.d/02periodic
[ -f "/etc/apt/apt.conf.d/no-languages" ] && rm /etc/apt/apt.conf.d/no-languages
@@ -115,7 +133,8 @@ create_board_package()
[ -f "/lib/systemd/system/resize2fs.service" ] && rm /lib/systemd/system/resize2fs.service
[ -f "/usr/lib/orangepi/apt-updates" ] && rm /usr/lib/orangepi/apt-updates
[ -f "/usr/lib/orangepi/firstrun-config.sh" ] && rm /usr/lib/orangepi/firstrun-config.sh
dpkg-divert --quiet --package linux-${RELEASE}-root-${DEB_BRANCH}${BOARD} --add --rename --divert /etc/mpv/mpv-dist.conf /etc/mpv/mpv.conf
# fix for https://bugs.launchpad.net/ubuntu/+source/lightdm-gtk-greeter/+bug/1897491
[ -d "/var/lib/lightdm" ] && (chown -R lightdm:lightdm /var/lib/lightdm ; chmod 0750 /var/lib/lightdm)
exit 0
EOF
@@ -126,7 +145,6 @@ create_board_package()
#!/bin/sh
if [ remove = "\$1" ] || [ abort-install = "\$1" ]; then
dpkg-divert --quiet --package linux-${RELEASE}-root-${DEB_BRANCH}${BOARD} --remove --rename --divert /etc/mpv/mpv-dist.conf /etc/mpv/mpv.conf
systemctl disable orangepi-hardware-monitor.service orangepi-hardware-optimize.service >/dev/null 2>&1
systemctl disable orangepi-zram-config.service orangepi-ramlog.service >/dev/null 2>&1
@@ -143,7 +161,7 @@ create_board_package()
# ${BOARD} BSP post installation script
#
systemctl --no-reload enable orangepi-ramlog.service
[ -f /etc/lib/systemd/system/orangepi-ramlog.service ] && systemctl --no-reload enable orangepi-ramlog.service
# check if it was disabled in config and disable in new service
if [ -n "\$(grep -w '^ENABLED=false' /etc/default/log2ram 2> /dev/null)" ]; then
@@ -162,25 +180,6 @@ create_board_package()
fi
EOF
if [[ $RELEASE == bionic && $BOARD != orangepi4 ]] || [[ $RELEASE == focal && $BOARDFAMILY == sun50iw6 ]]; then
cat <<-EOF >> "${destination}"/DEBIAN/postinst
# temporally disable acceleration on some arch in Bionic due to broken mesa packages
echo 'Section "Device"
\tIdentifier \t"Default Device"
\tOption \t"AccelMethod" "none"
EndSection' >> /etc/X11/xorg.conf.d/01-orangepi-defaults.conf
EOF
elif [[ $RELEASE == bionic && $BOARD == orangepi4 ]]; then
cat <<-EOF >> "${destination}"/DEBIAN/postinst
# temporally disable acceleration on some arch in Bionic due to broken mesa packages
echo 'Section "Device"
\tIdentifier \t"Default Device"
\tOption \t"AccelMethod" "glamor"
EndSection' >> /etc/X11/xorg.conf.d/01-orangepi-defaults.conf
EOF
fi
# install bootscripts if they are not present. Fix upgrades from old images
if [[ $FORCE_BOOTSCRIPT_UPDATE == yes ]]; then
cat <<-EOF >> "${destination}"/DEBIAN/postinst
@@ -214,9 +213,9 @@ create_board_package()
rootdev=\$(sed -e 's/^.*root=//' -e 's/ .*\$//' < /proc/cmdline)
rootfstype=\$(sed -e 's/^.*rootfstype=//' -e 's/ .*$//' < /proc/cmdline)
# recreate orangepiEnv.txt only not exists
if [ ! -f /boot/orangepiEnv.txt ]; then
cp /usr/share/orangepi/orangepiEnv.txt /boot/ >/dev/null 2>&1
# recreate orangepiEnv.txt if it and extlinux does not exists
if [ ! -f /boot/orangepiEnv.txt ] && [ ! -f /boot/extlinux/extlinux.conf ]; then
cp /usr/share/orangepi/orangepiEnv.txt /boot >/dev/null 2>&1
echo "rootdev="\$rootdev >> /boot/orangepiEnv.txt
echo "rootfstype="\$rootfstype >> /boot/orangepiEnv.txt
fi
@@ -227,17 +226,17 @@ create_board_package()
fi
[ ! -f "/etc/network/interfaces" ] && cp /etc/network/interfaces.default /etc/network/interfaces
[ ! -f "/etc/network/interfaces" ] && [ -f "/etc/network/interfaces.default" ] && cp /etc/network/interfaces.default /etc/network/interfaces
ln -sf /var/run/motd /etc/motd
rm -f /etc/update-motd.d/00-header /etc/update-motd.d/10-help-text
if [ -f "/boot/bin/$BOARD.bin" ] && [ ! -f "/boot/script.bin" ]; then ln -sf bin/$BOARD.bin /boot/script.bin >/dev/null 2>&1 || cp /boot/bin/$BOARD.bin /boot/script.bin; fi
if [ ! -f "/etc/default/orangepi-motd" ]; then
mv /etc/default/orangepi-motd.dpkg-dist /etc/default/orangepi-motd
fi
if [ ! -f "/etc/default/orangepi-ramlog" ]; then
if [ ! -f "/etc/default/orangepi-ramlog" ] && [ -f /etc/default/orangepi-ramlog.dpkg-dist ]; then
mv /etc/default/orangepi-ramlog.dpkg-dist /etc/default/orangepi-ramlog
fi
if [ ! -f "/etc/default/orangepi-zram-config" ]; then
if [ ! -f "/etc/default/orangepi-zram-config" ] && [ -f /etc/default/orangepi-zram-config.dpkg-dist ]; then
mv /etc/default/orangepi-zram-config.dpkg-dist /etc/default/orangepi-zram-config
fi
@@ -245,6 +244,15 @@ create_board_package()
mv /usr/lib/chromium-browser/master_preferences.dpkg-dist /usr/lib/chromium-browser/master_preferences
fi
# Read release value
if [ -f /etc/lsb-release ]; then
RELEASE=\$(cat /etc/lsb-release | grep CODENAME | cut -d"=" -f2 | sed 's/.*/\u&/')
sed -i "s/^PRETTY_NAME=.*/PRETTY_NAME=\"${VENDOR} $REVISION "\${RELEASE}"\"/" /etc/os-release
echo "${VENDOR} ${REVISION} \${RELEASE} \\l \n" > /etc/issue
echo "${VENDOR} ${REVISION} \${RELEASE}" > /etc/issue.net
fi
# Reload services
systemctl --no-reload enable orangepi-hardware-monitor.service orangepi-hardware-optimize.service orangepi-zram-config.service >/dev/null 2>&1
exit 0
EOF
@@ -257,7 +265,7 @@ create_board_package()
#EOF
# copy common files from a premade directory structure
rsync -a "${EXTER}"/packages/bsp/common/* "${destination}"/
rsync -a "${EXTER}"/packages/bsp/common/* ${destination}
# trigger uInitrd creation after installation, to apply
# /etc/initramfs/post-update.d/99-uboot
@@ -265,6 +273,13 @@ create_board_package()
activate update-initramfs
EOF
# copy distribution support status
local releases=($(find ${EXTER}/config/distributions -mindepth 1 -maxdepth 1 -type d))
for i in ${releases[@]}
do
echo "$(echo $i | sed 's/.*\///')=$(cat $i/support)" >> "${destination}"/etc/orangepi-distribution-status
done
# armhwinfo, firstrun, orangepimonitor, etc. config file
cat <<-EOF > "${destination}"/etc/orangepi-release
# PLEASE DO NOT EDIT THIS FILE
@@ -274,9 +289,9 @@ create_board_package()
BUILD_REPOSITORY_URL=${BUILD_REPOSITORY_URL}
BUILD_REPOSITORY_COMMIT=${BUILD_REPOSITORY_COMMIT}
DISTRIBUTION_CODENAME=${RELEASE}
DISTRIBUTION_STATUS=${DISTRIBUTION_STATUS}
VERSION=${REVISION}
LINUXFAMILY=${LINUXFAMILY}
BRANCH=${BRANCH}
ARCH=${ARCHITECTURE}
IMAGE_TYPE=$IMAGE_TYPE
BOARD_TYPE=$BOARD_TYPE
@@ -314,6 +329,11 @@ create_board_package()
# execute $LINUXFAMILY-specific tweaks
[[ $(type -t family_tweaks_bsp) == function ]] && family_tweaks_bsp
call_extension_method "post_family_tweaks_bsp" << 'POST_FAMILY_TWEAKS_BSP'
*family_tweaks_bsp overrrides what is in the config, so give it a chance to override the family tweaks*
This should be implemented by the config to tweak the BSP, after the board or family has had the chance to.
POST_FAMILY_TWEAKS_BSP
# add some summary to the image
fingerprint_image "${destination}/etc/orangepi.txt"
@@ -322,10 +342,10 @@ create_board_package()
find "${destination}" ! -type l -print0 2>/dev/null | xargs -0r chmod 'go=rX,u+rw,a-s'
# create board DEB file
display_alert "Building package" "$CHOSEN_ROOTFS" "info"
fakeroot dpkg-deb -b "${destination}" "${destination}.deb" >> "${DEST}"/debug/install.log 2>&1
fakeroot dpkg-deb -b -Z${DEB_COMPRESS} "${destination}" "${destination}.deb" >> "${DEST}"/${LOG_SUBPATH}/output.log 2>&1
mkdir -p "${DEB_STORAGE}/${RELEASE}/"
mv "${destination}.deb" "${DEB_STORAGE}/${RELEASE}/"
rsync --remove-source-files -rq "${destination}.deb" "${DEB_STORAGE}/${RELEASE}/"
# cleanup
rm -rf "${destination}"
rm -rf ${bsptempdir}
}