Files
iopsyswrt/iop
Dariusz Iwanoczko 281c748f13 Dockerfile: Switch docker base image to Debian bookworm-slim
Ubuntu delete snapshots after some time what could cause a problems with
use packages with specific versions.

This commit move and adapt the Dockerfile to Debian bookworm-slim.
Advantage of Debian over Ubuntu is that that all package versions are
archived via snapshots.debian.org (which we might move to in a later
commit). Ubuntu has a similar service, but does not retain all versions.

Move coccinelle from Debian archives because the version from Debian
works equally well and is even the same version 1.1.1 in bookworm.

Compile python2.7 from source, because it is no longer supplied in the
repos because it has been EOL for a very long time.

Issue: #17329
2025-10-01 19:19:56 +02:00

521 lines
14 KiB
Bash
Executable File

#!/bin/bash
arg=$1
arr_index=0
declare -a command_array
declare -a help_array
# Check if we should clone feeds with ssh or http
developer=0
which git >/dev/null && git remote -v 2>/dev/null | grep -qE '(git@|ssh://)' && developer=1
# Utility functions
function register_command {
command_array[$arr_index]=$1
help_array[$arr_index]=$2
arr_index=$((arr_index+1))
}
function dump_commands {
for i in $(seq 0 $arr_index); do
output+=("${command_array[$i]}" "${help_array[$i]}")
done
printf "Available commands:\n"
printf " %-25s%s\n" "${output[@]}" | sort
printf "\n"
}
# Parse yaml file, look for specified feed definition and create feeds.conf-like output
function parse_yaml_feed() {
local yaml_file="$1"
local feed="$2"
local yaml_content=$(cat "$yaml_file")
# Extract the values
local names=($(echo "$yaml_content" | grep -oP '(?<=name: ).*'))
local urls=($(echo "$yaml_content" | grep -oP '(?<=uri: ).*'))
local revisions=($(echo "$yaml_content" | grep -oP '(?<=revision: ).*'))
# Create the output string
local output=""
for ((i=0; i<${#names[@]}; i++)); do
if [ ${names[i]} == ${feed} ]; then
output+="src-git-full ${names[i]} ${urls[i]}^${revisions[i]}\n"
fi
done
echo -e "$output"
}
function has_profiles_feed() {
# regex taken from ./scripts/feeds
grep -qP '^src-([\w\-]+)((?:\s+--\w+(?:=\S+)?)*)\s+(profiles)' feeds.conf
}
# Register bootstrap command that installs other commands from feeds
function bootstrap() {
cp feeds.conf.io feeds.conf
parse_yaml_feed "profiles/include/iop_feed.yml" iopsys >> feeds.conf
feeds=(iopsys)
if has_profiles_feed; then
feeds+=(profiles)
fi
if [ "$developer" == 1 ]; then
./scripts/feeds update -g "${feeds[@]}" || exit 1
else
./scripts/feeds update "${feeds[@]}" || exit 1
fi
./scripts/feeds install -p iopsys iop || exit 1
}
register_command "bootstrap" "Initial command to run to install other commands"
function install_locales()
{
sudo locale-gen en_US.UTF-8
}
function install_pkgs()
{
local packages_misc="
bc
bison
build-essential
ccache
cpio
curl
device-tree-compiler
dialog
file
flex
g++
g++-multilib
gawk
gdisk
gettext
git
automake
gtk-doc-tools
jq
libelf-dev
liblzo2-dev
libncurses5
libncurses5-dev
libssl-dev
ncurses-term
pv
python3
python3-cryptography
python3-distutils
python3-jsonschema
rsync
subversion
svn-buildpackage
swig
unzip
uuid-dev
wget
zlib1g-dev
xxd
cmake
quilt
cryptsetup
libcap-dev
libseccomp-dev
libyajl-dev
coccinelle
"
local packages_perl="libconvert-binary-c-perl libdigest-crc-perl"
# do we need 32 bit compatibility libs ?
if [ "$(uname -m | awk '{print$1}')" == "x86_64" ]; then
local packages_x64="libc6-dev-i386 lib32z1 libncurses5:i386"
fi
# filter out already installed packages
local packages_all="$packages_misc $packages_perl $packages_x64"
local needed=""
for pkg in $packages_all
do
if ! dpkg -s $pkg >/dev/null 2>/dev/null
then
needed="$needed $pkg"
fi
done
# install needed packages
if [ -n "$needed" ]
then
echo "Need to install dpkg packages [$needed]"
read -p "Do you approve installation of these packages (y/n): " ans
if [ "$ans" == "y" ]; then
sudo apt-get update && sudo apt-get install $needed || exit $?
else
echo "can't continue. aborting!"
exit 1
fi
fi
}
check_bash()
{
local mysh=$(ls -hl /bin/sh | awk -F'[ ,/]' '{print$NF}')
if [ "$mysh" != "bash" ]; then
echo "On Debian based systems, e.g. Ubuntu, /bin/sh must point to bash instead of $mysh"
read -p "Do you approve this change (y/n): " ans
if [ "$ans" == "y" ]; then
sudo rm -f /bin/sh
sudo ln -s bash /bin/sh
else
echo "Warning! You haven't pointed /bin/sh to bash."
exit 1
fi
fi
}
download_check_hash() {
local url="$1"
local sha256="$2"
local tarball="$(mktemp iop_brcm_tar.XXXXXXX)"
wget -nv "$url" -O "$tarball" || return 1
if ! sha256sum --quiet -c <(echo "${sha256} *${tarball}") >&2; then
echo "Hash mismatch of tarball $url (expected: $sha256)" >&2
sha256sum "$tarball" >&2
rm -f $tarball
return 1
fi
printf "%s" "$tarball"
}
download_extract_bcm() {
local type="$1"
local url="$2"
local sha256="$3"
local path="$4"
local path_strip_no=0
if [ ! -z "$5" ]; then
path_strip_no="$5"
fi
local tarball="$(download_check_hash "$url" "$sha256")"
if [ -z "$tarball" ]; then
echo "Error: Error occurred during download or hash verification for $url"
exit 1
fi
case "$type" in
toolchain)
# current 10.3/4.19/2.30/2.32 BCM toolchain has owner of files set to some employee who created the tar
# Change to root during extraction
sudo tar --owner=root --group=root -C "$path" --strip-components=$path_strip_no -Pxf "$tarball"
;;
hnd_toolchain)
sudo mkdir -p "$path" && \
sudo tar --owner=root --group=root -C "$path" -xf "$tarball" --strip-components=1
;;
wlan_fw_tools)
(
set -e
sudo mkdir -p "$path"
sudo unzip -j \
"$tarball" \
bcawlan-fw-build-post-process-tools/post-process-tools/\* \
-d "$path/bin"
sudo find "$path/bin" -type f -not -name '*.ini' -execdir chmod +x '{}' ';'
)
;;
*)
echo "Error: Unknown type $type" >&2
false
;;
esac
local ret=$?
rm -f "$tarball"
return "$ret"
}
check_brcm_tools(){
local install_arm=0
local install_arm_softfp=0
local install_arm_hf=0
local install_aarch64=0
local install_wlan_fw_tools=0
local TOOLCHAIN_DIR="/opt/toolchains/"
if [ ! -d ${TOOLCHAIN_DIR}/crosstools-arm-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_arm=1
echo "Need to install Broadcom ARM toolchain"
fi
if [ ! -d ${TOOLCHAIN_DIR}/crosstools-arm_softfp-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_arm_softfp=1
echo "Need to install Broadcom ARM-softfp toolchain"
fi
if [ ! -d ${TOOLCHAIN_DIR}crosstools-arm_hf-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_arm_hf=1
echo "Need to install Broadcom ARM-hf toolchain"
fi
if [ ! -d ${TOOLCHAIN_DIR}crosstools-aarch64-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1 ]; then
install_aarch64=1
echo "Need to install Broadcom aarch64 toolchain"
fi
if [ ! -d /opt/bcawlan-fw-build-post-process-tools ]; then
install_wlan_fw_tools=1
echo "Need to install bcawlan-fw-build-post-process-tools"
fi
if [ "$install_arm" -eq 1 \
-o "$install_arm_softfp" -eq 1 \
-o "$install_arm_hf" -eq 1 \
-o "$install_aarch64" -eq 1 \
-o "$install_wlan_fw_tools" -eq 1 ]; then
read -p "Do you approve installation of the aforementioned missing toolchains and tools (y/n): " ans
if [ "$ans" == "y" ]; then
echo "Downloading toolchain/tools"
else
echo "can't continue. aborting"
exit 1
fi
# create install dir
sudo mkdir -p ${TOOLCHAIN_DIR}
if [ $install_arm -eq 1 ]; then
echo "Installing ARM toolchain"
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-arm-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
38657d72a7726db3e13621784d3e1ad65e2721c0538e87cc38cf3266bde26d6f \
${TOOLCHAIN_DIR}
fi
if [ $install_arm_softfp -eq 1 ]; then
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-arm_softfp-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
9af29bac2ba6cbe51ee09467dbe97dc76a47bbf00df1fffafa1433817d2a147b \
${TOOLCHAIN_DIR}
fi
if [ $install_arm_hf -eq 1 ]; then
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-arm_hf-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
3e57bbbb5e0b832813aa93274dfa937260833af645c2bc03cb1c88d4e98def92 \
${TOOLCHAIN_DIR}
fi
if [ $install_aarch64 -eq 1 ]; then
echo "Installing aarch64 toolchain"
download_extract_bcm \
toolchain \
https://download.iopsys.eu/iopsys/toolchain/crosstools-aarch64-gcc-10.3-linux-4.19-glibc-2.32-binutils-2.36.1.Rel1.13.tar.bz2 \
aed8c327951a5a7bfd67f9d2e92f844923a216994764e0aa32903bd40ea8945a \
${TOOLCHAIN_DIR}
fi
if [ $install_wlan_fw_tools -eq 1 ]; then
echo "Installing bcawlan-fw-build-post-process-tools"
download_extract_bcm \
wlan_fw_tools \
https://download.iopsys.eu/iopsys/toolchain/bcawlan-fw-build-post-process-tools.zip \
1082d631317aef900ab2bfe549830bfbc76da87f21ff78cd3129f369f3f92101 \
/opt/bcawlan-fw-build-post-process-tools
fi
fi
}
check_gcc_version(){
gcc_ver=$(ls -l $(which gcc) | awk '{ print $NF }')
# if /usr/bin/gcc -> /etc/alternatives/cc
if [ -L $gcc_ver ]; then
gcc_ver=$(ls -l $gcc_ver | awk '{ print $NF }')
fi
# transform gcc-* to just a number.
gcc_ver=$(echo $gcc_ver | cut -d- -f2)
if [ "$gcc_ver" != 4.8 ]; then
echo "Your current gcc version is $gcc_ver, but it must be changed to 4.8"
read -p "Do you approve this change (y/n): " ans
if [ "$ans" == "y" ]; then
if ! dpkg -s gcc-4.8 >/dev/null 2>/dev/null ;then
sudo apt-get install gcc-4.8
fi
if ! dpkg -s g++-4.8 >/dev/null 2>/dev/null ;then
sudo apt-get install g++-4.8
fi
if ! dpkg -s gcc-4.8-multilib >/dev/null 2>/dev/null ;then
sudo apt-get install gcc-4.8-multilib
fi
sudo update-alternatives --install /usr/bin/g++ c++ /usr/bin/g++-4.8 100
sudo update-alternatives --install /usr/bin/g++ c++ /usr/bin/g++-$gcc_ver 90
sudo update-alternatives --install /usr/bin/gcc cc /usr/bin/gcc-4.8 100
sudo update-alternatives --install /usr/bin/gcc cc /usr/bin/gcc-$gcc_ver 90
sudo update-alternatives --install /usr/bin/cpp cpp /usr/bin/cpp-4.8 100
sudo update-alternatives --install /usr/bin/cpp cpp /usr/bin/cpp-$gcc_ver 90
sudo update-alternatives --set c++ /usr/bin/g++-4.8
sudo update-alternatives --set cc /usr/bin/gcc-4.8
sudo update-alternatives --set cpp /usr/bin/cpp-4.8
sudo ln -s /etc/alternatives/cc /usr/bin/cc
echo "The deafult gcc version has now been changed from $gcc_ver to 4.8"
fi
fi
}
restore_gcc() {
if dpkg -s gcc-5 >/dev/null 2>/dev/null
then
gcc_ver=$(ls -l $(which gcc) | awk '{ print $NF }')
# if /usr/bin/gcc -> /etc/alternatives/cc
if [ -L $gcc_ver ]; then
gcc_ver=$(ls -l $gcc_ver | awk '{ print $NF }')
fi
# transform gcc-* to just a number.
gcc_ver=$(echo $gcc_ver | cut -d- -f2)
# is 4.8 the default reset back to 5
if [ "$gcc_ver" = "4.8" ]; then
echo "Your current gcc version is $gcc_ver that is not the distro default. set it back to default ?"
read -p "Do you approve this change (y/n): " ans
if [ "$ans" == "y" ]; then
sudo update-alternatives --set c++ /usr/bin/g++-5
sudo update-alternatives --set cc /usr/bin/gcc-5
sudo update-alternatives --set cpp /usr/bin/cpp-5
# force a reinstall of default version
# yes it needs to be done twice.
sudo apt-get install --reinstall gcc cpp g++
sudo apt-get install --reinstall gcc cpp g++
fi
fi
fi
}
# Compare modification date of two files
# return 0 (true) if first file is older, 1 (false) otherwise
is_older() {
local target=$(stat -c %Y $1 2> /dev/null)
local ref=$(stat -c %Y $2 2> /dev/null)
[ -z "$target" -o -z "$ref" ] && return 1
[ $target -lt $ref ] && return 0
return 1
}
install_iop_completion() {
local instloc=/usr/share/bash-completion/completions/iop
local srcloc=./feeds/iopsys/iop/iop.completion
local inst=0
if [ ! -e $instloc ]; then
echo "Bash completion for './iop' utility not found"
inst=1
elif is_older $instloc $srcloc ; then
echo "Bash completion for './iop' utility is outdated"
inst=1
fi
if [ $inst -eq 1 ]; then
read -p "Install latest version to '$instloc' (y/n): " ans
if [ "$ans" == "y" ]; then
sudo cp $srcloc $instloc
echo "Start a new shell to enable ./iop command completion!"
fi
fi
}
function setup_host {
#===============#
# Prerequisites #
#===============#
install_locales
install_pkgs
check_bash
check_brcm_tools
#check_gcc_version
restore_gcc
install_iop_completion
echo ""
echo ""
echo "You have successfully installed and configred prerequisites to be able to build an iopsys firmware"
echo ""
echo ""
}
register_command "setup_host" "Install needed packets to host machine"
# Plugin scripts call register command to export their interface
if [ -d package/feeds/iopsys/iop/scripts ]; then
for f in package/feeds/iopsys/iop/scripts/*; do
source $f
done
fi
function feeds_update {
# Call bootstrap to update feeds/iopsys for transiton in old/new genconfig state
echo "Calling bootstrap to update required feeds"
bootstrap
# always return true
exit 0
}
register_command "feeds_update" "Compatibility function only"
function set-feed-rev() {
./scripts/set-feed-rev "$@"
}
register_command "set-feed-rev" "Update feeds revisions in feeds.conf.io and profiles"
# Register commands from external files
source ./scripts/genconfig_wrap.sh
source ./scripts/iopupgrade.sh
if [ -z $arg ] || [ $arg == "--help" ]; then
printf "Usage: iop <command> [<args>]\n\n"
dump_commands
exit -1
fi
# Check all registered commands for a match
for i in $(seq 0 $arr_index); do
if [ $arg == "${command_array[$i]}" ]; then
# Run the command and pass all args
# except for the first to it
$arg "${@:2}"
exit 0
fi
done
# No registered command for the passed input arg
printf "Error: no such command $arg\n\n"
dump_commands
exit -1