[Mellanox] Facilitate automatic integration of sdk kernel patches (#14652)
#### Why I did it Facilitate Automatic integration of sdk kernel patches into SONiC. **Inputs to the Script:** 1) `MLNX_SDK_VERSION` Eg: `4.5.4206` 2) `MLNX_SDK_ISSU_VERSION` Eg: `101` **Note: If nothing is provided the one already present in the sdk.mk file is used** 3) `MLNX_SDK_SOURCE_BASE_URL:` **Note: If nothing is provided the upstream sdk drivers url is used** 4) `CREATE_BRANCH: (y|n)` Creates a branch instead of a commit (optional, default: n) 5) `BRANCH_SONIC`: Only relevant when CREATE_BRANCH is y. `Default: master`. Note: These should be provided through `SONIC_OVERRIDE_BUILD_VARS ` parameter **Output:** 1) Script creates a commit in sonic-linux-kernel with any updates to sdk-kernel patches in sonic in accordance with the version provided by `MLNX_SDK_VERSION` **Note: Script Doesn't commit anything to linux-kernel when there aren't any changes required..** #### How I did it 1) Added a new make target which can be invoked by calling `make integrate-mlnx-sdk` ``` user@server:/sonic-buildimage/src/sonic-linux-kernel$ git rev-parse --abbrev-ref HEAD master_6f38dca_integrate_4.5.4206 user@server:/sonic-buildimage/src/sonic-linux-kernel$ git log --oneline -n 1 d64d1e7 (HEAD -> master_6f38dca_integrate_4.5.4206) Intgerate MLNX SDK 4.5.4206 Kernel Patches ``` Changes made will be summarized under `sonic-buildimage/integrate-mlnx-sdk_user.out` file. Debugging and troubleshooting output is written to `sonic-buildimage/integrate-mlnx-sdk.log` files [log_files.zip](https://github.com/sonic-net/sonic-buildimage/files/11226441/log_files.zip) #### Limitations: 1) Assumes that the sdk kernel patches are always upstreamed #### How to verify it Build the Kernel and test
This commit is contained in:
parent
220ea74cbb
commit
6852fcdc24
@ -28,7 +28,9 @@ PTCH_LIST = $(TEMP_HW_MGMT_DIR)/series
|
||||
KCFG_LIST = $(TEMP_HW_MGMT_DIR)/kconfig
|
||||
HWMGMT_NONUP_LIST = $(BUILD_WORKDIR)/$($(MLNX_HW_MANAGEMENT)_SRC_PATH)/hwmgmt_nonup_patches
|
||||
HWMGMT_USER_OUTFILE = $(BUILD_WORKDIR)/integrate-mlnx-hw-mgmt_user.out
|
||||
SDK_USER_OUTFILE = $(BUILD_WORKDIR)/integrate-mlnx-sdk_user.out
|
||||
TMPFILE_OUT := $(shell mktemp)
|
||||
SDK_TMPDIR := $(shell mktemp -d)
|
||||
SB_COM_MSG := $(shell mktemp -t sb_commit_msg_file_XXXXX.log)
|
||||
SLK_COM_MSG := $(shell mktemp -t slk_commit_msg_file_XXXXX.log)
|
||||
SB_HEAD = $(shell git rev-parse --short HEAD)
|
||||
@ -140,4 +142,54 @@ endif
|
||||
|
||||
popd $(LOG_SIMPLE)
|
||||
|
||||
SONIC_PHONY_TARGETS += integrate-mlnx-hw-mgmt
|
||||
integrate-mlnx-sdk:
|
||||
$(FLUSH_LOG)
|
||||
rm -rf $(MLNX_SDK_VERSION).zip sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz
|
||||
|
||||
ifeq ($(SDK_FROM_SRC),y)
|
||||
wget $(MLNX_SDK_SOURCE_BASE_URL)/sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz $(LOG_SIMPLE)
|
||||
tar -xf sx_kernel-$(MLNX_SDK_VERSION)-$(MLNX_SDK_ISSU_VERSION).tar.gz --strip-components=1 -C $(SDK_TMPDIR) $(LOG_SIMPLE)
|
||||
else
|
||||
# Download from upstream repository
|
||||
wget $(MLNX_SDK_DRIVERS_GITHUB_URL)/archive/refs/heads/$(MLNX_SDK_VERSION).zip $(LOG_SIMPLE)
|
||||
unzip $(MLNX_SDK_VERSION).zip -d $(SDK_TMPDIR) $(LOG_SIMPLE)
|
||||
mv $(SDK_TMPDIR)/Spectrum-SDK-Drivers-$(MLNX_SDK_VERSION)/* $(SDK_TMPDIR) $(LOG_SIMPLE)
|
||||
endif
|
||||
|
||||
pushd $(BUILD_WORKDIR)/src/sonic-linux-kernel; git clean -f -- patch/; git stash -- patch/
|
||||
ifeq ($(CREATE_BRANCH), y)
|
||||
git checkout -B "$(BRANCH_SONIC)_$(SLK_HEAD)_integrate_$(MLNX_SDK_VERSION)" HEAD
|
||||
echo $(BRANCH_SONIC)_$(SLK_HEAD)_integrate_$(MLNX_SDK_VERSION) branch created in sonic-linux-kernel $(LOG_SIMPLE)
|
||||
endif
|
||||
popd
|
||||
|
||||
echo "#### Integrate SDK $(MLNX_SDK_VERSION) Kernel Patches into SONiC" > ${SDK_USER_OUTFILE}
|
||||
|
||||
pushd $(BUILD_WORKDIR)/$(PLATFORM_PATH) $(LOG_SIMPLE)
|
||||
|
||||
# Run tests
|
||||
pushd integration-scripts/tests; pytest-3 -v; popd
|
||||
|
||||
integration-scripts/sdk_kernel_patches.py \
|
||||
--sonic_kernel_ver $(KERNEL_VERSION) \
|
||||
--patches $(SDK_TMPDIR) \
|
||||
--slk_msg $(SLK_COM_MSG) \
|
||||
--sdk_ver $(MLNX_SDK_VERSION) \
|
||||
--build_root $(BUILD_WORKDIR) $(LOG_SIMPLE)
|
||||
|
||||
# Commit the changes in linux kernel and and log the diff
|
||||
pushd $(BUILD_WORKDIR)/src/sonic-linux-kernel
|
||||
git add -- patch/
|
||||
|
||||
echo -en "\n###-> series file changes in sonic-linux-kernel <-###\n" >> ${SDK_USER_OUTFILE}
|
||||
git diff --no-color --staged -- patch/series >> ${SDK_USER_OUTFILE}
|
||||
|
||||
echo -en "\n###-> summary of files updated in sonic-linux-kernel <-###\n" >> ${SDK_USER_OUTFILE}
|
||||
git diff --no-color --staged --stat >> ${SDK_USER_OUTFILE}
|
||||
|
||||
git diff --staged --quiet || git commit -m "$$(cat $(SLK_COM_MSG))"
|
||||
popd
|
||||
|
||||
popd $(LOG_SIMPLE)
|
||||
|
||||
SONIC_PHONY_TARGETS += integrate-mlnx-hw-mgmt integrate-mlnx-sdk
|
||||
|
@ -21,6 +21,7 @@ import re
|
||||
|
||||
MARK_ID = "###->"
|
||||
MLNX_KFG_MARKER = "mellanox"
|
||||
SDK_MARKER = "mellanox_sdk"
|
||||
HW_MGMT_MARKER = "mellanox_hw_mgmt"
|
||||
SLK_PATCH_LOC = "src/sonic-linux-kernel/patch/"
|
||||
SLK_KCONFIG = SLK_PATCH_LOC + "kconfig-inclusions"
|
||||
@ -30,6 +31,7 @@ NON_UP_PATCH_DIR = "platform/mellanox/non-upstream-patches/"
|
||||
NON_UP_PATCH_LOC = NON_UP_PATCH_DIR + "patches"
|
||||
NON_UP_PATCH_DIFF = NON_UP_PATCH_DIR + "series.patch"
|
||||
KCFG_HDR_RE = "\[(.*)\]"
|
||||
KERNEL_BACKPORTS = "kernel_backports"
|
||||
# kconfig_inclusion headers to consider
|
||||
HDRS = ["common", "amd64"]
|
||||
|
||||
@ -186,3 +188,22 @@ class Action():
|
||||
|
||||
def write_user_out(self):
|
||||
pass
|
||||
|
||||
|
||||
def build_commit_description(changes):
|
||||
if not changes:
|
||||
return ""
|
||||
content = "\n"
|
||||
content = content + " ## Patch List\n"
|
||||
for key, value in changes.items():
|
||||
content = content + f"* {key} : {value}\n"
|
||||
return content
|
||||
|
||||
def parse_id(id_):
|
||||
if id_ and id_ != "N/A":
|
||||
id_ = "https://github.com/torvalds/linux/commit/" + id_
|
||||
|
||||
if id_ == "N/A":
|
||||
id_ = ""
|
||||
|
||||
return id_
|
||||
|
@ -110,14 +110,6 @@ def load_patch_table(path, k_version):
|
||||
table.append(table_line)
|
||||
return table
|
||||
|
||||
def build_commit_description(changes):
|
||||
if not changes:
|
||||
return ""
|
||||
content = "\n"
|
||||
content = content + " ## Patch List\n"
|
||||
for key, value in changes.items():
|
||||
content = content + f"* {key} : {value}\n"
|
||||
return content
|
||||
|
||||
class Data:
|
||||
# list of new upstream patches
|
||||
@ -394,17 +386,12 @@ class PostProcess(HwMgmtAction):
|
||||
old_non_up_patches = [ptch.strip() for ptch in Data.old_non_up]
|
||||
return old_up_patches, old_non_up_patches
|
||||
|
||||
def parse_id(self, id_):
|
||||
if id_:
|
||||
id_ = "https://github.com/gregkh/linux/commit/" + id_
|
||||
return id_
|
||||
|
||||
def create_commit_msg(self, table):
|
||||
title = COMMIT_TITLE.format(self.args.hw_mgmt_ver)
|
||||
changes_slk, changes_sb = {}, {}
|
||||
old_up_patches, old_non_up_patches = self.list_patches()
|
||||
for patch in table:
|
||||
id_ = self.parse_id(patch.get(COMMIT_ID, ""))
|
||||
id_ = parse_id(patch.get(COMMIT_ID, ""))
|
||||
patch_ = patch.get(PATCH_NAME)
|
||||
if patch_ in Data.new_up and patch_ not in old_up_patches:
|
||||
changes_slk[patch_] = id_
|
||||
|
214
platform/mellanox/integration-scripts/sdk_kernel_patches.py
Executable file
214
platform/mellanox/integration-scripts/sdk_kernel_patches.py
Executable file
@ -0,0 +1,214 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
# Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import argparse
|
||||
import copy
|
||||
|
||||
from helper import *
|
||||
|
||||
COMMIT_TITLE = "Integrate SDK {} Kernel Patches"
|
||||
|
||||
DELIMITTER = "========================"
|
||||
|
||||
class Data:
|
||||
# old sonic-linux-kernel series file
|
||||
old_series = list()
|
||||
# updated sonic-linux-kernel series file
|
||||
new_series = list()
|
||||
# list of any new SDK patches to add
|
||||
new_patches = list()
|
||||
# list of current patch list in sonic-linux-kernel
|
||||
old_patches = list()
|
||||
# index of the mlnx_hw_mgmt patches start marker in old_series
|
||||
i_sdk_start = -1
|
||||
# index of the mlnx_hw_mgmt patches end marker in old_series
|
||||
i_sdk_end = -1
|
||||
# kernel directory to consider the patches
|
||||
k_dir = ""
|
||||
|
||||
|
||||
class SDKAction(Action):
|
||||
def __init__(self, args):
|
||||
super().__init__(args)
|
||||
|
||||
def check(self):
|
||||
if not (self.args.patches and os.path.exists(self.args.patches)):
|
||||
print("-> ERR: patch directory is missing ")
|
||||
return False
|
||||
|
||||
if not (self.args.build_root and os.path.exists(self.args.build_root)):
|
||||
print("-> ERR: build_root is missing")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def read_data(self):
|
||||
Data.old_series = FileHandler.read_raw(os.path.join(self.args.build_root, SLK_SERIES))
|
||||
|
||||
def find_sdk_patches(self):
|
||||
for index in range(Data.i_sdk_start+1, Data.i_sdk_end):
|
||||
patch = Data.old_series[index].strip()
|
||||
if patch:
|
||||
Data.old_patches.append(Data.old_series[index].strip())
|
||||
print("-> INFO Current mellanox sdk upstream patches. \n{}".format("\n".join(Data.old_patches)))
|
||||
|
||||
def get_kernel_dir(self):
|
||||
# Get the kernel dir name to get the patches
|
||||
try:
|
||||
(kernel, major, minor) = self.args.sonic_kernel_ver.split(".")
|
||||
minor_int = int(minor)
|
||||
except Exception as e:
|
||||
print("-> FATAL Kernel version formatting error: " + str(e))
|
||||
sys.exit(1)
|
||||
|
||||
major_kernel_path = os.path.join(KERNEL_BACKPORTS, "{}.{}".format(kernel, major))
|
||||
|
||||
# if the k_dir with actual minor doesn't exit, use the closest minor version
|
||||
for minor_i in range(minor_int, 0, -1):
|
||||
path = os.path.join(major_kernel_path, "{}.{}.{}".format(kernel, major, minor_i))
|
||||
if os.path.exists(os.path.join(self.args.patches, path)):
|
||||
minor = str(minor_i)
|
||||
Data.k_dir = path
|
||||
print(f"-> INFO Kernel minor version dir {Data.k_dir} found ")
|
||||
break
|
||||
|
||||
if not Data.k_dir:
|
||||
print("-> Couldn't find the relevant kernel directory")
|
||||
sys.exit(1)
|
||||
|
||||
path_to_check = os.path.join(self.args.patches, Data.k_dir)
|
||||
if not os.path.exists(path_to_check):
|
||||
print("-> FATAL Kernel dir with patches doesn't exist: {}".format(path_to_check))
|
||||
sys.exit(1)
|
||||
|
||||
def update_series(self):
|
||||
# Remove patches if they are already present in existing series file
|
||||
patch_ids_remove = set()
|
||||
for id in range(0, len(Data.old_series)):
|
||||
for patch in Data.new_patches:
|
||||
if patch in Data.old_series[id]:
|
||||
patch_ids_remove.add(id)
|
||||
|
||||
# Modify the series files
|
||||
temp_series = copy.deepcopy(Data.old_series)
|
||||
Data.old_series.clear()
|
||||
for id in range(0, len(temp_series)):
|
||||
if id not in patch_ids_remove:
|
||||
Data.old_series.append(temp_series[id])
|
||||
else:
|
||||
print("-> INFO Patch {} will be removed from the existing series".format(temp_series[id]))
|
||||
print("-> INFO Updated Series file after removing SDK patches: \n{}".format("".join(Data.old_series)))
|
||||
|
||||
def add_new_patch_series(self):
|
||||
new_patches = [patch + "\n" for patch in Data.new_patches]
|
||||
Data.new_series = Data.old_series[0:Data.i_sdk_start+1] + new_patches + Data.old_series[Data.i_sdk_end:]
|
||||
|
||||
def process_update(self):
|
||||
src_path = os.path.join(self.args.patches, Data.k_dir)
|
||||
dst_path = os.path.join(self.args.build_root, SLK_PATCH_LOC)
|
||||
|
||||
for patch in Data.new_patches:
|
||||
print(f"-> Moving patch: {patch}")
|
||||
shutil.copy(os.path.join(src_path, patch), dst_path)
|
||||
|
||||
FileHandler.write_lines(os.path.join(self.args.build_root, SLK_SERIES), Data.new_series, True)
|
||||
print("-> INFO Written sonic-linux-kernel series file \n{}".format("".join(Data.new_series)))
|
||||
|
||||
def get_new_patches(self):
|
||||
patches_path = os.path.join(self.args.patches, Data.k_dir)
|
||||
Data.new_patches = FileHandler.read_dir(patches_path, "*.patch")
|
||||
Data.new_patches.sort()
|
||||
|
||||
def refresh_markers(self):
|
||||
print("-> INFO Refreshing Markers ")
|
||||
(Data.i_sdk_start, Data.i_sdk_end) = FileHandler.find_marker_indices(Data.old_series, SDK_MARKER)
|
||||
if Data.i_sdk_start < 0 or Data.i_sdk_end > len(Data.old_series):
|
||||
print("-> FATAL mellanox_sdk marker not found. Couldn't continue.. exiting")
|
||||
sys.exit(1)
|
||||
print("-> INFO mellanox_sdk markers found. start: {}, end: {}".format(Data.i_sdk_start, Data.i_sdk_end))
|
||||
|
||||
def fetch_patch_table(self, root_dir):
|
||||
lines = FileHandler.read_strip(os.path.join(root_dir, "README"))
|
||||
delim_id = 0
|
||||
for id in range(0, len(lines)):
|
||||
if DELIMITTER in lines[id]:
|
||||
delim_id = id
|
||||
break
|
||||
|
||||
table = dict()
|
||||
for id in range(delim_id+1, len(lines)):
|
||||
tokens = lines[id].split()
|
||||
if len(tokens) != 3:
|
||||
print("-> INFO Error Formatted line, {}".format(" ".join(lines[id])))
|
||||
continue
|
||||
patch, commit = tokens[0], tokens[1]
|
||||
if ".patch" not in patch:
|
||||
print(f"-> INFO Unexpected Patch name {patch}")
|
||||
continue
|
||||
table[patch.strip()] = commit.strip()
|
||||
|
||||
print(f"-> INFO Final Patch Table: {table}")
|
||||
return table
|
||||
|
||||
def create_commit_msg(self, patch_table):
|
||||
changes = {}
|
||||
for patch in Data.new_patches:
|
||||
if patch not in Data.old_patches:
|
||||
changes[patch] = parse_id(patch_table.get(patch.strip(), ""))
|
||||
slk_commit_msg = COMMIT_TITLE.format(self.args.sdk_ver) + "\n" + build_commit_description(changes)
|
||||
print(f"-> INFO Commit Message: {slk_commit_msg}")
|
||||
return slk_commit_msg
|
||||
|
||||
def perform(self):
|
||||
self.read_data()
|
||||
self.refresh_markers()
|
||||
self.find_sdk_patches()
|
||||
self.get_kernel_dir()
|
||||
self.get_new_patches()
|
||||
self.update_series()
|
||||
self.refresh_markers()
|
||||
self.add_new_patch_series()
|
||||
self.process_update()
|
||||
patch_table = self.fetch_patch_table(os.path.join(self.args.patches, Data.k_dir))
|
||||
slk_msg = self.create_commit_msg(patch_table)
|
||||
if self.args.slk_msg:
|
||||
with open(self.args.slk_msg, 'w') as f:
|
||||
f.write(slk_msg)
|
||||
|
||||
|
||||
|
||||
def create_parser():
|
||||
# Create argument parser
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
# Optional arguments
|
||||
parser.add_argument("--sonic_kernel_ver", type=str)
|
||||
parser.add_argument("--patches", type=str)
|
||||
parser.add_argument("--slk_msg", type=str)
|
||||
parser.add_argument("--sdk_ver", type=str)
|
||||
parser.add_argument("--build_root", type=str)
|
||||
return parser
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = create_parser()
|
||||
action = SDKAction(parser.parse_args())
|
||||
action.check()
|
||||
action.perform()
|
@ -54,15 +54,15 @@ NEW_UP_LIST = """\
|
||||
TEST_SLK_COMMIT = """\
|
||||
Intgerate HW-MGMT 7.0030.0937 Changes
|
||||
## Patch List
|
||||
* 0002-i2c-mlxcpld-Decrease-polling-time-for-performance-im.patch : https://github.com/gregkh/linux/commit/cb9744178f33
|
||||
* 0003-i2c-mlxcpld-Add-support-for-I2C-bus-frequency-settin.patch : https://github.com/gregkh/linux/commit/66b0c2846ba8
|
||||
* 0005-i2c-mux-mlxcpld-Move-header-file-out-of-x86-realm.patch : https://github.com/gregkh/linux/commit/98d29c410475
|
||||
* 0006-i2c-mux-mlxcpld-Convert-driver-to-platform-driver.patch : https://github.com/gregkh/linux/commit/84af1b168c50
|
||||
* 0007-i2c-mux-mlxcpld-Prepare-mux-selection-infrastructure.patch : https://github.com/gregkh/linux/commit/81566938083a
|
||||
* 0008-i2c-mux-mlxcpld-Get-rid-of-adapter-numbers-enforceme.patch : https://github.com/gregkh/linux/commit/cae5216387d1
|
||||
* 0009-i2c-mux-mlxcpld-Extend-driver-to-support-word-addres.patch : https://github.com/gregkh/linux/commit/c52a1c5f5db5
|
||||
* 0010-i2c-mux-mlxcpld-Extend-supported-mux-number.patch : https://github.com/gregkh/linux/commit/699c0506543e
|
||||
* 0011-i2c-mux-mlxcpld-Add-callback-to-notify-mux-creation-.patch : https://github.com/gregkh/linux/commit/a39bd92e92b9
|
||||
* 0002-i2c-mlxcpld-Decrease-polling-time-for-performance-im.patch : https://github.com/torvalds/linux/commit/cb9744178f33
|
||||
* 0003-i2c-mlxcpld-Add-support-for-I2C-bus-frequency-settin.patch : https://github.com/torvalds/linux/commit/66b0c2846ba8
|
||||
* 0005-i2c-mux-mlxcpld-Move-header-file-out-of-x86-realm.patch : https://github.com/torvalds/linux/commit/98d29c410475
|
||||
* 0006-i2c-mux-mlxcpld-Convert-driver-to-platform-driver.patch : https://github.com/torvalds/linux/commit/84af1b168c50
|
||||
* 0007-i2c-mux-mlxcpld-Prepare-mux-selection-infrastructure.patch : https://github.com/torvalds/linux/commit/81566938083a
|
||||
* 0008-i2c-mux-mlxcpld-Get-rid-of-adapter-numbers-enforceme.patch : https://github.com/torvalds/linux/commit/cae5216387d1
|
||||
* 0009-i2c-mux-mlxcpld-Extend-driver-to-support-word-addres.patch : https://github.com/torvalds/linux/commit/c52a1c5f5db5
|
||||
* 0010-i2c-mux-mlxcpld-Extend-supported-mux-number.patch : https://github.com/torvalds/linux/commit/699c0506543e
|
||||
* 0011-i2c-mux-mlxcpld-Add-callback-to-notify-mux-creation-.patch : https://github.com/torvalds/linux/commit/a39bd92e92b9
|
||||
|
||||
"""
|
||||
|
||||
|
300
platform/mellanox/integration-scripts/tests/test_sdkaction.py
Normal file
300
platform/mellanox/integration-scripts/tests/test_sdkaction.py
Normal file
@ -0,0 +1,300 @@
|
||||
#
|
||||
# Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
# Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import sys
|
||||
from unittest import mock, TestCase
|
||||
from pyfakefs.fake_filesystem_unittest import Patcher
|
||||
sys.path.append('../')
|
||||
from sdk_kernel_patches import *
|
||||
|
||||
MOCK_SLK_SERIES = """\
|
||||
# Trtnetlink-catch-EOPNOTSUPP-errors.patch
|
||||
|
||||
# Mellanox patches for 5.10
|
||||
###-> mellanox_sdk-start
|
||||
###-> mellanox_sdk-end
|
||||
|
||||
###-> mellanox_hw_mgmt-start
|
||||
0001-i2c-mlxcpld-Update-module-license.patch
|
||||
###-> mellanox_hw_mgmt-end
|
||||
|
||||
0001-psample-Encapsulate-packet-metadata-in-a-struct.patch
|
||||
0002-psample-Add-additional-metadata-attributes.patch
|
||||
#####
|
||||
"""
|
||||
|
||||
EXP_SLK_SERIES_STG1 = """\
|
||||
# Trtnetlink-catch-EOPNOTSUPP-errors.patch
|
||||
|
||||
# Mellanox patches for 5.10
|
||||
###-> mellanox_sdk-start
|
||||
###-> mellanox_sdk-end
|
||||
|
||||
###-> mellanox_hw_mgmt-start
|
||||
0001-i2c-mlxcpld-Update-module-license.patch
|
||||
###-> mellanox_hw_mgmt-end
|
||||
|
||||
#####
|
||||
"""
|
||||
|
||||
MOCK_SLK_SERIES_1 = """\
|
||||
# Trtnetlink-catch-EOPNOTSUPP-errors.patch
|
||||
|
||||
# Mellanox patches for 5.10
|
||||
###-> mellanox_sdk-start
|
||||
0001-psample-Encapsulate-packet-metadata-in-a-struct.patch
|
||||
###-> mellanox_sdk-end
|
||||
|
||||
###-> mellanox_hw_mgmt-start
|
||||
0001-i2c-mlxcpld-Update-module-license.patch
|
||||
###-> mellanox_hw_mgmt-end
|
||||
|
||||
#####
|
||||
"""
|
||||
|
||||
MOCK_FINAL_SLK_SERIES = """\
|
||||
# Trtnetlink-catch-EOPNOTSUPP-errors.patch
|
||||
|
||||
# Mellanox patches for 5.10
|
||||
###-> mellanox_sdk-start
|
||||
0001-psample-Encapsulate-packet-metadata-in-a-struct.patch
|
||||
0002-psample-Add-additional-metadata-attributes.patch
|
||||
0003-psample-define-the-macro-PSAMPLE_MD_EXTENDED_ATTR.patch
|
||||
0004-new-sdk-driver-change-1.patch
|
||||
0005-new-sdk-driver-change-1.patch
|
||||
###-> mellanox_sdk-end
|
||||
|
||||
###-> mellanox_hw_mgmt-start
|
||||
0001-i2c-mlxcpld-Update-module-license.patch
|
||||
###-> mellanox_hw_mgmt-end
|
||||
|
||||
#####
|
||||
"""
|
||||
|
||||
PTCH_LIST = ["0001-psample-Encapsulate-packet-metadata-in-a-struct.patch", \
|
||||
"0002-psample-Add-additional-metadata-attributes.patch"]
|
||||
|
||||
EXT_PTCH_LIST = ["0003-psample-define-the-macro-PSAMPLE_MD_EXTENDED_ATTR.patch", \
|
||||
"0004-new-sdk-driver-change-1.patch", \
|
||||
"0005-new-sdk-driver-change-1.patch"]
|
||||
|
||||
MOCK_SLK_VER = "5.10.104"
|
||||
|
||||
MOCK_README = """\
|
||||
Copy the whole directory which contains this README to some folder on the machine where you plan to build the linux kernel,
|
||||
then execute "./apply_patches_example.sh -d <your_linux_kernel_source_folder>".
|
||||
|
||||
Patch Upstream-Commit From-Kernel-Version
|
||||
==========================================================================================================================================
|
||||
0001-psample-Encapsulate-packet-metadata-in-a-struct.patch a03e99d39f1943ec88f6fd3b0b9f34c20663d401 5.13
|
||||
0002-psample-Add-additional-metadata-attributes.patch 07e1a5809b595df6e125504dff6245cb2c8ed3de 5.13
|
||||
0003-psample-define-the-macro-PSAMPLE_MD_EXTENDED_ATTR.patch N/A N/A
|
||||
wrong-patch-name Whatevrr rqrwf vwvwvrvrv
|
||||
==================================================
|
||||
"""
|
||||
|
||||
TEST_SLK_COMMIT = """\
|
||||
Integrate SDK 4.5.1000 Kernel Patches
|
||||
|
||||
## Patch List
|
||||
* 0001-psample-Encapsulate-packet-metadata-in-a-struct.patch : https://github.com/torvalds/linux/commit/a03e99d39f1943ec88f6fd3b0b9f34c20663d401
|
||||
* 0002-psample-Add-additional-metadata-attributes.patch : https://github.com/torvalds/linux/commit/07e1a5809b595df6e125504dff6245cb2c8ed3de
|
||||
* 0003-psample-define-the-macro-PSAMPLE_MD_EXTENDED_ATTR.patch :
|
||||
"""
|
||||
|
||||
LINES_READ = ""
|
||||
|
||||
def mock_sdk_args():
|
||||
with mock.patch("sys.argv", ["sdk_kernel_patches.py",
|
||||
"--sonic_kernel_ver", MOCK_SLK_VER,
|
||||
"--patches", "/tmp",
|
||||
"--sdk_ver", "4.5.1000",
|
||||
"--slk_msg", "/tmp/slk-commit-msg.hgsdhg",
|
||||
"--build_root", "/sonic"]):
|
||||
parser = create_parser()
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def check_lists(exp, rec):
|
||||
print(" ------- Expected ----------- ")
|
||||
print("".join(exp))
|
||||
print("Size: {}".format(len(exp)))
|
||||
print(" ------- Recieved ----------- ")
|
||||
print("".join(rec))
|
||||
print("Size: {}".format(len(rec)))
|
||||
if len(exp) != len(rec):
|
||||
return False
|
||||
for i in range(0, len(exp)):
|
||||
if exp[i] != rec[i]:
|
||||
return False
|
||||
return True
|
||||
|
||||
def read_strip_mock(path, as_string=False):
|
||||
global LINES_READ
|
||||
return LINES_READ
|
||||
|
||||
class TestSDKAction(TestCase):
|
||||
def setUp(self):
|
||||
self.action = SDKAction(mock_sdk_args())
|
||||
self.action.check()
|
||||
self.path_kernel = os.path.join(KERNEL_BACKPORTS, "5.10")
|
||||
self.patcher = Patcher()
|
||||
self.patcher.setUp()
|
||||
|
||||
def tearDown(self):
|
||||
Data.new_series = list()
|
||||
Data.new_patches = list()
|
||||
Data.old_series = list()
|
||||
Data.old_patches = list()
|
||||
Data.k_dir = ""
|
||||
Data.i_sdk_start = -1
|
||||
Data.i_sdk_end = -1
|
||||
self.patcher.tearDown()
|
||||
global LINES_READ
|
||||
LINES_READ = ""
|
||||
|
||||
def create_files(self, root_dir, lis):
|
||||
for file in lis:
|
||||
self.patcher.fs.create_file(os.path.join(root_dir, file))
|
||||
|
||||
def test_get_kernel_dir_1(self):
|
||||
dir_ = os.path.join(self.path_kernel, MOCK_SLK_VER)
|
||||
self.patcher.fs.create_dir(os.path.join("/tmp", dir_))
|
||||
self.action.get_kernel_dir()
|
||||
assert dir_ == Data.k_dir
|
||||
|
||||
def test_get_kernel_dir_2(self):
|
||||
dir_ = os.path.join(self.path_kernel, "5.10.99")
|
||||
self.patcher.fs.create_dir(os.path.join("/tmp", dir_))
|
||||
self.action.get_kernel_dir()
|
||||
assert dir_ == Data.k_dir
|
||||
|
||||
dir_2 = os.path.join(self.path_kernel, "5.10.105")
|
||||
self.patcher.fs.create_dir(os.path.join("/tmp", dir_2))
|
||||
self.action.get_kernel_dir()
|
||||
assert dir_ == Data.k_dir
|
||||
|
||||
def test_find_sdk_patches(self):
|
||||
Data.old_series = MOCK_SLK_SERIES.splitlines(True)
|
||||
self.action.refresh_markers()
|
||||
self.action.find_sdk_patches()
|
||||
assert "mellanox_sdk-start" in Data.old_series[Data.i_sdk_start]
|
||||
assert "mellanox_sdk-end" in Data.old_series[Data.i_sdk_end]
|
||||
assert not Data.old_patches
|
||||
|
||||
Data.old_series = MOCK_SLK_SERIES_1.splitlines(True)
|
||||
self.action.refresh_markers()
|
||||
self.action.find_sdk_patches()
|
||||
assert "mellanox_sdk-start" in Data.old_series[Data.i_sdk_start]
|
||||
assert "mellanox_sdk-end" in Data.old_series[Data.i_sdk_end]
|
||||
assert len(Data.old_patches) == 1
|
||||
assert Data.old_patches[-1] == "0001-psample-Encapsulate-packet-metadata-in-a-struct.patch"
|
||||
|
||||
def test_get_new_patches(self):
|
||||
root_dir = "/tmp/kernel_backports/5.10/5.10.27"
|
||||
self.create_files(root_dir, PTCH_LIST)
|
||||
self.action.get_kernel_dir()
|
||||
print(Data.k_dir)
|
||||
self.action.get_new_patches()
|
||||
assert len(Data.new_patches) == 2
|
||||
assert Data.new_patches[0] == "0001-psample-Encapsulate-packet-metadata-in-a-struct.patch"
|
||||
assert Data.new_patches[1] == "0002-psample-Add-additional-metadata-attributes.patch"
|
||||
|
||||
def test_update_series(self):
|
||||
root_dir = "/tmp/kernel_backports/5.10/5.10.27"
|
||||
self.create_files(root_dir, PTCH_LIST)
|
||||
Data.old_series = MOCK_SLK_SERIES.splitlines(True)
|
||||
self.action.refresh_markers()
|
||||
self.action.find_sdk_patches()
|
||||
self.action.get_kernel_dir()
|
||||
self.action.get_new_patches()
|
||||
self.action.update_series()
|
||||
assert check_lists(EXP_SLK_SERIES_STG1.splitlines(True), Data.old_series)
|
||||
self.action.refresh_markers()
|
||||
assert "mellanox_sdk-start" in Data.old_series[Data.i_sdk_start]
|
||||
assert "mellanox_sdk-end" in Data.old_series[Data.i_sdk_end]
|
||||
|
||||
def test_update_series_1(self):
|
||||
root_dir = "/tmp/kernel_backports/5.10/5.10.27"
|
||||
self.create_files(root_dir, PTCH_LIST)
|
||||
Data.old_series = MOCK_SLK_SERIES_1.splitlines(True)
|
||||
self.action.refresh_markers()
|
||||
self.action.find_sdk_patches()
|
||||
self.action.get_kernel_dir()
|
||||
self.action.get_new_patches()
|
||||
self.action.update_series()
|
||||
assert check_lists(EXP_SLK_SERIES_STG1.splitlines(True), Data.old_series)
|
||||
self.action.refresh_markers()
|
||||
assert "mellanox_sdk-start" in Data.old_series[Data.i_sdk_start]
|
||||
assert "mellanox_sdk-end" in Data.old_series[Data.i_sdk_end]
|
||||
|
||||
def test_process_patches_1(self):
|
||||
root_dir = "/tmp/kernel_backports/5.10/5.10.27"
|
||||
self.create_files(root_dir, PTCH_LIST)
|
||||
self.create_files(root_dir, EXT_PTCH_LIST)
|
||||
Data.old_series = MOCK_SLK_SERIES.splitlines(True)
|
||||
self.action.refresh_markers()
|
||||
self.action.find_sdk_patches()
|
||||
self.action.get_kernel_dir()
|
||||
self.action.get_new_patches()
|
||||
self.action.update_series()
|
||||
self.action.refresh_markers()
|
||||
self.action.add_new_patch_series()
|
||||
assert check_lists(MOCK_FINAL_SLK_SERIES.splitlines(True), Data.new_series)
|
||||
|
||||
def test_process_patches_2(self):
|
||||
root_dir = "/tmp/kernel_backports/5.10/5.10.27"
|
||||
self.create_files(root_dir, PTCH_LIST)
|
||||
self.create_files(root_dir, EXT_PTCH_LIST)
|
||||
Data.old_series = MOCK_SLK_SERIES_1.splitlines(True)
|
||||
self.action.refresh_markers()
|
||||
self.action.find_sdk_patches()
|
||||
self.action.get_kernel_dir()
|
||||
self.action.get_new_patches()
|
||||
self.action.update_series()
|
||||
self.action.refresh_markers()
|
||||
self.action.add_new_patch_series()
|
||||
assert check_lists(MOCK_FINAL_SLK_SERIES.splitlines(True), Data.new_series)
|
||||
|
||||
@mock.patch('helper.FileHandler.read_strip', side_effect=read_strip_mock)
|
||||
def test_patch_table(self, mock_read_strip_mock):
|
||||
global LINES_READ
|
||||
LINES_READ = MOCK_README.splitlines()
|
||||
table = self.action.fetch_patch_table("")
|
||||
assert "0001-psample-Encapsulate-packet-metadata-in-a-struct.patch" in table
|
||||
assert "0002-psample-Add-additional-metadata-attributes.patch" in table
|
||||
assert "0003-psample-define-the-macro-PSAMPLE_MD_EXTENDED_ATTR.patch" in table
|
||||
assert table["0001-psample-Encapsulate-packet-metadata-in-a-struct.patch"] == "a03e99d39f1943ec88f6fd3b0b9f34c20663d401"
|
||||
assert table["0002-psample-Add-additional-metadata-attributes.patch"] == "07e1a5809b595df6e125504dff6245cb2c8ed3de"
|
||||
assert table["0003-psample-define-the-macro-PSAMPLE_MD_EXTENDED_ATTR.patch"] == "N/A"
|
||||
|
||||
@mock.patch('helper.FileHandler.read_strip', side_effect=read_strip_mock)
|
||||
def test_commit_msg(self, mock_read_strip_mock):
|
||||
global LINES_READ
|
||||
LINES_READ = MOCK_README.splitlines()
|
||||
root_dir = "/tmp/kernel_backports/5.10/5.10.27"
|
||||
self.create_files(root_dir, PTCH_LIST)
|
||||
self.create_files(root_dir, ["0003-psample-define-the-macro-PSAMPLE_MD_EXTENDED_ATTR.patch"])
|
||||
Data.old_series = MOCK_SLK_SERIES.splitlines(True)
|
||||
self.action.refresh_markers()
|
||||
self.action.find_sdk_patches()
|
||||
self.action.get_kernel_dir()
|
||||
self.action.get_new_patches()
|
||||
table = self.action.fetch_patch_table("")
|
||||
msg = self.action.create_commit_msg(table)
|
||||
print(msg)
|
||||
assert check_lists(TEST_SLK_COMMIT.splitlines(True), msg.splitlines(True))
|
@ -5,7 +5,7 @@ MAIN_TARGET = sx-kernel_1.mlnx.$(MLNX_SDK_DEB_VERSION)_$(CONFIGURED_ARCH).deb
|
||||
DERIVED_TARGETS = sx-kernel-dev_1.mlnx.$(MLNX_SDK_DEB_VERSION)_$(CONFIGURED_ARCH).deb
|
||||
PACKAGE_NAME = sx_kernel
|
||||
|
||||
MLNX_SX_KERNEL_GITHUB_URL_BASE = https://github.com/Mellanox/Spectrum-SDK-Drivers/archive/refs/heads
|
||||
MLNX_SX_KERNEL_GITHUB_URL_BASE = $(MLNX_SDK_DRIVERS_GITHUB_URL)/archive/refs/heads
|
||||
|
||||
$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
|
||||
# get sources
|
||||
|
@ -17,6 +17,7 @@
|
||||
MLNX_SDK_VERSION = 4.5.5142
|
||||
MLNX_SDK_ISSU_VERSION = 101
|
||||
|
||||
MLNX_SDK_DRIVERS_GITHUB_URL = https://github.com/Mellanox/Spectrum-SDK-Drivers
|
||||
MLNX_ASSETS_GITHUB_URL = https://github.com/Mellanox/Spectrum-SDK-Drivers-SONiC-Bins
|
||||
MLNX_SDK_ASSETS_RELEASE_TAG = sdk-$(MLNX_SDK_VERSION)-$(BLDENV)-$(CONFIGURED_ARCH)
|
||||
MLNX_SDK_ASSETS_URL = $(MLNX_ASSETS_GITHUB_URL)/releases/download/$(MLNX_SDK_ASSETS_RELEASE_TAG)
|
||||
@ -31,7 +32,7 @@ else
|
||||
SDK_FROM_SRC = n
|
||||
endif
|
||||
|
||||
export MLNX_SDK_SOURCE_BASE_URL MLNX_SDK_VERSION MLNX_SDK_ISSU_VERSION MLNX_SDK_DEB_VERSION MLNX_ASSETS_GITHUB_URL
|
||||
export MLNX_SDK_SOURCE_BASE_URL MLNX_SDK_VERSION MLNX_SDK_ISSU_VERSION MLNX_SDK_DEB_VERSION MLNX_ASSETS_GITHUB_URL MLNX_SDK_DRIVERS_GITHUB_URL
|
||||
|
||||
MLNX_SDK_RDEBS += $(APPLIBS) $(SX_COMPLIB) $(SX_EXAMPLES) \
|
||||
$(SX_GEN_UTILS) $(SX_SCEW) $(SXD_LIBS) $(WJH_LIBS) $(SX_ACL_HELPER) \
|
||||
|
Reference in New Issue
Block a user