From f70149933c5110f65ccf7d589a7d70781fe111a8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Feb 2025 10:47:33 +0000 Subject: [PATCH 01/12] Use getConnection() to allow build on localhost Depending on the passed IP addr/host name, getConnection() will select the right LocalCmd/RemoteCmd, which is better than hardcoded. --- ci-scripts/cls_containerize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index b1c5120097..5ab0e8f795 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -359,7 +359,7 @@ class Containerize(): svr = self.eNB_serverId[self.eNB_instance] lIpAddr, lSourcePath = self.GetCredentials(svr) logging.debug('Building on server: ' + lIpAddr) - cmd = cls_cmd.RemoteCmd(lIpAddr) + cmd = cls_cmd.getConnection(lIpAddr) # Checking the hostname to get adapted on cli and dockerfileprefixes cmd.run('hostnamectl') From 4ed801dce3bab19a26eecf7740c5524d3862be15 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Feb 2025 15:39:49 +0100 Subject: [PATCH 02/12] Add correct T_headers dependencies T_headers needs to ensure that T headers have actually been created. This can be forced by depending on generate_T. --- common/utils/T/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/CMakeLists.txt b/common/utils/T/CMakeLists.txt index 01dda120ca..5425a564b1 100644 --- a/common/utils/T/CMakeLists.txt +++ b/common/utils/T/CMakeLists.txt @@ -49,7 +49,7 @@ add_custom_target(generate_T DEPENDS T_IDs.h check_vcd) # headers have really been created, we make this headers library explicitly # depend on the generated headers. add_library(T_headers INTERFACE) -add_dependencies(T_headers T_IDs.h T_messages.txt.h) +add_dependencies(T_headers T_IDs.h generate_T) target_include_directories(T_headers INTERFACE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) if(T_TRACER) From 252c9db24660284cb1e1ddc2148e03f2806a84b7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Feb 2025 11:01:20 +0000 Subject: [PATCH 03/12] Correctly express dependency on LOG headers Various libraries in this commit use the log headers (that is the direct dependency). The log headers in turn include the T headers (transitive dependency). Building on gracehopper with its many cores triggers the build of these libraries before T headers have been generated. To resolve this and force the generation of T headers before building the libraries, correctly express their dependency on the log headers, which in turn ensures that T headers have been generated. Depending on log_headers is preferrable because it is really the headers that we depend on. Using instead e.g., utils, would trigger build of source files, that we don't need for these libraries. This commit is part of a larger cleanup that I have that is not merged yet. Follow-up work will generalize this in the repo, and ensure that every(!) library builds. We have to add CONFIG_LIB, as the log module has a direct dependency onto the configuration module (it uses it). I am not sure why this was not relevant before. --- common/utils/LOG/CMakeLists.txt | 7 ++++++- openair1/PHY/CODING/CMakeLists.txt | 2 ++ openair3/NAS/COMMON/IES/CMakeLists.txt | 1 + openair3/NAS/COMMON/UTIL/CMakeLists.txt | 1 + openair3/NAS/NR_UE/5GS/5GMM/IES/CMakeLists.txt | 5 +++-- openair3/NAS/NR_UE/5GS/5GSM/MSG/CMakeLists.txt | 2 +- openair3/NAS/UE/API/USIM/CMakeLists.txt | 1 + openair3/UICC/CMakeLists.txt | 1 + 8 files changed, 16 insertions(+), 4 deletions(-) diff --git a/common/utils/LOG/CMakeLists.txt b/common/utils/LOG/CMakeLists.txt index c525969015..ff224329de 100644 --- a/common/utils/LOG/CMakeLists.txt +++ b/common/utils/LOG/CMakeLists.txt @@ -1,10 +1,15 @@ +add_library(log_headers INTERFACE) +target_include_directories(log_headers INTERFACE .) +target_link_libraries(log_headers INTERFACE T_headers) + set(log_sources log.c) if (ENABLE_LTTNG) set(log_sources ${log_sources} lttng-tp.c) endif() add_library(LOG ${log_sources}) target_include_directories(LOG PUBLIC .) -target_link_libraries(LOG PRIVATE ${T_LIB}) +target_link_libraries(LOG PRIVATE CONFIG_LIB) +target_link_libraries(LOG PUBLIC log_headers) if (ENABLE_LTTNG) target_link_libraries(LOG PUBLIC lttng-ust) endif() diff --git a/openair1/PHY/CODING/CMakeLists.txt b/openair1/PHY/CODING/CMakeLists.txt index e4e8d43a95..4eee35a2cd 100644 --- a/openair1/PHY/CODING/CMakeLists.txt +++ b/openair1/PHY/CODING/CMakeLists.txt @@ -7,6 +7,8 @@ add_library(coding MODULE 3gpplte_turbo_decoder.c ) set_target_properties(coding PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) +#ensure that the T header files are generated before targets depending on them +target_link_libraries(coding PRIVATE log_headers) add_library(ldpc_orig MODULE nrLDPC_decoder/nrLDPC_decoder.c diff --git a/openair3/NAS/COMMON/IES/CMakeLists.txt b/openair3/NAS/COMMON/IES/CMakeLists.txt index 67cc9d782a..dd10fe3018 100644 --- a/openair3/NAS/COMMON/IES/CMakeLists.txt +++ b/openair3/NAS/COMMON/IES/CMakeLists.txt @@ -4,3 +4,4 @@ add_library(nas_common_ies_lib OBJECT ) target_include_directories(nas_common_ies_lib PUBLIC .) +target_link_libraries(nas_common_ies_lib PUBLIC log_headers) diff --git a/openair3/NAS/COMMON/UTIL/CMakeLists.txt b/openair3/NAS/COMMON/UTIL/CMakeLists.txt index dc29dff207..0947e80991 100644 --- a/openair3/NAS/COMMON/UTIL/CMakeLists.txt +++ b/openair3/NAS/COMMON/UTIL/CMakeLists.txt @@ -2,5 +2,6 @@ add_library(nas_utils OBJECT TLVDecoder.c OctetString.c ) +target_link_libraries(nas_utils PUBLIC log_headers) target_include_directories(nas_utils PRIVATE .) diff --git a/openair3/NAS/NR_UE/5GS/5GMM/IES/CMakeLists.txt b/openair3/NAS/NR_UE/5GS/5GMM/IES/CMakeLists.txt index 24ed3022a6..e865dd0046 100644 --- a/openair3/NAS/NR_UE/5GS/5GMM/IES/CMakeLists.txt +++ b/openair3/NAS/NR_UE/5GS/5GMM/IES/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(fgs_5gmm_ies_lib OBJECT SORTransparentContainer.c ) -target_link_libraries(fgs_5gmm_ies_lib PUBLIC - nas_common_ies_lib +target_link_libraries(fgs_5gmm_ies_lib + PUBLIC nas_common_ies_lib + PRIVATE log_headers ) diff --git a/openair3/NAS/NR_UE/5GS/5GSM/MSG/CMakeLists.txt b/openair3/NAS/NR_UE/5GS/5GSM/MSG/CMakeLists.txt index 1630a48222..de75e7157f 100644 --- a/openair3/NAS/NR_UE/5GS/5GSM/MSG/CMakeLists.txt +++ b/openair3/NAS/NR_UE/5GS/5GSM/MSG/CMakeLists.txt @@ -1,6 +1,6 @@ add_library(fgs_5gsm_lib OBJECT PduSessionEstablishRequest.c PduSessionEstablishmentAccept.c) -target_link_libraries(fgs_5gsm_lib PUBLIC nas_common_ies_lib) +target_link_libraries(fgs_5gsm_lib PUBLIC nas_common_ies_lib log_headers) target_include_directories(fgs_5gsm_lib PUBLIC . ../../) diff --git a/openair3/NAS/UE/API/USIM/CMakeLists.txt b/openair3/NAS/UE/API/USIM/CMakeLists.txt index 90a9cb40fe..63ae905461 100644 --- a/openair3/NAS/UE/API/USIM/CMakeLists.txt +++ b/openair3/NAS/UE/API/USIM/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(usim_lib OBJECT aka_functions.c usim_api.c ) +target_link_libraries(usim_lib PRIVATE log_headers) target_include_directories(usim_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/openair3/UICC/CMakeLists.txt b/openair3/UICC/CMakeLists.txt index 0570c7238f..c80694e1a5 100644 --- a/openair3/UICC/CMakeLists.txt +++ b/openair3/UICC/CMakeLists.txt @@ -1,2 +1,3 @@ add_library(lib_uicc OBJECT usim_interface.c) target_include_directories(lib_uicc PRIVATE .) +target_link_libraries(lib_uicc PRIVATE log_headers) From 8cbfa7b797e61b38f17021ff5419a3ac0f99890b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 28 Feb 2025 13:32:11 +0000 Subject: [PATCH 04/12] Use absolute path for copy Local_Cmd forces use to use absolute paths for copy operations (because that makes more clear where files are being copied). Use the absolute path to avoid the corresponding exception. --- ci-scripts/cls_containerize.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 5ab0e8f795..6c63703d74 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -93,7 +93,7 @@ def CopyLogsToExecutor(cmd, sourcePath, log_name): os.remove(f'./{log_name}.zip') if (os.path.isdir(f'./{log_name}')): shutil.rmtree(f'./{log_name}') - cmd.copyin(f'{sourcePath}/cmake_targets/{log_name}.zip', f'./{log_name}.zip') + cmd.copyin(src=f'{sourcePath}/cmake_targets/{log_name}.zip', tgt=f'{os.getcwd()}/{log_name}.zip') cmd.run(f'rm -f {log_name}.zip') ZipFile(f'{log_name}.zip').extractall('.') From 677a904b6ccd00f659a0ef97f801cc7d2eb847de Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 28 Feb 2025 14:21:10 +0000 Subject: [PATCH 05/12] Avoid x86-specific Dockerfiles/enable ARM Dockerfiles hardcoded one copy operation to x86; generalize to capture ARM as well. Since the target directory cannot have any globs, we need to manually check the right directory, then move the file. Note that this is only necessary since we are forced to switch the compiler, as Ubuntu's default gcc-11 does not work with FlexRIC. When upgrading to Ubuntu 24, these lines should disappear and asan be installed as normal. See commit 94497435e738 ("Upgrade CI images to Ubuntu 22"). --- docker/Dockerfile.gNB.ubuntu22 | 13 ++++++++++++- docker/Dockerfile.nr-cuup.ubuntu22 | 13 ++++++++++++- docker/Dockerfile.nrUE.ubuntu22 | 13 ++++++++++++- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/docker/Dockerfile.gNB.ubuntu22 b/docker/Dockerfile.gNB.ubuntu22 index 35e442f93d..da2074c64b 100644 --- a/docker/Dockerfile.gNB.ubuntu22 +++ b/docker/Dockerfile.gNB.ubuntu22 @@ -77,7 +77,18 @@ RUN apt-get update && \ # library version. Installing it above would install the wrong version. Hence, # copy the right version from ran-build. When upgrading to Ubuntu24, install # the correct one above! -COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libasan.so.8.0.0 /usr/lib/x86_64-linux-gnu/ +# note: this dockerfile should work for both x86 and arm, hence the glob below +# which should either match "x86_64" (x86) or "aarch64" (ARM); since the target +# directory needs to be also one of those two, but globs don't work in target +# directories, work around this with mv +COPY --from=gnb-build /usr/lib/*-linux-gnu/libasan.so.8.0.0 /usr/lib/ +ARG TARGETPLATFORM +RUN case "${TARGETPLATFORM}" in \ + "linux/amd64") TARGET_DIR=x86_64-linux-gnu ;; \ + "linux/arm64") TARGET_DIR=aarch64-linux-gnu ;; \ + *) exit 1 ;; \ + esac; \ + mv /usr/lib/libasan.so.8.0.0 /usr/lib/$TARGET_DIR/libasan.so.8.0.0 WORKDIR /opt/oai-gnb/bin COPY --from=gnb-build \ diff --git a/docker/Dockerfile.nr-cuup.ubuntu22 b/docker/Dockerfile.nr-cuup.ubuntu22 index 242fac61b8..2952afa34b 100644 --- a/docker/Dockerfile.nr-cuup.ubuntu22 +++ b/docker/Dockerfile.nr-cuup.ubuntu22 @@ -54,7 +54,18 @@ RUN apt-get update && \ # library version. Installing it above would install the wrong version. Hence, # copy the right version from ran-build. When upgrading to Ubuntu24, install # the correct one above! -COPY --from=gnb-build /usr/lib/x86_64-linux-gnu/libasan.so.8.0.0 /usr/lib/x86_64-linux-gnu/ +# note: this dockerfile should work for both x86 and arm, hence the glob below +# which should either match "x86_64" (x86) or "aarch64" (ARM); since the target +# directory needs to be also one of those two, but globs don't work in target +# directories, work around this with mv +COPY --from=gnb-build /usr/lib/*-linux-gnu/libasan.so.8.0.0 /usr/lib/ +ARG TARGETPLATFORM +RUN case "${TARGETPLATFORM}" in \ + "linux/amd64") TARGET_DIR=x86_64-linux-gnu ;; \ + "linux/arm64") TARGET_DIR=aarch64-linux-gnu ;; \ + *) exit 1 ;; \ + esac; \ + mv /usr/lib/libasan.so.8.0.0 /usr/lib/$TARGET_DIR/libasan.so.8.0.0 ## Copy E2 SM models COPY --from=gnb-build /usr/local/lib/flexric /usr/local/lib/flexric diff --git a/docker/Dockerfile.nrUE.ubuntu22 b/docker/Dockerfile.nrUE.ubuntu22 index dc0d425956..45ad4bbe03 100644 --- a/docker/Dockerfile.nrUE.ubuntu22 +++ b/docker/Dockerfile.nrUE.ubuntu22 @@ -77,7 +77,18 @@ RUN apt-get update && \ # library version. Installing it above would install the wrong version. Hence, # copy the right version from ran-build. When upgrading to Ubuntu24, install # the correct one above! -COPY --from=nr-ue-build /usr/lib/x86_64-linux-gnu/libasan.so.8.0.0 /usr/lib/x86_64-linux-gnu/ +# note: this dockerfile should work for both x86 and arm, hence the glob below +# which should either match "x86_64" (x86) or "aarch64" (ARM); since the target +# directory needs to be also one of those two, but globs don't work in target +# directories, work around this with mv +COPY --from=nr-ue-build /usr/lib/*-linux-gnu/libasan.so.8.0.0 /usr/lib/ +ARG TARGETPLATFORM +RUN case "${TARGETPLATFORM}" in \ + "linux/amd64") TARGET_DIR=x86_64-linux-gnu ;; \ + "linux/arm64") TARGET_DIR=aarch64-linux-gnu ;; \ + *) exit 1 ;; \ + esac; \ + mv /usr/lib/libasan.so.8.0.0 /usr/lib/$TARGET_DIR/libasan.so.8.0.0 WORKDIR /opt/oai-nr-ue/bin COPY --from=nr-ue-build \ From 9d796fb31fca243198e3f194e48b8efcf624e19b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 28 Feb 2025 16:10:35 +0100 Subject: [PATCH 06/12] getopt_long() returns int Use the right type for variable, as getopt_long() returns an int. Using char is not a problem on x86, but prevents the return of -1 in case of parameter reading end. This led to infinite loops on ARM, which is fixed through the variable type change. An additional counter measure (showing the problem) would be to print and error out when reading an undefined parameter, which is added here as well. This has been forgotten when making the same change for getopt() in cf9854601cce ("getopt() returns int"). --- openair3/NAS/TOOLS/nvram.c | 4 +++- openair3/NAS/TOOLS/usim.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/openair3/NAS/TOOLS/nvram.c b/openair3/NAS/TOOLS/nvram.c index 80d8b34893..ad39462dc9 100644 --- a/openair3/NAS/TOOLS/nvram.c +++ b/openair3/NAS/TOOLS/nvram.c @@ -69,7 +69,7 @@ int main (int argc, char * const argv[]) {NULL, 0, NULL, 0} }; int option_index; - char option_short; + int option_short; /* * Read command line parameters @@ -94,6 +94,8 @@ int main (int argc, char * const argv[]) output_dir = optarg; break; default: + fprintf(stderr, "unknown option %d, exit\n", option_short); + exit(1); break; } } diff --git a/openair3/NAS/TOOLS/usim.c b/openair3/NAS/TOOLS/usim.c index 84b4cfbdf8..9d74499144 100644 --- a/openair3/NAS/TOOLS/usim.c +++ b/openair3/NAS/TOOLS/usim.c @@ -69,7 +69,7 @@ int main (int argc, char * const argv[]) {NULL, 0, NULL, 0} }; int option_index; - char option_short; + int option_short; /* * Read command line parameters @@ -94,6 +94,8 @@ int main (int argc, char * const argv[]) output_dir = optarg; break; default: + fprintf(stderr, "unknown option %d, exit\n", option_short); + exit(1); break; } } From 3f5181d50d643aa99d2976e1ce9c8dd55f9d8da4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 28 Feb 2025 15:36:52 +0000 Subject: [PATCH 07/12] Match nvipc.zip through glob The (existing) Aerial pipeline on devkit uses an older version of nvipc, which is upgraded on gracehopper. Use a glob to match them equally, which also aligns this code with the corresponding Dockerfile, which already uses that glob. --- ci-scripts/cls_containerize.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 6c63703d74..2658cbf9fa 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -491,10 +491,10 @@ class Containerize(): elif image != 'ran-build': cmd.run(f'sed -i -e "s#ran-build:latest#ran-build:{imageTag}#" docker/Dockerfile.{pattern}{self.dockerfileprefix}') if image == 'oai-gnb-aerial': - cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.2024.05.23.tar.gz .') + cmd.run('cp -f /opt/nvidia-ipc/nvipc_src.*.tar.gz .') ret = cmd.run(f'{self.cli} build {self.cliBuildOptions} --target {image} --tag {name}:{imageTag} --file docker/Dockerfile.{pattern}{self.dockerfileprefix} {option} . > cmake_targets/log/{name}.log 2>&1', timeout=1200) if image == 'oai-gnb-aerial': - cmd.run('rm -f nvipc_src.2024.05.23.tar.gz') + cmd.run('rm -f nvipc_src.*.tar.gz') if image == 'ran-build' and ret.returncode == 0: cmd.run(f"docker run --name test-log -d {name}:{imageTag} /bin/true") cmd.run(f"docker cp test-log:/oai-ran/cmake_targets/log/ cmake_targets/log/{name}/") From 3e823b25c18e8d30224b610985f9be1ac6b2f728 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 1 Mar 2025 19:39:00 +0100 Subject: [PATCH 08/12] Add ARM-specific image-build and XML After the preceding commits, it's now possible to build images on ARM. Add a specific "native_arm" build kind to only build what we need as of now (do not only call it "arm", as that would match the kind "build_cross_arm64"). Add the corresponding XML. Pushing of images is disabled, as this does not work as of now. --- ci-scripts/cls_containerize.py | 6 +++ .../xml_files/container_image_build_arm.xml | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 ci-scripts/xml_files/container_image_build_arm.xml diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 2658cbf9fa..d93003a37a 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -407,6 +407,12 @@ class Containerize(): result = re.search('build_cross_arm64', self.imageKind) if result is not None: self.dockerfileprefix = '.ubuntu22.cross-arm64' + result = re.search('native_arm', self.imageKind) + if result is not None: + imageNames.append(('oai-gnb', 'gNB', 'oai-gnb', '')) + imageNames.append(('oai-nr-cuup', 'nr-cuup', 'oai-nr-cuup', '')) + imageNames.append(('oai-nr-ue', 'nrUE', 'oai-nr-ue', '')) + imageNames.append(('oai-gnb-aerial', 'gNB.aerial', 'oai-gnb-aerial', '')) self.testCase_id = HTML.testCase_id cmd.cd(lSourcePath) diff --git a/ci-scripts/xml_files/container_image_build_arm.xml b/ci-scripts/xml_files/container_image_build_arm.xml new file mode 100644 index 0000000000..ed51dbc844 --- /dev/null +++ b/ci-scripts/xml_files/container_image_build_arm.xml @@ -0,0 +1,54 @@ + + + build-tab + Build Container Images for ARM + wrench + + 800813 + 000001 + 000010 + + + + + Create_Workspace + Create new Workspace for server 0 + 0 + 0 + + + Build_Image + Build all Images + native_arm + 0 + 0 + + + + + + + + + From d67d5793ce68a89f5c115f3d069bf2116758f53c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 1 Mar 2025 19:41:44 +0100 Subject: [PATCH 09/12] Add push image with tag prefix The only currently viable way to push ARM images to our registry is to use a custom tag prefix. Modify the python test code to specify such a tag, and default to "" (no prefix). --- ci-scripts/cls_containerize.py | 13 +++++++------ ci-scripts/main.py | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index d93003a37a..aa29da000e 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -726,9 +726,9 @@ class Containerize(): HTML.CreateHtmlTabFooter(False) return False - def Push_Image_to_Local_Registry(self, HTML, svr_id): + def Push_Image_to_Local_Registry(self, HTML, svr_id, tag_prefix=""): lIpAddr, lSourcePath = self.GetCredentials(svr_id) - logging.debug('Pushing images from server: ' + lIpAddr) + logging.debug('Pushing images to server: ' + lIpAddr) ssh = cls_cmd.getConnection(lIpAddr) imagePrefix = 'porcepix.sboai.cs.eurecom.fr' ret = ssh.run(f'docker login -u oaicicd -p oaicicd {imagePrefix}') @@ -743,7 +743,7 @@ class Containerize(): if self.ranAllowMerge: orgTag = 'ci-temp' for image in IMAGES: - tagToUse = CreateTag(self.ranCommitID, self.ranBranch, self.ranAllowMerge) + tagToUse = tag_prefix + CreateTag(self.ranCommitID, self.ranBranch, self.ranAllowMerge) imageTag = f"{image}:{tagToUse}" ret = ssh.run(f'docker image tag {image}:{orgTag} {imagePrefix}/{imageTag}') if ret.returncode != 0: @@ -757,9 +757,10 @@ class Containerize(): return False # Creating a develop tag on the local private registry if not self.ranAllowMerge: - ssh.run(f'docker image tag {image}:{orgTag} {imagePrefix}/{image}:develop') - ssh.run(f'docker push {imagePrefix}/{image}:develop') - ssh.run(f'docker rmi {imagePrefix}/{image}:develop') + devTag = f"{tag_prefix}develop" + ssh.run(f'docker image tag {image}:{orgTag} {imagePrefix}/{image}:{devTag}') + ssh.run(f'docker push {imagePrefix}/{image}:{devTag}') + ssh.run(f'docker rmi {imagePrefix}/{image}:{devTag}') ssh.run(f'docker rmi {imagePrefix}/{imageTag} {image}:{orgTag}') ret = ssh.run(f'docker logout {imagePrefix}') diff --git a/ci-scripts/main.py b/ci-scripts/main.py index cafcb24313..ebd2252bc6 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -387,7 +387,8 @@ def ExecuteActionWithParam(action): elif action == 'Push_Local_Registry': svr_id = test.findtext('svr_id') - success = CONTAINERS.Push_Image_to_Local_Registry(HTML, svr_id) + tag_prefix = test.findtext('tag_prefix') or "" + success = CONTAINERS.Push_Image_to_Local_Registry(HTML, svr_id, tag_prefix) elif action == 'Pull_Local_Registry' or action == 'Clean_Test_Server_Images': if force_local: From 01d48c1d82901d9ccc8cc341dc62aeeabc6470ba Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 28 Feb 2025 17:16:59 +0000 Subject: [PATCH 10/12] Add pull image with tag prefix and XML After the parent commit, the registry might contain prefixed images. This commit adds the functionality to pull such prefixed image. Since we rename the pulled image (to have a consistent name, from whichever registry we might pull), remove the prefix as well so that it can be used with other CI functionality (remove image, use in test, ...) Examples for renaming: - pull from internal_registry for x86 internal_registry/oai-gnb:branchA => oai-ci/oai-gnb:branchA - pull from internal registry for ARM with "arm_" prefix internal_registry/oai-gnb:arm_branchA => oai-ci/oai-gnb:branchA - pull from x86 other registry (e.g., openshift) openshift/namespace/oai-gnb:branchA => oai-ci/oai-gnb:branchA --- ci-scripts/cls_cluster.py | 4 +- ci-scripts/cls_containerize.py | 15 +++--- ci-scripts/main.py | 6 ++- .../container_sa_gh_aerial_quectel.xml | 49 +++++++++++++++++++ 4 files changed, 63 insertions(+), 11 deletions(-) create mode 100644 ci-scripts/xml_files/container_sa_gh_aerial_quectel.xml diff --git a/ci-scripts/cls_cluster.py b/ci-scripts/cls_cluster.py index 7293e252a1..3044d3276c 100644 --- a/ci-scripts/cls_cluster.py +++ b/ci-scripts/cls_cluster.py @@ -226,7 +226,7 @@ class Cluster: def _undeploy_pod(self, filename): self.cmd.run(f'oc delete -f {filename}') - def PullClusterImage(self, HTML, node, images): + def PullClusterImage(self, HTML, node, images, tag_prefix): logging.debug(f'Pull OC image {images} to server {node}') self.testCase_id = HTML.testCase_id with cls_cmd.getConnection(node) as cmd: @@ -242,7 +242,7 @@ class Cluster: return False tag = cls_containerize.CreateTag(self.ranCommitID, self.ranBranch, self.ranAllowMerge) registry = f'{self.OCRegistry}/{CI_OC_RAN_NAMESPACE}' - success, msg = cls_containerize.Containerize.Pull_Image(cmd, images, tag, registry, None, None) + success, msg = cls_containerize.Containerize.Pull_Image(cmd, images, tag, tag_prefix, registry, None, None) OC_logout(cmd) param = f"on node {node}" if success: diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index aa29da000e..dc461dfe7e 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -775,7 +775,7 @@ class Containerize(): HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) return True - def Pull_Image(cmd, images, tag, registry, username, password): + def Pull_Image(cmd, images, tag, tag_prefix, registry, username, password): if username is not None and password is not None: logging.info(f"logging into registry {username}@{registry}") response = cmd.run(f'docker login -u {username} -p {password} {registry}', silent=True, reportNonZero=False) @@ -785,14 +785,15 @@ class Containerize(): return False, msg pulled_images = [] for image in images: + imagePrefTag = f"{image}:{tag_prefix}{tag}" imageTag = f"{image}:{tag}" - response = cmd.run(f'docker pull {registry}/{imageTag}') + response = cmd.run(f'docker pull {registry}/{imagePrefTag}') if response.returncode != 0: - msg = f'Could not pull {image} from local registry: {imageTag}' + msg = f'Could not pull {image} from local registry: {imagePrefTag}' logging.error(msg) return False, msg - cmd.run(f'docker tag {registry}/{imageTag} oai-ci/{imageTag}') - cmd.run(f'docker rmi {registry}/{imageTag}') + cmd.run(f'docker tag {registry}/{imagePrefTag} oai-ci/{imageTag}') + cmd.run(f'docker rmi {registry}/{imagePrefTag}') pulled_images += [f"oai-ci/{imageTag}"] if username is not None and password is not None: response = cmd.run(f'docker logout {registry}') @@ -800,13 +801,13 @@ class Containerize(): msg = "Pulled Images:\n" + '\n'.join(pulled_images) return True, msg - def Pull_Image_from_Registry(self, HTML, svr_id, images, tag=None, registry="porcepix.sboai.cs.eurecom.fr", username="oaicicd", password="oaicicd"): + def Pull_Image_from_Registry(self, HTML, svr_id, images, tag=None, tag_prefix="", registry="porcepix.sboai.cs.eurecom.fr", username="oaicicd", password="oaicicd"): lIpAddr, lSourcePath = self.GetCredentials(svr_id) logging.debug('\u001B[1m Pulling image(s) on server: ' + lIpAddr + '\u001B[0m') if not tag: tag = CreateTag(self.ranCommitID, self.ranBranch, self.ranAllowMerge) with cls_cmd.getConnection(lIpAddr) as cmd: - success, msg = Containerize.Pull_Image(cmd, images, tag, registry, username, password) + success, msg = Containerize.Pull_Image(cmd, images, tag, tag_prefix, registry, username, password) param = f"on node {lIpAddr}" if success: HTML.CreateHtmlTestRowQueue(param, 'OK', [msg]) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index ebd2252bc6..472cb2665f 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -395,13 +395,14 @@ def ExecuteActionWithParam(action): # Do not pull or remove images when running locally. User is supposed to handle image creation & cleanup return True svr_id = test.findtext('svr_id') + tag_prefix = test.findtext('tag_prefix') or "" images = test.findtext('images').split() # hack: for FlexRIC, we need to overwrite the tag to use tag = None if len(images) == 1 and images[0] == "oai-flexric": tag = CONTAINERS.flexricTag if action == "Pull_Local_Registry": - success = CONTAINERS.Pull_Image_from_Registry(HTML, svr_id, images, tag=tag) + success = CONTAINERS.Pull_Image_from_Registry(HTML, svr_id, images, tag=tag, tag_prefix=tag_prefix) if action == "Clean_Test_Server_Images": success = CONTAINERS.Clean_Test_Server_Images(HTML, svr_id, images, tag=tag) @@ -421,9 +422,10 @@ def ExecuteActionWithParam(action): success = cls_oaicitest.Custom_Script(HTML, node, script, command_fail) elif action == 'Pull_Cluster_Image': + tag_prefix = test.findtext('tag_prefix') or "" images = test.findtext('images').split() node = test.findtext('node') - success = CLUSTER.PullClusterImage(HTML, node, images) + success = CLUSTER.PullClusterImage(HTML, node, images, tag_prefix=tag_prefix) else: logging.warning(f"unknown action {action}, skip step") diff --git a/ci-scripts/xml_files/container_sa_gh_aerial_quectel.xml b/ci-scripts/xml_files/container_sa_gh_aerial_quectel.xml new file mode 100644 index 0000000000..ea60cb2b6f --- /dev/null +++ b/ci-scripts/xml_files/container_sa_gh_aerial_quectel.xml @@ -0,0 +1,49 @@ + + + TEST-GH-AERIAL-SA + Gracehopper AERIAL 100 MHz TDD SA + tasks + + 111111 + 333333 + + + + + Pull_Local_Registry + Pull Images from Local Registry + 0 + oai-gnb-aerial + arm_ + + + + Clean_Test_Server_Images + true + Clean Test Images on Test Server + 0 + oai-gnb-aerial + + + From 4ff8cf6c8068b56eef9e819f933067db13192cdf Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Mar 2025 09:21:50 +0100 Subject: [PATCH 11/12] Push ARM build images to registry for arm_ prefix --- ci-scripts/xml_files/container_image_build_arm.xml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ci-scripts/xml_files/container_image_build_arm.xml b/ci-scripts/xml_files/container_image_build_arm.xml index ed51dbc844..722d23ddcf 100644 --- a/ci-scripts/xml_files/container_image_build_arm.xml +++ b/ci-scripts/xml_files/container_image_build_arm.xml @@ -45,10 +45,11 @@ 0 - - - - - + + Push_Local_Registry + Push Images to Local Registry + 0 + arm_ + From 5b07283003a01c922ddb2d516dbdd560f14040c8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 18 Mar 2025 14:51:52 +0100 Subject: [PATCH 12/12] Add ARM build pipeline to RAN-Container-Parent and documentation --- ci-scripts/Jenkinsfile-GitLab-Container | 22 ++++++++++++++++++++++ doc/TESTBenches.md | 10 ++++++++++ 2 files changed, 32 insertions(+) diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index b0151a5ed1..51825ce0d2 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -145,6 +145,28 @@ pipeline { } } } + stage ("Ubuntu-ARM-Image-Builder") { + steps { + script { + triggerSlaveJob ('RAN-Ubuntu-ARM-Image-Builder', 'Ubuntu-ARM-Image-Builder') + } + } + post { + always { + script { + // Using a unique variable name for each test stage to avoid overwriting on a global variable + // due to parallel-time concurrency + ubuntuArmBuildStatus = finalizeSlaveJob('RAN-Ubuntu-ARM-Image-Builder') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + failingStages += ubuntuArmBuildStatus + } + } + } + } stage ("RHEL-Cluster-Image-Builder") { steps { script { diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index 9a137ddd1a..f7bb78c432 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -25,6 +25,7 @@ | aerial2 | 172.21.16.131 | CI-Aerial2-Usage | gNB (PNF/Nvidia CUBB + VNF) | Foxconn RU, _Nvidia Aerial SDK integrated_ | | cacofonix | 172.21.16.150 | CI-Cacofonix-Usage | gNB (n78, FHI7.2) | | | matix | 172.21.19.58 | CI-Matix-Usage | gNB (n77) | N310 | +| gracehopper1-oai | -- | Gracehopper1 | build, gNB/Aerial | _Nvidia Aerial SDK integrated_ | Note: The available resources, and their current usage, is indicated here: - [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/): @@ -122,6 +123,15 @@ information on how the images are built. - target image from `Dockerfile.lteUE.ubuntu22` - target image from `Dockerfile.lteRU.ubuntu22` - build unit tests from `ci-scripts/docker/Dockerfile.unittest.ubuntu22`, and run them +- [RAN-Ubuntu-ARM-Image-Builder](https://jenkins-oai.eurecom.fr/job/RAN-Ubuntu-ARM-Image-Builder/) + ~BUILD-ONLY ~4G-LTE ~5G-NR + - gracehopper1-oai: ARM Ubuntu 22 image build using docker + - base image from `Dockerfile.base.ubuntu22` + - build image from `Dockerfile.build.ubuntu22`, followed by + - target image from `Dockerfile.gNB.ubuntu22` + - target image from `Dockerfile.nr-cuup.ubuntu22` + - target image from `Dockerfile.nrUE.ubuntu22` + - target image from `Dockerfile.gNB.aerial.ubuntu22` #### Image Test pipelines