Skip to content

Commit

Permalink
Merge pull request facebook#2 from adamcalabrigo/arista-build-tools
Browse files Browse the repository at this point in the history
Adds arista directory w/build + packaging tools and platform scripts
  • Loading branch information
adamcalabrigo authored Feb 7, 2023
2 parents 7b35f6a + 801e6dd commit d1534ba
Show file tree
Hide file tree
Showing 21 changed files with 2,928 additions and 0 deletions.
97 changes: 97 additions & 0 deletions arista/README.md
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.
235 changes: 235 additions & 0 deletions arista/build-utils/build.sh
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
30 changes: 30 additions & 0 deletions arista/build-utils/package.sh
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
Loading

0 comments on commit d1534ba

Please sign in to comment.