[arm] Refactor installer and build to allow arm builds targeted at grub platforms (#11341)

Refactors the SONiC Installer to support greater flexibility in building for a given architecture and bootloader. 

#### Why I did it

Currently the SONiC installer assumes that if a platform is ARM based that it uses the `uboot` bootloader and uses the `grub` bootloader otherwise. This is not a correct assumption to make as ARM is not strictly tied to uboot and x86 is not strictly tied to grub. 

#### How I did it

To implement this I introduce the following changes:
* Remove the different arch folders from the `installer/` directory
* Merge the generic components of the ARM and x86 installer into `installer/installer.sh`
* Refactor x86 + grub specific functions into `installer/default_platform.conf` 
* Modify installer to call `default_platform.conf` file and also call `platform/[platform]/patform.conf` file as well to override as needed
* Update references to the installer in the `build_image.sh` script
* Add `TARGET_BOOTLOADER` variable that is by default `uboot` for ARM devices and `grub` for x86 unless overridden in `platform/[platform]/rules.mk`
* Update bootloader logic in `build_debian.sh` to be based on `TARGET_BOOTLOADER` instead of `TARGET_ARCH` and to reference the grub package in a generic manner

#### How to verify it

This has been tested on a ARM test platform as well as on Mellanox amd64 switches as well to ensure there was no impact. 

#### Description for the changelog
[arm] Refactor installer and build to allow arm builds targeted at grub platforms

#### Link to config_db schema for YANG module changes

N/A
This commit is contained in:
Alexander Allen 2022-07-12 18:00:57 -04:00 committed by GitHub
parent 5171589f4d
commit 429254cb2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 240 additions and 568 deletions

View File

@ -104,6 +104,12 @@ ifeq ($(PLATFORM_ARCH),)
override PLATFORM_ARCH = $(CONFIGURED_ARCH) override PLATFORM_ARCH = $(CONFIGURED_ARCH)
endif endif
ifeq ($(CONFIGURED_ARCH),amd64)
TARGET_BOOTLOADER = grub
else
TARGET_BOOTLOADER = uboot
endif
ifeq ($(BLDENV), bullseye) ifeq ($(BLDENV), bullseye)
SLAVE_DIR = sonic-slave-bullseye SLAVE_DIR = sonic-slave-bullseye
else ifeq ($(BLDENV), buster) else ifeq ($(BLDENV), buster)

View File

@ -65,7 +65,7 @@ if [[ -d $FILESYSTEM_ROOT ]]; then
fi fi
mkdir -p $FILESYSTEM_ROOT mkdir -p $FILESYSTEM_ROOT
mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR
mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR/x86_64-grub mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR/grub
touch $FILESYSTEM_ROOT/$PLATFORM_DIR/firsttime touch $FILESYSTEM_ROOT/$PLATFORM_DIR/firsttime
## ensure proc is mounted ## ensure proc is mounted
@ -162,7 +162,7 @@ if [ "$SONIC_ENABLE_SECUREBOOT_SIGNATURE" = "y" ]; then
fi fi
echo '[INFO] Signing SONiC linux kernel image' echo '[INFO] Signing SONiC linux kernel image'
K=$FILESYSTEM_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-amd64 K=$FILESYSTEM_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH}
sbsign --key $SIGNING_KEY --cert $SIGNING_CERT --output /tmp/${K##*/} ${K} sbsign --key $SIGNING_KEY --cert $SIGNING_CERT --output /tmp/${K##*/} ${K}
sudo cp -f /tmp/${K##*/} ${K} sudo cp -f /tmp/${K##*/} ${K}
fi fi
@ -392,11 +392,17 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
systemd-sysv \ systemd-sysv \
ntp ntp
if [[ $CONFIGURED_ARCH == amd64 ]]; then if [[ $TARGET_BOOTLOADER == grub ]]; then
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \ if [[ $CONFIGURED_ARCH == amd64 ]]; then
grub-pc-bin GRUB_PKG=grub-pc-bin
elif [[ $CONFIGURED_ARCH == arm64 ]]; then
GRUB_PKG=grub-efi-arm64-bin
fi
sudo mv $FILESYSTEM_ROOT/grub-pc-bin*.deb $FILESYSTEM_ROOT/$PLATFORM_DIR/x86_64-grub sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \
$GRUB_PKG
sudo mv $FILESYSTEM_ROOT/grub*.deb $FILESYSTEM_ROOT/$PLATFORM_DIR/grub
fi fi
## Disable kexec supported reboot which was installed by default ## Disable kexec supported reboot which was installed by default
@ -572,7 +578,7 @@ fi
## Update initramfs ## Update initramfs
sudo chroot $FILESYSTEM_ROOT update-initramfs -u sudo chroot $FILESYSTEM_ROOT update-initramfs -u
## Convert initrd image to u-boot format ## Convert initrd image to u-boot format
if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then if [[ $TARGET_BOOTLOADER == uboot ]]; then
INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH}
if [[ $CONFIGURED_ARCH == armhf ]]; then if [[ $CONFIGURED_ARCH == armhf ]]; then
INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-armmp INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-armmp

View File

@ -84,7 +84,7 @@ generate_onie_installer_image()
## Generate an ONIE installer image ## Generate an ONIE installer image
## Note: Don't leave blank between lines. It is single line command. ## Note: Don't leave blank between lines. It is single line command.
./onie-mk-demo.sh $TARGET_PLATFORM $TARGET_MACHINE $TARGET_PLATFORM-$TARGET_MACHINE-$ONIEIMAGE_VERSION \ ./onie-mk-demo.sh $CONFIGURED_ARCH $TARGET_MACHINE $TARGET_PLATFORM-$TARGET_MACHINE-$ONIEIMAGE_VERSION \
installer platform/$TARGET_MACHINE/platform.conf $output_file OS $IMAGE_VERSION $ONIE_IMAGE_PART_SIZE \ installer platform/$TARGET_MACHINE/platform.conf $output_file OS $IMAGE_VERSION $ONIE_IMAGE_PART_SIZE \
$ONIE_INSTALLER_PAYLOAD $ONIE_INSTALLER_PAYLOAD
} }
@ -111,7 +111,7 @@ if [ "$IMAGE_TYPE" = "onie" ]; then
mkdir -p `dirname $OUTPUT_ONIE_IMAGE` mkdir -p `dirname $OUTPUT_ONIE_IMAGE`
sudo rm -f $OUTPUT_ONIE_IMAGE sudo rm -f $OUTPUT_ONIE_IMAGE
generate_device_list "./installer/$TARGET_PLATFORM/platforms_asic" generate_device_list "./installer/platforms_asic"
generate_onie_installer_image generate_onie_installer_image
@ -125,7 +125,7 @@ elif [ "$IMAGE_TYPE" = "raw" ]; then
mkdir -p `dirname $OUTPUT_RAW_IMAGE` mkdir -p `dirname $OUTPUT_RAW_IMAGE`
sudo rm -f $OUTPUT_RAW_IMAGE sudo rm -f $OUTPUT_RAW_IMAGE
generate_device_list "./installer/$TARGET_PLATFORM/platforms_asic" generate_device_list "./installer/platforms_asic"
generate_onie_installer_image "$tmp_output_onie_image" generate_onie_installer_image "$tmp_output_onie_image"
@ -159,7 +159,7 @@ elif [ "$IMAGE_TYPE" = "raw" ]; then
elif [ "$IMAGE_TYPE" = "kvm" ]; then elif [ "$IMAGE_TYPE" = "kvm" ]; then
generate_device_list "./installer/$TARGET_PLATFORM/platforms_asic" generate_device_list "./installer/platforms_asic"
generate_onie_installer_image generate_onie_installer_image
# Generate single asic KVM image # Generate single asic KVM image

View File

@ -297,7 +297,7 @@ sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libnss-radius_*.deb || \
sudo sed -i -e '/^passwd/s/ radius//' $FILESYSTEM_ROOT/etc/nsswitch.conf sudo sed -i -e '/^passwd/s/ radius//' $FILESYSTEM_ROOT/etc/nsswitch.conf
# Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f') # Install a custom version of kdump-tools (and its dependencies via 'apt-get -y install -f')
if [[ $CONFIGURED_ARCH == amd64 ]]; then if [[ $TARGET_BOOTLOADER == grub ]]; then
sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \ sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true chroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends install sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true chroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends install
cat $IMAGE_CONFIGS/kdump/kdump-tools | sudo tee -a $FILESYSTEM_ROOT/etc/default/kdump-tools > /dev/null cat $IMAGE_CONFIGS/kdump/kdump-tools | sudo tee -a $FILESYSTEM_ROOT/etc/default/kdump-tools > /dev/null

View File

@ -293,7 +293,7 @@ if [ -f $FIRST_BOOT_FILE ]; then
# we now install a grub for SONiC. # we now install a grub for SONiC.
if [ -n "$onie_platform" ] && [ -n "$grub_installation_needed" ]; then if [ -n "$onie_platform" ] && [ -n "$grub_installation_needed" ]; then
grub_bin=$(ls /host/image-$SONIC_VERSION/platform/x86_64-grub/grub-pc-bin*.deb 2> /dev/null) grub_bin=$(ls /host/image-$SONIC_VERSION/platform/grub/grub*.deb 2> /dev/null)
if [ -z "$grub_bin" ]; then if [ -z "$grub_bin" ]; then
log_migration "Unable to locate grub package !" log_migration "Unable to locate grub package !"
firsttime_exit firsttime_exit

View File

@ -1,197 +0,0 @@
#!/bin/sh
# Copyright (C) Marvell Inc
#
_trap_push() {
local next="$1"
eval "trap_push() {
local oldcmd='$(echo "$next" | sed -e s/\'/\'\\\\\'\'/g)'
local newcmd=\"\$1; \$oldcmd\"
trap -- \"\$newcmd\" EXIT INT TERM HUP
_trap_push \"\$newcmd\"
}"
}
_trap_push true
set -e
if [ -d "/etc/sonic" ]; then
echo "Installing SONiC in SONiC"
install_env="sonic"
elif grep -Fxqs "DISTRIB_ID=onie" /etc/lsb-release > /dev/null
then
echo "Installing SONiC in ONIE"
install_env="onie"
else
echo "Installing SONiC in BUILD"
install_env="build"
fi
cd $(dirname $0)
if [ -r ./machine.conf ]; then
. ./machine.conf
fi
if [ -r ./onie-image-armhf.conf ]; then
. ./onie-image-armhf.conf
fi
echo "ONIE Installer: platform: $platform"
# Make sure run as root or under 'sudo'
if [ $(id -u) -ne 0 ]
then echo "Please run as root"
exit 1
fi
if [ -r /etc/machine.conf ]; then
. /etc/machine.conf
elif [ -r /host/machine.conf ]; then
. /host/machine.conf
elif [ "$install_env" != "build" ]; then
echo "cannot find machine.conf"
exit 1
fi
echo "onie_platform: $onie_platform"
# Get platform specific linux kernel command line arguments
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX=""
# Default var/log device size in MB
VAR_LOG_SIZE=4096
[ -r platforms/$onie_platform ] && . platforms/$onie_platform
# Verify image platform is inside devices list
if [ "$install_env" = "onie" ]; then
if ! grep -Fxq "$onie_platform" platforms_asic; then
echo "The image you're trying to install is of a different ASIC type as the running platform's ASIC"
while true; do
read -r -p "Do you still wish to install this image? [y/n]: " input
case $input in
[Yy])
echo "Force installing..."
break
;;
[Nn])
echo "Exited installation!"
exit 1
;;
*)
echo "Error: Invalid input"
;;
esac
done
fi
fi
# If running in ONIE
if [ "$install_env" = "onie" ]; then
# The onie bin tool prefix
onie_bin=
# The persistent ONIE directory location
onie_root_dir=/mnt/onie-boot/onie
# The onie file system root
onie_initrd_tmp=/
fi
# The build system prepares this script by replacing %%DEMO-TYPE%%
# with "OS" or "DIAG".
demo_type="%%DEMO_TYPE%%"
# The build system prepares this script by replacing %%IMAGE_VERSION%%
# with git revision hash as a version identifier
image_version="%%IMAGE_VERSION%%"
timestamp="$(date -u +%Y%m%d)"
demo_volume_label="SONiC-${demo_type}"
demo_volume_revision_label="SONiC-${demo_type}-${image_version}"
. ./platform.conf
image_dir="image-$image_version"
if [ "$install_env" = "onie" ]; then
# Create/format the flash
create_partition
mount_partition
elif [ "$install_env" = "sonic" ]; then
demo_mnt="/host"
# Get current SONiC image (grub/aboot/uboot)
eval running_sonic_revision="$(cat /proc/cmdline | sed -n 's/^.*loop=\/*image-\(\S\+\)\/.*$/\1/p')"
# Verify SONiC image exists
if [ ! -d "$demo_mnt/image-$running_sonic_revision" ]; then
echo "ERROR: SONiC installation is corrupted: path $demo_mnt/image-$running_sonic_revision doesn't exist"
exit 1
fi
# Prevent installing existing SONiC if it is running
if [ "$image_dir" = "image-$running_sonic_revision" ]; then
echo "Not installing SONiC version $running_sonic_revision, as current running SONiC has the same version"
exit 0
fi
# Remove extra SONiC images if any
for f in $demo_mnt/image-* ; do
if [ -d $f ] && [ "$f" != "$demo_mnt/image-$running_sonic_revision" ] && [ "$f" != "$demo_mnt/$image_dir" ]; then
echo "Removing old SONiC installation $f"
rm -rf $f
fi
done
fi
# Create target directory or clean it up if exists
if [ -d $demo_mnt/$image_dir ]; then
echo "Directory $demo_mnt/$image_dir/ already exists. Cleaning up..."
rm -rf $demo_mnt/$image_dir/*
else
mkdir $demo_mnt/$image_dir || {
echo "Error: Unable to create SONiC directory"
exit 1
}
fi
# Decompress the file for the file system directly to the partition
if [ x"$docker_inram" = x"on" ]; then
# when disk is small, keep dockerfs.tar.gz in disk, expand it into ramfs during initrd
unzip -o $ONIE_INSTALLER_PAYLOAD -x "platform.tar.gz" -d $demo_mnt/$image_dir
else
unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" "platform.tar.gz" -d $demo_mnt/$image_dir
if [ "$install_env" = "onie" ]; then
TAR_EXTRA_OPTION="--numeric-owner"
else
TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp"
fi
mkdir -p $demo_mnt/$image_dir/$DOCKERFS_DIR
unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR
fi
mkdir -p $demo_mnt/$image_dir/platform
unzip -op $ONIE_INSTALLER_PAYLOAD "platform.tar.gz" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/platform
if [ "$install_env" = "onie" ]; then
# Store machine description in target file system
if [ -f /etc/machine-build.conf ]; then
# onie_ variable are generate at runtime.
# they are no longer hardcoded in /etc/machine.conf
# also remove single quotes around the value
set | grep ^onie | sed -e "s/='/=/" -e "s/'$//" > $demo_mnt/machine.conf
else
cp /etc/machine.conf $demo_mnt
fi
fi
extra_cmdline_linux=%%EXTRA_CMDLINE_LINUX%%
echo "EXTRA_CMDLINE_LINUX=$extra_cmdline_linux"
# Update Bootloader Menu with installed image
bootloader_menu_config
# Set NOS mode if available. For manufacturing diag installers, you
# probably want to skip this step so that the system remains in ONIE
# "installer" mode for installing a true NOS later.
if [ -x /bin/onie-nos-mode ] ; then
/bin/onie-nos-mode -s
fi

View File

@ -1,119 +1,5 @@
#!/bin/sh #!/bin/sh
# Copyright (C) 2014-2015 Curt Brune <curt@cumulusnetworks.com>
# Copyright (C) 2014-2015 david_yang <david_yang@accton.com>
#
# SPDX-License-Identifier: GPL-2.0
# Appends a command to a trap, which is needed because default trap behavior is to replace
# previous trap for the same signal
# - 1st arg: code to add
# - ref: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal
_trap_push() {
local next="$1"
eval "trap_push() {
local oldcmd='$(echo "$next" | sed -e s/\'/\'\\\\\'\'/g)'
local newcmd=\"\$1; \$oldcmd\"
trap -- \"\$newcmd\" EXIT INT TERM HUP
_trap_push \"\$newcmd\"
}"
}
_trap_push true
read_conf_file() {
local conf_file=$1
while IFS='=' read -r var value || [ -n "$var" ]
do
# remove newline character
var=$(echo $var | tr -d '\r\n')
value=$(echo $value | tr -d '\r\n')
# remove comment string
var=${var%#*}
value=${value%#*}
# skip blank line
[ -z "$var" ] && continue
# remove double quote in the beginning
tmp_val=${value#\"}
# remove double quote in the end
value=${tmp_val%\"}
eval "$var=\"$value\""
done < "$conf_file"
}
# Main
set -e
cd $(dirname $0)
if [ -d "/etc/sonic" ]; then
echo "Installing SONiC in SONiC"
install_env="sonic"
elif grep -Fxqs "DISTRIB_ID=onie" /etc/lsb-release > /dev/null
then
echo "Installing SONiC in ONIE"
install_env="onie"
else
echo "Installing SONiC in BUILD"
install_env="build"
fi
if [ -r ./machine.conf ]; then
read_conf_file "./machine.conf"
fi
if [ -r ./onie-image.conf ]; then
. ./onie-image.conf
fi
echo "ONIE Installer: platform: $platform"
# Make sure run as root or under 'sudo'
if [ $(id -u) -ne 0 ]
then echo "Please run as root"
exit 1
fi
# get running machine from conf file
if [ -r /etc/machine.conf ]; then
read_conf_file "/etc/machine.conf"
elif [ -r /host/machine.conf ]; then
read_conf_file "/host/machine.conf"
elif [ "$install_env" != "build" ]; then
echo "cannot find machine.conf"
exit 1
fi
echo "onie_platform: $onie_platform"
# Get platform specific linux kernel command line arguments
ONIE_PLATFORM_EXTRA_CMDLINE_LINUX=""
# Default var/log device size in MB
VAR_LOG_SIZE=4096
[ -r platforms/$onie_platform ] && . platforms/$onie_platform
# Verify image platform is inside devices list
if [ "$install_env" = "onie" ]; then
if ! grep -Fxq "$onie_platform" platforms_asic; then
echo "The image you're trying to install is of a different ASIC type as the running platform's ASIC"
while true; do
read -r -p "Do you still wish to install this image? [y/n]: " input
case $input in
[Yy])
echo "Force installing..."
break
;;
[Nn])
echo "Exited installation!"
exit 1
;;
*)
echo "Error: Invalid input"
;;
esac
done
fi
fi
# Pick up console port and speed from install enviroment if not defined yet. # Pick up console port and speed from install enviroment if not defined yet.
# Console port and speed setting in cmdline is like "console=ttyS0,9600n", # Console port and speed setting in cmdline is like "console=ttyS0,9600n",
@ -145,69 +31,75 @@ if [ -z "$CONSOLE_SPEED" ]; then
fi fi
fi fi
# Install demo on same block device as ONIE create_partition()
if [ "$install_env" != "build" ]; then {
onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//')
blk_dev=$(echo $onie_dev | sed -e 's/[1-9][0-9]*$//' | sed -e 's/\([0-9]\)\(p\)/\1/')
# check if we have an nvme device # Install demo on same block device as ONIE
blk_suffix= if [ "$install_env" != "build" ]; then
echo $blk_dev | grep -q nvme0 && blk_suffix="p" onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//')
blk_dev=$(echo $onie_dev | sed -e 's/[1-9][0-9]*$//' | sed -e 's/\([0-9]\)\(p\)/\1/')
# Note: ONIE has no mount setting for / with device node, so below will be empty string # check if we have an nvme device
cur_part=$(cat /proc/mounts | awk "{ if(\$2==\"/\") print \$1 }" | grep $blk_dev || true) blk_suffix=
echo $blk_dev | grep -q nvme0 && blk_suffix="p"
[ -b "$blk_dev" ] || { # Note: ONIE has no mount setting for / with device node, so below will be empty string
echo "Error: Unable to determine block device of ONIE install"
cur_part=$(cat /proc/mounts | awk "{ if(\$2==\"/\") print \$1 }" | grep $blk_dev || true)
[ -b "$blk_dev" ] || {
echo "Error: Unable to determine block device of ONIE install"
exit 1
}
fi
# auto-detect whether BIOS or UEFI
if [ -d "/sys/firmware/efi/efivars" ] ; then
firmware="uefi"
else
firmware="bios"
fi
if [ "$install_env" = "onie" ]; then
# determine ONIE partition type
onie_partition_type=$(${onie_bin} onie-sysinfo -t)
# demo partition size in MB
demo_part_size="%%ONIE_IMAGE_PART_SIZE%%"
if [ "$firmware" = "uefi" ] ; then
create_demo_uefi_partition $blk_dev
elif [ "$onie_partition_type" = "gpt" ] ; then
create_demo_gpt_partition $blk_dev
elif [ "$onie_partition_type" = "msdos" ] ; then
create_demo_msdos_partition $blk_dev
else
echo "ERROR: Unsupported partition type: $onie_partition_type"
exit 1
fi
fi
}
mount_partition()
{
demo_dev=$(echo $blk_dev | sed -e 's/\(mmcblk[0-9]\)/\1p/')$demo_part
echo $blk_dev | grep -q nvme0 && demo_dev=$(echo $blk_dev | sed -e 's/\(nvme[0-9]n[0-9]\)/\1p/')$demo_part
# Make filesystem
mkfs.ext4 -L $demo_volume_label $demo_dev
# Mount demo filesystem
demo_mnt=$(${onie_bin} mktemp -d) || {
echo "Error: Unable to create file system mount point"
exit 1 exit 1
} }
fi trap_push "${onie_bin} fuser -km $demo_mnt || ${onie_bin} umount $demo_mnt || ${onie_bin} rmdir $demo_mnt || true"
${onie_bin} mount -t ext4 -o defaults,rw $demo_dev $demo_mnt || {
# If running in ONIE echo "Error: Unable to mount $demo_dev on $demo_mnt"
if [ "$install_env" = "onie" ]; then
# The onie bin tool prefix
onie_bin=
# The persistent ONIE directory location
onie_root_dir=/mnt/onie-boot/onie
# The onie file system root
onie_initrd_tmp=/
fi
# The build system prepares this script by replacing %%DEMO-TYPE%%
# with "OS" or "DIAG".
demo_type="%%DEMO_TYPE%%"
# The build system prepares this script by replacing %%IMAGE_VERSION%%
# with git revision hash as a version identifier
image_version="%%IMAGE_VERSION%%"
timestamp="$(date -u +%Y%m%d)"
demo_volume_label="SONiC-${demo_type}"
demo_volume_revision_label="SONiC-${demo_type}-${image_version}"
# auto-detect whether BIOS or UEFI
if [ -d "/sys/firmware/efi/efivars" ] ; then
firmware="uefi"
else
firmware="bios"
fi
if [ "$install_env" = "onie" ]; then
# determine ONIE partition type
onie_partition_type=$(${onie_bin} onie-sysinfo -t)
# demo partition size in MB
demo_part_size="%%ONIE_IMAGE_PART_SIZE%%"
if [ "$firmware" = "uefi" ] ; then
create_demo_partition="create_demo_uefi_partition"
elif [ "$onie_partition_type" = "gpt" ] ; then
create_demo_partition="create_demo_gpt_partition"
elif [ "$onie_partition_type" = "msdos" ] ; then
create_demo_partition="create_demo_msdos_partition"
else
echo "ERROR: Unsupported partition type: $onie_partition_type"
exit 1 exit 1
fi }
fi
}
# Creates a new partition for the DEMO OS. # Creates a new partition for the DEMO OS.
# #
@ -457,161 +349,71 @@ demo_install_uefi_grub()
# Configure EFI NVRAM Boot variables. --create also sets the # Configure EFI NVRAM Boot variables. --create also sets the
# new boot number as active. # new boot number as active.
grub=$(find /boot/efi/EFI/$demo_volume_label/ -name grub*.efi -exec basename {} \;)
efibootmgr --quiet --create \ efibootmgr --quiet --create \
--label "$demo_volume_label" \ --label "$demo_volume_label" \
--disk $blk_dev --part $uefi_part \ --disk $blk_dev --part $uefi_part \
--loader "/EFI/$demo_volume_label/grubx64.efi" || { --loader "/EFI/$demo_volume_label/$grub" || {
echo "ERROR: efibootmgr failed to create new boot variable on: $blk_dev" echo "ERROR: efibootmgr failed to create new boot variable on: $blk_dev"
exit 1 exit 1
} }
} }
image_dir="image-$image_version"
if [ "$install_env" = "onie" ]; then bootloader_menu_config()
eval $create_demo_partition $blk_dev {
demo_dev=$(echo $blk_dev | sed -e 's/\(mmcblk[0-9]\)/\1p/')$demo_part
echo $blk_dev | grep -q nvme0 && demo_dev=$(echo $blk_dev | sed -e 's/\(nvme[0-9]n[0-9]\)/\1p/')$demo_part
# Make filesystem
mkfs.ext4 -L $demo_volume_label $demo_dev
# Mount demo filesystem
demo_mnt=$(${onie_bin} mktemp -d) || {
echo "Error: Unable to create file system mount point"
exit 1
}
trap_push "${onie_bin} fuser -km $demo_mnt || ${onie_bin} umount $demo_mnt || ${onie_bin} rmdir $demo_mnt || true"
${onie_bin} mount -t ext4 -o defaults,rw $demo_dev $demo_mnt || {
echo "Error: Unable to mount $demo_dev on $demo_mnt"
exit 1
}
elif [ "$install_env" = "sonic" ]; then
demo_mnt="/host"
# Get current SONiC image (grub/aboot/uboot)
eval running_sonic_revision="$(cat /proc/cmdline | sed -n 's/^.*loop=\/*image-\(\S\+\)\/.*$/\1/p')"
# Verify SONiC image exists
if [ ! -d "$demo_mnt/image-$running_sonic_revision" ]; then
echo "ERROR: SONiC installation is corrupted: path $demo_mnt/image-$running_sonic_revision doesn't exist"
exit 1
fi
# Prevent installing existing SONiC if it is running
if [ "$image_dir" = "image-$running_sonic_revision" ]; then
echo "Not installing SONiC version $running_sonic_revision, as current running SONiC has the same version"
exit 0
fi
# Remove extra SONiC images if any
for f in $demo_mnt/image-* ; do
if [ -d $f ] && [ "$f" != "$demo_mnt/image-$running_sonic_revision" ] && [ "$f" != "$demo_mnt/$image_dir" ]; then
echo "Removing old SONiC installation $f"
rm -rf $f
fi
done
else
demo_mnt="build_raw_image_mnt"
demo_dev=$cur_wd/"%%OUTPUT_RAW_IMAGE%%"
mkfs.ext4 -L $demo_volume_label $demo_dev
echo "Mounting $demo_dev on $demo_mnt..."
mkdir $demo_mnt
mount -t auto -o loop $demo_dev $demo_mnt
fi
echo "Installing SONiC to $demo_mnt/$image_dir"
# Create target directory or clean it up if exists
if [ -d $demo_mnt/$image_dir ]; then
echo "Directory $demo_mnt/$image_dir/ already exists. Cleaning up..."
rm -rf $demo_mnt/$image_dir/*
else
mkdir $demo_mnt/$image_dir || {
echo "Error: Unable to create SONiC directory"
exit 1
}
fi
# Decompress the file for the file system directly to the partition
if [ x"$docker_inram" = x"on" ]; then
# when disk is small, keep dockerfs.tar.gz in disk, expand it into ramfs during initrd
unzip -o $ONIE_INSTALLER_PAYLOAD -x "platform.tar.gz" -d $demo_mnt/$image_dir
else
unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" "platform.tar.gz" -d $demo_mnt/$image_dir
if [ "$install_env" = "onie" ]; then if [ "$install_env" = "onie" ]; then
TAR_EXTRA_OPTION="--numeric-owner" # Store installation log in target file system
else rm -f $onie_initrd_tmp/tmp/onie-support*.tar.bz2
TAR_EXTRA_OPTION="--numeric-owner --warning=no-timestamp" ${onie_bin} onie-support /tmp
fi mv $onie_initrd_tmp/tmp/onie-support*.tar.bz2 $demo_mnt/$image_dir/
mkdir -p $demo_mnt/$image_dir/$DOCKERFS_DIR
unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR
fi
mkdir -p $demo_mnt/$image_dir/platform if [ "$firmware" = "uefi" ] ; then
unzip -op $ONIE_INSTALLER_PAYLOAD "platform.tar.gz" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/platform
if [ "$install_env" = "onie" ]; then
# Store machine description in target file system
if [ -f /etc/machine-build.conf ]; then
# onie_ variable are generate at runtime.
# they are no longer hardcoded in /etc/machine.conf
# also remove single quotes around the value
set | grep ^onie | sed -e "s/='/=/" -e "s/'$//" > $demo_mnt/machine.conf
else
cp /etc/machine.conf $demo_mnt
fi
# Store installation log in target file system
rm -f $onie_initrd_tmp/tmp/onie-support*.tar.bz2
${onie_bin} onie-support /tmp
mv $onie_initrd_tmp/tmp/onie-support*.tar.bz2 $demo_mnt/$image_dir/
if [ "$firmware" = "uefi" ] ; then
demo_install_uefi_grub "$demo_mnt" "$blk_dev" demo_install_uefi_grub "$demo_mnt" "$blk_dev"
else else
demo_install_grub "$demo_mnt" "$blk_dev" demo_install_grub "$demo_mnt" "$blk_dev"
fi
fi fi
fi
# Create a minimal grub.cfg that allows for: # Create a minimal grub.cfg that allows for:
# - configure the serial console # - configure the serial console
# - allows for grub-reboot to work # - allows for grub-reboot to work
# - a menu entry for the DEMO OS # - a menu entry for the DEMO OS
# - menu entries for ONIE # - menu entries for ONIE
grub_cfg=$(mktemp) grub_cfg=$(mktemp)
trap_push "rm $grub_cfg || true" trap_push "rm $grub_cfg || true"
# Set a few GRUB_xxx environment variables that will be picked up and # Set a few GRUB_xxx environment variables that will be picked up and
# used by the 50_onie_grub script. This is similiar to what an OS # used by the 50_onie_grub script. This is similiar to what an OS
# would specify in /etc/default/grub. # would specify in /etc/default/grub.
# #
# GRUB_SERIAL_COMMAND # GRUB_SERIAL_COMMAND
# GRUB_CMDLINE_LINUX # GRUB_CMDLINE_LINUX
[ -r ./platform.conf ] && . ./platform.conf [ -r ./platform.conf ] && . ./platform.conf
# Check if the CPU vendor is 'Intel' and disable c-states if True # Check if the CPU vendor is 'Intel' and disable c-states if True
CPUVENDOR="$(cat /proc/cpuinfo | grep -m 1 vendor_id | awk '{print $3}')" CPUVENDOR="$(cat /proc/cpuinfo | grep -m 1 vendor_id | awk '{print $3}')"
echo "Switch CPU vendor is: $CPUVENDOR" echo "Switch CPU vendor is: $CPUVENDOR"
if echo "$CPUVENDOR" | grep -i 'Intel' >/dev/null 2>&1; then if echo "$CPUVENDOR" | grep -i 'Intel' >/dev/null 2>&1; then
echo "Switch CPU cstates are: disabled" echo "Switch CPU cstates are: disabled"
CSTATES="intel_idle.max_cstate=0" CSTATES="intel_idle.max_cstate=0"
else else
CSTATES="" CSTATES=""
fi fi
DEFAULT_GRUB_SERIAL_COMMAND="serial --port=${CONSOLE_PORT} --speed=${CONSOLE_SPEED} --word=8 --parity=no --stop=1" DEFAULT_GRUB_SERIAL_COMMAND="serial --port=${CONSOLE_PORT} --speed=${CONSOLE_SPEED} --word=8 --parity=no --stop=1"
DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet $CSTATES" DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet $CSTATES"
GRUB_SERIAL_COMMAND=${GRUB_SERIAL_COMMAND:-"$DEFAULT_GRUB_SERIAL_COMMAND"} GRUB_SERIAL_COMMAND=${GRUB_SERIAL_COMMAND:-"$DEFAULT_GRUB_SERIAL_COMMAND"}
GRUB_CMDLINE_LINUX=${GRUB_CMDLINE_LINUX:-"$DEFAULT_GRUB_CMDLINE_LINUX"} GRUB_CMDLINE_LINUX=${GRUB_CMDLINE_LINUX:-"$DEFAULT_GRUB_CMDLINE_LINUX"}
export GRUB_SERIAL_COMMAND export GRUB_SERIAL_COMMAND
export GRUB_CMDLINE_LINUX export GRUB_CMDLINE_LINUX
# Add common configuration, like the timeout and serial console. # Add common configuration, like the timeout and serial console.
cat <<EOF > $grub_cfg cat <<EOF > $grub_cfg
$GRUB_SERIAL_COMMAND $GRUB_SERIAL_COMMAND
terminal_input console serial terminal_input console serial
terminal_output console serial terminal_output console serial
@ -620,8 +422,8 @@ set timeout=5
EOF EOF
# Add the logic to support grub-reboot and grub-set-default # Add the logic to support grub-reboot and grub-set-default
cat <<EOF >> $grub_cfg cat <<EOF >> $grub_cfg
if [ -s \$prefix/grubenv ]; then if [ -s \$prefix/grubenv ]; then
load_env load_env
fi fi
@ -639,35 +441,34 @@ if [ "\${onie_entry}" ]; then
unset onie_entry unset onie_entry
save_env onie_entry next_entry save_env onie_entry next_entry
fi fi
EOF EOF
if [ "$demo_type" = "DIAG" ] ; then if [ "$demo_type" = "DIAG" ] ; then
# Make sure ONIE install mode is the default boot mode for the # Make sure ONIE install mode is the default boot mode for the
# diag partition. # diag partition.
cat <<EOF >> $grub_cfg cat <<EOF >> $grub_cfg
set default=ONIE set default=ONIE
EOF EOF
$onie_root_dir/tools/bin/onie-boot-mode -q -o install $onie_root_dir/tools/bin/onie-boot-mode -q -o install
fi fi
# Add a menu entry for the SONiC OS # Add a menu entry for the SONiC OS
# Note: assume that apparmor is supported in the kernel # Note: assume that apparmor is supported in the kernel
demo_grub_entry="$demo_volume_revision_label" demo_grub_entry="$demo_volume_revision_label"
if [ "$install_env" = "sonic" ]; then if [ "$install_env" = "sonic" ]; then
old_sonic_menuentry=$(cat /host/grub/grub.cfg | sed "/^menuentry '${demo_volume_label}-${running_sonic_revision}'/,/}/!d") old_sonic_menuentry=$(cat /host/grub/grub.cfg | sed "/^menuentry '${demo_volume_label}-${running_sonic_revision}'/,/}/!d")
grub_cfg_root=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/") grub_cfg_root=$(echo $old_sonic_menuentry | sed -e "s/.*root\=\(.*\)rw.*/\1/")
onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d") onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d")
elif [ "$install_env" = "build" ]; then elif [ "$install_env" = "build" ]; then
grub_cfg_root=%%SONIC_ROOT%% grub_cfg_root=%%SONIC_ROOT%%
else # install_env = "onie" else # install_env = "onie"
uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p') uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p')
if [ -z "$uuid" ]; then if [ -z "$uuid" ]; then
grub_cfg_root=$demo_dev grub_cfg_root=$demo_dev
else else
grub_cfg_root=UUID=$uuid grub_cfg_root=UUID=$uuid
fi
fi fi
fi
# Add extra linux command line # Add extra linux command line
extra_cmdline_linux=%%EXTRA_CMDLINE_LINUX%% extra_cmdline_linux=%%EXTRA_CMDLINE_LINUX%%
@ -692,25 +493,27 @@ menuentry '$demo_grub_entry' {
} }
EOF EOF
if [ "$install_env" = "onie" ]; then if [ "$install_env" = "onie" ]; then
# Add menu entries for ONIE -- use the grub fragment provided by the # Add menu entries for ONIE -- use the grub fragment provided by the
# ONIE distribution. # ONIE distribution.
$onie_root_dir/grub.d/50_onie_grub >> $grub_cfg $onie_root_dir/grub.d/50_onie_grub >> $grub_cfg
mkdir -p $onie_initrd_tmp/$demo_mnt/grub mkdir -p $onie_initrd_tmp/$demo_mnt/grub
else else
cat <<EOF >> $grub_cfg cat <<EOF >> $grub_cfg
$old_sonic_menuentry $old_sonic_menuentry
$onie_menuentry $onie_menuentry
EOF EOF
fi fi
if [ "$install_env" = "build" ]; then if [ "$install_env" = "build" ]; then
cp $grub_cfg $demo_mnt/grub.cfg cp $grub_cfg $demo_mnt/grub.cfg
umount $demo_mnt umount $demo_mnt
else else
cp $grub_cfg $onie_initrd_tmp/$demo_mnt/grub/grub.cfg cp $grub_cfg $onie_initrd_tmp/$demo_mnt/grub/grub.cfg
fi fi
cd / cd /
echo "Installed SONiC base image $demo_volume_label successfully" echo "Installed SONiC base image $demo_volume_label successfully"
}

View File

@ -1,7 +1,16 @@
#!/bin/sh #!/bin/sh
# Copyright (C) Marvell Inc # Copyright (C) 2020 Marvell Inc
# Copyright (C) 2014-2015 Curt Brune <curt@cumulusnetworks.com>
# Copyright (C) 2014-2015 david_yang <david_yang@accton.com>
# #
# SPDX-License-Identifier: GPL-2.0
# Appends a command to a trap, which is needed because default trap behavior is to replace
# previous trap for the same signal
# - 1st arg: code to add
# - ref: http://stackoverflow.com/questions/3338030/multiple-bash-traps-for-the-same-signal
_trap_push() { _trap_push() {
local next="$1" local next="$1"
@ -14,6 +23,26 @@ _trap_push() {
} }
_trap_push true _trap_push true
read_conf_file() {
local conf_file=$1
while IFS='=' read -r var value || [ -n "$var" ]
do
# remove newline character
var=$(echo $var | tr -d '\r\n')
value=$(echo $value | tr -d '\r\n')
# remove comment string
var=${var%#*}
value=${value%#*}
# skip blank line
[ -z "$var" ] && continue
# remove double quote in the beginning
tmp_val=${value#\"}
# remove double quote in the end
value=${tmp_val%\"}
eval "$var=\"$value\""
done < "$conf_file"
}
set -e set -e
if [ -d "/etc/sonic" ]; then if [ -d "/etc/sonic" ]; then
@ -30,11 +59,17 @@ fi
cd $(dirname $0) cd $(dirname $0)
if [ -r ./machine.conf ]; then if [ -r ./machine.conf ]; then
. ./machine.conf read_conf_file "./machine.conf"
fi fi
if [ -r ./onie-image-arm64.conf ]; then # Load generic onie-image.conf
. ./onie-image-arm64.conf if [ -r ./onie-image.conf ]; then
. ./onie-image.conf
fi
# Load arch-specific onie-image-[arch].conf if exists
if [ -r ./onie-image-*.conf ]; then
. ./onie-image-*.conf
fi fi
echo "ONIE Installer: platform: $platform" echo "ONIE Installer: platform: $platform"
@ -45,15 +80,17 @@ if [ $(id -u) -ne 0 ]
exit 1 exit 1
fi fi
# get running machine from conf file
if [ -r /etc/machine.conf ]; then if [ -r /etc/machine.conf ]; then
. /etc/machine.conf read_conf_file "/etc/machine.conf"
elif [ -r /host/machine.conf ]; then elif [ -r /host/machine.conf ]; then
. /host/machine.conf read_conf_file "/host/machine.conf"
elif [ "$install_env" != "build" ]; then elif [ "$install_env" != "build" ]; then
echo "cannot find machine.conf" echo "cannot find machine.conf"
exit 1 exit 1
fi fi
echo "onie_platform: $onie_platform" echo "onie_platform: $onie_platform"
# Get platform specific linux kernel command line arguments # Get platform specific linux kernel command line arguments
@ -110,7 +147,12 @@ demo_volume_label="SONiC-${demo_type}"
demo_volume_revision_label="SONiC-${demo_type}-${image_version}" demo_volume_revision_label="SONiC-${demo_type}-${image_version}"
. ./platform.conf . ./default_platform.conf
if [ -r ./platform.conf ]; then
. ./platform.conf
fi
image_dir="image-$image_version" image_dir="image-$image_version"
@ -139,8 +181,19 @@ elif [ "$install_env" = "sonic" ]; then
rm -rf $f rm -rf $f
fi fi
done done
else
demo_mnt="build_raw_image_mnt"
demo_dev=$cur_wd/"%%OUTPUT_RAW_IMAGE%%"
mkfs.ext4 -L $demo_volume_label $demo_dev
echo "Mounting $demo_dev on $demo_mnt..."
mkdir $demo_mnt
mount -t auto -o loop $demo_dev $demo_mnt
fi fi
echo "Installing SONiC to $demo_mnt/$image_dir"
# Create target directory or clean it up if exists # Create target directory or clean it up if exists
if [ -d $demo_mnt/$image_dir ]; then if [ -d $demo_mnt/$image_dir ]; then
echo "Directory $demo_mnt/$image_dir/ already exists. Cleaning up..." echo "Directory $demo_mnt/$image_dir/ already exists. Cleaning up..."

View File

@ -23,9 +23,9 @@ if [ ! -d $installer_dir ] || \
exit 1 exit 1
fi fi
if [ ! -d $installer_dir/$arch ] || \ if [ ! -d $installer_dir ] || \
[ ! -r $installer_dir/$arch/install.sh ] ; then [ ! -r $installer_dir/install.sh ] ; then
echo "Error: Invalid arch installer directory: $installer_dir/$arch" echo "Error: Invalid arch installer directory: $installer_dir"
exit 1 exit 1
fi fi
@ -75,9 +75,9 @@ tmp_dir=$(mktemp --directory)
tmp_installdir="$tmp_dir/installer" tmp_installdir="$tmp_dir/installer"
mkdir $tmp_installdir || clean_up 1 mkdir $tmp_installdir || clean_up 1
cp -r $installer_dir/$arch/* $tmp_installdir || clean_up 1 cp -r $installer_dir/* $tmp_installdir || clean_up 1
cp onie-image.conf $tmp_installdir cp onie-image.conf $tmp_installdir
cp onie-image-*.conf $tmp_installdir cp onie-image-$arch.conf $tmp_installdir
# Set sonic fips config for the installer script # Set sonic fips config for the installer script
if [ "$ENABLE_FIPS" = "y" ]; then if [ "$ENABLE_FIPS" = "y" ]; then

View File

@ -75,6 +75,7 @@ export BUILD_TIMESTAMP
export SONIC_IMAGE_VERSION export SONIC_IMAGE_VERSION
export CONFIGURED_PLATFORM export CONFIGURED_PLATFORM
export CONFIGURED_ARCH export CONFIGURED_ARCH
export TARGET_BOOTLOADER
export PYTHON_WHEELS_PATH export PYTHON_WHEELS_PATH
export IMAGE_DISTRO export IMAGE_DISTRO
export IMAGE_DISTRO_DEBS_PATH export IMAGE_DISTRO_DEBS_PATH