From 0e5c31914298f103e9c3133bba1e9fca7b68fe7e Mon Sep 17 00:00:00 2001 From: Kalimuthu Velappan Date: Fri, 22 Apr 2022 04:30:37 -0700 Subject: [PATCH] Sonic image build optimization The current SONIC build infrastructure always prepares the rootfs for final image generation. Because of rootfs preparation, final image generation takes long regardless of SONiC changes. The rootfs preparation consists of two parts. Debian packages installation Bootstrap preparation General packages installation, such as curl, vim, sudo, python3, etc Sonic packages installation Packages that are built and installed from the sonic repo. Docker images that are built and installed from the sonic repo The build time can be optimized by generating the Debian packages as a base image and it can be run in parallel with the other targets, before the final image. Benefits: - High hit rate, for fewer dependencies. - Reduce the cache size. - Improve the concurrency when the cache is not hit, the step has small dependencies and can be run with any other steps. Other enhancements: - The docker load is also optimized by running in parallel. - Added support for gipz compression - Added tmpfs support for rootfs and final image generation. --- Makefile.cache | 21 +- build_debian.sh | 335 +++--------- build_debian_rootfs.sh | 512 ++++++++++++++++++ build_image.sh | 6 +- .../build_templates/sonic_debian_extension.j2 | 360 ++++-------- functions.sh | 29 + installer/x86_64/install.sh | 18 +- onie-image.conf | 2 - platform/broadcom/one-image.mk | 7 +- rules/config | 10 + rules/fsroot.dep | 27 + rules/fsroot.mk | 5 + rules/functions | 17 + scripts/build_debian_base_system.sh | 2 + scripts/build_kvm_image.sh | 2 +- scripts/fsutil.sh | 320 +++++++++++ slave.mk | 107 +++- 17 files changed, 1230 insertions(+), 550 deletions(-) create mode 100755 build_debian_rootfs.sh create mode 100644 rules/fsroot.dep create mode 100644 rules/fsroot.mk create mode 100755 scripts/fsutil.sh diff --git a/Makefile.cache b/Makefile.cache index 50fac768a599..550b5eb5547a 100644 --- a/Makefile.cache +++ b/Makefile.cache @@ -254,8 +254,14 @@ define LOAD_FROM_CACHE # Load the cache if cache is enabled and cache file is present in the cache # Update the cache_loaded variable $(if $(and $(CACHE_FILE_SELECT),$(filter $(RCACHE_OPTIONS),$(SONIC_DPKG_CACHE_METHOD))), - $(if $(LOAD_DRV_DEB), $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mxzvf $(CACHE_FILE_SELECT) 1>> $($(1)_DST_PATH)/$(1).log ,echo ); - echo "File $(CACHE_FILE_SELECT) is loaded from cache into $($(1)_BASE_PATH)" >> $($(1)_DST_PATH)/$(1).log + $(if $(or $(LOAD_DRV_DEB), $($(1)_FORCE_COPY) ), \ + $(if $($(1)_LOAD_HANDLER), \ + $(call $($(1)_LOAD_HANDLER), $(CACHE_FILE_SELECT), $($(1)_DST_PATH)/$(1) ), \ + $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mxzvf $(CACHE_FILE_SELECT) 1>> $($(1)_DST_PATH)/$(1).log \ + ) \ + ,echo \ + ); + echo "File $(CACHE_FILE_SELECT) is loaded into $($(1)_DST_PATH)" >> $($(1)_DST_PATH)/$(1).log $(eval $(1)_CACHE_LOADED := Yes) $(if $(call CHECK_WCACHE_ENABLED,$(1)), $(shell touch $(CACHE_FILE_SELECT))) echo "[ CACHE::LOADED ] $($(1)_CACHE_DIR)/$($(1)_MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log @@ -293,9 +299,14 @@ define SAVE_INTO_CACHE echo "Target $(1) dependencies are modifed - global save cache skipped" >> $($(1)_DST_PATH)/$(1).log $(eval $(1)_CACHE_DIR := $(SONIC_DPKG_LOCAL_CACHE_DIR)) ) - $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mczvf $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) $(2) $(addprefix $($(1)_DST_PATH)/,$($(1)_DERIVED_DEBS) $($(1)_EXTRA_DEBS) ) \ - 1>>$($(1)_DST_PATH)/$(1).log - sudo chmod 777 $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) + + # Call user handler if exists + $(eval $(1)_SAVE_FILES := $(2) $(addprefix $($(1)_DST_PATH)/,$($(1)_DERIVED_DEBS) $($(1)_EXTRA_DEBS) ) ) + $(if $($(1)_SAVE_HANDLER), + $(call $($(1)_SAVE_HANDLER), $($(1)_SAVE_FILES), $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) ), + $($(1)_CACHE_USER) tar -C $($(1)_BASE_PATH) -mczvf $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) $($(1)_SAVE_FILES) 1>>$($(1)_DST_PATH)/$(1).log \ + ) + chmod 777 $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) &>/dev/null || sudo chmod 777 $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) echo "File $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE) saved in cache " >> $($(1)_DST_PATH)/$(1).log echo "[ CACHE::SAVED ] $($(1)_CACHE_DIR)/$(MOD_CACHE_FILE)" >> $($(1)_DST_PATH)/$(1).log diff --git a/build_debian.sh b/build_debian.sh index 676c0298ec7d..3dc162e26a58 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -5,10 +5,14 @@ ## USAGE: ## USERNAME=username PASSWORD=password ./build_debian ## ENVIRONMENT: +## BUILD_TARGET +## The name of the installer that is currently being created ## USERNAME ## The name of the default admin user ## PASSWORD ## The password, expected by chpasswd command +## NUMPROCS +## Limit the number of processes to use with mksquashfs ## Default user [ -n "$USERNAME" ] || { @@ -22,6 +26,10 @@ exit 1 } +## Number of CPU processes to use for mksquashfs +[ -n "$NUMPROCS" ] || { + NUMPROCS=$(nproc) +} ## Include common functions . functions.sh @@ -35,9 +43,6 @@ DOCKER_VERSION=5:20.10.14~3-0~debian-$IMAGE_DISTRO CONTAINERD_IO_VERSION=1.5.11-1 LINUX_KERNEL_VERSION=5.10.0-12-2 -## Working directory to prepare the file system -FILESYSTEM_ROOT=./fsroot -PLATFORM_DIR=platform ## Hostname for the linux image HOSTNAME=sonic DEFAULT_USERINFO="Default admin user,,," @@ -59,43 +64,29 @@ TRUSTED_GPG_DIR=$BUILD_TOOL_PATH/trusted.gpg.d exit 1 } -## Prepare the file system directory -if [[ -d $FILESYSTEM_ROOT ]]; then - sudo rm -rf $FILESYSTEM_ROOT || die "Failed to clean chroot directory" -fi -mkdir -p $FILESYSTEM_ROOT -mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR -mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR/x86_64-grub -touch $FILESYSTEM_ROOT/$PLATFORM_DIR/firsttime + +## Working directory to prepare the file system +FILESYSTEM_BASE=/sonic/build/${BASE_IMAGE_NAME} +FILESYSTEM_ROOT=${FILESYSTEM_BASE} +PLATFORM_DIR=platform +BUILD_PATH=target/fs/${TARGET_MACHINE} + +mkdir -p ${BUILD_PATH} +sudo chmod -R 777 ${BUILD_PATH} +mkdir -p ${FILESYSTEM_ROOT} ## ensure proc is mounted -sudo mount proc /proc -t proc || true +sudo mountpoint -q /proc || sudo mount -t proc proc /proc || true ## make / as a mountpoint in chroot env, needed by dockerd pushd $FILESYSTEM_ROOT sudo mount --bind . . popd -## Build the host debian base system -echo '[INFO] Build host debian base system...' -TARGET_PATH=$TARGET_PATH scripts/build_debian_base_system.sh $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT -# Prepare buildinfo -sudo scripts/prepare_debian_image_buildinfo.sh $CONFIGURED_ARCH $IMAGE_DISTRO $FILESYSTEM_ROOT $http_proxy +trap_push "sudo LANG=C BASE_IMAGE_NAME=${BASE_IMAGE_NAME} scripts/fsutil.sh rootfs umount || true" +BASE_IMAGE_NAME=${BASE_IMAGE_NAME} scripts/fsutil.sh rootfs mount -sudo chown root:root $FILESYSTEM_ROOT - -## Config hostname and hosts, otherwise 'sudo ...' will complain 'sudo: unable to resolve host ...' -sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '$HOSTNAME' > /etc/hostname" -sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '127.0.0.1 $HOSTNAME' >> /etc/hosts" -sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '127.0.0.1 localhost' >> /etc/hosts" - -## Config basic fstab -sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'echo "proc /proc proc defaults 0 0" >> /etc/fstab' -sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'echo "sysfs /sys sysfs defaults 0 0" >> /etc/fstab' - -## Setup proxy -[ -n "$http_proxy" ] && sudo /bin/bash -c "echo 'Acquire::http::Proxy \"$http_proxy\";' > $FILESYSTEM_ROOT/etc/apt/apt.conf.d/01proxy" trap_push 'sudo LANG=C chroot $FILESYSTEM_ROOT umount /proc || true' sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc @@ -104,39 +95,12 @@ echo '[INFO] Mount all' ## Output all the mounted device for troubleshooting sudo LANG=C chroot $FILESYSTEM_ROOT mount -## Install the trusted gpg public keys -[ -d $TRUSTED_GPG_DIR ] && [ ! -z "$(ls $TRUSTED_GPG_DIR)" ] && sudo cp $TRUSTED_GPG_DIR/* ${FILESYSTEM_ROOT}/etc/apt/trusted.gpg.d/ - -## Pointing apt to public apt mirrors and getting latest packages, needed for latest security updates -sudo cp files/apt/sources.list.$CONFIGURED_ARCH $FILESYSTEM_ROOT/etc/apt/sources.list -sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages},no-check-valid-until} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ -## Note: set lang to prevent locale warnings in your chroot -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y update -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y upgrade -echo '[INFO] Install and setup eatmydata' -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install eatmydata -sudo LANG=C chroot $FILESYSTEM_ROOT ln -s /usr/bin/eatmydata /usr/local/bin/dpkg -echo 'Dir::Bin::dpkg "/usr/local/bin/dpkg";' | sudo tee $FILESYSTEM_ROOT/etc/apt/apt.conf.d/00image-install-eatmydata > /dev/null +# mount the docker tmpfs +BASE_IMAGE_NAME=${BASE_IMAGE_NAME} scripts/fsutil.sh dockerfs mount -echo '[INFO] Install packages for building image' -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install makedev psmisc -## Create device files -echo '[INFO] MAKEDEV' -if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'cd /dev && MAKEDEV generic-arm' -else - sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'cd /dev && MAKEDEV generic' -fi -## Install initramfs-tools and linux kernel -## Note: initramfs-tools recommends depending on busybox, and we really want busybox for -## 1. commands such as touch -## 2. mount supports squashfs -## However, 'dpkg -i' plus 'apt-get install -f' will ignore the recommended dependency. So -## we install busybox explicitly -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox linux-base echo '[INFO] Install SONiC linux kernel image' ## Note: duplicate apt-get command to ensure every line return zero sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/initramfs-tools-core_*.deb || \ @@ -220,184 +184,6 @@ if [ -f platform/$CONFIGURED_PLATFORM/modules ]; then cat platform/$CONFIGURED_PLATFORM/modules | sudo tee -a $FILESYSTEM_ROOT/etc/initramfs-tools/modules > /dev/null fi -## Add mtd and uboot firmware tools package -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install u-boot-tools libubootenv-tool mtd-utils device-tree-compiler - -## Install docker -echo '[INFO] Install docker' -## Install apparmor utils since they're missing and apparmor is enabled in the kernel -## Otherwise Docker will fail to start -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install apparmor -sudo cp files/image_config/ntp/ntp-apparmor $FILESYSTEM_ROOT/etc/apparmor.d/local/usr.sbin.ntpd -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install apt-transport-https \ - ca-certificates \ - curl \ - gnupg2 \ - software-properties-common -if [[ $CONFIGURED_ARCH == armhf ]]; then - # update ssl ca certificates for secure pem - sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT c_rehash -fi -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -o /tmp/docker.asc -fsSL https://download.docker.com/linux/debian/gpg -sudo LANG=C chroot $FILESYSTEM_ROOT mv /tmp/docker.asc /etc/apt/trusted.gpg.d/ -sudo LANG=C chroot $FILESYSTEM_ROOT add-apt-repository \ - "deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian $IMAGE_DISTRO stable" -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} docker-ce-cli=${DOCKER_VERSION} containerd.io=${CONTAINERD_IO_VERSION} - -# Uninstall 'python3-gi' installed as part of 'software-properties-common' to remove debian version of 'PyGObject' -# pip version of 'PyGObject' will be installed during installation of 'sonic-host-services' -sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 python3-gi - -if [ "$INCLUDE_KUBERNETES" == "y" ] -then - ## Install Kubernetes - echo '[INFO] Install kubernetes' - sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -fsSL \ - https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ - sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add - - ## Check out the sources list update matches current Debian version - sudo cp files/image_config/kubernetes/kubernetes.list $FILESYSTEM_ROOT/etc/apt/sources.list.d/ - sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update - sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubernetes-cni=${KUBERNETES_CNI_VERSION}-00 - sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubelet=${KUBERNETES_VERSION}-00 - sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubectl=${KUBERNETES_VERSION}-00 - sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00 -else - echo '[INFO] Skipping Install kubernetes' -fi - -## Add docker config drop-in to specify dockerd command line -sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/docker.service.d/ -## Note: $_ means last argument of last command -sudo cp files/docker/docker.service.conf $_ - -## Create default user -## Note: user should be in the group with the same name, and also in sudo/docker/redis groups -sudo LANG=C chroot $FILESYSTEM_ROOT useradd -G sudo,docker $USERNAME -c "$DEFAULT_USERINFO" -m -s /bin/bash -## Create password for the default user -echo "$USERNAME:$PASSWORD" | sudo LANG=C chroot $FILESYSTEM_ROOT chpasswd - -## Create redis group -sudo LANG=C chroot $FILESYSTEM_ROOT groupadd -f redis -sudo LANG=C chroot $FILESYSTEM_ROOT usermod -aG redis $USERNAME - -if [[ $CONFIGURED_ARCH == amd64 ]]; then - ## Pre-install hardware drivers - sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install \ - firmware-linux-nonfree -fi - -## Pre-install the fundamental packages -## Note: gdisk is needed for sgdisk in install.sh -## Note: parted is needed for partprobe in install.sh -## Note: ca-certificates is needed for easy_install -## Note: don't install python-apt by pip, older than Debian repo one -## Note: fdisk and gpg are needed by fwutil -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ - file \ - ifmetric \ - iproute2 \ - bridge-utils \ - isc-dhcp-client \ - sudo \ - vim \ - tcpdump \ - dbus \ - ntpstat \ - openssh-server \ - python3-apt \ - traceroute \ - iputils-ping \ - net-tools \ - bsdmainutils \ - ca-certificates \ - i2c-tools \ - efibootmgr \ - usbutils \ - pciutils \ - iptables-persistent \ - ebtables \ - logrotate \ - curl \ - kexec-tools \ - less \ - unzip \ - gdisk \ - sysfsutils \ - squashfs-tools \ - grub2-common \ - rsyslog \ - screen \ - hping3 \ - tcptraceroute \ - mtr-tiny \ - locales \ - cgroup-tools \ - ipmitool \ - ndisc6 \ - makedumpfile \ - conntrack \ - python3 \ - python3-distutils \ - python3-pip \ - python-is-python3 \ - cron \ - libprotobuf23 \ - libgrpc++1 \ - libgrpc10 \ - haveged \ - fdisk \ - gpg \ - jq \ - auditd - -# Have systemd create the auditd log directory -sudo mkdir -p ${FILESYSTEM_ROOT}/etc/systemd/system/auditd.service.d -sudo tee ${FILESYSTEM_ROOT}/etc/systemd/system/auditd.service.d/log-directory.conf >/dev/null <> /etc/initramfs-tools/conf.d/driver-policy" - -# Copy vmcore-sysctl.conf to add more vmcore dump flags to kernel -sudo cp files/image_config/kdump/vmcore-sysctl.conf $FILESYSTEM_ROOT/etc/sysctl.d/ - -#Adds a locale to a debian system in non-interactive mode -sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT locale-gen "en_US.UTF-8" -sudo LANG=en_US.UTF-8 DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT update-locale "LANG=en_US.UTF-8" -sudo LANG=C chroot $FILESYSTEM_ROOT bash -c "find /usr/share/i18n/locales/ ! -name 'en_US' -type f -exec rm -f {} +" - -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ - picocom \ - systemd \ - systemd-sysv \ - ntp - -if [[ $CONFIGURED_ARCH == amd64 ]]; then - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \ - grub-pc-bin - - sudo mv $FILESYSTEM_ROOT/grub-pc-bin*.deb $FILESYSTEM_ROOT/$PLATFORM_DIR/x86_64-grub -fi ## Disable kexec supported reboot which was installed by default sudo sed -i 's/LOAD_KEXEC=true/LOAD_KEXEC=false/' $FILESYSTEM_ROOT/etc/default/kexec @@ -460,35 +246,6 @@ done < files/image_config/sysctl/sysctl-net.conf sudo augtool --autosave "$sysctl_net_cmd_string" -r $FILESYSTEM_ROOT -# Upgrade pip via PyPI and uninstall the Debian version -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install --upgrade pip -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python3-pip - -# For building Python packages -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'setuptools==49.6.00' -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'wheel==0.35.1' - -# docker Python API package is needed by Ansible docker module as well as some SONiC applications -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'docker==5.0.3' - -# Install scapy -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'scapy==2.4.4' - -## Note: keep pip installed for maintainance purpose - -# Install GCC, needed for building/installing some Python packages -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install gcc - -## Create /var/run/redis folder for docker-database to mount -sudo mkdir -p $FILESYSTEM_ROOT/var/run/redis - -## Config DHCP for eth0 -sudo tee -a $FILESYSTEM_ROOT/etc/network/interfaces > /dev/null < /etc/hostname" +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '127.0.0.1 $HOSTNAME' >> /etc/hosts" +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c "echo '127.0.0.1 localhost' >> /etc/hosts" + +## Config basic fstab +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'echo "proc /proc proc defaults 0 0" >> /etc/fstab' +sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'echo "sysfs /sys sysfs defaults 0 0" >> /etc/fstab' + +## Setup proxy +[ -n "$http_proxy" ] && sudo /bin/bash -c "echo 'Acquire::http::Proxy \"$http_proxy\";' > $FILESYSTEM_ROOT/etc/apt/apt.conf.d/01proxy" + +## make / as a mountpoint in chroot env, needed by dockerd +#pushd $FILESYSTEM_ROOT +#sudo mount --bind . . +#trap_push 'sudo umount $FILESYSTEM_ROOT || true' +#popd + +trap_push 'sudo LANG=C chroot $FILESYSTEM_ROOT umount /proc || true' +sudo LANG=C chroot $FILESYSTEM_ROOT mount proc /proc -t proc +## Note: mounting is necessary to makedev and install linux image +echo '[INFO] Mount all' +## Output all the mounted device for troubleshooting +sudo LANG=C chroot $FILESYSTEM_ROOT mount + +## Install the trusted gpg public keys +[ -d $TRUSTED_GPG_DIR ] && [ ! -z "$(ls $TRUSTED_GPG_DIR)" ] && sudo cp $TRUSTED_GPG_DIR/* ${FILESYSTEM_ROOT}/etc/apt/trusted.gpg.d/ + +## Pointing apt to public apt mirrors and getting latest packages, needed for latest security updates +sudo cp files/apt/sources.list.$CONFIGURED_ARCH $FILESYSTEM_ROOT/etc/apt/sources.list +sudo cp files/apt/apt.conf.d/{81norecommends,apt-{clean,gzip-indexes,no-languages},no-check-valid-until} $FILESYSTEM_ROOT/etc/apt/apt.conf.d/ + +## Note: set lang to prevent locale warnings in your chroot +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y update +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y upgrade + + +# Pre-install the list of deian packages which are required at the later part of the installation. +# These packages are installed either directly or required as a dependency for the main package. +# Pre-installation of these packages will skip the installation of the same package at the later stage +# and will speed up the build process. +# These packages are not removed from the original place to avoid the merge issues during branch merge. +DEB_PKG_LIST_FILE=files/build/versions/host-image/versions-deb-${IMAGE_DISTRO}-${CONFIGURED_ARCH} +if [[ ! -z ${SONIC_VERSION_CACHE} && ${SONIC_VERSION_CACHE} != "none" && -e ${DEB_PKG_LIST_FILE} ]]; then + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ + $(cat ${DEB_PKG_LIST_FILE} | sed 's/==/=/g'| tr "\n" " ") +fi + + +echo '[INFO] Install and setup eatmydata' +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install eatmydata +sudo LANG=C chroot $FILESYSTEM_ROOT ln -s /usr/bin/eatmydata /usr/local/bin/dpkg +echo 'Dir::Bin::dpkg "/usr/local/bin/dpkg";' | sudo tee $FILESYSTEM_ROOT/etc/apt/apt.conf.d/00image-install-eatmydata > /dev/null + +echo '[INFO] Install packages for building image' +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install makedev psmisc + +## Create device files +echo '[INFO] MAKEDEV' +if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then + sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'cd /dev && MAKEDEV generic-arm' +else + sudo LANG=C chroot $FILESYSTEM_ROOT /bin/bash -c 'cd /dev && MAKEDEV generic' +fi +## Install initramfs-tools and linux kernel +## Note: initramfs-tools recommends depending on busybox, and we really want busybox for +## 1. commands such as touch +## 2. mount supports squashfs +## However, 'dpkg -i' plus 'apt-get install -f' will ignore the recommended dependency. So +## we install busybox explicitly +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install busybox linux-base + + +## Install docker +echo '[INFO] Install docker' +## Install apparmor utils since they're missing and apparmor is enabled in the kernel +## Otherwise Docker will fail to start +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install apparmor +sudo cp files/image_config/ntp/ntp-apparmor $FILESYSTEM_ROOT/etc/apparmor.d/local/usr.sbin.ntpd +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install apt-transport-https \ + ca-certificates \ + curl \ + gnupg2 \ + software-properties-common +if [[ $CONFIGURED_ARCH == armhf ]]; then + # update ssl ca certificates for secure pem + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT c_rehash +fi +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -o /tmp/docker.gpg -fsSL https://download.docker.com/linux/debian/gpg +sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add /tmp/docker.gpg +sudo LANG=C chroot $FILESYSTEM_ROOT rm /tmp/docker.gpg +sudo LANG=C chroot $FILESYSTEM_ROOT add-apt-repository \ + "deb [arch=$CONFIGURED_ARCH] https://download.docker.com/linux/debian $IMAGE_DISTRO stable" +sudo LANG=C FORCE_UPDATE=Y chroot $FILESYSTEM_ROOT apt-get update +if dpkg --compare-versions ${DOCKER_VERSION} ge "18.09"; then + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} docker-ce-cli=${DOCKER_VERSION} +else + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install docker-ce=${DOCKER_VERSION} +fi + +# Uninstall 'python3-gi' installed as part of 'software-properties-common' to remove debian version of 'PyGObject' +# pip version of 'PyGObject' will be installed during installation of 'sonic-host-services' +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y remove software-properties-common gnupg2 python3-gi + +if [ "$INCLUDE_KUBERNETES" == "y" ] +then + ## Install Kubernetes + echo '[INFO] Install kubernetes' + sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT curl -fsSL \ + https://packages.cloud.google.com/apt/doc/apt-key.gpg | \ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-key add - + ## Check out the sources list update matches current Debian version + sudo cp files/image_config/kubernetes/kubernetes.list $FILESYSTEM_ROOT/etc/apt/sources.list.d/ + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get update + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubernetes-cni=${KUBERNETES_CNI_VERSION}-00 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubelet=${KUBERNETES_VERSION}-00 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubectl=${KUBERNETES_VERSION}-00 + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00 +else + echo '[INFO] Skipping Install kubernetes' +fi + +## Add docker config drop-in to specify dockerd command line +sudo mkdir -p $FILESYSTEM_ROOT/etc/systemd/system/docker.service.d/ +## Note: $_ means last argument of last command +sudo cp files/docker/docker.service.conf $_ +## Fix systemd race between docker and containerd +sudo sed -i '/After=/s/$/ containerd.service/' $FILESYSTEM_ROOT/lib/systemd/system/docker.service + +## Create default user +## Note: user should be in the group with the same name, and also in sudo/docker/redis groups +sudo LANG=C chroot $FILESYSTEM_ROOT useradd -G sudo,docker $USERNAME -c "$DEFAULT_USERINFO" -m -s /bin/bash +## Create password for the default user +echo "$USERNAME:$PASSWORD" | sudo LANG=C chroot $FILESYSTEM_ROOT chpasswd + +## Create redis group +sudo LANG=C chroot $FILESYSTEM_ROOT groupadd -f redis +sudo LANG=C chroot $FILESYSTEM_ROOT usermod -aG redis $USERNAME + +if [[ $CONFIGURED_ARCH == amd64 ]]; then + ## Pre-install hardware drivers + sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install \ + firmware-linux-nonfree +fi + +## Pre-install the fundamental packages +## Note: gdisk is needed for sgdisk in install.sh +## Note: parted is needed for partprobe in install.sh +## Note: ca-certificates is needed for easy_install +## Note: don't install python-apt by pip, older than Debian repo one +## Note: fdisk and gpg are needed by fwutil +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ + file \ + ifmetric \ + iproute2 \ + bridge-utils \ + isc-dhcp-client \ + sudo \ + vim \ + tcpdump \ + dbus \ + ntpstat \ + openssh-server \ + python3-apt \ + traceroute \ + iputils-ping \ + net-tools \ + bsdmainutils \ + ca-certificates \ + i2c-tools \ + efibootmgr \ + usbutils \ + pciutils \ + iptables-persistent \ + ebtables \ + logrotate \ + curl \ + kexec-tools \ + less \ + unzip \ + gdisk \ + sysfsutils \ + squashfs-tools \ + grub2-common \ + rsyslog \ + screen \ + hping3 \ + tcptraceroute \ + mtr-tiny \ + locales \ + cgroup-tools \ + ipmitool \ + ndisc6 \ + makedumpfile \ + conntrack \ + python3 \ + python3-distutils \ + python3-pip \ + python-is-python3 \ + cron \ + libprotobuf23 \ + libgrpc++1 \ + libgrpc10 \ + haveged \ + fdisk \ + gpg \ + jq \ + auditd + + + +# Have systemd create the auditd log directory +sudo mkdir -p ${FILESYSTEM_ROOT}/etc/systemd/system/auditd.service.d +sudo tee ${FILESYSTEM_ROOT}/etc/systemd/system/auditd.service.d/log-directory.conf >/dev/null <> /etc/initramfs-tools/conf.d/driver-policy" + +# Copy vmcore-sysctl.conf to add more vmcore dump flags to kernel +sudo cp files/image_config/kdump/vmcore-sysctl.conf $FILESYSTEM_ROOT/etc/sysctl.d/ + +#Adds a locale to a debian system in non-interactive mode +sudo sed -i '/^#.* en_US.* /s/^#//' $FILESYSTEM_ROOT/etc/locale.gen && \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT locale-gen "en_US.UTF-8" +sudo LANG=en_US.UTF-8 DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT update-locale "LANG=en_US.UTF-8" +sudo LANG=C chroot $FILESYSTEM_ROOT bash -c "find /usr/share/i18n/locales/ ! -name 'en_US' -type f -exec rm -f {} +" + +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ + picocom \ + systemd \ + systemd-sysv \ + ntp + +if [[ $CONFIGURED_ARCH == amd64 ]]; then + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \ + grub-pc-bin + + sudo mv $FILESYSTEM_ROOT/grub-pc-bin*.deb $FILESYSTEM_ROOT/$PLATFORM_DIR/x86_64-grub +fi + +# Pre-install the list of deian packages which are required at the later part of the installation. +# These packages are installed either directly or required as a dependency for the main package. +# Pre-installation of these packages will skip the installation of the same package at the later stage +# and will speed up the build process. +# These packages are not removed from the original place to avoid the merge issues during branch merge. +PIP_PKG_LIST_FILE=files/build/versions/host-image/versions-pip3-${IMAGE_DISTRO}-${CONFIGURED_ARCH} +if [[ ! -z ${SONIC_VERSION_CACHE} && ${SONIC_VERSION_CACHE} != "none" && -e ${PIP_PKG_LIST_FILE} ]]; then + sudo https_proxy=$https_proxy LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT pip3 install \ + $(cat ${PIP_PKG_LIST_FILE} | tr "\n" " ") +fi + + +# Install dependencies for SONiC config engine +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ + python3-dev + +# Install j2cli for handling jinja template +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "j2cli==0.3.10" + +# Install Python client for Redis +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "redis==3.5.3" + + +## Add mtd and uboot firmware tools package +sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install u-boot-tools libubootenv-tool mtd-utils device-tree-compiler + + +# Upgrade pip via PyPI and uninstall the Debian version +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install --upgrade pip +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python3-pip + +# For building Python packages +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'setuptools==49.6.00' +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'wheel==0.35.1' + +# docker Python API package is needed by Ansible docker module as well as some SONiC applications +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'docker==5.0.3' + +# Install scapy +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install 'scapy==2.4.4' + +## Note: keep pip installed for maintainance purpose + +# Install GCC, needed for building/installing some Python packages +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install gcc + +## Create /var/run/redis folder for docker-database to mount +sudo mkdir -p $FILESYSTEM_ROOT/var/run/redis + +## Config DHCP for eth0 +sudo tee -a $FILESYSTEM_ROOT/etc/network/interfaces > /dev/null <= 3.4, as it causes a +# conflict with the new 'enum' module in the standard library +# https://github.com/robshakir/pyangbind/issues/232 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install pyangbind==0.8.1 +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 uninstall -y enum34 + + +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install PyYAML==5.3.1 + +sync; sync; sync; +## Output all the mounted device for troubleshooting +echo '[INFO] Show Mount all' +sudo LANG=C chroot $FILESYSTEM_ROOT mount +sync; sync; sync; + +#Exit trap handles the umount +#sudo LANG=C chroot $FILESYSTEM_ROOT umount /proc || true +#BASE_IMAGE_NAME=${BASE_IMAGE_NAME} scripts/fsutil.sh rootfs umount + +## ensure proc is mounted +sudo mountpoint -q /proc || sudo mount -t proc proc /proc || true +echo "Rootfs Done" diff --git a/build_image.sh b/build_image.sh index 71351dbfe7e0..23be33e0d6bd 100755 --- a/build_image.sh +++ b/build_image.sh @@ -24,6 +24,7 @@ fi } IMAGE_VERSION="${SONIC_IMAGE_VERSION}" +BUILD_PATH=target/fs/${TARGET_MACHINE} generate_kvm_image() { @@ -82,11 +83,12 @@ generate_onie_installer_image() done done + PAYLOAD_LIST="${BUILD_PATH}/$ONIE_INSTALLER_PAYLOAD" ## 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 \ installer platform/$TARGET_MACHINE/platform.conf $output_file OS $IMAGE_VERSION $ONIE_IMAGE_PART_SIZE \ - $ONIE_INSTALLER_PAYLOAD + $PAYLOAD_LIST } # Generate asic-specific device list @@ -179,7 +181,7 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then sudo rm -f $OUTPUT_ABOOT_IMAGE sudo rm -f $ABOOT_BOOT_IMAGE ## Add main payload - cp $ONIE_INSTALLER_PAYLOAD $OUTPUT_ABOOT_IMAGE + cp ${BUILD_PATH}/$ONIE_INSTALLER_PAYLOAD $OUTPUT_ABOOT_IMAGE ## Add Aboot boot0 file j2 -f env files/Aboot/boot0.j2 ./onie-image.conf > files/Aboot/boot0 sed -i -e "s/%%IMAGE_VERSION%%/$IMAGE_VERSION/g" files/Aboot/boot0 diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 185184fb91d5..a6598f7a51c1 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -92,202 +92,98 @@ sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_FIRMWARE/ # Keeping it generic. It should not harm anyways. sudo mkdir -p $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM -# Install a patched version of ifupdown2 (and its dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/ifupdown2_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f - -# Install a patched version of ntp (and its dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT --force-confdef --force-confold -i $debs_path/ntp_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y \ - -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install -f - -# Install dependencies for SONiC config engine -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ - python3-dev - -# Install j2cli for handling jinja template -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "j2cli==0.3.10" - -# Install Python client for Redis -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "redis==3.5.3" - -# Install redis-dump-load Python 3 package -# Note: the scripts will be overwritten by corresponding Python 2 package -REDIS_DUMP_LOAD_PY3_WHEEL_NAME=$(basename {{redis_dump_load_py3_wheel_path}}) -sudo cp {{redis_dump_load_py3_wheel_path}} $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $REDIS_DUMP_LOAD_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$REDIS_DUMP_LOAD_PY3_WHEEL_NAME - -# Install Python module for psutil -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install psutil - -# Install Python module for ipaddr -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install ipaddr - -# Install Python module for grpcio and grpcio-toole -if [[ $CONFIGURED_ARCH == amd64 ]]; then - sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "grpcio==1.39.0" - sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "grpcio-tools==1.39.0" -fi +declare -ga HOST_DPKGS=( \ + $debs_path/ifupdown2_*.deb \ + $debs_path/ntp_*.deb \ + $debs_path/libyang_*.deb + $debs_path/libyang-cpp_*.deb + $debs_path/python3-yang_*.deb + $debs_path/sonic-utilities-data_*.deb \ + $debs_path/bash_*.deb \ + $debs_path/sonic-host-services-data_*.deb \ + {% if enable_ztp == "y" %} $debs_path/sonic-ztp_*.deb {% endif %} \ + {% for machine_debs in lazy_build_installer_debs.strip().split() -%} + {% set machine, pkgname = machine_debs.split('|') %} + {% if TARGET_MACHINE == machine %} $debs_path/{{pkgname}} {% endif %} \ + {% endfor %} + $debs_path/sonic-device-data_*.deb \ + $debs_path/libtac2_*.deb \ + $debs_path/libpam-tacplus_*.deb \ + $debs_path/libnss-tacplus_*.deb \ + $debs_path/bash-tacplus_*.deb \ + $debs_path/audisp-tacplus_*.deb \ + $debs_path/libpam-radius-auth_*.deb \ + $debs_path/libnss-radius_*.deb \ + {% if CONFIGURED_ARCH == "amd64" %} $debs_path/kdump-tools_*.deb {% endif %} \ + # Install python-swss-common package and all its dependent packages + {% if python_swss_debs.strip() -%} + {% for deb in python_swss_debs.strip().split(' ') -%} + {{deb}} \ + {% endfor %} + {% endif %} + $debs_path/monit_*.deb \ + $debs_path/openssh-server_${OPENSSH_VERSION}_*.deb \ + {% if sonic_asic_platform == 'broadcom' %} $debs_path/flashrom_*.deb {% endif %} \ + {% if installer_debs.strip() -%} + {% for deb in installer_debs.strip().split(' ') -%} + {{deb}} \ + {% endfor %} + {% endif %} + + {% if lazy_installer_debs.strip() -%} + {% for file in lazy_installer_debs.strip().split(' ') -%} + {% set deb = file.split('@')[1] -%} + {{deb}} + {% endfor %} + {% endif %} + ) + + + +sudo dpkg --root=$FILESYSTEM_ROOT --force-confdef --force-confold -i $(ls ${HOST_DPKGS[@]}) || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + + + + +declare -ga HOST_PPKGS=( \ + {{redis_dump_load_py3_wheel_path}} \ + {{swsssdk_py3_wheel_path}} \ + {{sonic_py_common_py3_wheel_path}} \ + {{sonic_yang_models_py3_wheel_path}} \ + {{sonic_yang_mgmt_py3_wheel_path}} \ + {{config_engine_py3_wheel_path}} \ + {{platform_common_py3_wheel_path}} \ + {% if pddf_support == "y" %} {{pddf_platform_api_base_py3_wheel_path}} {% endif %} \ + {{system_health_py3_wheel_path}} \ + {{sonic_utilities_py3_wheel_path}} \ + {{sonic_host_services_py3_wheel_path}} \ + {{sonic_ctrmgmt_py3_wheel_path}} + ) + + +declare -ga HOST_PPKGS_LIST=() +for ppkg in ${HOST_PPKGS[@]}; do + sudo cp ${ppkg} $FILESYSTEM_ROOT/$(basename ${ppkg} ) + HOST_PPKGS_LIST+=( $(basename ${ppkg}) ) +done +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install ${HOST_PPKGS_LIST[@]} +sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT rm -rf ${HOST_PPKGS_LIST[@]} -# Install SwSS SDK Python 3 package -# Note: the scripts will be overwritten by corresponding Python 2 package -SWSSSDK_PY3_WHEEL_NAME=$(basename {{swsssdk_py3_wheel_path}}) -sudo cp {{swsssdk_py3_wheel_path}} $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SWSSSDK_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SWSSSDK_PY3_WHEEL_NAME - -# Install sonic-py-common Python 3 package -SONIC_PY_COMMON_PY3_WHEEL_NAME=$(basename {{sonic_py_common_py3_wheel_path}}) -sudo cp {{sonic_py_common_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_PY_COMMON_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SONIC_PY_COMMON_PY3_WHEEL_NAME - -# Install dependency pkgs for SONiC config engine Python 2 package -if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libxslt-dev libz-dev -fi - -# Install sonic-yang-models Python 3 package, install dependencies -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang_*.deb -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libyang-cpp_*.deb -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/python3-yang_*.deb -SONIC_YANG_MODEL_PY3_WHEEL_NAME=$(basename {{sonic_yang_models_py3_wheel_path}}) -sudo cp {{sonic_yang_models_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MODEL_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MODEL_PY3_WHEEL_NAME - -# Install sonic-yang-mgmt Python3 package -SONIC_YANG_MGMT_PY3_WHEEL_NAME=$(basename {{sonic_yang_mgmt_py3_wheel_path}}) -sudo cp {{sonic_yang_mgmt_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_YANG_MGMT_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SONIC_YANG_MGMT_PY3_WHEEL_NAME - -# For sonic-config-engine Python 3 package -# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed. -# Then immediately uninstall enum34, as enum34 should not be installed for Python >= 3.4, as it causes a -# conflict with the new 'enum' module in the standard library -# https://github.com/robshakir/pyangbind/issues/232 -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install pyangbind==0.8.1 -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 uninstall -y enum34 - -# Install SONiC config engine Python 3 package -CONFIG_ENGINE_PY3_WHEEL_NAME=$(basename {{config_engine_py3_wheel_path}}) -sudo cp {{config_engine_py3_wheel_path}} $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $CONFIG_ENGINE_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$CONFIG_ENGINE_PY3_WHEEL_NAME - - -# Install sonic-platform-common Python 3 package -PLATFORM_COMMON_PY3_WHEEL_NAME=$(basename {{platform_common_py3_wheel_path}}) -sudo cp {{platform_common_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $PLATFORM_COMMON_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_COMMON_PY3_WHEEL_NAME - -{% if pddf_support == "y" %} -# Install pddf-platform-api-base Python 3 package -PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME=$(basename {{pddf_platform_api_base_py3_wheel_path}}) -sudo cp {{pddf_platform_api_base_py3_wheel_path}} $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$PLATFORM_PDDF_COMMON_PY3_WHEEL_NAME -{% endif %} {# Barefoot platform vendors' sonic_platform packages import the Python 'thrift' library #} {% if sonic_asic_platform == "barefoot" %} sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install thrift==0.13.0 {% endif %} -# Install system-health Python 3 package -SYSTEM_HEALTH_PY3_WHEEL_NAME=$(basename {{system_health_py3_wheel_path}}) -sudo cp {{system_health_py3_wheel_path}} $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SYSTEM_HEALTH_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SYSTEM_HEALTH_PY3_WHEEL_NAME - -# Install prerequisites needed for installing the Python m2crypto package, used by sonic-utilities -# These packages can be uninstalled after intallation -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install build-essential libssl-dev swig - -# Install prerequisites needed for using the Python m2crypto package, used by sonic-utilities -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install openssl - -# Install SONiC Utilities Python package -SONIC_UTILITIES_PY3_WHEEL_NAME=$(basename {{sonic_utilities_py3_wheel_path}}) -sudo cp {{sonic_utilities_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_UTILITIES_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SONIC_UTILITIES_PY3_WHEEL_NAME - -# Install sonic-utilities data files (and any dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-utilities-data_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f - -# Install customized bash version to patch bash plugin support. -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/bash_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f - # sonic-utilities-data installs bash-completion as a dependency. However, it is disabled by default # in bash.bashrc, so we copy a version of the file with it enabled here. sudo cp -f $IMAGE_CONFIGS/bash/bash.bashrc $FILESYSTEM_ROOT/etc/ -# Install prerequisites needed for installing the dependent Python packages of sonic-host-services -# These packages can be uninstalled after installation -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libcairo2-dev libdbus-1-dev libgirepository1.0-dev libsystemd-dev pkg-config - -# Mark runtime dependencies as manually installed to avoid them being auto-removed while uninstalling build dependencies -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-mark manual gir1.2-glib-2.0 libdbus-1-3 libgirepository-1.0-1 libsystemd0 python3-dbus - -# Install systemd-python for SONiC host services -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install systemd-python - -# Install SONiC host services package -SONIC_HOST_SERVICES_PY3_WHEEL_NAME=$(basename {{sonic_host_services_py3_wheel_path}}) -sudo cp {{sonic_host_services_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_HOST_SERVICES_PY3_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_HOST_SERVICES_PY3_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SONIC_HOST_SERVICES_PY3_WHEEL_NAME - -# Install SONiC host services data files (and any dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-host-services-data_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f - -{% if enable_ztp == "y" %} -# Install ZTP (and its dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-ztp_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -{% endif %} - -{% for machine_debs in lazy_build_installer_debs.strip().split() -%} -{% set machine, pkgname = machine_debs.split('|') %} -if [[ -z "{{machine}}" || -n "{{machine}}" && $TARGET_MACHINE == "{{machine}}" ]]; then -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/{{pkgname}} || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -fi -{% endfor %} - -# Install SONiC Device Data (and its dependencies via 'apt-get -y install -f') -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/sonic-device-data_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f - -# Install pam-tacplus and nss-tacplus -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libtac2_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libpam-tacplus_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libnss-tacplus_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -# Install bash-tacplus -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/bash-tacplus_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -# Install audisp-tacplus -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/audisp-tacplus_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f # Disable tacplus by default sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove tacplus sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf -# Install pam-radius-auth and nss-radius -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libpam-radius-auth_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/libnss-radius_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f # Disable radius by default # radius does not have any profiles #sudo LANG=C chroot $FILESYSTEM_ROOT pam-auth-update --remove radius tacplus @@ -295,8 +191,6 @@ 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 -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 for kernel_release in $(ls $FILESYSTEM_ROOT/lib/modules/); do @@ -305,16 +199,8 @@ for kernel_release in $(ls $FILESYSTEM_ROOT/lib/modules/); do done fi -# Install python-swss-common package and all its dependent packages -{% if python_swss_debs.strip() -%} -{% for deb in python_swss_debs.strip().split(' ') -%} -sudo dpkg --root=$FILESYSTEM_ROOT -i {{deb}} || sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -{% endfor %} -{% endif %} # Install custom-built monit package and SONiC configuration files -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \ - sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f sudo cp $IMAGE_CONFIGS/monit/monitrc $FILESYSTEM_ROOT/etc/monit/ sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc sudo cp $IMAGE_CONFIGS/monit/conf.d/* $FILESYSTEM_ROOT/etc/monit/conf.d/ @@ -326,16 +212,7 @@ sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/memory_checker sudo cp $IMAGE_CONFIGS/monit/restart_service $FILESYSTEM_ROOT/usr/bin/ sudo chmod 755 $FILESYSTEM_ROOT/usr/bin/restart_service -# Install custom-built smartmontools -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install smartmontools=7.2-1 - -# Install custom-built openssh sshd -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/openssh-server_${OPENSSH_VERSION}_*.deb -{% if sonic_asic_platform == 'broadcom' %} -# Install custom-built flashrom -sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/flashrom_*.deb -{% endif %} # Copy crontabs sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/ @@ -418,20 +295,6 @@ sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/b sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/ sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json -sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install libffi-dev libssl-dev - -if [[ $CONFIGURED_ARCH == armhf ]]; then - # The azure-storage package depends on the cryptography package. Newer - # versions of cryptography require the rust compiler, the correct version - # for which is not readily available in buster. Hence we pre-install an - # older version here to satisfy the azure-storage dependency. - # Note: This is not a problem for other architectures as pre-built versions - # of cryptography are available for those. This sequence can be removed - # after upgrading to debian bullseye. - sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install cryptography==3.3.1 -fi -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install azure-storage==0.36.0 -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install watchdog==0.10.3 {% if include_kubernetes == "y" %} # Point to kubelet to /etc/resolv.conf @@ -446,11 +309,6 @@ sudo cp $BUILD_TEMPLATES/kube_cni.10-flannel.conflist $FILESYSTEM_ROOT_USR_SHARE # Required even if include_kubernetes != y, as it contains the # the container wrapper for docker start/stop/wait commands. # -SONIC_CTRMGMT_WHEEL_NAME=$(basename {{sonic_ctrmgmt_py3_wheel_path}}) -sudo cp {{sonic_ctrmgmt_py3_wheel_path}} $FILESYSTEM_ROOT/$SONIC_CTRMGMT_WHEEL_NAME -sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install $SONIC_CTRMGMT_WHEEL_NAME -sudo rm -rf $FILESYSTEM_ROOT/$SONIC_CTRMGMT_WHEEL_NAME - # Copy remote container mangement files # File called from each container upon start/stop to record the state sudo mkdir -p ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS} @@ -589,11 +447,6 @@ exit 101 EOF sudo chmod a+x $FILESYSTEM_ROOT/usr/sbin/policy-rc.d -{% if installer_debs.strip() -%} -{% for deb in installer_debs.strip().split(' ') -%} -sudo dpkg --root=$FILESYSTEM_ROOT -i {{deb}} || sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f -{% endfor %} -{% endif %} ## Run depmod command for target kernel modules sudo LANG=C chroot $FILESYSTEM_ROOT depmod -a {{kversion}} @@ -607,7 +460,6 @@ sudo LANG=C chroot $FILESYSTEM_ROOT depmod -a {{kversion}} {% set debfilename = deb.split('/')|last -%} {% set debname = debfilename.split('_')|first -%} -sudo dpkg --root=$FILESYSTEM_ROOT -i {{deb}} || sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f --download-only sudo mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR/{{dev}} sudo mkdir -p $FILESYSTEM_ROOT/$PLATFORM_DIR/common @@ -653,9 +505,12 @@ if [ $MULTIARCH_QEMU_ENVIRON == y ]; then sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs fi +DOCKER_LOCK_FILE=target/docker.lock +FLOCK ${DOCKER_LOCK_FILE} 3600 +declare -ga DLIST=() +export -f sonic_get_version +export FILESYSTEM_ROOT SONIC_NATIVE_DOCKERD_FOR_DOCKERFS {% if installer_images.strip() -%} -## ensure proc is mounted -sudo mount proc /proc -t proc || true if [[ $CONFIGURED_ARCH == armhf ]]; then # A workaround to fix the armhf build hung issue, caused by sonic-platform-nokia-7215_1.0_armhf.deb post installation script ps -eo pid,cmd | grep python | grep "/etc/entropy.py" | awk '{print $1}' | xargs sudo kill -9 2>/dev/null || true @@ -665,29 +520,47 @@ sudo mkdir $FILESYSTEM_ROOT/target sudo mount --bind target $FILESYSTEM_ROOT/target sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker info +function load_docker() +{ + local imagefilepath=$1 + local imagename=$2 + local machine=$3 + if [[ -z "${machine}" || -n "${machine}" && $TARGET_MACHINE == "${machine}" ]]; then + sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker load < ${imagefilepath} + sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker tag ${imagename}:latest ${imagename}:"${SONIC_IMAGE_VERSION}" + # Check if manifest exists for ${imagename} and it is a valid JSON + sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker inspect ${imagename}:latest \ + | jq '.[0].Config.Labels["com.azure.sonic.manifest"]' -r > /tmp/${imagename}-manifest.json + jq -e . /tmp/${imagename}-manifest.json || { + >&2 echo "docker image ${imagename} has no manifest or manifest is not a valid JSON" + exit 1 + } + if [[ ${imagename} =~ .*-dbg ]]; then + local imagebasename = ${imagename/-dbg/} + sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker tag ${imagename}:latest ${imagebasename}:"${SONIC_IMAGE_VERSION}" + sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker tag ${imagename}:latest ${imagebasename}:latest + fi + fi +} +export -f load_docker + {% for docker_installation_target in installer_images.strip().split() -%} {% set pkgname, docker_build_path, machine, image = docker_installation_target.split('|') %} {% set imagefilepath = image.split(':')|first -%} {% set imagefilename = imagefilepath.split('/')|last -%} {% set imagename = imagefilename.split('.')|first -%} -if [[ -z "{{machine}}" || -n "{{machine}}" && $TARGET_MACHINE == "{{machine}}" ]]; then -sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker load -i {{imagefilepath}} -sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker tag {{imagename}}:latest {{imagename}}:"${SONIC_IMAGE_VERSION}" -# Check if manifest exists for {{imagename}} and it is a valid JSON -sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker inspect {{imagename}}:latest \ - | jq '.[0].Config.Labels["com.azure.sonic.manifest"]' -r > /tmp/manifest.json -jq -e . /tmp/manifest.json || { - >&2 echo "docker image {{imagename}} has no manifest or manifest is not a valid JSON" - exit 1 -} -{% if imagename.endswith('-dbg') %} -{% set imagebasename = imagename.replace('-dbg', '') -%} -sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker tag {{imagename}}:latest {{imagebasename}}:"${SONIC_IMAGE_VERSION}" -sudo LANG=C DOCKER_HOST="$DOCKER_HOST" chroot $FILESYSTEM_ROOT docker tag {{imagename}}:latest {{imagebasename}}:latest -{% endif %} -fi +DLIST+=( load_docker\ {{imagefilepath}}\ {{imagename}}\ {{machine}} ) {% endfor %} +#### RUN in parallel if RAMDISK is enabled #### +NPROC=$(nproc) +if [[ "${SONIC_USE_TMPFS_BUILD}" == "y" ]]; then + if [ ${NPROC} -gt 12 ]; then NPROC=12; fi +else + NPROC=1 +fi +printf '%s\n' "${DLIST[@]}" | xargs -I{} -P ${NPROC} bash -c "SONIC_IMAGE_VERSION=${SONIC_IMAGE_VERSION} {}" + SONIC_PACKAGE_MANAGER_FOLDER="/var/lib/sonic-package-manager/" sudo mkdir -p $FILESYSTEM_ROOT/$SONIC_PACKAGE_MANAGER_FOLDER target_machine="$TARGET_MACHINE" j2 $BUILD_TEMPLATES/packages.json.j2 | sudo tee $FILESYSTEM_ROOT/$SONIC_PACKAGE_MANAGER_FOLDER/packages.json @@ -740,6 +613,7 @@ if [ $MULTIARCH_QEMU_ENVIRON == y ]; then else sudo chroot $FILESYSTEM_ROOT $DOCKER_CTL_SCRIPT stop fi +FUNLOCK ${DOCKER_LOCK_FILE} sudo bash -c "echo { > $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/ctr_image_names.json" {% for entry in feature_vs_image_names.split(' ') -%} diff --git a/functions.sh b/functions.sh index 6015704d58dd..6c045e4b2e26 100644 --- a/functions.sh +++ b/functions.sh @@ -66,3 +66,32 @@ sonic_get_version() { echo "${branch_name}.${BUILD_NUMBER}${dirty:--$(git rev-parse --short HEAD)}" | sed 's/\//_/g' fi } + +# Lock macro for shared file access +# Parameters: +# $(1) - Lock file name +# $(2) - Timeout value +function FLOCK() +{ + if [[ ! -f ${1}.lock ]]; then + touch ${1}.lock + chmod 777 ${1}.lock; + fi + local lock_fd=${1//[.\/-]/_}_lock_fd + eval $(echo exec {${lock_fd}}\<\>"${1}.lock") + echo ${!lock_fd} + if ! flock -x -w ${2} "${!lock_fd}" ; then + echo "ERROR: Lock timeout trying to access ${1}.lock"; + exit 1; + fi + echo "Lock acquired .." +} +# UnLock macro for shared file access +# Parameters: +# $(1) - Lock file name +function FUNLOCK() +{ + local lock_fd=${1//[.\/-]/_}_lock_fd + eval $(echo exec "${!lock_fd}<&-") +} + diff --git a/installer/x86_64/install.sh b/installer/x86_64/install.sh index f41a671543e8..ac79c93a9262 100755 --- a/installer/x86_64/install.sh +++ b/installer/x86_64/install.sh @@ -536,9 +536,17 @@ 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 -d $demo_mnt/$image_dir + if $( unzip -l $ONIE_INSTALLER_PAYLOAD 2>/dev/null 1>/dev/null ); then + unzip -o $ONIE_INSTALLER_PAYLOAD -d $demo_mnt/$image_dir + else + tar -C $demo_mnt/$image_dir -xvf $ONIE_INSTALLER_PAYLOAD + fi else - unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mnt/$image_dir + if $( unzip -l $ONIE_INSTALLER_PAYLOAD 2>/dev/null 1>/dev/null ); then + unzip -o $ONIE_INSTALLER_PAYLOAD -x "$FILESYSTEM_DOCKERFS" -d $demo_mnt/$image_dir + else + tar -C $demo_mnt/$image_dir -xvf $ONIE_INSTALLER_PAYLOAD boot/ platform/ $FILESYSTEM_SQUASHFS + fi if [ "$install_env" = "onie" ]; then TAR_EXTRA_OPTION="--numeric-owner" @@ -546,7 +554,11 @@ 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 + if $( unzip -l $ONIE_INSTALLER_PAYLOAD 2>/dev/null 1>/dev/null ); then + unzip -op $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR + else + tar -O -xvf $ONIE_INSTALLER_PAYLOAD "$FILESYSTEM_DOCKERFS" | tar xz $TAR_EXTRA_OPTION -f - -C $demo_mnt/$image_dir/$DOCKERFS_DIR + fi fi if [ "$install_env" = "onie" ]; then diff --git a/onie-image.conf b/onie-image.conf index 73deded2027e..b59f528f4dbc 100644 --- a/onie-image.conf +++ b/onie-image.conf @@ -12,8 +12,6 @@ ONIEIMAGE_VERSION=r0 -## Filesystem root -FILESYSTEM_ROOT=./fsroot-${TARGET_MACHINE} ## Filename for squashfs file system FILESYSTEM_SQUASHFS=fs.squashfs diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index 4405070460ad..bf861e6fb5c8 100644 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -2,7 +2,6 @@ SONIC_ONE_IMAGE = sonic-broadcom.bin $(SONIC_ONE_IMAGE)_MACHINE = broadcom -$(SONIC_ONE_IMAGE)_DEPENDENT_MACHINE = broadcom-dnx $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(PDDF_PLATFORM_MODULE) $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) @@ -88,3 +87,9 @@ $(SONIC_ONE_IMAGE)_DOCKERS = $(SONIC_INSTALL_DOCKER_IMAGES) endif SONIC_INSTALLERS += $(SONIC_ONE_IMAGE) + +SONIC_ONE_IMAGE_DNX=sonic-broadcom-dnx.bin +$(eval $(call add_dependent_machine,$(SONIC_ONE_IMAGE),$(SONIC_ONE_IMAGE_DNX))) +$(SONIC_ONE_IMAGE_DNX)_MACHINE=broadcom-dnx + +SONIC_INSTALLERS += $(SONIC_ONE_IMAGE_DNX) diff --git a/rules/config b/rules/config index 415aa795e767..0fec4dfb19ce 100644 --- a/rules/config +++ b/rules/config @@ -229,3 +229,13 @@ DEFAULT_CONTAINER_REGISTRY ?= # ENABLE_FIPS - support FIPS flag, if enabled, no additional config requred for the image to support FIPS ENABLE_FIPS_FEATURE ?= y ENABLE_FIPS ?= n + + +# Use tmpfs to build the rootfs and the final image. +SONIC_USE_TMPFS_BUILD ?=n + +# Select the final FS image compression type. +# zip : Standard, optimized for compression. +# pigz : Parallel compression, optimized for speed. +SONIC_FS_IMAGE_COMPRESSION_TYPE ?=zip + diff --git a/rules/fsroot.dep b/rules/fsroot.dep new file mode 100644 index 000000000000..336dadc3e271 --- /dev/null +++ b/rules/fsroot.dep @@ -0,0 +1,27 @@ + +SPATH := $($(FSROOT)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/fsroot.mk rules/fsroot.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(SONIC_COMMON_DOCKER_FILES_LIST) +DEP_FILES += build_debian_rootfs.sh +DEP_FILES += build_debian.sh +DEP_FILES += onie-image.conf +DEP_FILES += scripts/fsutil.sh + +define COPY_FROM_CACHE + cp $(1) $(2) +endef + +define COPY_TO_CACHE + cp $(1) $(2) +endef + +#DPKG FRK - Add more dependency files +$(FSROOT)_CACHE_MODE := GIT_CONTENT_SHA +$(FSROOT)_CACHE_USER := sudo +$(FSROOT)_FORCE_COPY := yes +$(FSROOT)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(FSROOT)_DEP_FILES := $(DEP_FILES) +$(FSROOT)_LOAD_HANDLER := COPY_FROM_CACHE +$(FSROOT)_SAVE_HANDLER := COPY_TO_CACHE + diff --git a/rules/fsroot.mk b/rules/fsroot.mk new file mode 100644 index 000000000000..598afa16ef1c --- /dev/null +++ b/rules/fsroot.mk @@ -0,0 +1,5 @@ +FSROOT := fsroot.img + +$(FSROOT)_SRC_PATH = $(PWD) +SONIC_INSTALL_PKGS += $(FSROOT) + diff --git a/rules/functions b/rules/functions index 62b3c8a98375..b7ebfe60160e 100644 --- a/rules/functions +++ b/rules/functions @@ -134,6 +134,23 @@ $(1)_DBG_DOCKER += $(2) SONIC_DBG_DOCKERS += $(2) endef +############################################################################### +## Definition of dependent machines +############################################################################### + +# call: +# add_dbg_docker some_docker.gz, some-docker-dbg.gz +define add_dependent_machine +$(2)_PATH = $($(1)_PATH) +$(2)_MACHINE = $($(1)_MACHINE) +$(2)_IMAGE_TYPE = $($(1)_IMAGE_TYPE) +$(2)_INSTALLS = $($(1)_INSTALLS) +$(2)_LAZY_INSTALLS = $($(1)_LAZY_INSTALLS) +$(2)_LAZY_BUILD_INSTALLS = $($(1)_LAZY_BUILD_INSTALLS) +$(2)_DOCKERS = $($(1)_DOCKERS) +SONIC_DEPENDENT_INSTALLERS += $(2) +endef + ############################################################################### diff --git a/scripts/build_debian_base_system.sh b/scripts/build_debian_base_system.sh index 72e3779ff3e2..5b1949dac764 100755 --- a/scripts/build_debian_base_system.sh +++ b/scripts/build_debian_base_system.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -x + CONFIGURED_ARCH=$1 IMAGE_DISTRO=$2 FILESYSTEM_ROOT=$3 diff --git a/scripts/build_kvm_image.sh b/scripts/build_kvm_image.sh index 6e5fd7dec742..ac9ffc68b02f 100755 --- a/scripts/build_kvm_image.sh +++ b/scripts/build_kvm_image.sh @@ -36,7 +36,7 @@ create_disk() prepare_installer_disk() { - fallocate -l 2048M $INSTALLER_DISK + fallocate -x -l 2048M $INSTALLER_DISK mkfs.vfat $INSTALLER_DISK diff --git a/scripts/fsutil.sh b/scripts/fsutil.sh new file mode 100755 index 000000000000..de92568ea0f7 --- /dev/null +++ b/scripts/fsutil.sh @@ -0,0 +1,320 @@ +#!/bin/bash +## This script is to create the tmpfs for different mount point during +## the ONIE installer image generation to speed up the processing. +## +## USAGE: +## ./tmpfs +## ENVIRONMENT: +## storage => Can be imagefs, rootfs, overlayfs, dockerfs, installerfs or allfs +## type => It can be one of the operation: allocate, deallocate, create, delete, mount or umount + +## Include common functions +. functions.sh + +## Enable debug output for script +set -x + + +## Use tmpfs +if [[ "${SONIC_USE_TMPFS_BUILD}" == "y" ]]; then + BUILD_TMP_ROOTFS_SIZE=6G + BUILD_ROOTFS_FILE_SIZE=4 #4G + BUILD_TMP_DOCKERFS_SIZE=16G + BUILD_TMP_FS_SIZE=8G +else + BUILD_ROOTFS_FILE_SIZE=10 #10G +fi + +## Read ONIE image related config file +. ./onie-image.conf + +## Working directory to prepare the file system +FILESYSTEM_BASE=/sonic/build/${BASE_IMAGE_NAME} +FILESYSTEM_ROOT=${FILESYSTEM_BASE}/ +mkdir -p ${FILESYSTEM_ROOT} + + +FSROOT_IMAGE_BASE_DIR=target/image/ +FSROOT_IMAGE_DIR=${FSROOT_IMAGE_BASE_DIR}/${BASE_IMAGE_NAME} +mkdir -p ${FSROOT_IMAGE_DIR} +FSROOT_IMAGE_FILENAME=fsroot.img +FSROOT_IMAGE_FILE=${FSROOT_IMAGE_DIR}/${FSROOT_IMAGE_FILENAME} +BUILD_PATH=target/fs/${TARGET_MACHINE} + + +mount_imagefs() +{ + umount_allfs + delete_rootfs_image + if [[ -e ${FSROOT_IMAGE_FILE} ]]; then + return + fi + + if [[ "${SONIC_USE_TMPFS_BUILD}" == "y" ]] ; then + sudo mount -t tmpfs -o size=${BUILD_TMP_ROOTFS_SIZE} tmpfs ${FSROOT_IMAGE_DIR} + fi +} + +create_rootfs_image() +{ + # Create special tmpfs mount point for fsroot + if [[ ! -e ${FSROOT_IMAGE_FILE} ]]; then + dd if=/dev/zero of=${FSROOT_IMAGE_FILE} bs=1G count=${BUILD_ROOTFS_FILE_SIZE} + mkfs.ext4 -F ${FSROOT_IMAGE_FILE} + fi +} +delete_rootfs_image() +{ + sudo rm -f ${FSROOT_IMAGE_FILE} || true + +} + +umount_imagefs() +{ + if [[ "${SONIC_USE_TMPFS_BUILD}" != "y" ]] ; then + return + fi + if $(mountpoint -q ${FSROOT_IMAGE_DIR}); then + # save the log file + cp ${FSROOT_IMAGE_FILE}.log ${FSROOT_IMAGE_BASE_DIR}/${BASE_IMAGE_NAME}-${FSROOT_IMAGE_FILENAME}.log + sudo umount ${FSROOT_IMAGE_DIR} || true + fi + +} +imagefs_fun() +{ + case $2 in + mount) + mount_imagefs + ;; + umount) + umount_imagefs + ;; + create) + create_rootfs_image + ;; + delete) + delete_rootfs_image + ;; + *) + echo "Usage: $0 $1 {create|delete|mount|umount}" + exit 1 + ;; + esac +} + + + + + +mount_rootfs() +{ + mkdir -p ${FILESYSTEM_BASE} + + sudo mount -o rw,loop ${FSROOT_IMAGE_FILE} ${FILESYSTEM_BASE} || true + sudo chmod 777 ${FILESYSTEM_BASE} +} + + +umount_rootfs() +{ + if $( mountpoint -q ${FILESYSTEM_BASE} ) ;then + sudo umount -f ${FILESYSTEM_BASE} || true + fi +} + + +rootfs_fun() +{ + case $2 in + mount) + mount_rootfs + ;; + umount) + umount_rootfs + ;; + *) + echo "Usage: $0 $1 {mount|umount}" + exit 1 + ;; + esac +} + +mount_overlayfs() +{ + mkdir -p ${FILESYSTEM_BASE}/${FSROOT_IMAGE_FILENAME} + cp ${FSROOT_IMAGE_FILE} ${FSROOT_IMAGE_FILENAME} + sudo mount -o rw,loop ${FSROOT_IMAGE_FILENAME} ${FILESYSTEM_BASE}/${FSROOT_IMAGE_FILENAME} || true + #sudo mount -o rw,loop ${FSROOT_IMAGE_FILENAME} ${FILESYSTEM_BASE}/${FSROOT_IMAGE_FILENAME} || true + #sudo mkdir -p ${FILESYSTEM_BASE}/fsroot ${FILESYSTEM_BASE}/upper ${FILESYSTEM_BASE}/work + #sudo chmod 777 ${FILESYSTEM_BASE} + #sudo mount -t overlay overlay -o lowerdir=${FILESYSTEM_BASE}/${FSROOT_IMAGE_FILENAME},upperdir=${FILESYSTEM_BASE}/upper,workdir=${FILESYSTEM_BASE}/work ${FILESYSTEM_BASE}/fsroot +} + + +umount_overlayfs() +{ + if $( mountpoint -q ${FILESYSTEM_BASE}/${FSROOT_IMAGE_FILENAME} ) ;then + sudo umount -f ${FILESYSTEM_BASE}/${FSROOT_IMAGE_FILENAME} || true + fi + if $( mountpoint -q ${FILESYSTEM_BASE} ) ;then + sudo umount -f ${FILESYSTEM_BASE} || true + fi +} + + +overlayfs_fun() +{ + case $2 in + mount) + mount_overlayfs + ;; + umount) + umount_overlayfs + ;; + *) + echo "Usage: $0 $1 {mount|umount}" + exit 1 + ;; + esac +} + + +DOCKER_BASE_PATH=${FILESYSTEM_ROOT}/var/lib/docker +mount_dockerfs() +{ + sudo mkdir -p ${DOCKER_BASE_PATH} + if [[ "${SONIC_USE_TMPFS_BUILD}" == "y" ]] ; then + sudo mount -t tmpfs -o size=${BUILD_TMP_DOCKERFS_SIZE} tmpfs ${DOCKER_BASE_PATH} + fi +} +umount_dockerfs() +{ + if [[ "${SONIC_USE_TMPFS_BUILD}" != "y" ]] ; then + return + fi + if $( mountpoint -q ${DOCKER_BASE_PATH} );then + sudo umount -f ${DOCKER_BASE_PATH} || true + fi +} + +dockerfs_fun() +{ + case $2 in + mount) + mount_dockerfs + ;; + umount) + umount_dockerfs + ;; + *) + echo "Usage: $0 $1 {mount|umount}" + exit 1 + ;; + esac +} + + + + +mount_installerfs() +{ + sudo mkdir -p ${BUILD_PATH} + if [[ "${SONIC_USE_TMPFS_BUILD}" == "y" ]] ; then + sudo mount -t tmpfs -o size=${BUILD_TMP_FS_SIZE} tmpfs ${BUILD_PATH} + fi +} +umount_installerfs() +{ + if [[ "${SONIC_USE_TMPFS_BUILD}" != "y" ]] ; then + return + fi + if $( mountpoint -q ${BUILD_PATH} ); then + sudo umount ${BUILD_PATH} || true + fi +} + +installerfs_fun() +{ + case $2 in + mount) + mount_installerfs + ;; + umount) + umount_installerfs + ;; + *) + echo "Usage: $0 $1 {mount|umount}" + exit 1 + ;; + esac +} + + + + +mount_allfs() +{ + mount_imagefs + create_rootfs_image + mount_rootfs + mount_dockerfs + mount_installerfs +} + +umount_allfs() +{ + + umount_dockerfs + umount_rootfs + #umount_overlayfs + umount_imagefs + umount_installerfs +} + +allfs_fun() +{ + case $2 in + mount) + mount_allfs + ;; + umount) + umount_allfs + ;; + *) + echo "Usage: $0 $1 {mount|umount}" + exit 1 + ;; + esac +} + + +case "$1" in + imagefs) + imagefs_fun $1 $2 + ;; + rootfs) + rootfs_fun $1 $2 + ;; + overlayfs) + overlayfs_fun $1 $2 + ;; + dockerfs) + dockerfs_fun $1 $2 + ;; + installerfs) + installerfs_fun $1 $2 + ;; + allfs) + allfs_fun $1 $2 + ;; + *) + echo "Usage: $0 {imagefs|rootfs|overlayfs|dockerfs|installerfs|allfs} " + exit 1 + ;; +esac + + + + + diff --git a/slave.mk b/slave.mk index 44d9e0ed8849..a62b44680c66 100644 --- a/slave.mk +++ b/slave.mk @@ -41,6 +41,7 @@ BUSTER_DEBS_PATH = $(TARGET_PATH)/debs/buster BUSTER_FILES_PATH = $(TARGET_PATH)/files/buster BULLSEYE_DEBS_PATH = $(TARGET_PATH)/debs/bullseye BULLSEYE_FILES_PATH = $(TARGET_PATH)/files/bullseye +FSROOT_PATH = $(TARGET_PATH)/image DBG_IMAGE_MARK = dbg DBG_SRC_ARCHIVE_FILE = $(TARGET_PATH)/sonic_src.tar.gz DPKG_ADMINDIR_PATH = /sonic/dpkg @@ -106,6 +107,7 @@ configure : @mkdir -p $(PYTHON_DEBS_PATH) @mkdir -p $(PYTHON_WHEELS_PATH) @mkdir -p $(DPKG_ADMINDIR_PATH) + @mkdir -p target/image @echo $(PLATFORM) > .platform @echo $(PLATFORM_ARCH) > .arch @@ -1019,6 +1021,53 @@ $(DOCKER_LOAD_TARGETS) : $(TARGET_PATH)/%.gz-load : .platform docker-start $$(TA $(call docker-image-load,$*) $(FOOTER) +SONIC_INSTALLERS_FSIMG = $(foreach ins,$(SONIC_INSTALLERS),$(ins)/fsroot.img \ + $(eval $(ins)/fsroot.img_DST_PATH=$(FSROOT_PATH)/$(ins)) \ + $(eval $(ins)/fsroot.img_BASE_IMAGE_NAME=$(ins)) \ + $(eval $(ins)/fsroot.img_FS_IMAGE_NAME=fsroot.img) \ + $(shell mkdir -p $(FSROOT_PATH)/$(ins)) \ + ) +SONIC_INSTALLERS_FSIMG_TARGET = $(addprefix $(FSROOT_PATH)/,$(SONIC_INSTALLERS_FSIMG)) + +.PHONY: $(SONIC_INSTALLERS_FSIMG_TARGET) +$(SONIC_INSTALLERS_FSIMG_TARGET) : $(FSROOT_PATH)/% : .platform \ + $(call dpkg_depend,$(FSROOT_PATH)/$(FSROOT).dep) + + $(HEADER) + + + # Create imagefs for rootfs + BASE_IMAGE_NAME=$($*_BASE_IMAGE_NAME) \ + SONIC_USE_TMPFS_BUILD=$(SONIC_USE_TMPFS_BUILD) \ + scripts/fsutil.sh imagefs mount $(LOG) + + # Load the target deb from DPKG cache + $(eval $($*_FS_IMAGE_NAME)_DST_PATH=$(FSROOT_PATH)/$($*_BASE_IMAGE_NAME)) + $(call LOAD_CACHE,$($*_FS_IMAGE_NAME),$@) + + # Skip building the target if it is already loaded from cache + if [ -z '$($($*_FS_IMAGE_NAME)_CACHE_LOADED)' ] ; then + + $(eval FSCMD= \ + USERNAME="$(USERNAME)" \ + PASSWORD="$(PASSWORD)" \ + NUMPROCS="$(SONIC_CONFIG_MAKE_JOBS)" \ + DBGOPT="$(DBGOPT)" CPORT=$(CPORT) CUSER=$(CUSER) \ + SONIC_VERSION_CACHE=$(SONIC_VERSION_CACHE) \ + BASE_IMAGE_NAME=$($*_BASE_IMAGE_NAME) \ + SONIC_USE_TMPFS_BUILD=$(SONIC_USE_TMPFS_BUILD) \ + ./build_debian_rootfs.sh ) + echo "ROOTFS CMD: $(FSCMD)" $(LOG) + $(FSCMD) $(LOG) + + # Save the target deb into DPKG cache + $(call SAVE_CACHE,$($*_FS_IMAGE_NAME),$@) + + fi + sync; sync; sync + + $(FOOTER) + ############################################################################### ## Installers ############################################################################### @@ -1027,6 +1076,7 @@ $(DOCKER_LOAD_TARGETS) : $(TARGET_PATH)/%.gz-load : .platform docker-start $$(TA $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ .platform \ onie-image.conf \ + build_debian_rootfs.sh \ build_debian.sh \ scripts/dbg_files.sh \ build_image.sh \ @@ -1076,9 +1126,12 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(addprefix $(FILES_PATH)/,$($(SONIC_CTRMGRD)_FILES)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_YANG_MGMT_PY3)) \ $(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH)) \ - $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_HOST_SERVICES_PY3)) + $(addprefix $(PYTHON_WHEELS_PATH)/,$(SONIC_HOST_SERVICES_PY3)) \ + | $(FSROOT_PATH)/$$*/fsroot.img + $(HEADER) # Pass initramfs and linux kernel explicitly. They are used for all platforms + export TARGET_MACHINE="$($*_MACHINE)" export debs_path="$(IMAGE_DISTRO_DEBS_PATH)" export files_path="$(FILES_PATH)" export python_debs_path="$(PYTHON_DEBS_PATH)" @@ -1208,7 +1261,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ chmod +x $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh $(if $($(docker:-dbg.gz=.gz)_MACHINE),\ - mv $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh $($(docker:-dbg.gz=.gz)_MACHINE)_$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh + cp $($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh $($(docker:-dbg.gz=.gz)_MACHINE)_$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh ) ) @@ -1258,17 +1311,17 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ ) # Build images for the MACHINE, DEPENDENT_MACHINE defined. - $(foreach dep_machine, $($*_MACHINE) $($*_DEPENDENT_MACHINE), \ - DEBUG_IMG="$(INSTALL_DEBUG_TOOLS)" \ - DEBUG_SRC_ARCHIVE_DIRS="$(DBG_SRC_ARCHIVE)" \ - DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ - scripts/dbg_files.sh + DEBUG_IMG="$(INSTALL_DEBUG_TOOLS)" \ + DEBUG_SRC_ARCHIVE_DIRS="$(DBG_SRC_ARCHIVE)" \ + DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ + scripts/dbg_files.sh $(LOG) + $(eval IMGCMD= \ DEBUG_IMG="$(INSTALL_DEBUG_TOOLS)" \ DEBUG_SRC_ARCHIVE_FILE="$(DBG_SRC_ARCHIVE_FILE)" \ USERNAME="$(USERNAME)" \ PASSWORD="$(PASSWORD)" \ - TARGET_MACHINE=$(dep_machine) \ + TARGET_MACHINE=$($*_MACHINE) \ IMAGE_TYPE=$($*_IMAGE_TYPE) \ TARGET_PATH=$(TARGET_PATH) \ SONIC_ENFORCE_VERSIONS=$(SONIC_ENFORCE_VERSIONS) \ @@ -1278,19 +1331,31 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ SIGNING_CERT="$(SIGNING_CERT)" \ PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) \ - ./build_debian.sh $(LOG) - - USERNAME="$(USERNAME)" \ - PASSWORD="$(PASSWORD)" \ - TARGET_MACHINE=$(dep_machine) \ - IMAGE_TYPE=$($*_IMAGE_TYPE) \ - SONIC_ENABLE_IMAGE_SIGNATURE="$(SONIC_ENABLE_IMAGE_SIGNATURE)" \ - SIGNING_KEY="$(SIGNING_KEY)" \ - SIGNING_CERT="$(SIGNING_CERT)" \ - CA_CERT="$(CA_CERT)" \ - TARGET_PATH="$(TARGET_PATH)" \ - ./build_image.sh $(LOG) - ) + BASE_IMAGE_NAME=$* \ + SONIC_USE_TMPFS_BUILD=$(SONIC_USE_TMPFS_BUILD) \ + SONIC_FS_IMAGE_COMPRESSION_TYPE=$(SONIC_FS_IMAGE_COMPRESSION_TYPE) \ + ./build_debian.sh ) + $(IMGCMD) $(LOG) + + USERNAME="$(USERNAME)" \ + PASSWORD="$(PASSWORD)" \ + TARGET_MACHINE=$($*_MACHINE) \ + IMAGE_TYPE=$($*_IMAGE_TYPE) \ + SONIC_ENABLE_IMAGE_SIGNATURE="$(SONIC_ENABLE_IMAGE_SIGNATURE)" \ + SIGNING_KEY="$(SIGNING_KEY)" \ + SIGNING_CERT="$(SIGNING_CERT)" \ + CA_CERT="$(CA_CERT)" \ + TARGET_PATH="$(TARGET_PATH)" \ + BASE_IMAGE_NAME=$* \ + SONIC_USE_TMPFS_BUILD=$(SONIC_USE_TMPFS_BUILD) \ + SONIC_FS_IMAGE_COMPRESSION_TYPE=$(SONIC_FS_IMAGE_COMPRESSION_TYPE) \ + ./build_image.sh $(LOG) + + # umount all tmfs + BASE_IMAGE_NAME=$* \ + TARGET_MACHINE=$($*_MACHINE) \ + SONIC_USE_TMPFS_BUILD=$(SONIC_USE_TMPFS_BUILD) \ + scripts/fsutil.sh imagefs umount $(LOG) $(foreach docker, $($*_DOCKERS), \ rm -f *$($(docker:-dbg.gz=.gz)_CONTAINER_NAME).sh