From 429254cb2d756e1851050c659d48a718fd7e1973 Mon Sep 17 00:00:00 2001 From: Alexander Allen Date: Tue, 12 Jul 2022 18:00:57 -0400 Subject: [PATCH] [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 --- Makefile.work | 6 + build_debian.sh | 20 +- build_image.sh | 8 +- .../build_templates/sonic_debian_extension.j2 | 2 +- files/image_config/platform/rc.local | 2 +- installer/armhf/install.sh | 197 ------- .../install.sh => default_platform.conf} | 493 ++++++------------ installer/{arm64 => }/install.sh | 67 ++- .../{x86_64 => }/tests/sample_machine.conf | 0 .../{x86_64 => }/tests/test_read_conf.sh | 2 +- onie-mk-demo.sh | 10 +- slave.mk | 1 + 12 files changed, 240 insertions(+), 568 deletions(-) delete mode 100755 installer/armhf/install.sh rename installer/{x86_64/install.sh => default_platform.conf} (54%) rename installer/{arm64 => }/install.sh (76%) rename installer/{x86_64 => }/tests/sample_machine.conf (100%) rename installer/{x86_64 => }/tests/test_read_conf.sh (99%) diff --git a/Makefile.work b/Makefile.work index b9d930a5d9..c9db8b00f8 100644 --- a/Makefile.work +++ b/Makefile.work @@ -104,6 +104,12 @@ ifeq ($(PLATFORM_ARCH),) override PLATFORM_ARCH = $(CONFIGURED_ARCH) endif +ifeq ($(CONFIGURED_ARCH),amd64) +TARGET_BOOTLOADER = grub +else +TARGET_BOOTLOADER = uboot +endif + ifeq ($(BLDENV), bullseye) SLAVE_DIR = sonic-slave-bullseye else ifeq ($(BLDENV), buster) diff --git a/build_debian.sh b/build_debian.sh index a4c1fddca1..92ecb7ac16 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -65,7 +65,7 @@ if [[ -d $FILESYSTEM_ROOT ]]; then fi mkdir -p $FILESYSTEM_ROOT 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 ## ensure proc is mounted @@ -162,7 +162,7 @@ if [ "$SONIC_ENABLE_SECUREBOOT_SIGNATURE" = "y" ]; then fi 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} sudo cp -f /tmp/${K##*/} ${K} fi @@ -392,11 +392,17 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in systemd-sysv \ ntp -if [[ $CONFIGURED_ARCH == amd64 ]]; then - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \ - grub-pc-bin +if [[ $TARGET_BOOTLOADER == grub ]]; then + if [[ $CONFIGURED_ARCH == amd64 ]]; then + 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 ## Disable kexec supported reboot which was installed by default @@ -572,7 +578,7 @@ fi ## Update initramfs sudo chroot $FILESYSTEM_ROOT update-initramfs -u ## 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} if [[ $CONFIGURED_ARCH == armhf ]]; then INITRD_FILE=initrd.img-${LINUX_KERNEL_VERSION}-armmp diff --git a/build_image.sh b/build_image.sh index 69ea4ddf56..ddf134e845 100755 --- a/build_image.sh +++ b/build_image.sh @@ -84,7 +84,7 @@ generate_onie_installer_image() ## Generate an ONIE installer image ## 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 \ $ONIE_INSTALLER_PAYLOAD } @@ -111,7 +111,7 @@ if [ "$IMAGE_TYPE" = "onie" ]; then mkdir -p `dirname $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 @@ -125,7 +125,7 @@ elif [ "$IMAGE_TYPE" = "raw" ]; then mkdir -p `dirname $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" @@ -159,7 +159,7 @@ elif [ "$IMAGE_TYPE" = "raw" ]; 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 single asic KVM image diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index db35658ed9..57449e655c 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -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 # 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 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 diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 647d552427..8f3de778f7 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -293,7 +293,7 @@ if [ -f $FIRST_BOOT_FILE ]; then # we now install a grub for SONiC. 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 log_migration "Unable to locate grub package !" firsttime_exit diff --git a/installer/armhf/install.sh b/installer/armhf/install.sh deleted file mode 100755 index 4ced27f48f..0000000000 --- a/installer/armhf/install.sh +++ /dev/null @@ -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 diff --git a/installer/x86_64/install.sh b/installer/default_platform.conf similarity index 54% rename from installer/x86_64/install.sh rename to installer/default_platform.conf index 926c54683a..af3fa8fc22 100755 --- a/installer/x86_64/install.sh +++ b/installer/default_platform.conf @@ -1,119 +1,5 @@ #!/bin/sh -# Copyright (C) 2014-2015 Curt Brune -# Copyright (C) 2014-2015 david_yang -# -# 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. # Console port and speed setting in cmdline is like "console=ttyS0,9600n", @@ -145,69 +31,75 @@ if [ -z "$CONSOLE_SPEED" ]; then fi fi -# Install demo on same block device as ONIE -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/') +create_partition() +{ - # check if we have an nvme device - blk_suffix= - echo $blk_dev | grep -q nvme0 && blk_suffix="p" + # Install demo on same block device as ONIE + 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/') - # Note: ONIE has no mount setting for / with device node, so below will be empty string - cur_part=$(cat /proc/mounts | awk "{ if(\$2==\"/\") print \$1 }" | grep $blk_dev || true) + # check if we have an nvme device + blk_suffix= + echo $blk_dev | grep -q nvme0 && blk_suffix="p" - [ -b "$blk_dev" ] || { - echo "Error: Unable to determine block device of ONIE install" + # Note: ONIE has no mount setting for / with device node, so below will be empty string + + 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 } -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}" - -# 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" + 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 - fi -fi + } + +} # 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 # new boot number as active. + grub=$(find /boot/efi/EFI/$demo_volume_label/ -name grub*.efi -exec basename {} \;) efibootmgr --quiet --create \ --label "$demo_volume_label" \ --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" exit 1 } } -image_dir="image-$image_version" -if [ "$install_env" = "onie" ]; then - 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 +bootloader_menu_config() +{ 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 + # 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/ -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 - - # 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 + if [ "$firmware" = "uefi" ] ; then demo_install_uefi_grub "$demo_mnt" "$blk_dev" - else + else demo_install_grub "$demo_mnt" "$blk_dev" + fi fi -fi -# Create a minimal grub.cfg that allows for: -# - configure the serial console -# - allows for grub-reboot to work -# - a menu entry for the DEMO OS -# - menu entries for ONIE + # Create a minimal grub.cfg that allows for: + # - configure the serial console + # - allows for grub-reboot to work + # - a menu entry for the DEMO OS + # - menu entries for ONIE -grub_cfg=$(mktemp) -trap_push "rm $grub_cfg || true" + grub_cfg=$(mktemp) + trap_push "rm $grub_cfg || true" -# 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 -# would specify in /etc/default/grub. -# -# GRUB_SERIAL_COMMAND -# GRUB_CMDLINE_LINUX + # 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 + # would specify in /etc/default/grub. + # + # GRUB_SERIAL_COMMAND + # 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 -CPUVENDOR="$(cat /proc/cpuinfo | grep -m 1 vendor_id | awk '{print $3}')" -echo "Switch CPU vendor is: $CPUVENDOR" -if echo "$CPUVENDOR" | grep -i 'Intel' >/dev/null 2>&1; then - echo "Switch CPU cstates are: disabled" - CSTATES="intel_idle.max_cstate=0" -else - CSTATES="" -fi + # 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}')" + echo "Switch CPU vendor is: $CPUVENDOR" + if echo "$CPUVENDOR" | grep -i 'Intel' >/dev/null 2>&1; then + echo "Switch CPU cstates are: disabled" + CSTATES="intel_idle.max_cstate=0" + else + CSTATES="" + fi -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" -GRUB_SERIAL_COMMAND=${GRUB_SERIAL_COMMAND:-"$DEFAULT_GRUB_SERIAL_COMMAND"} -GRUB_CMDLINE_LINUX=${GRUB_CMDLINE_LINUX:-"$DEFAULT_GRUB_CMDLINE_LINUX"} -export GRUB_SERIAL_COMMAND -export GRUB_CMDLINE_LINUX + 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" + GRUB_SERIAL_COMMAND=${GRUB_SERIAL_COMMAND:-"$DEFAULT_GRUB_SERIAL_COMMAND"} + GRUB_CMDLINE_LINUX=${GRUB_CMDLINE_LINUX:-"$DEFAULT_GRUB_CMDLINE_LINUX"} + export GRUB_SERIAL_COMMAND + export GRUB_CMDLINE_LINUX -# Add common configuration, like the timeout and serial console. -cat < $grub_cfg + # Add common configuration, like the timeout and serial console. + cat < $grub_cfg $GRUB_SERIAL_COMMAND terminal_input console serial terminal_output console serial @@ -620,8 +422,8 @@ set timeout=5 EOF -# Add the logic to support grub-reboot and grub-set-default -cat <> $grub_cfg + # Add the logic to support grub-reboot and grub-set-default + cat <> $grub_cfg if [ -s \$prefix/grubenv ]; then load_env fi @@ -639,35 +441,34 @@ if [ "\${onie_entry}" ]; then unset onie_entry save_env onie_entry next_entry fi - EOF -if [ "$demo_type" = "DIAG" ] ; then - # Make sure ONIE install mode is the default boot mode for the - # diag partition. - cat <> $grub_cfg + if [ "$demo_type" = "DIAG" ] ; then + # Make sure ONIE install mode is the default boot mode for the + # diag partition. + cat <> $grub_cfg set default=ONIE EOF - $onie_root_dir/tools/bin/onie-boot-mode -q -o install -fi - -# Add a menu entry for the SONiC OS -# Note: assume that apparmor is supported in the kernel -demo_grub_entry="$demo_volume_revision_label" -if [ "$install_env" = "sonic" ]; then - 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/") - onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d") -elif [ "$install_env" = "build" ]; then - grub_cfg_root=%%SONIC_ROOT%% -else # install_env = "onie" - uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p') - if [ -z "$uuid" ]; then - grub_cfg_root=$demo_dev - else - grub_cfg_root=UUID=$uuid + $onie_root_dir/tools/bin/onie-boot-mode -q -o install + fi + + # Add a menu entry for the SONiC OS + # Note: assume that apparmor is supported in the kernel + demo_grub_entry="$demo_volume_revision_label" + if [ "$install_env" = "sonic" ]; then + 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/") + onie_menuentry=$(cat /host/grub/grub.cfg | sed "/menuentry ONIE/,/}/!d") + elif [ "$install_env" = "build" ]; then + grub_cfg_root=%%SONIC_ROOT%% + else # install_env = "onie" + uuid=$(blkid "$demo_dev" | sed -ne 's/.* UUID=\"\([^"]*\)\".*/\1/p') + if [ -z "$uuid" ]; then + grub_cfg_root=$demo_dev + else + grub_cfg_root=UUID=$uuid + fi fi -fi # Add extra linux command line extra_cmdline_linux=%%EXTRA_CMDLINE_LINUX%% @@ -692,25 +493,27 @@ menuentry '$demo_grub_entry' { } EOF -if [ "$install_env" = "onie" ]; then - # Add menu entries for ONIE -- use the grub fragment provided by the - # ONIE distribution. - $onie_root_dir/grub.d/50_onie_grub >> $grub_cfg - mkdir -p $onie_initrd_tmp/$demo_mnt/grub -else -cat <> $grub_cfg + if [ "$install_env" = "onie" ]; then + # Add menu entries for ONIE -- use the grub fragment provided by the + # ONIE distribution. + $onie_root_dir/grub.d/50_onie_grub >> $grub_cfg + mkdir -p $onie_initrd_tmp/$demo_mnt/grub + else + cat <> $grub_cfg $old_sonic_menuentry $onie_menuentry EOF -fi + fi -if [ "$install_env" = "build" ]; then - cp $grub_cfg $demo_mnt/grub.cfg - umount $demo_mnt -else - cp $grub_cfg $onie_initrd_tmp/$demo_mnt/grub/grub.cfg -fi + if [ "$install_env" = "build" ]; then + cp $grub_cfg $demo_mnt/grub.cfg + umount $demo_mnt + else + cp $grub_cfg $onie_initrd_tmp/$demo_mnt/grub/grub.cfg + fi -cd / + cd / -echo "Installed SONiC base image $demo_volume_label successfully" + echo "Installed SONiC base image $demo_volume_label successfully" + +} diff --git a/installer/arm64/install.sh b/installer/install.sh similarity index 76% rename from installer/arm64/install.sh rename to installer/install.sh index 54ce1dda93..8f4a515579 100755 --- a/installer/arm64/install.sh +++ b/installer/install.sh @@ -1,7 +1,16 @@ #!/bin/sh -# Copyright (C) Marvell Inc +# Copyright (C) 2020 Marvell Inc +# Copyright (C) 2014-2015 Curt Brune +# Copyright (C) 2014-2015 david_yang # +# 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" @@ -14,6 +23,26 @@ _trap_push() { } _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 if [ -d "/etc/sonic" ]; then @@ -30,11 +59,17 @@ fi cd $(dirname $0) if [ -r ./machine.conf ]; then - . ./machine.conf + read_conf_file "./machine.conf" fi -if [ -r ./onie-image-arm64.conf ]; then - . ./onie-image-arm64.conf +# Load generic onie-image.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 echo "ONIE Installer: platform: $platform" @@ -45,15 +80,17 @@ if [ $(id -u) -ne 0 ] exit 1 fi +# get running machine from conf file if [ -r /etc/machine.conf ]; then - . /etc/machine.conf + read_conf_file "/etc/machine.conf" elif [ -r /host/machine.conf ]; then - . /host/machine.conf + 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 @@ -110,7 +147,12 @@ demo_volume_label="SONiC-${demo_type}" 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" @@ -139,8 +181,19 @@ elif [ "$install_env" = "sonic" ]; then 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..." diff --git a/installer/x86_64/tests/sample_machine.conf b/installer/tests/sample_machine.conf similarity index 100% rename from installer/x86_64/tests/sample_machine.conf rename to installer/tests/sample_machine.conf diff --git a/installer/x86_64/tests/test_read_conf.sh b/installer/tests/test_read_conf.sh similarity index 99% rename from installer/x86_64/tests/test_read_conf.sh rename to installer/tests/test_read_conf.sh index 06b7fc145e..a293058b01 100644 --- a/installer/x86_64/tests/test_read_conf.sh +++ b/installer/tests/test_read_conf.sh @@ -58,4 +58,4 @@ TEST_CONF "$onie_skip_ethmgmt_macs" "$exp_onie_skip_ethmgmt_macs" TEST_CONF "$onie_grub_image_name" "$exp_onie_grub_image_name" echo "PASS!!" -exit 0 \ No newline at end of file +exit 0 diff --git a/onie-mk-demo.sh b/onie-mk-demo.sh index 55d0404a14..0905673d42 100755 --- a/onie-mk-demo.sh +++ b/onie-mk-demo.sh @@ -23,9 +23,9 @@ if [ ! -d $installer_dir ] || \ exit 1 fi -if [ ! -d $installer_dir/$arch ] || \ - [ ! -r $installer_dir/$arch/install.sh ] ; then - echo "Error: Invalid arch installer directory: $installer_dir/$arch" +if [ ! -d $installer_dir ] || \ + [ ! -r $installer_dir/install.sh ] ; then + echo "Error: Invalid arch installer directory: $installer_dir" exit 1 fi @@ -75,9 +75,9 @@ tmp_dir=$(mktemp --directory) tmp_installdir="$tmp_dir/installer" 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-$arch.conf $tmp_installdir # Set sonic fips config for the installer script if [ "$ENABLE_FIPS" = "y" ]; then diff --git a/slave.mk b/slave.mk index 9366149023..8a400a8c88 100644 --- a/slave.mk +++ b/slave.mk @@ -75,6 +75,7 @@ export BUILD_TIMESTAMP export SONIC_IMAGE_VERSION export CONFIGURED_PLATFORM export CONFIGURED_ARCH +export TARGET_BOOTLOADER export PYTHON_WHEELS_PATH export IMAGE_DISTRO export IMAGE_DISTRO_DEBS_PATH