SONiC Image and Build System ===== ###### tags: `SONiC` contributed by < Dung-Ru Tsai > Build the Docker Image/installer image `git clone --recursive https://github.com/Azure/sonic-buildimage` [Build p4 Image Jenkins Log:](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/543/console) [Build image Getting Started](https://github.com/Azure/sonic-buildimage/blob/master/README.md) [SONiC Building System Guide](https://github.com/Azure/sonic-buildimage/blob/master/README.buildsystem.md) # Install the Dependencies: ```bash sudo apt install python3-pip sudo apt-get install -y python-pip sudo pip install --force-reinstall --upgrade jinja2>=2.10 sudo pip install j2cli ``` # Build images ```bash= # Ensure the 'overlay' module is loaded on your development system sudo modprobe overlay # Enter the source directory cd sonic-buildimage # (Optional) Checkout a specific branch. By default, it uses master branch. For example, to checkout the branch 201911, use "git checkout 201911" git checkout [branch_name] # Execute make init once after cloning the repo, or after fetching remote repo with submodule updates make init # Execute make configure once to configure ASIC make configure PLATFORM=[ASIC_VENDOR] make configure PLATFORM=vs # Build SONiC image make all ls -al target -rwxr-xr-x 1 dutsai dutsai 864759062 Mar 4 13:18 sonic-vs.bin -rw-r--r-- 1 dutsai dutsai 404782 Mar 3 18:13 sonic-vs.bin.log -rwxr-xr-x 1 dutsai dutsai 877791856 Mar 4 13:20 sonic-vs.img.gz ``` ## Backend build - Contruct the build sonic environment docker. - The build system will build the Backend first. - Makefile, slave.mk and sonic-slave-xxx/Dockerfile are the backend of buildimage. - `sonic-slave-xxx/Dockerfile` describe what builder-docker looks like. Makefile => Makefile.work => slave.mk ## Front End Build Build the sonic image content, the design methologies is inheritance the makefile. ![](https://i.imgur.com/yHqrmOJ.png) ### `rules/`: collection of recipes for platform independent targets. - **Recipes**: Necessary steps and take`rules/swss.mk` as example - xxx_SRC_PATH: path to sources - xxx_DEPENDS: build dependencies - xxx_RDEPENDS: runtime dependencies - SONIC_DPKG_DEBS: add our target to `SONIC_DPKG_DEBS` target group - add_derived_package - **Target groups**: Main target group for building `.deb` packages - SONIC_DPKG_DEBS (Necessary) - It will become makefile target - slave.mk: `$(addprefix $(DEBS_PATH)/, $(SONIC_DPKG_DEBS)) ` - `make target/debs/swss_1.0.0_amd64.deb` - SONIC_PYTHON_STDEB_DEBS - SONIC_MAKE_DEBS: just define your own Makefile and add it to buildimage ```clike= SOME_NEW_DEB = some_new_deb.deb # name of your package $(SOME_NEW_DEB)_SRC_PATH = $(SRC_PATH)/project_name # path to directory with sources $(SOME_NEW_DEB)_DEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # build dependencies $(SOME_NEW_DEB)_RDEPENDS = $(SOME_OTHER_DEB1) $(SOME_OTHER_DEB2) ... # runtime dependencies SONIC_MAKE_DEBS += $(SOME_NEW_DEB) # add package to this target group ``` If some packages have to be built locally due to some legal issues or they are already prebuilt and available online, you might find next four target groups useful. - SONIC_COPY_DEBS - SONIC_COPY_FILES - SONIC_ONLINE_DEBS: debian packages that should be fetched from an online source - SONIC_ONLINE_FILES - SONIC_SIMPLE_DOCKER_IMAGES - SONIC_DOCKER_IMAGES Container makefile `rules/docker-orchagent.mk`: ```bash= DOCKER_ORCHAGENT_STEM = docker-orchagent #docker image name $(DOCKER_ORCHAGENT)_CONTAINER_NAME = swss # container name ``` Dabeian package makefile`rules/swss.mk`: ```bash= SWSS = swss_1.0.0_$(CONFIGURED_ARCH).deb ``` ### `rules/config`: configuration file for a build system - config system default login password ```c DEFAULT_PASSWORD = YourPaSsWoRd ``` ### `dockers/`: place where you can find Dockerfiles for generic docker images. ### `src/`: source code for generic packages goes ### `platform/`: contains all vendor-specific recipes # Clean the Build `make reset` # Only Build your change .deb and docker: ### Docker image ```bash= make target/docker-orchagent.gz ``` ### Debian packages ```bash= make target/debs/swss_1.0.0_amd64.deb make target/debs/swss_1.0.0_amd64.deb-clean make target/debs/stretch/libsairedis_1.0.0_amd64.deb make target/debs/stretch/libsairedis_1.0.0_amd64.deb-clean ``` # Output Image folder: `sonic-buildimage/target` ```bash= dutsai@diag-tpe-01:/ws-dutsai/sonic-buildimage/target (master)$ ls cache docker-dhcp-relay.gz.log docker-orchagent.gz docker-sonic-mgmt-framework.gz python-debs debs docker-fpm-frr.gz docker-orchagent.gz.log docker-sonic-mgmt-framework.gz.log python-wheels docker-base-buster.gz docker-fpm-frr.gz.log docker-platform-monitor.gz docker-sonic-telemetry.gz sonic-vs.bin docker-base-buster.gz-load.log docker-gbsyncd-vs.gz docker-platform-monitor.gz.log docker-sonic-telemetry.gz.log sonic-vs.bin.log docker-base-buster.gz.log docker-gbsyncd-vs.gz.log docker-ptf.gz.log docker-sonic-vs.gz sonic-vs.img.gz docker-config-engine-buster.gz docker-lldp.gz docker-router-advertiser.gz docker-sonic-vs.gz.log sonic-vs.img.gz.log docker-config-engine-buster.gz-load.log docker-lldp.gz.log docker-router-advertiser.gz.log docker-syncd-vs.gz sonic-vs.raw docker-config-engine-buster.gz.log docker-macsec.gz docker-sflow.gz docker-syncd-vs.gz.log sonic-vs.raw.log docker-database.gz docker-macsec.gz.log docker-sflow.gz.log docker-teamd.gz versions docker-database.gz.log docker-nat.gz docker-snmp.gz docker-teamd.gz.log docker-dhcp-relay.gz docker-nat.gz.log docker-snmp.gz.log files ``` | | make command | Image Type | Testbed | Log | | ------------- | ------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------- | ---------------------- | | Run on ONIE | target/sonic-vs.bin | sonic-vs.bin | | sonic-vs.bin.log | | Run on KVM | target/sonic-vs.img.gz | sonic-vs.img.gz | [KVM Testbed](https://github.com/Azure/sonic-mgmt/blob/master/docs/testbed/README.testbed.VsSetup.md) | sonic-vs.img.gz.log | | | target/sonic-vs.raw | | | sonic-vs.raw.log | | Run on docker | target/docker-sonic-vs.gz | docker-sonic-vs.gz | | docker-sonic-vs.gz.log | # sonic-slave environment update Enter the slave docker (build environment docker) `$ make sonic-slave-bash` Build the environment Docker `$ make sonic-slave-build` One can print out all available targets by executing the following command: `$ make list` # Debug dockers and debug SONiC installer image ```bash= INSTALL_DEBUG_TOOLS=y make target/sonic-vs.img.gz ``` Debug images carry a suffix of "-dbg" e.g. target/docker-orchagent-dbg.gz Enlarge the memory size for KVM: `scripts/build_kvm_image.sh`: ```bash= +++ b/scripts/build_kvm_image.sh @@ -4,7 +4,7 @@ # # SPDX-License-Identifier: GPL-2.0 -MEM=3072 +MEM=4096 DISK=$1 ONIE_RECOVERY_ISO=$2 ``` :::info $INSTALLER = target/sonic-vs.bin ::: [GDB Debug with SONiC](https://github.com/Azure/sonic-buildimage/blob/master/README.buildsystem.md#build-debug-dockers-and-debug-sonic-installer-image) The gdb could be used in each container. ```bash= tar -zxvf /src/sonic_src.tar.gz -C /debug docker exec -it bgp bash gdb -p 48 (gdb) directory /debug/src/sonic-frr/frr/staticd ``` # Target images (Docker Images in SONiC) - The target directory is `./target`, containing the NOS installer image and docker images. - **sonic-generic.bin**: SONiC switch installer image (ONIE compatible) - **sonic-aboot.bin**: SONiC switch installer image (Aboot compatible) - **docker-base.gz**: base docker image where other docker images are built from, only used in build process (gzip tar archive) - **docker-database.gz**: docker image for in-memory key-value store, used as inter-process communication (gzip tar archive) - **docker-fpm.gz**: docker image for quagga with fpm module enabled (gzip tar archive) - **docker-orchagent.gz**: docker image for SWitch State Service (SWSS) (gzip tar archive) - **docker-sonic-vs.gz**: docker image for all-in-one for software virtual switch (gzip tar archive) - **docker-sonic-mgmt.gz**: docker image for [managing, configuring and monitoring SONiC](https://github.com/Azure/sonic-mgmt) (gzip tar archive) # Extract the denian package to specific folder ``` dpkg -x syncd-vs_1.0.0_amd64.deb your_path ``` # Develope/Push code procedure Gitflow ```sequence Note over commiter: Start Note over commiter: submodule at dev_branch commiter->submodule_gitlab: push Note over submodule_gitlab: Merge Request submodule_gitlab-->jenkins: trigger Note over jenkins: test dev_branch Reviewer->submodule_gitlab: Merge and delete dev_branch submodule_gitlab-->jenkins: trigger Note over jenkins: test 202012.clounix Note over commiter: buildimage at dev_branch Note over commiter: commit submodule id to buildimage commiter->buildimage_gitlab: push dev_branch to buildimage Note over buildimage_gitlab: Merge Request buildimage_gitlab-->jenkins: trigger Note over jenkins: test dev_branch Reviewer->buildimage_gitlab: Merge and delete dev_branch buildimage_gitlab-->jenkins: trigger Note over jenkins: test 202012.clounix Note over jenkins: END ``` # Useful MAKE Optional - SONIC_BUILD_JOBS=4 # Build Fail case ## make target/python-wheels/sonic_config_engine-1.0-py2-none-any.whl ```bash= Using /sonic/src/sonic-config-engine/.eggs/contextlib2-21.6.0-py2.7.egg running egg_info writing requirements to sonic_config_engine.egg-info/requires.txt writing sonic_config_engine.egg-info/PKG-INFO writing top-level names to sonic_config_engine.egg-info/top_level.txt writing dependency_links to sonic_config_engine.egg-info/dependency_links.txt reading manifest file 'sonic_config_engine.egg-info/SOURCES.txt' reading manifest template 'MANIFEST.in' writing manifest file 'sonic_config_engine.egg-info/SOURCES.txt' running build_ext test_comprehensive (tests.test_cfggen_pfx_filter.TestPfxFilter) ... Traceback (most recent call last): File "./sonic-cfggen", line 33, in <module> import netaddr File "/sonic/src/sonic-config-engine/.eggs/netaddr-0.8.0-py2.7.egg/netaddr/__init__.py", line 18, in <module> from netaddr.core import (AddrConversionError, AddrFormatError, File "/sonic/src/sonic-config-engine/.eggs/netaddr-0.8.0-py2.7.egg/netaddr/core.py", line 11, in <module> from netaddr.compat import _callable, _iter_dict_keys File "/sonic/src/sonic-config-engine/.eggs/netaddr-0.8.0-py2.7.egg/netaddr/compat.py", line 93, in <module> import importlib_resources as _importlib_resources File "/sonic/src/sonic-config-engine/.eggs/importlib_resources-3.3.1-py2.7.egg/importlib_resources/__init__.py", line 5, in <module> from ._common import ( File "/sonic/src/sonic-config-engine/.eggs/importlib_resources-3.3.1-py2.7.egg/importlib_resources/_common.py", line 9, in <module> from ._compat import ( File "/sonic/src/sonic-config-engine/.eggs/importlib_resources-3.3.1-py2.7.egg/importlib_resources/_compat.py", line 15, in <module> from contextlib2 import suppress # type: ignore File "/sonic/src/sonic-config-engine/.eggs/contextlib2-21.6.0-py2.7.egg/contextlib2/__init__.py", line 56 async def __aenter__(self): ^ SyntaxError: invalid syntax ERROR ``` - [Wheel vs Egg](https://packaging.python.org/discussions/wheel-vs-egg/) - `async` keyword is after 3.7 python, - Our last build pass is #79 20210626 https://jenkins.clounix.com/job/sonic/job/vs/job/202012.clounix/job/sonic-buildimage/79/ However the contextlib2 has a big change. ![](https://i.imgur.com/GQ3pvr1.png) src/sonic-config-engine/.eggs/contextlib2-21.6.0-py2.7.egg/contextlib2/__init__.py Because the module __init__.py using the async keyword. The .egg and sonic_config_engine.egg-info are create during the sonic build. the package version could setup in `src/sonic-config-engine/setup.py` The fix version is here. https://pypi.org/project/contextlib2/0.6.0.post1/ ## make target/docker-base-buster.gz ``` 08:45:49 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? 08:45:49 [ building ] [ target/docker-base-buster.gz ] 08:45:49 Unable to find image 'debian:buster' locally 08:45:51 buster: Pulling from library/debian 08:45:52 0bc3020d05f1: Pulling fs layer 08:45:58 0bc3020d05f1: Verifying Checksum 08:45:58 0bc3020d05f1: Download complete 08:46:00 0bc3020d05f1: Pull complete 08:46:00 Digest: sha256:33a8231b1ec668c044b583971eea94fff37151de3a1d5a3737b08665300c8a0b 08:46:00 Status: Downloaded newer image for debian:buster 08:51:37 [ finished ] [ target/docker-base-buster.gz ] 08:51:37 [ FAIL LOG START ] [ target/docker-base-buster.gz ] 08:51:37 [ REASON ] : target/docker-base-buster.gz does not exist NON-EXISTENT PREREQUISITES: docker-start ``` Don't knwo why, just retest.