forked from facebook/fboss
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request facebook#2 from adamcalabrigo/arista-build-tools
Adds arista directory w/build + packaging tools and platform scripts
- Loading branch information
Showing
21 changed files
with
2,928 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# Arista FBOSS OSS | ||
|
||
Copyright (C) 2023 Arista Networks, Inc. | ||
|
||
## Purpose | ||
|
||
This directory contains Arista-specific code for building, packaging, and installing | ||
FBOSS OSS on Arista platforms. | ||
|
||
## Directory Structure | ||
|
||
The table below outlines the structure of this directory. | ||
|
||
| Directory | Description | | ||
|-------------|--------------------------------------------------| | ||
| build-utils | Helper scripts for build tasks. | | ||
| core | Core FBOSS scripts and config. | | ||
| platform | Platform-specific scripts and config. | | ||
| rpm | Spec files for Arista code packages. | | ||
|
||
## How to Build | ||
|
||
### In a Docker Container | ||
|
||
The simplest way to build the FBOSS OSS + SAI + SDK is in an FBOSS CentOS 8 build | ||
container. For ease of use, the `fbossctl` script is provided to automate building | ||
and packaging. Run `fbossctl help` to show the usage. | ||
|
||
To build, first clone this git repository locally on your user server. Next, | ||
designate a build directory: this is where all build artifacts will live. You can | ||
set the build directory by setting the `FBOSS_BUILD_DIR` env var. If this var is | ||
not set, fbossctl will use `//garage/$USER/fboss-build` as the default build directory. | ||
|
||
With the build directory set, run `fbossctl build` to build FBOSS OSS + SAI + SDK | ||
from source. The `--arch` flag must be set to specify the SDK architecture. For your | ||
first build, you will need to build FBOSS OSS, SAI, and the SDK. This build will take | ||
around 40 minutes. All build artifacts can be found in `$FBOSS_BUILD_DIR/FBOSS_DIR`. | ||
|
||
### Manually | ||
|
||
To build FBOSS OSS + SAI + SDK manually outside of a container, you can use the | ||
build-utils/build.sh script. The arguments are the same as `fbossctl build`, but an | ||
extra `--build-dir` argument must be provided to specify the build directory. | ||
|
||
### Rebuilding | ||
|
||
To rebuild the SDK and FBOSS OSS from scratch, use `fbossctl build --rebuild-all`. | ||
To rebuild just FBOSS OSS, use `fbossctl build --rebuild-fboss`. | ||
To rebuild only the FBOSS OSS binaries, use `fbossctl build --fboss-bins-only`; | ||
this is by far the fastest option. | ||
|
||
## How to Package | ||
|
||
Multiple spec files are included in `rpm/` to package the built source into | ||
RPMs that can be installed on an Arista switch. The `arista-fboss-core.spec` file | ||
contains the core FBOSS libraries and services, and `arista-platform-*.spec` files | ||
contain platform-specific scripts and config files. | ||
|
||
To build all RPMs, simply run `fbossctl package`. If you only want to build a | ||
specific RPM, then provide the name of the RPM as an optional argument, e.g. | ||
`fbossctl package arista-fboss-core`. | ||
|
||
Built RPMs can be found in `$FBOSS_BUILD_DIR/FBOSS_DIR/rpmbuild/RPMS/`. | ||
|
||
## How to install on a Switch | ||
|
||
To install FBOSS OSS on an Arista switch in the lab, first build and package the | ||
source as RPMs. With your RPMs built, sanitize your DUT using | ||
`a dut sanitize --os=fbossOss --osArgs="ossRpmDir=<dir>"`. | ||
|
||
### How to Quickly Reinstall Changes | ||
|
||
When quickly testing changes with an already sanitized DUT, you can simply | ||
copy your newly built RPMs to the switch. `fbossctl update-dut <dut>` | ||
provides a convenient way to copy the latest RPMs to <dut>:/tmp. After copying | ||
the RPMs, SSH to the DUT and install the RPMs using `rpm -Uvh <rpm>`. | ||
|
||
To re-initialize FBOSS OSS, run `/opt/fboss/bin/fboss_init.sh`. | ||
|
||
## Other fbossctl Options | ||
|
||
If you want to play around in the FBOSS CentOS 8 build container, run | ||
`fbossctl shell`. This will drop you into a bash session in a build container, | ||
which can be convenient for debug. | ||
|
||
To delete the $FBOSS_BUILD_DIR/FBOSS_DIR directory, run `fbossctl clean`. | ||
|
||
## How to add a New Platform | ||
|
||
To add support for a new platform, create a new directory in `platform` with | ||
any platform-specific code, then add a new spec file in `rpms/` with | ||
instructions on how to build the platform code. Any special initialization | ||
needs to be put in a `platform_init.sh` script that gets installed in | ||
`/opt/fboss/bin/`; this will automatically get called during the generic | ||
`fboss_init.sh`. Any service-specific configuration files should go in the | ||
`platform/<platform>/config` directory. Make sure to also include a `fruid.json` | ||
which FBOSS will use to identify the platform. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,235 @@ | ||
#!/bin/bash | ||
|
||
# Add /usr/local/bin, for doxygen. | ||
export PATH="$PATH:/usr/local/bin" | ||
|
||
if [ -f /.dockerenv ]; then | ||
echo "running in a container - assuming /var/FBOSS base" | ||
FBOSS_DIR="/var/FBOSS" | ||
else | ||
echo "Running outside of container. Using $FBOSS_DIR" | ||
if ! [ -d "$FBOSS_DIR" ]; | ||
then | ||
echo "Invalid FBOSS_DIR, provide a valid directory path." | ||
exit 1 | ||
fi | ||
FBOSS_DIR="$(realpath $FBOSS_DIR)" | ||
fi | ||
|
||
usage() { | ||
echo "Usage: $1 --arch <dnx|xgs> [ --build-dir <build directory> ] " | ||
echo " [ --rebuild-all ] [ --rebuild-fboss ] " | ||
echo " [ --fboss-bins-only ]" | ||
exit 1 | ||
} | ||
|
||
while [[ $# -gt 0 ]]; do | ||
case $1 in | ||
--build-dir) | ||
FBOSS_DIR=$2 | ||
shift | ||
shift | ||
;; | ||
--rebuild-all) | ||
REBUILD_SDK=TRUE | ||
REBUILD_FBOSS=TRUE | ||
shift | ||
;; | ||
--rebuild-fboss) | ||
REBUILD_FBOSS=TRUE | ||
shift | ||
;; | ||
--fboss-bins-only) | ||
FBOSS_BINS_ONLY=TRUE | ||
shift | ||
;; | ||
--arch) | ||
if [ "$2" == "dnx" ]; | ||
then | ||
ARCH="dnx" | ||
elif [ "$2" == "xgs" ]; | ||
then | ||
ARCH="xgs" | ||
else | ||
echo "Invalid architecture $2, please provide one of xgs or dnx." | ||
exit 1 | ||
fi | ||
shift | ||
shift | ||
;; | ||
-*|--*) | ||
echo "Unknown option $1" | ||
exit 1 | ||
;; | ||
*) | ||
POSITIONAL_ARGS+=("$1") # save positional arg | ||
shift | ||
;; | ||
esac | ||
done | ||
|
||
if [ -z "$ARCH" ]; then | ||
usage | ||
fi | ||
|
||
set -ex | ||
echo "================= Running build with $FBOSS_DIR and ARCH=$ARCH" | ||
|
||
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters | ||
|
||
export KERNEL_SRC="$FBOSS_DIR/4.18.0-408.el8.x86_64" | ||
|
||
# install missing dependencies for SDK build. | ||
dnf install -y sudo | ||
sudo dnf install --enablerepo powertools -y perl-List-MoreUtils perl-YAML.noarch \ | ||
perl-Data-Compare perl-Moose perl-MooseX-Role* perl-Clone libyaml-devel | ||
sudo dnf install -y python3-filelock platform-python-devel | ||
|
||
# Setup unversioned-python aliased to python3 | ||
alternatives --set python /usr/bin/python3 | ||
# Install python3 module dependencies | ||
pip3 install GitPython | ||
|
||
SAI_DIR="$FBOSS_DIR/Jupiter_SAI/" | ||
if [ $ARCH == "dnx" ]; | ||
then | ||
SAI_BUILD_DIR="$SAI_DIR/output/x86-dnx-deb" | ||
else | ||
SAI_BUILD_DIR="$SAI_DIR/output/x86-xgsall-deb" | ||
fi | ||
|
||
# Delete SDK var in the env. It can cause the SDK build to fail. | ||
export SDK="" | ||
cd $SAI_BUILD_DIR | ||
echo "****REBUILD_SDK $REBUILD_SDK" | ||
if ! [ -z "$REBUILD_SDK" ]; | ||
then | ||
echo "======== Clean up Broadcom SDK build artifacts ========" | ||
time make clean -j 8 | ||
for dir in $(ls $SAI_BUILD_DIR) | ||
do | ||
if [ -d $SAI_BUILD_DIR/$dir ]; | ||
then | ||
rm -r "$SAI_BUILD_DIR/$dir" | ||
fi | ||
done | ||
|
||
echo "======= Starting SDK build ========" | ||
time make -j 8 | ||
export KERNDIR="$KERNEL_SRC" | ||
export BCM_KERNEL_MODULES_DIR="$SAI_DIR/sdk-src/hsdk_6.5.26_SAI_8.1.0_GA/$ARCH-sdk-6.5.26-gpl-modules" | ||
cd $BCM_KERNEL_MODULES_DIR | ||
export SDK=$PWD | ||
make -C systems/linux/user/common/ platform=x86-smp_generic_64-2_6 \ | ||
kernel_version=2_6 LINUX_UAPI_SPLIT=1 clean | ||
make -C systems/linux/user/common/ platform=x86-smp_generic_64-2_6 \ | ||
kernel_version=2_6 LINUX_UAPI_SPLIT=1 kernel_modules | ||
else | ||
# Need this defined for FBOSS operations below. | ||
export BCM_KERNEL_MODULES_DIR="$SAI_DIR/sdk-src/hsdk_6.5.26_SAI_8.1.0_GA/$ARCH-sdk-6.5.26-gpl-modules" | ||
fi | ||
|
||
# Instructions from | ||
# https://github.com/facebook/fboss/blob/main/installer/howto/Building_FBOSS_on_containers.md | ||
# With some changes to avoid overwriting git repos etc. | ||
SCRATCH_DIR="$FBOSS_DIR/tmp_build_dir" | ||
cd $FBOSS_DIR/ | ||
if ! [ -d fboss.git ]; | ||
then | ||
git clone https://github.com/facebook/fboss fboss.git | ||
fi | ||
|
||
# Cleanup fboss build artefacts with --rebuild-fboss | ||
if ! [ -z "$REBUILD_FBOSS" ]; | ||
then | ||
echo "======== Clean up FBOSS build artifacts ========" | ||
rm -rf $SCRATCH_DIR/build # remove existing build dir if any | ||
rm -rf $SCRATCH_DIR/installed # remove existing build dir if any | ||
rm -rf $SCRATCH_DIR/extracted # remove existing build dir if any | ||
rm -rf "$SCRATCH_DIR"/fboss_bins* | ||
fi | ||
cd $FBOSS_DIR/fboss.git | ||
|
||
# Optionally, pin the fboss and its dependencies to known | ||
# stable commit hash | ||
rm -rf build/deps/github_hashes/facebook | ||
rm -rf build/deps/github_hashes/facebookincubator | ||
tar -xvf fboss/stable_commits/latest_stable_hashes.tar.gz | ||
|
||
echo "======= Starting FBOSS build ========" | ||
|
||
# Install dependencies for FBOSS build | ||
bash $FBOSS_DIR/fboss.git/installer/centos-8-x64_64/install-tools.sh | ||
|
||
# Prepare FBOSS Build | ||
echo "****FBOSS_BINS_ONLY $FBOSS_BINS_ONLY" | ||
if ! [ -z "$FBOSS_BINS_ONLY" ]; | ||
then | ||
# Only re-run cmake | ||
cd $SCRATCH_DIR/build/fboss | ||
./run_cmake.py --install | ||
else | ||
rm -rf $FBOSS_DIR/built-sai | ||
mkdir -p $FBOSS_DIR/built-sai/experimental | ||
mkdir -p $FBOSS_DIR/built-bcm-sai | ||
cp $SAI_BUILD_DIR/libraries/libsai.a $FBOSS_DIR/built-bcm-sai/libsai_impl.a | ||
cp $SAI_DIR/include/experimental/*.* $FBOSS_DIR/built-sai/experimental | ||
cd $FBOSS_DIR/fboss.git/installer/centos-8-x64_64 | ||
./build-helper.py $FBOSS_DIR/built-bcm-sai/libsai_impl.a \ | ||
$FBOSS_DIR/built-sai/experimental/ $FBOSS_DIR/sai_impl_output | ||
|
||
# Build FBOSS | ||
export SAI_ONLY=1 | ||
export SAI_BRCM_IMPL=1 # Needed only for BRCM SAI | ||
export GETDEPS_USE_WGET=1 | ||
cd "$FBOSS_DIR/fboss.git" | ||
|
||
time ./build/fbcode_builder/getdeps.py build --num-jobs 8 --allow-system-packages \ | ||
--scratch-path "$SCRATCH_DIR" fboss | ||
cd $FBOSS_DIR/fboss.git | ||
./installer/centos-7-x86_64/package-fboss.py --scratch-path "$SCRATCH_DIR" | ||
|
||
# Check if any dynamic libraries are missing in the output directory and copy them over. | ||
fboss_output_dir=$(find $SCRATCH_DIR -maxdepth 1 -name "fboss_bins*") | ||
ld_lib_path="$LD_LIBRARY_PATH:$fboss_output_dir/lib:$fboss_output_dir/lib64" | ||
sai_test="$fboss_output_dir/bin/sai_test-sai_impl-1.10.2" | ||
missing_libs=$(LD_LIBRARY_PATH="$ld_lib_path" ldd "$sai_test" | awk '/not found/{print $1}') | ||
for lib in $missing_libs | ||
do | ||
lib_path=$(find "$SCRATCH_DIR/installed" -name $lib) | ||
echo "Copying $lib from $lib_path to $fboss_output_dir/lib64" | ||
cp -L $lib_path $fboss_output_dir/lib64 | ||
done | ||
|
||
# Verify that no more libs are missing | ||
missing_libs=$(LD_LIBRARY_PATH="$ld_lib_path" ldd "$sai_test" | awk '/not found/{print $1}') | ||
if ! [ -z "$missing_libs" ]; | ||
then | ||
echo "Test executables still missing dynamic libraries $missing_libs" | ||
exit 1 | ||
fi | ||
|
||
# Also add libevent_core as there's a dependency for libevent. | ||
lib="libevent_core-2.1.so.7" | ||
lib_path=$(find "$SCRATCH_DIR/installed" -name $lib) | ||
echo "Copying $lib from $lib_path to $fboss_output_dir/lib64" | ||
cp -L $lib_path $fboss_output_dir/lib64 | ||
|
||
# Copy over kernel modules | ||
for kernel_module in linux-kernel-bde.ko linux-user-bde.ko linux-bcm-knet.ko | ||
do | ||
module_path=$(find $BCM_KERNEL_MODULES_DIR -name "$kernel_module" | head -n 1) | ||
echo "Copying $module from $module_path to $fboss_output_dir/lib/modules" | ||
cp $module_path $fboss_output_dir/lib/modules | ||
done | ||
|
||
# Copy over firmware files | ||
for fw in custom_led.bin linkscan_led_fw.bin | ||
do | ||
fw_path=$(find $FBOSS_DIR -name "$fw") | ||
echo "Copying $fw from $fw_path to $fboss_output_dir" | ||
cp $fw_path $fboss_output_dir | ||
done | ||
fi | ||
|
||
set +ex |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/bin/bash | ||
# Package FBOSS OSS into RPMs. RPMs to build can be specified as input. If not | ||
# RPMs are given, all will be rebuilt. | ||
|
||
if [[ ! -f /.dockerenv ]]; then | ||
echo "Please run this script from within the docker build container." | ||
fi | ||
|
||
FBOSS_REPO_RPM_DIR="/var/FBOSS/fboss.git/arista/rpm" | ||
FBOSS_RPM_DIR="/var/FBOSS/rpmbuild/RPMS/" | ||
RPM_DIR="/root/rpmbuild/RPMS/x86_64" | ||
RPMS=() | ||
set -ex | ||
|
||
mkdir -p "${FBOSS_RPM_DIR}" | ||
|
||
# Find the RPMs to build. | ||
if [[ $# -lt 1 ]]; then | ||
RPMS=($(find "${FBOSS_REPO_RPM_DIR}" -type f -name *.spec)) | ||
else | ||
for rpm in "${@}"; do | ||
RPMS+=("${FBOSS_REPO_RPM_DIR}/${rpm}.spec") | ||
done | ||
fi | ||
|
||
for rpm in "${RPMS[@]}"; do | ||
rpmbuild -bb "${rpm}" | ||
built_rpm=$(find "${RPM_DIR}" -type f -name "$(basename ${rpm%.*})*") | ||
cp -f "${built_rpm}" "${FBOSS_RPM_DIR}" | ||
done |
Oops, something went wrong.