From 7b3486949aa6fe59b902a6a1d5d0ba815d49bb17 Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Thu, 8 Oct 2026 18:06:46 +0800 Subject: [PATCH 01/10] Packaging: add the DEB package files for Ubuntu 26.04 Add devops/build/packaging/deb/ubuntu26.04, copied from ubuntu24.04. The package names in control change with each Ubuntu release, so adjust these for 26.04 (resolute): - gcc-13 and g++-13 become gcc-15 and g++-15, the compiler of the 26.04 build image. - libcgroup2 becomes libcgroup3, in Build-Depends and Depends. - libxml2 becomes libxml2-16 in Depends. The libxml2 package no longer has an installable version. The changelog distribution is now resolute. Verified on Ubuntu 26.04 with the published build and test images: the DEB builds, "apt-get install" of it succeeds in the test image, no shared library of the installed files is unresolved, and a cluster started with gpinitsystem from the installed package works. Assisted-by: Claude Code --- .../build/packaging/deb/ubuntu26.04/changelog | 6 + devops/build/packaging/deb/ubuntu26.04/compat | 2 + .../build/packaging/deb/ubuntu26.04/control | 109 ++++++++++++++++++ .../build/packaging/deb/ubuntu26.04/install | 2 + .../build/packaging/deb/ubuntu26.04/postinst | 13 +++ devops/build/packaging/deb/ubuntu26.04/rules | 64 ++++++++++ .../packaging/deb/ubuntu26.04/source/format | 2 + .../deb/ubuntu26.04/source/local-options | 3 + 8 files changed, 201 insertions(+) create mode 100644 devops/build/packaging/deb/ubuntu26.04/changelog create mode 100644 devops/build/packaging/deb/ubuntu26.04/compat create mode 100644 devops/build/packaging/deb/ubuntu26.04/control create mode 100644 devops/build/packaging/deb/ubuntu26.04/install create mode 100644 devops/build/packaging/deb/ubuntu26.04/postinst create mode 100644 devops/build/packaging/deb/ubuntu26.04/rules create mode 100644 devops/build/packaging/deb/ubuntu26.04/source/format create mode 100644 devops/build/packaging/deb/ubuntu26.04/source/local-options diff --git a/devops/build/packaging/deb/ubuntu26.04/changelog b/devops/build/packaging/deb/ubuntu26.04/changelog new file mode 100644 index 00000000000..2c4eeed2af3 --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/changelog @@ -0,0 +1,6 @@ +apache-cloudberry-db-incubating (2.0.0) resolute; urgency=medium + + * Initial release. + + -- Cloudberry Team Wed, 26 Mar 2025 11:10:44 +0000 + diff --git a/devops/build/packaging/deb/ubuntu26.04/compat b/devops/build/packaging/deb/ubuntu26.04/compat new file mode 100644 index 00000000000..48c962ffa2b --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/compat @@ -0,0 +1,2 @@ +9 + diff --git a/devops/build/packaging/deb/ubuntu26.04/control b/devops/build/packaging/deb/ubuntu26.04/control new file mode 100644 index 00000000000..176356e2e4a --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/control @@ -0,0 +1,109 @@ +Source: apache-cloudberry-db-incubating +Maintainer: Apache Cloudberry (Incubating) +Section: database +Build-Depends: debhelper (>= 9), + bison, + ca-certificates-java, + ca-certificates, + cmake, + curl, + cgroup-tools, + flex, + gcc-15, + g++-15, + git, + krb5-multidev, + libapr1-dev, + libbz2-dev, + libcurl4-gnutls-dev, + libevent-dev, + libkrb5-dev, + libldap-dev, + libperl-dev, + libreadline-dev, + libssl-dev, + libxml2-dev, + libyaml-dev, + libzstd-dev, + libaprutil1-dev, + libpam0g-dev, + libpam0g, + libcgroup3, + libyaml-0-2, + libldap2, + libssl3t64, + libxerces-c-dev, + libxerces-c3.2t64, + ninja-build, + quilt, + unzip, + wget, + zlib1g-dev, + libuv1-dev + +Package: apache-cloudberry-db-incubating +Provides: apache-cloudberry-db +Architecture: any +Depends: curl, + cgroup-tools, + debianutils, + hostname, + iputils-ping, + iproute2, + keyutils, + krb5-multidev, + less, + libapr1t64, + libbz2-1.0, + libcurl4t64, + libcurl3t64-gnutls, + libevent-2.1-7t64, + libreadline8t64, + libxml2-16, + libyaml-0-2, + libldap2, + libzstd1, + libcgroup3, + libssl3t64, + libpam0g, + libprotobuf32t64, + libpsl5t64, + libuv1t64, + liburing2, + libxerces-c3.2t64, + locales, + lsof, + lz4, + net-tools, + openssh-client, + openssh-server, + openssl, + python3, + rsync, + wget, + xz-utils, + zlib1g +Description: Apache Cloudberry (incubating) is an advanced, open-source, massively + parallel processing (MPP) data warehouse developed from PostgreSQL and + Greenplum. It is designed for high-performance analytics on + large-scale data sets, offering powerful analytical capabilities and + enhanced security features. + Key Features: + - Massively parallel processing for optimized performance + - Advanced analytics for complex data processing + - Integration with ETL and BI tools + - Compatibility with multiple data sources and formats + - Enhanced security features + Apache Cloudberry supports both batch processing and real-time data + warehousing, making it a versatile solution for modern data + environments. + Apache Cloudberry (incubating) is an effort undergoing incubation at + the Apache Software Foundation (ASF), sponsored by the Apache + Incubator PMC. + Incubation is required of all newly accepted projects until a further + review indicates that the infrastructure, communications, and decision + making process have stabilized in a manner consistent with other + successful ASF projects. + While incubation status is not necessarily a reflection of the + completeness or stability of the code, it does indicate that the + project has yet to be fully endorsed by the ASF. diff --git a/devops/build/packaging/deb/ubuntu26.04/install b/devops/build/packaging/deb/ubuntu26.04/install new file mode 100644 index 00000000000..e3d847a3c99 --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/install @@ -0,0 +1,2 @@ +debian/build/* /usr/cloudberry-db + diff --git a/devops/build/packaging/deb/ubuntu26.04/postinst b/devops/build/packaging/deb/ubuntu26.04/postinst new file mode 100644 index 00000000000..708e3ed29b7 --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/postinst @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +GPADMIN=gpadmin +GPHOME=/usr/cloudberry-db + +if [ "$1" = configure ]; then + + ln -sf ${GPHOME} /usr/local/cloudberry-db + +fi + diff --git a/devops/build/packaging/deb/ubuntu26.04/rules b/devops/build/packaging/deb/ubuntu26.04/rules new file mode 100644 index 00000000000..463486cf03f --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/rules @@ -0,0 +1,64 @@ +#!/usr/bin/make -f + +DH_VERBOSE = 1 +DPKG_EXPORT_BUILDFLAGS = 1 + +CBDB_BIN_PATH := /usr/local/cloudberry-db +DEBIAN_DESTINATION := $(shell pwd)/debian/build + +# assumes that CWD is root of cbdb source +CBDB_PKG_VERSION := $(CBDB_PKG_VERSION) +PACKAGE_CBDB := $(shell cat debian/control | egrep "^Package: " | cut -d " " -f 2) +PATH := ${DEBIAN_DESTINATION}/bin:${PATH} + +.PHONY: gpinstall + +include /usr/share/dpkg/default.mk + +%: + dh $@ --parallel + +gpinstall: + # If the build staging directory is empty, copy from the pre-installed location. + # In CI, BUILD_DESTINATION already points here so it will be populated. + # For local manual packaging, copy from the installed Cloudberry path. + @mkdir -p ${DEBIAN_DESTINATION} + @if [ -z "$$(ls -A ${DEBIAN_DESTINATION} 2>/dev/null)" ]; then \ + echo "Copying pre-built binaries from ${CBDB_BIN_PATH} to ${DEBIAN_DESTINATION}..."; \ + cp -a ${CBDB_BIN_PATH}/* ${DEBIAN_DESTINATION}/; \ + else \ + echo "Build staging directory already populated, skipping copy."; \ + fi + # Copy Apache compliance files into the build staging directory + cp -a LICENSE NOTICE DISCLAIMER ${DEBIAN_DESTINATION}/ + cp -a licenses ${DEBIAN_DESTINATION}/ + # Create debian/copyright for Debian policy compliance + mkdir -p $(shell pwd)/debian + cat LICENSE NOTICE > $(shell pwd)/debian/copyright + +override_dh_auto_install: gpinstall + # the staging directory for creating a debian is NOT the right GPHOME. + # change GPHOME to point to the post-install target install directory. + sed -i "s#GPHOME=.*#GPHOME=${CBDB_BIN_PATH}#g" ${DEBIAN_DESTINATION}/cloudberry-env.sh + +override_dh_auto_build: + echo "Skipping build" + +override_dh_auto_clean: + echo "Skipping clean" + +override_dh_auto_configure: + echo "Skipping configure" + +override_dh_auto_test: + echo "Skipping auto test" + +override_dh_gencontrol: + echo "using version ${CBDB_PKG_VERSION} for binary Cloudberry" + dh_gencontrol -- -v${CBDB_PKG_VERSION} -p${PACKAGE_CBDB} + +override_dh_shlibdeps: + LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/$(DEB_HOST_MULTIARCH)/libfakeroot:${DEBIAN_DESTINATION}/lib dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info + +clean_dev_local: + rm -rf ${DEBIAN_DESTINATION} diff --git a/devops/build/packaging/deb/ubuntu26.04/source/format b/devops/build/packaging/deb/ubuntu26.04/source/format new file mode 100644 index 00000000000..435dd71905d --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/source/format @@ -0,0 +1,2 @@ +3.0 (native) + diff --git a/devops/build/packaging/deb/ubuntu26.04/source/local-options b/devops/build/packaging/deb/ubuntu26.04/source/local-options new file mode 100644 index 00000000000..adf39a30992 --- /dev/null +++ b/devops/build/packaging/deb/ubuntu26.04/source/local-options @@ -0,0 +1,3 @@ +#abort-on-upstream-changes +#unapply-patches + From ae14a992dc720bb956110f65363becf4f93a5901 Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Thu, 8 Oct 2026 18:06:46 +0800 Subject: [PATCH 02/10] CI: add Ubuntu 26.04 to the DEB build and test matrix Run the DEB build, the DEB install test and the DEB test suites on Ubuntu 26.04, using the cbdb-build-ubuntu26.04 and cbdb-test-ubuntu26.04 images. Add 26.04 to the three places that list the Ubuntu versions: the build matrix, the install test matrix, and the default of the test matrix that is generated for the "all" case of workflow_dispatch. The 26.04 jobs need the Ubuntu 26.04 fixes for PAX, contrib/xml2 and the gpMgmt scripts, so they fail until those are merged. Assisted-by: Claude Code --- .github/workflows/build-deb-cloudberry.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-deb-cloudberry.yml b/.github/workflows/build-deb-cloudberry.yml index e4232cd4a04..77be9fb7744 100644 --- a/.github/workflows/build-deb-cloudberry.yml +++ b/.github/workflows/build-deb-cloudberry.yml @@ -289,7 +289,7 @@ jobs: # Determine ubuntu versions UBUNTU_INPUT="${{ github.event.inputs.ubuntu_version }}" if [[ "$UBUNTU_INPUT" == "all" || -z "$UBUNTU_INPUT" ]]; then - UBUNTU_VERSIONS_JSON='["22.04","24.04"]' + UBUNTU_VERSIONS_JSON='["22.04","24.04","26.04"]' else UBUNTU_VERSIONS_JSON=$(echo "$UBUNTU_INPUT" | jq -R 'split(",") | map(gsub("\\s+";"")) | map(select(length > 0)) | unique') fi @@ -378,7 +378,7 @@ jobs: strategy: fail-fast: false matrix: - ubuntu_version: ['22.04', '24.04'] + ubuntu_version: ['22.04', '24.04', '26.04'] container: image: apache/incubator-cloudberry:cbdb-build-ubuntu${{ matrix.ubuntu_version }}-latest @@ -706,7 +706,7 @@ jobs: strategy: fail-fast: false matrix: - ubuntu_version: ['22.04', '24.04'] + ubuntu_version: ['22.04', '24.04', '26.04'] container: image: apache/incubator-cloudberry:cbdb-test-ubuntu${{ matrix.ubuntu_version }}-latest From be85b9dbc2d92ecfde01fc3a9cd2bce5505f3bbd Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 10:49:05 +0800 Subject: [PATCH 03/10] Fix unit test function signatures for C23 GCC 15 compiles C as C23 by default. In C23, "void f()" means "void f(void)", and not an unspecified parameter list as before, so a function defined with empty parentheses no longer converts to a function pointer type that has parameters. Together with GCC 14 making -Wincompatible-pointer-types an error, "make unittest-check" fails on Ubuntu 26.04 in 9 test files: error: passing argument 5 of '_will_return' from incompatible pointer type [-Wincompatible-pointer-types] error: initialization of 'void (*)(void **)' from incompatible pointer type 'void (*)(void)' Give 11 functions the parameter list of the type they are used as: - 9 side effect callbacks passed to will_return_with_sideeffect() and will_be_called_with_sideeffect(), of type void (*)(void *): _ExceptionalCondition (6 files), _errfinish_impl (2 files) and RedZoneHandler_DetectRunawaySession_TrackedBytesSanity. None of them is called directly. The use of _ExceptionalCondition in vmem_tracker_test.c is inside #ifdef USE_ASSERT_CHECKING, so it is only compiled in a build with --enable-cassert. - 2 cmockery test functions in ginpostinglist_test.c, of type void (*)(void **). Checked on Ubuntu 26.04 (GCC 15.2) with "make -k unittest-check". With the CI configuration it had 21 errors in 9 files before, and now passes. With --enable-cassert it has no compile errors, and all unit tests pass. Assisted-by: Claude Code Backpatch-through: REL_2_STABLE (cherry picked from commit d0c3bbdb3efcc0a0e7ac1f7df911b7e47b4a2885) --- src/backend/access/gin/test/ginpostinglist_test.c | 4 ++-- src/backend/tcop/test/postgres_test.c | 2 +- src/backend/utils/init/test/postinit_test.c | 2 +- src/backend/utils/mmgr/test/idle_tracker_test.c | 2 +- src/backend/utils/mmgr/test/memprot_test.c | 2 +- src/backend/utils/mmgr/test/redzone_handler_test.c | 2 +- src/backend/utils/mmgr/test/runaway_cleaner_test.c | 2 +- src/backend/utils/mmgr/test/vmem_tracker_test.c | 4 ++-- src/backend/utils/test/session_state_test.c | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/backend/access/gin/test/ginpostinglist_test.c b/src/backend/access/gin/test/ginpostinglist_test.c index 1ef57f0043a..7be86b0051d 100644 --- a/src/backend/access/gin/test/ginpostinglist_test.c +++ b/src/backend/access/gin/test/ginpostinglist_test.c @@ -34,7 +34,7 @@ make_item_pointer(BlockId block_id, OffsetNumber offset_number) * Cloudberry append-only tables allow for the full 16 bits of OffsetNumber */ static void -test_compress_gin_posting_list_with_item_pointer_with_offset_larger_than_eleven_bits() +test_compress_gin_posting_list_with_item_pointer_with_offset_larger_than_eleven_bits(void **state) { OffsetNumber offset_number_larger_than_11_bits = 3000; int number_of_item_pointers = 1; @@ -59,7 +59,7 @@ test_compress_gin_posting_list_with_item_pointer_with_offset_larger_than_eleven_ } static void -test_compress_gin_posting_list_with_multiple_item_pointers() +test_compress_gin_posting_list_with_multiple_item_pointers(void **state) { OffsetNumber offset_number_with_all_bits_on = 65535; OffsetNumber offset_number_larger_than_11_bits = 5000; diff --git a/src/backend/tcop/test/postgres_test.c b/src/backend/tcop/test/postgres_test.c index 700efc5bfa6..583c511cd92 100644 --- a/src/backend/tcop/test/postgres_test.c +++ b/src/backend/tcop/test/postgres_test.c @@ -13,7 +13,7 @@ #define PG_RE_THROW() siglongjmp(*PG_exception_stack, 1) static void -_errfinish_impl() +_errfinish_impl(void *arg) { PG_RE_THROW(); } diff --git a/src/backend/utils/init/test/postinit_test.c b/src/backend/utils/init/test/postinit_test.c index 898799ae132..126bb091dd9 100644 --- a/src/backend/utils/init/test/postinit_test.c +++ b/src/backend/utils/init/test/postinit_test.c @@ -16,7 +16,7 @@ #define PG_RE_THROW() siglongjmp(*PG_exception_stack, 1) static void -_errfinish_impl() +_errfinish_impl(void *arg) { PG_RE_THROW(); } diff --git a/src/backend/utils/mmgr/test/idle_tracker_test.c b/src/backend/utils/mmgr/test/idle_tracker_test.c index 9c8e51941ee..792b358804b 100755 --- a/src/backend/utils/mmgr/test/idle_tracker_test.c +++ b/src/backend/utils/mmgr/test/idle_tracker_test.c @@ -43,7 +43,7 @@ InitFakeSessionState(int activeProcessCount, int cleanupCountdown, RunawayStatus * back to the next available PG_CATCH(); */ static void -_ExceptionalCondition() +_ExceptionalCondition(void *arg) { PG_RE_THROW(); } diff --git a/src/backend/utils/mmgr/test/memprot_test.c b/src/backend/utils/mmgr/test/memprot_test.c index f7e9ff5fa8b..911eb1cc37e 100755 --- a/src/backend/utils/mmgr/test/memprot_test.c +++ b/src/backend/utils/mmgr/test/memprot_test.c @@ -49,7 +49,7 @@ static void our_free(void* ptr) * back to the next available PG_CATCH(); */ static void -_ExceptionalCondition() +_ExceptionalCondition(void *arg) { PG_RE_THROW(); } diff --git a/src/backend/utils/mmgr/test/redzone_handler_test.c b/src/backend/utils/mmgr/test/redzone_handler_test.c index 3073adbcdb9..dee79a8f5fc 100755 --- a/src/backend/utils/mmgr/test/redzone_handler_test.c +++ b/src/backend/utils/mmgr/test/redzone_handler_test.c @@ -30,7 +30,7 @@ extern bool sessionStateInited; * back to the next available PG_CATCH(); */ static void -_ExceptionalCondition() +_ExceptionalCondition(void *arg) { PG_RE_THROW(); } diff --git a/src/backend/utils/mmgr/test/runaway_cleaner_test.c b/src/backend/utils/mmgr/test/runaway_cleaner_test.c index c3cacb34bab..9d7b1a8b387 100755 --- a/src/backend/utils/mmgr/test/runaway_cleaner_test.c +++ b/src/backend/utils/mmgr/test/runaway_cleaner_test.c @@ -59,7 +59,7 @@ InitFakeSessionState(int activeProcessCount, int cleanupCountdown, RunawayStatus * back to the next available PG_CATCH(); */ static void -_ExceptionalCondition() +_ExceptionalCondition(void *arg) { PG_RE_THROW(); } diff --git a/src/backend/utils/mmgr/test/vmem_tracker_test.c b/src/backend/utils/mmgr/test/vmem_tracker_test.c index f087fe0f3a1..b98a297b0c7 100755 --- a/src/backend/utils/mmgr/test/vmem_tracker_test.c +++ b/src/backend/utils/mmgr/test/vmem_tracker_test.c @@ -22,7 +22,7 @@ * back to the next available PG_CATCH(); */ static -void _ExceptionalCondition() +void _ExceptionalCondition(void *arg) { PG_RE_THROW(); } @@ -314,7 +314,7 @@ void test__VmemTracker_ReserveVmem__TrackedBytesSanity(void **state) * trackedBytes during runaway detector for a particular reservation. */ static -void RedZoneHandler_DetectRunawaySession_TrackedBytesSanity() +void RedZoneHandler_DetectRunawaySession_TrackedBytesSanity(void *arg) { assert_true(0 != trackedBytes && trackedBytes == preAllocTrackedBytes); } diff --git a/src/backend/utils/test/session_state_test.c b/src/backend/utils/test/session_state_test.c index 08aa8933983..fb853dea25e 100755 --- a/src/backend/utils/test/session_state_test.c +++ b/src/backend/utils/test/session_state_test.c @@ -46,7 +46,7 @@ * back to the next available PG_CATCH(); */ static void -_ExceptionalCondition() +_ExceptionalCondition(void *arg) { PG_RE_THROW(); } From 4633f98e54fad2f1380996f37661b70733691aaf Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 15:47:44 +0800 Subject: [PATCH 04/10] Fix scan_flaky_fault_injectors.sh with uutils coreutils On Ubuntu 26.04, "make installcheck-good" and "installcheck-cbdb-parallel" stop before any test runs: scanning for flaky fault-injection tests... comm: file 1 is not in sorted order comm: input is not in sorted order make: *** [GNUmakefile:213: installcheck-good] Error 1 Ubuntu 26.04 replaces GNU coreutils with uutils coreutils. In the UTF-8 locale of the build images (en_US.UTF-8), its sort -u and comm do not agree on the order of the two test lists, so comm rejects its input. GNU coreutils 9.4 on Ubuntu 24.04 does not have this problem. Make sort and comm use the same order by running the script in the C locale. The test names are ASCII, so only the collation changes. Checked on Ubuntu 26.04 in the build image: the script fails in the default locale and passes with LC_ALL=C. It passes in both ways on Ubuntu 24.04. Assisted-by: Claude Code Backpatch-through: REL_2_STABLE (cherry picked from commit ac6f4170273df91ff104517ff730a4cc7715e642) --- src/test/regress/scan_flaky_fault_injectors.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/regress/scan_flaky_fault_injectors.sh b/src/test/regress/scan_flaky_fault_injectors.sh index 8fe97655444..cfecffb1971 100755 --- a/src/test/regress/scan_flaky_fault_injectors.sh +++ b/src/test/regress/scan_flaky_fault_injectors.sh @@ -7,6 +7,12 @@ set -e +# sort(1) and comm(1) must use the same collation. With a UTF-8 locale they can +# disagree on the order (as the uutils coreutils of Ubuntu 26.04 do), and comm +# then fails with "input is not in sorted order". The C locale gives plain +# byte order for both, and the test names are ASCII. +export LC_ALL=C + fault_injection_tests=$(mktemp fault_injection_tests.XXX) parallel_tests=$(mktemp parallel_tests.XXX) retcode=0 From bfb37ee6473b00c27e6c1c2f10f78bd5dc455525 Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 15:47:44 +0800 Subject: [PATCH 05/10] Fix gpdiff.pl duplicate "verbose" option specification With Perl 5.40 (Getopt::Long 2.57, as in Ubuntu 26.04), every run of gpdiff.pl prints a warning: Duplicate specification "verbose|Verbose" for option "verbose" It is printed more than a thousand times in a test run, and it reaches the test output. Getopt::Long ignores case by default and gpdiff.pl does not turn that off (it only sets pass_through), so "Verbose" is already matched by "verbose". Use "verbose" alone. Both -verbose and -Verbose still work. Checked on Ubuntu 26.04: the warning is gone with the new specification, and Ubuntu 24.04 (Getopt::Long 2.54) is not affected either way. Assisted-by: Claude Code Backpatch-through: REL_2_STABLE (cherry picked from commit a76a748eb10745a6c08a63632d6b11fdc91f87d8) --- src/test/regress/gpdiff.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/regress/gpdiff.pl b/src/test/regress/gpdiff.pl index c3a4c200ca9..3a9d562f36f 100755 --- a/src/test/regress/gpdiff.pl +++ b/src/test/regress/gpdiff.pl @@ -252,7 +252,7 @@ sub filefunc "man" => sub { lazy_pod2usage(-msg => $pmsg, -exitstatus => 0, -verbose => 2) }, "help" => sub { lazy_pod2usage(-msg => $pmsg, -exitstatus => 1) }, "version|v" => \&print_version , - "verbose|Verbose" => \$glob_atmsort_args{VERBOSE}, + "verbose" => \$glob_atmsort_args{VERBOSE}, "gpd_ignore_plans|gp_ignore_plans" => \$glob_atmsort_args{IGNORE_PLANS}, "gpd_init|gp_init_file=s" => \@{$glob_atmsort_args{INIT_FILES}} ); From bf4e9867aa18e68486b2c4679ec8b1e9c8bfc396 Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 15:47:44 +0800 Subject: [PATCH 06/10] Fix the DLSUFFIX redefinition in the backend unit tests Every object of the backend unit tests is compiled with -DDLSUFFIX=.so, and pg_config.h then defines DLSUFFIX as ".so": pg_config.h:47:9: warning: 'DLSUFFIX' redefined 47 | #define DLSUFFIX ".so" : note: this is the location of the previous definition The two definitions differ, because the one from the command line is not a string. The warning is printed more than a hundred times in a unittest-check run, and the command line value is never the one that is used. Quote the value, as src/backend/utils/fmgr/Makefile already does. The two definitions are then the same, and there is no warning. Checked with GCC 13 and GCC 15: the unquoted form warns, and the quoted form does not. Assisted-by: Claude Code Backpatch-through: REL_2_STABLE (cherry picked from commit 00917fceb8b0d245e57bb8360c58acb21e0b1a79) --- src/backend/mock.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/mock.mk b/src/backend/mock.mk index c72c2dca2b0..fc25b6741de 100644 --- a/src/backend/mock.mk +++ b/src/backend/mock.mk @@ -12,7 +12,7 @@ override CPPFLAGS+= -I$(top_srcdir)/src/backend/libpq \ -I$(top_srcdir)/src/backend/postmaster \ -I$(top_srcdir)/src/test/unit/mock/ \ -I. -I$(top_builddir)/src/port \ - -DDLSUFFIX=$(DLSUFFIX) \ + -DDLSUFFIX=\"$(DLSUFFIX)\" \ -DUNITTEST \ -I$(top_srcdir)/src/backend/utils/stat From 68febf70ae853f9dc0d4b4ae2eef961dc0f3c63d Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 15:47:44 +0800 Subject: [PATCH 07/10] Fix return in a finally block in buildMirrorSegments.py Python 3.14 (PEP 765) warns at compile time about a return in a finally block. Every gp* utility that imports gppylib.operations.buildMirrorSegments prints it on stderr: buildMirrorSegments.py:293: SyntaxWarning: 'return' in a 'finally' block This breaks tests that compare the output of those utilities, such as contrib/sslinfo, where "gpstop -arf" is run from the test and the two extra lines make the result differ from the expected file. In _update_config(), "return backout_map" was in the finally block that restores the SIGINT handler. A return there discards any exception from the try block, so a failure of updateSystemConfig() was silently ignored and None was returned. The caller then went on with the recovery, and _revert_config_update() failed later with a TypeError from len(None). Return after the finally block. The SIGINT handler is restored in the same way, and an exception from updateSystemConfig() is now raised to the caller with its own message, as every other step of the recovery does. This is the only return, break or continue in a finally block in the repository. Assisted-by: Claude Code Backpatch-through: REL_2_STABLE (cherry picked from commit 4e1f55a606fbd8c928d380c2b3044a1fe7292c91) --- gpMgmt/bin/gppylib/operations/buildMirrorSegments.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gpMgmt/bin/gppylib/operations/buildMirrorSegments.py b/gpMgmt/bin/gppylib/operations/buildMirrorSegments.py index 2e5212357d0..869a37d312b 100644 --- a/gpMgmt/bin/gppylib/operations/buildMirrorSegments.py +++ b/gpMgmt/bin/gppylib/operations/buildMirrorSegments.py @@ -290,7 +290,8 @@ def _update_config(self, recovery_info_by_host, gpArray): finally: # Re-enable Ctrl-C signal.signal(signal.SIGINT, old_handler) - return backout_map + + return backout_map def _remove_progress_files(self, recovery_info_by_host, recovery_results): remove_progress_file_cmds = [] From cc466ddc479ceb01a555b7ce6062491eee13460e Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 15:49:06 +0800 Subject: [PATCH 08/10] Fix invalid escape sequences in Python scripts Python 3.12 and later warn at compile time about a backslash that is not a valid escape sequence in a normal string, and the warning is printed every time such a script is run: mocker.py:245: SyntaxWarning: "\[" is an invalid escape sequence. Such sequences will not work in the future. Did you mean "\\["? The warning of mocker.py is printed about sixty times in a unittest-check run, once for every test directory, and the ones of contrib/try_convert/scripts show up in the "make installcheck" of the contrib modules. The warning is the same on Ubuntu 24.04 and 26.04. Double the backslash of each invalid escape sequence, which gives the same string value as before, in 12 files: mocker.py, gpcheckperf, gpmemreport, gpssh-exkeys, two scripts in src/backend/gporca/scripts and the scripts in contrib/try_convert/scripts. Checked for each file that the syntax tree of the new source is the same as the one of the old source, which means every string has the same value, and that the file compiles without a warning. No Python file in the repository has an invalid escape sequence now. Assisted-by: Claude Code Backpatch-through: REL_2_STABLE (cherry picked from commit 4cb8cfae2f424ea0bfc8501d9e54024aeace1af4) --- contrib/try_convert/scripts/check_test.py | 2 +- contrib/try_convert/scripts/error_safe_check.py | 12 ++++++------ contrib/try_convert/scripts/find_calls.py | 14 +++++++------- contrib/try_convert/scripts/find_casts.py | 12 ++++++------ contrib/try_convert/scripts/find_ereturns.py | 12 ++++++------ contrib/try_convert/scripts/verify.py | 12 ++++++------ gpMgmt/bin/gpcheckperf | 4 ++-- gpMgmt/bin/gpmemreport | 2 +- gpMgmt/bin/gpssh-exkeys | 2 +- src/backend/gporca/scripts/cal_bitmap_test.py | 2 +- src/backend/gporca/scripts/fix_mdps.py | 4 ++-- src/test/unit/mock/mocker.py | 2 +- 12 files changed, 40 insertions(+), 40 deletions(-) diff --git a/contrib/try_convert/scripts/check_test.py b/contrib/try_convert/scripts/check_test.py index 52e66ed158e..93a4c2ebf99 100644 --- a/contrib/try_convert/scripts/check_test.py +++ b/contrib/try_convert/scripts/check_test.py @@ -64,7 +64,7 @@ preline = lines[i-1] line = lines[i] if len(line) > 0 and len(preline) > 0 and (line[0] == '-' or line[0] == '+') and (preline[0] != '-' and preline[0] != '+'): - words = re.split('::|\*|;|\n| |\(|\)|,|\.|\".*\"|\'.*\'|<.*>', preline) + words = re.split('::|\\*|;|\n| |\\(|\\)|,|\\.|\".*\"|\'.*\'|<.*>', preline) ans = [] is_prining = False for word in words: diff --git a/contrib/try_convert/scripts/error_safe_check.py b/contrib/try_convert/scripts/error_safe_check.py index 2852f5eff3e..51bc5a9c0b4 100644 --- a/contrib/try_convert/scripts/error_safe_check.py +++ b/contrib/try_convert/scripts/error_safe_check.py @@ -21,11 +21,11 @@ import os, glob -p_any = '(?:\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\$)+?' -p_spaces = '\s*' +p_any = '(?:\\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\\$)+?' +p_spaces = '\\s*' def create_pattern(funcCall): - return '\n(\w+)\s+?(\w+)' + p_spaces + '\((' + p_any + ')\)' + p_spaces + '(\n\{' + '(' + p_any + ')' + f'({funcCall})' + '\s*' + '(' + p_any + ')' + '\n+\})' + return '\n(\\w+)\\s+?(\\w+)' + p_spaces + '\\((' + p_any + ')\\)' + p_spaces + '(\n\\{' + '(' + p_any + ')' + f'({funcCall})' + '\\s*' + '(' + p_any + ')' + '\n+\\})' pattern = create_pattern('ereturn') @@ -100,9 +100,9 @@ def find_functions_with_call(functions): if m[5] != 'ereturn': func_call = m[4][-20:] + m[5] + m[6][:20] - safe_call_pattern = f'if{p_spaces}\(!{m[5]}\({p_any}\)\)' - safe_call_void_pattern = f'\(void\){p_spaces}{m[5]}\({p_any}\)\)' - direct_safe_call_pattern = f'DirectFunctionCall1Safe\({m[5]}' + safe_call_pattern = f'if{p_spaces}\\(!{m[5]}\\({p_any}\\)\\)' + safe_call_void_pattern = f'\\(void\\){p_spaces}{m[5]}\\({p_any}\\)\\)' + direct_safe_call_pattern = f'DirectFunctionCall1Safe\\({m[5]}' if re.search(safe_call_pattern, func_call) is None and \ re.search(safe_call_void_pattern, func_call) is None and \ re.search(direct_safe_call_pattern, func_call) is None: diff --git a/contrib/try_convert/scripts/find_calls.py b/contrib/try_convert/scripts/find_calls.py index 328307bd911..36ba56d7f3c 100644 --- a/contrib/try_convert/scripts/find_calls.py +++ b/contrib/try_convert/scripts/find_calls.py @@ -22,14 +22,14 @@ from general import source_filenames -p_any = '(?:\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\$)+?' -p_spaces = '\s*' -p_space = '\s+' +p_any = '(?:\\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\\$)+?' +p_spaces = '\\s*' +p_space = '\\s+' def remove_comments(body): body = re.sub('".*?"', '""', body) - body = re.sub('/\*[\s\S]*?\*/', '/* */', body) + body = re.sub('/\\*[\\s\\S]*?\\*/', '/* */', body) return body def find_functions(func_names, text): @@ -37,7 +37,7 @@ def find_functions(func_names, text): func_names_pattern_list = '|'.join(func_names) func_names_pattern = f'((?:{func_names_pattern_list}))' - func_pattern = '\n(\w+)\s+?' + func_names_pattern + p_spaces + '\((' + p_any + ')\)' + p_spaces + '(\n\{' + '(' + p_any + ')' + '\n+\})' + func_pattern = '\n(\\w+)\\s+?' + func_names_pattern + p_spaces + '\\((' + p_any + ')\\)' + p_spaces + '(\n\\{' + '(' + p_any + ')' + '\n+\\})' funcs = [] @@ -50,7 +50,7 @@ def find_functions(func_names, text): def find_safe_functions(text): - func_pattern = '\n((?:\w+\s+)+)(\w+)' + p_spaces + '\((' + p_any + 'Node' + p_spaces + '\*' + p_spaces + 'escontext' + ')\)' + p_spaces + '(\n\{' + '(' + p_any + ')' + '\n+\})' + func_pattern = '\n((?:\\w+\\s+)+)(\\w+)' + p_spaces + '\\((' + p_any + 'Node' + p_spaces + '\\*' + p_spaces + 'escontext' + ')\\)' + p_spaces + '(\n\\{' + '(' + p_any + ')' + '\n+\\})' funcs = [] @@ -62,7 +62,7 @@ def find_safe_functions(text): return funcs def create_pattern(funcCall): - return '\n((?:\w+\s+)+)(\w+)' + p_spaces + '\((' + p_any + ')\)' + p_spaces + '(\n\{' + '(' + p_any + ')' + '\W' + f'({funcCall})' + '\W' + '(' + p_any + ')' + '\n+\})' + return '\n((?:\\w+\\s+)+)(\\w+)' + p_spaces + '\\((' + p_any + ')\\)' + p_spaces + '(\n\\{' + '(' + p_any + ')' + '\\W' + f'({funcCall})' + '\\W' + '(' + p_any + ')' + '\n+\\})' def find_functions_with_call(functions): diff --git a/contrib/try_convert/scripts/find_casts.py b/contrib/try_convert/scripts/find_casts.py index 23e20c52f41..8b2a5b6d9d3 100644 --- a/contrib/try_convert/scripts/find_casts.py +++ b/contrib/try_convert/scripts/find_casts.py @@ -149,7 +149,7 @@ def get_extensions(): return create_casts, dict(create_functions) def find_create_casts_in_text(text): - create_cast_pattern = 'CREATE CAST\s*\((\w+) AS (\w+)\)\s*([\w\s\(\)]+);' + create_cast_pattern = 'CREATE CAST\\s*\\((\\w+) AS (\\w+)\\)\\s*([\\w\\s\\(\\)]+);' create_casts = [] for target, source, f in re.findall(create_cast_pattern, text): @@ -159,29 +159,29 @@ def find_create_casts_in_text(text): if re.match('WITHOUT FUNCTION', f) is not None: create_casts += [(target, source, 'WITHOUT FUNCTION')] - m = re.match('WITH FUNCTION ([\w\(\)]+)', f) + m = re.match('WITH FUNCTION ([\\w\\(\\)]+)', f) if m is not None: # print(m[1]) create_casts += [(target, source, m[1])] return create_casts -p_space = '\s+' +p_space = '\\s+' def find_create_function_in_text(text): - create_function_pattern = 'CREATE FUNCTION' + p_space + '(\w+)\([\w\s,]+\)' + p_space + 'RETURNS' + p_space + '\w+' + p_space + 'AS' + p_space + '([\',\w\s]+)' + p_space + 'LANGUAGE[\w\s,]+;' + create_function_pattern = 'CREATE FUNCTION' + p_space + '(\\w+)\\([\\w\\s,]+\\)' + p_space + 'RETURNS' + p_space + '\\w+' + p_space + 'AS' + p_space + '([\',\\w\\s]+)' + p_space + 'LANGUAGE[\\w\\s,]+;' create_functions = {} for sql_name, c_obj in re.findall(create_function_pattern, text): # print(target, source, f) - m = re.fullmatch("\'(\w+)\'", c_obj) + m = re.fullmatch("\'(\\w+)\'", c_obj) if m is not None: c_name = m[1] create_functions[sql_name] = c_name continue - m = re.fullmatch("\'MODULE_PATHNAME\',\s+\'(\w+)\'", c_obj) + m = re.fullmatch("\'MODULE_PATHNAME\',\\s+\'(\\w+)\'", c_obj) if m is not None: c_name = m[1] create_functions[sql_name] = c_name diff --git a/contrib/try_convert/scripts/find_ereturns.py b/contrib/try_convert/scripts/find_ereturns.py index d26d70bfafe..f2106022bac 100644 --- a/contrib/try_convert/scripts/find_ereturns.py +++ b/contrib/try_convert/scripts/find_ereturns.py @@ -23,12 +23,12 @@ from general import source_filenames -p_any = '(?:\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\$)+?' -p_anys = '(?:\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\$)*?' -p_spaces = '\s*' -p_space = '\s+' +p_any = '(?:\\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\\$)+?' +p_anys = '(?:\\S| |\t|\n+\t|\n+ |\n+#|\n+/|\n+\\$)*?' +p_spaces = '\\s*' +p_space = '\\s+' -ereturn_pattern = 'ereturn\(' + p_any + '\);' +ereturn_pattern = 'ereturn\\(' + p_any + '\\);' ereturns = {} @@ -46,7 +46,7 @@ for m in matches: def get_field(field, m): - errfield = re.search(f'{field}\("('+ p_anys + '"' + p_anys + ')[\)\n]', m) + errfield = re.search(f'{field}\\("('+ p_anys + '"' + p_anys + ')[\\)\n]', m) if errfield is not None: errfield = errfield[1] diff --git a/contrib/try_convert/scripts/verify.py b/contrib/try_convert/scripts/verify.py index 8eb8d0b65ae..09733789d18 100644 --- a/contrib/try_convert/scripts/verify.py +++ b/contrib/try_convert/scripts/verify.py @@ -113,7 +113,7 @@ def filter_supported_casts(casts): if cast[2] != 'WITH INOUT' and cast[2] != 'WITHOUT FUNCTION': sql_func_name = cast[2] - m = re.match('(\w+)\(', sql_func_name) + m = re.match('(\\w+)\\(', sql_func_name) if m is not None: sql_func_name = m[1] @@ -211,11 +211,11 @@ def filter_supported_casts(casts): if re.search(r'bool', return_type) is None: print(f' WARNING: safe function {name} returns result not bool') - m = re.match('(\w+)Safe', name) + m = re.match('(\\w+)Safe', name) if m is not None: loaded_null_functions[m[1]] = 1 - m = re.match('(\w+)_safe', name) + m = re.match('(\\w+)_safe', name) if m is not None: loaded_null_functions[m[1]] = 1 @@ -233,14 +233,14 @@ def filter_supported_casts(casts): from find_calls import get_all_functions_with -ereport_functions = get_all_functions_with('ereport\(ERROR,') +ereport_functions = get_all_functions_with('ereport\\(ERROR,') unsafe_convert_functions = {} for func_name in loaded_functions: body = loaded_functions[func_name] - pattern_call = '(\w+)\s*\(([\s\S]*?)\)' + pattern_call = '(\\w+)\\s*\\(([\\s\\S]*?)\\)' for token_match in re.finditer(pattern_call, body): @@ -276,7 +276,7 @@ def filter_supported_casts(casts): for func_name in loaded_functions: body = loaded_functions[func_name] - pattern_call = '\w+' + pattern_call = '\\w+' for token_match in re.finditer(pattern_call, body): diff --git a/gpMgmt/bin/gpcheckperf b/gpMgmt/bin/gpcheckperf index 6048d7f08c0..49d29f8fe96 100755 --- a/gpMgmt/bin/gpcheckperf +++ b/gpMgmt/bin/gpcheckperf @@ -434,7 +434,7 @@ def parseMultiDDResult(out): if o.find('multidd total bytes ') >= 0: h = line[1:i] o = o.split() - m = re.search("(^\d+)", o[-1]) + m = re.search("(^\\d+)", o[-1]) if m is None: sys.exit('[Error] expected %s to be a number' % o[-1]) bytes = int(m.group(1)) @@ -444,7 +444,7 @@ def parseMultiDDResult(out): h = line[1:i] o = o.split() o[1] = o[1].replace(',', '.') - m = re.search("(^\d+.\d+)", o[1]) + m = re.search("(^\\d+.\\d+)", o[1]) if m is None: sys.exit('[Error] expected %s to be a floating point number' % o[1]) time = float(m.group(1)) diff --git a/gpMgmt/bin/gpmemreport b/gpMgmt/bin/gpmemreport index 7e91d0893ff..ec239a761dd 100755 --- a/gpMgmt/bin/gpmemreport +++ b/gpMgmt/bin/gpmemreport @@ -53,7 +53,7 @@ class ProcessListing(object): @classmethod def process(cls, ps_dictionary): cmd = ps_dictionary['COMMAND'] - if re.match('^\S*postgres\S*\s', cmd) is not None: + if re.match('^\\S*postgres\\S*\\s', cmd) is not None: if cmd.startswith('postgres:'): if re.search(r'con\d+', cmd): return GPDBQueryProcess(ps_dictionary) diff --git a/gpMgmt/bin/gpssh-exkeys b/gpMgmt/bin/gpssh-exkeys index cf9853360fd..775069c74ef 100755 --- a/gpMgmt/bin/gpssh-exkeys +++ b/gpMgmt/bin/gpssh-exkeys @@ -747,7 +747,7 @@ try: # MPP-13617 def canonicalize(s): if ':' not in s: return s - return '\[' + s + '\]' + return '\\[' + s + '\\]' for h in GV.newHosts: diff --git a/src/backend/gporca/scripts/cal_bitmap_test.py b/src/backend/gporca/scripts/cal_bitmap_test.py index 3c54848cb4a..da602478d2f 100755 --- a/src/backend/gporca/scripts/cal_bitmap_test.py +++ b/src/backend/gporca/scripts/cal_bitmap_test.py @@ -433,7 +433,7 @@ def select_version(conn): rows = curs.fetchall() for row in rows: log_output(row[0]) - glob_gpdb_major_version = int(re.sub(".*Apache Cloudberry ([0-9]*)\..*", "\\1", row[0])) + glob_gpdb_major_version = int(re.sub(".*Apache Cloudberry ([0-9]*)\\..*", "\\1", row[0])) log_output("GPDB major version is %d" % glob_gpdb_major_version) log_output("Backend pid:") diff --git a/src/backend/gporca/scripts/fix_mdps.py b/src/backend/gporca/scripts/fix_mdps.py index 35550081e69..a5e92813991 100755 --- a/src/backend/gporca/scripts/fix_mdps.py +++ b/src/backend/gporca/scripts/fix_mdps.py @@ -95,9 +95,9 @@ def processLogFile(logFileLines): print("Log file contains partial plans for %s, please update this file by hand" % (current_file)) read_plan = 0 elif actualSizeMatch: - actualSize = re.search('Actual size: (\d+)', line).group(1) + actualSize = re.search('Actual size: (\\d+)', line).group(1) elif expectedSizeMatch: - expectedSize = re.search('Expected size: (\d+)', line).group(1) + expectedSize = re.search('Expected size: (\\d+)', line).group(1) if not dryrun: replacePlanSize(current_file, actualSize, expectedSize) print("Changed plan size in %s \n" % (current_file)) diff --git a/src/test/unit/mock/mocker.py b/src/test/unit/mock/mocker.py index 3913b123138..271e0f42917 100755 --- a/src/test/unit/mock/mocker.py +++ b/src/test/unit/mock/mocker.py @@ -242,7 +242,7 @@ def make_body(self): if body: return body - subscript = re.compile('\[\d*\]$') + subscript = re.compile('\\[\\d*\\]$') # otherwise, general method buf = [] # emit check_expected() From 9df6f17309832c81738e20a4e5cbb336827a2876 Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 15:49:06 +0800 Subject: [PATCH 09/10] Fix the chown separator in the test image init scripts init_system.sh of the test images runs "sudo chown -R gpadmin.gpadmin /data1". A dot between the user and the group is the old syntax, and chown warns about it at the start of every test job and every container start: chown: warning: '.' should be ':': 'gpadmin.gpadmin' Use "gpadmin:gpadmin" in the six test images (Rocky 8, 9 and 10, Ubuntu 22.04, 24.04 and 26.04). It does the same, without the warning. Checked with GNU coreutils 9.4 (Ubuntu 24.04) and uutils coreutils 0.10.0 (Ubuntu 26.04): both warn for the dot, and neither warns for the colon. Assisted-by: Claude Code (cherry picked from commit 5e1fcf34011359d6de4727131e67d24f3a47d4c7) --- devops/deploy/docker/test/rocky10/configs/init_system.sh | 2 +- devops/deploy/docker/test/rocky8/configs/init_system.sh | 2 +- devops/deploy/docker/test/rocky9/configs/init_system.sh | 2 +- devops/deploy/docker/test/ubuntu22.04/configs/init_system.sh | 2 +- devops/deploy/docker/test/ubuntu24.04/configs/init_system.sh | 2 +- devops/deploy/docker/test/ubuntu26.04/configs/init_system.sh | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/devops/deploy/docker/test/rocky10/configs/init_system.sh b/devops/deploy/docker/test/rocky10/configs/init_system.sh index 3ea7e34b0ff..7135c814fcc 100755 --- a/devops/deploy/docker/test/rocky10/configs/init_system.sh +++ b/devops/deploy/docker/test/rocky10/configs/init_system.sh @@ -100,7 +100,7 @@ ssh-keyscan -t rsa cdw > /home/gpadmin/.ssh/known_hosts 2>/dev/null # -------------------------------------------------------------------- sudo rm -rf /data1/* sudo mkdir -p /data1/coordinator /data1/standby_coordinator /data1/primary /data1/mirror -sudo chown -R gpadmin.gpadmin /data1 +sudo chown -R gpadmin:gpadmin /data1 # Copy the gpinitsystem configuration file to the home directory cp /tmp/gpinitsystem.conf /home/gpadmin diff --git a/devops/deploy/docker/test/rocky8/configs/init_system.sh b/devops/deploy/docker/test/rocky8/configs/init_system.sh index 3ea7e34b0ff..7135c814fcc 100755 --- a/devops/deploy/docker/test/rocky8/configs/init_system.sh +++ b/devops/deploy/docker/test/rocky8/configs/init_system.sh @@ -100,7 +100,7 @@ ssh-keyscan -t rsa cdw > /home/gpadmin/.ssh/known_hosts 2>/dev/null # -------------------------------------------------------------------- sudo rm -rf /data1/* sudo mkdir -p /data1/coordinator /data1/standby_coordinator /data1/primary /data1/mirror -sudo chown -R gpadmin.gpadmin /data1 +sudo chown -R gpadmin:gpadmin /data1 # Copy the gpinitsystem configuration file to the home directory cp /tmp/gpinitsystem.conf /home/gpadmin diff --git a/devops/deploy/docker/test/rocky9/configs/init_system.sh b/devops/deploy/docker/test/rocky9/configs/init_system.sh index 3ea7e34b0ff..7135c814fcc 100755 --- a/devops/deploy/docker/test/rocky9/configs/init_system.sh +++ b/devops/deploy/docker/test/rocky9/configs/init_system.sh @@ -100,7 +100,7 @@ ssh-keyscan -t rsa cdw > /home/gpadmin/.ssh/known_hosts 2>/dev/null # -------------------------------------------------------------------- sudo rm -rf /data1/* sudo mkdir -p /data1/coordinator /data1/standby_coordinator /data1/primary /data1/mirror -sudo chown -R gpadmin.gpadmin /data1 +sudo chown -R gpadmin:gpadmin /data1 # Copy the gpinitsystem configuration file to the home directory cp /tmp/gpinitsystem.conf /home/gpadmin diff --git a/devops/deploy/docker/test/ubuntu22.04/configs/init_system.sh b/devops/deploy/docker/test/ubuntu22.04/configs/init_system.sh index 1928fe511d9..06f3f6d907f 100644 --- a/devops/deploy/docker/test/ubuntu22.04/configs/init_system.sh +++ b/devops/deploy/docker/test/ubuntu22.04/configs/init_system.sh @@ -103,7 +103,7 @@ ssh-keyscan -t rsa cdw > /home/gpadmin/.ssh/known_hosts 2>/dev/null # -------------------------------------------------------------------- sudo rm -rf /data1/* sudo mkdir -p /data1/coordinator /data1/standby_coordinator /data1/primary /data1/mirror -sudo chown -R gpadmin.gpadmin /data1 +sudo chown -R gpadmin:gpadmin /data1 # Copy the gpinitsystem configuration file to the home directory cp /tmp/gpinitsystem.conf /home/gpadmin diff --git a/devops/deploy/docker/test/ubuntu24.04/configs/init_system.sh b/devops/deploy/docker/test/ubuntu24.04/configs/init_system.sh index 09eadc2b736..30cf7abd8d3 100644 --- a/devops/deploy/docker/test/ubuntu24.04/configs/init_system.sh +++ b/devops/deploy/docker/test/ubuntu24.04/configs/init_system.sh @@ -103,7 +103,7 @@ ssh-keyscan -t rsa cdw > /home/gpadmin/.ssh/known_hosts 2>/dev/null # -------------------------------------------------------------------- sudo rm -rf /data1/* sudo mkdir -p /data1/coordinator /data1/standby_coordinator /data1/primary /data1/mirror -sudo chown -R gpadmin.gpadmin /data1 +sudo chown -R gpadmin:gpadmin /data1 # Copy the gpinitsystem configuration file to the home directory cp /tmp/gpinitsystem.conf /home/gpadmin diff --git a/devops/deploy/docker/test/ubuntu26.04/configs/init_system.sh b/devops/deploy/docker/test/ubuntu26.04/configs/init_system.sh index 09eadc2b736..30cf7abd8d3 100644 --- a/devops/deploy/docker/test/ubuntu26.04/configs/init_system.sh +++ b/devops/deploy/docker/test/ubuntu26.04/configs/init_system.sh @@ -103,7 +103,7 @@ ssh-keyscan -t rsa cdw > /home/gpadmin/.ssh/known_hosts 2>/dev/null # -------------------------------------------------------------------- sudo rm -rf /data1/* sudo mkdir -p /data1/coordinator /data1/standby_coordinator /data1/primary /data1/mirror -sudo chown -R gpadmin.gpadmin /data1 +sudo chown -R gpadmin:gpadmin /data1 # Copy the gpinitsystem configuration file to the home directory cp /tmp/gpinitsystem.conf /home/gpadmin From c42a802668e946f149f4869cf08e027c1fc91c0f Mon Sep 17 00:00:00 2001 From: Dianjin Wang Date: Sat, 10 Oct 2026 15:49:07 +0800 Subject: [PATCH 10/10] CI: fix the listing of the test results directory The test jobs of the build workflows list the files of the results directory with: find "$results_dir" -type f -ls >> "$log_file" 2>&1 | tee -a ... $log_file is not set in that step, so the redirection fails and the job log gets an error instead of the list: line 102: : No such file or directory The listing is lost, and the error appears in every test job that has a results directory, on all Ubuntu versions. Remove the redirection, so that the list goes to tee, which shows it and appends it to the results log of the configuration, as the other echo lines of the step already do. Assisted-by: Claude Code Backpatch-through: REL_2_STABLE (cherry picked from commit fe0b10d496c7f74447f82fb7f3fa4e17beccf920) --- .github/workflows/build-cloudberry.yml | 2 +- .github/workflows/build-dbg-cloudberry.yml | 2 +- .github/workflows/build-deb-cloudberry.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-cloudberry.yml b/.github/workflows/build-cloudberry.yml index 83dcad822ad..34c4f189a12 100644 --- a/.github/workflows/build-cloudberry.yml +++ b/.github/workflows/build-cloudberry.yml @@ -1679,7 +1679,7 @@ jobs: echo "Found results directory: $results_dir" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log echo "Contents of results directory:" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log - find "$results_dir" -type f -ls >> "$log_file" 2>&1 | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log + find "$results_dir" -type f -ls 2>&1 | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log echo "-----------------------------------------" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log else echo "-----------------------------------------" diff --git a/.github/workflows/build-dbg-cloudberry.yml b/.github/workflows/build-dbg-cloudberry.yml index 4c3c4fd0e27..76aa4590849 100644 --- a/.github/workflows/build-dbg-cloudberry.yml +++ b/.github/workflows/build-dbg-cloudberry.yml @@ -1220,7 +1220,7 @@ jobs: echo "Found results directory: $results_dir" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log echo "Contents of results directory:" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log - find "$results_dir" -type f -ls >> "$log_file" 2>&1 | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log + find "$results_dir" -type f -ls 2>&1 | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log echo "-----------------------------------------" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log else echo "-----------------------------------------" diff --git a/.github/workflows/build-deb-cloudberry.yml b/.github/workflows/build-deb-cloudberry.yml index 77be9fb7744..510137dd6c4 100644 --- a/.github/workflows/build-deb-cloudberry.yml +++ b/.github/workflows/build-deb-cloudberry.yml @@ -1482,7 +1482,7 @@ jobs: echo "Found results directory: $results_dir" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log echo "Contents of results directory:" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log - find "$results_dir" -type f -ls >> "$log_file" 2>&1 | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log + find "$results_dir" -type f -ls 2>&1 | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log echo "-----------------------------------------" | tee -a build-logs/details/make-${{ matrix.test }}-config$i-results.log else echo "-----------------------------------------"