From 369c7e048abeac6f1c26da98703cc29c85d54b10 Mon Sep 17 00:00:00 2001 From: chrislu Date: Thu, 6 Nov 2025 11:58:31 -0800 Subject: [PATCH] apply the patch --- test/foundationdb/Dockerfile.build | 20 +- test/foundationdb/docker-compose.yml | 177 ++++++++---------- .../foundationdb_concurrent_test.go | 2 +- .../foundationdb_integration_test.go | 2 +- test/foundationdb/test_fdb_s3.sh | 2 +- test/foundationdb/wait_for_services.sh | 4 +- weed/filer/foundationdb/foundationdb_store.go | 8 +- .../foundationdb/foundationdb_store_test.go | 13 +- 8 files changed, 101 insertions(+), 127 deletions(-) diff --git a/test/foundationdb/Dockerfile.build b/test/foundationdb/Dockerfile.build index eb9016806..4b92d4de9 100644 --- a/test/foundationdb/Dockerfile.build +++ b/test/foundationdb/Dockerfile.build @@ -2,6 +2,9 @@ # Force x86_64 platform to use AMD64 FoundationDB packages FROM --platform=linux/amd64 golang:1.24-bookworm +ARG FOUNDATIONDB_VERSION=7.4.5 +ENV FOUNDATIONDB_VERSION=${FOUNDATIONDB_VERSION} + # Install system dependencies and FoundationDB RUN apt-get update && apt-get install -y \ build-essential \ @@ -11,9 +14,9 @@ RUN apt-get update && apt-get install -y \ # Install FoundationDB client libraries (x86_64 emulation) RUN echo "๐Ÿ—๏ธ Installing FoundationDB AMD64 package with x86_64 emulation..." \ - && wget -q https://github.com/apple/foundationdb/releases/download/7.1.61/foundationdb-clients_7.1.61-1_amd64.deb \ - && dpkg -i foundationdb-clients_7.1.61-1_amd64.deb \ - && rm foundationdb-clients_7.1.61-1_amd64.deb \ + && wget -q https://github.com/apple/foundationdb/releases/download/${FOUNDATIONDB_VERSION}/foundationdb-clients_${FOUNDATIONDB_VERSION}-1_amd64.deb \ + && dpkg -i foundationdb-clients_${FOUNDATIONDB_VERSION}-1_amd64.deb \ + && rm foundationdb-clients_${FOUNDATIONDB_VERSION}-1_amd64.deb \ && echo "๐Ÿ” Verifying FoundationDB installation..." \ && ls -la /usr/include/foundationdb/ \ && ls -la /usr/lib/*/libfdb_c* 2>/dev/null || echo "Library files:" \ @@ -23,7 +26,7 @@ RUN echo "๐Ÿ—๏ธ Installing FoundationDB AMD64 package with x86_64 emulation... # Set up Go environment for CGO ENV CGO_ENABLED=1 ENV GOOS=linux -ENV CGO_CFLAGS="-I/usr/include/foundationdb -I/usr/local/include/foundationdb -DFDB_API_VERSION=630" +ENV CGO_CFLAGS="-I/usr/include/foundationdb -I/usr/local/include/foundationdb -DFDB_USE_LATEST_API_VERSION" ENV CGO_LDFLAGS="-L/usr/lib -lfdb_c" # Create work directory @@ -34,6 +37,9 @@ COPY . . # Using Go 1.24 to match project requirements +# Download foundationdb binding +RUN go get github.com/apple/foundationdb/bindings/go@${FOUNDATIONDB_VERSION} + # Download dependencies (using versions from go.mod for deterministic builds) RUN go mod download @@ -46,9 +52,9 @@ RUN echo "๐Ÿ”จ Building SeaweedFS with FoundationDB support..." && \ echo "CGO_CFLAGS: $CGO_CFLAGS" && \ echo "CGO_LDFLAGS: $CGO_LDFLAGS" && \ go build -tags foundationdb -ldflags="-w -s" -o weed ./weed && \ - chmod +x weed && \ + chmod +x ./weed/weed && \ echo "โœ… Build successful!" && \ - ./weed version + ./weed/weed version # Test compilation (don't run tests as they need cluster) RUN echo "๐Ÿงช Compiling tests..." && \ @@ -59,7 +65,7 @@ RUN echo "๐Ÿงช Compiling tests..." && \ RUN mkdir -p /var/fdb/config /usr/local/bin # Copy binaries to final location -RUN cp weed /usr/local/bin/weed && \ +RUN cp weed/weed /usr/local/bin/weed && \ cp fdb_store_test /usr/local/bin/fdb_store_test # Default command diff --git a/test/foundationdb/docker-compose.yml b/test/foundationdb/docker-compose.yml index 938cd1ab3..2cf7b9c9e 100644 --- a/test/foundationdb/docker-compose.yml +++ b/test/foundationdb/docker-compose.yml @@ -1,111 +1,83 @@ -version: '3.9' - services: - # FoundationDB cluster nodes + fdb1: - image: foundationdb/foundationdb:7.1.61 - platform: linux/amd64 + image: $FOUNDATIONDB_IMAGE environment: - - FDB_NETWORKING_MODE=host - - FDB_COORDINATOR_PORT=4500 - - FDB_PORT=4501 - ports: - - "4500:4500" - - "4501:4501" - volumes: - - fdb1_data:/var/fdb/data - - fdb_config:/var/fdb/config + - FDB_CLUSTER_FILE_CONTENTS + - FDB_NETWORKING_MODE=container + - FDB_COORDINATOR_PORT=$FDB_PORT + - FDB_PORT=$FDB_PORT networks: - fdb_network - command: | - bash -c " - # Initialize cluster configuration - if [ ! -f /var/fdb/config/fdb.cluster ]; then - echo 'testing:testing@fdb1:4500,fdb2:4500,fdb3:4500' > /var/fdb/config/fdb.cluster - fi - # Start FDB processes - /usr/bin/fdbserver --config_path=/var/fdb/config --datadir=/var/fdb/data --logdir=/var/fdb/logs --public_address=fdb1:4501 --listen_address=0.0.0.0:4501 --coordination=fdb1:4500 & - /usr/bin/fdbserver --config_path=/var/fdb/config --datadir=/var/fdb/data --logdir=/var/fdb/logs --public_address=fdb1:4500 --listen_address=0.0.0.0:4500 --coordination=fdb1:4500 --class=coordination & - wait - " + healthcheck: + test: [ "CMD", "nc", "-z", "127.0.0.1", "4500" ] + interval: 5s + timeout: 5s + retries: 60 fdb2: - image: foundationdb/foundationdb:7.1.61 - platform: linux/amd64 + image: $FOUNDATIONDB_IMAGE environment: - - FDB_NETWORKING_MODE=host - - FDB_COORDINATOR_PORT=4502 - - FDB_PORT=4503 - ports: - - "4502:4502" - - "4503:4503" - volumes: - - fdb2_data:/var/fdb/data - - fdb_config:/var/fdb/config + - FDB_CLUSTER_FILE_CONTENTS + - FDB_NETWORKING_MODE=container + - FDB_COORDINATOR_PORT=$FDB_PORT + - FDB_PORT=$FDB_PORT networks: - fdb_network - depends_on: - - fdb1 - command: | - bash -c " - # Wait for cluster file from fdb1 - while [ ! -f /var/fdb/config/fdb.cluster ]; do sleep 1; done - # Start FDB processes - /usr/bin/fdbserver --config_path=/var/fdb/config --datadir=/var/fdb/data --logdir=/var/fdb/logs --public_address=fdb2:4503 --listen_address=0.0.0.0:4503 --coordination=fdb1:4500 & - /usr/bin/fdbserver --config_path=/var/fdb/config --datadir=/var/fdb/data --logdir=/var/fdb/logs --public_address=fdb2:4502 --listen_address=0.0.0.0:4502 --coordination=fdb1:4500 --class=coordination & - wait - " + healthcheck: + test: [ "CMD", "nc", "-z", "127.0.0.1", "4500" ] + interval: 5s + timeout: 5s + retries: 60 fdb3: - image: foundationdb/foundationdb:7.1.61 - platform: linux/amd64 + image: $FOUNDATIONDB_IMAGE environment: - - FDB_NETWORKING_MODE=host - - FDB_COORDINATOR_PORT=4504 - - FDB_PORT=4505 - ports: - - "4504:4504" - - "4505:4505" - volumes: - - fdb3_data:/var/fdb/data - - fdb_config:/var/fdb/config + - FDB_CLUSTER_FILE_CONTENTS + - FDB_NETWORKING_MODE=container + - FDB_COORDINATOR_PORT=$FDB_PORT + - FDB_PORT=$FDB_PORT networks: - fdb_network - depends_on: - - fdb1 - command: | - bash -c " - # Wait for cluster file from fdb1 - while [ ! -f /var/fdb/config/fdb.cluster ]; do sleep 1; done - # Start FDB processes - /usr/bin/fdbserver --config_path=/var/fdb/config --datadir=/var/fdb/data --logdir=/var/fdb/logs --public_address=fdb3:4505 --listen_address=0.0.0.0:4505 --coordination=fdb1:4500 & - /usr/bin/fdbserver --config_path=/var/fdb/config --datadir=/var/fdb/data --logdir=/var/fdb/logs --public_address=fdb3:4504 --listen_address=0.0.0.0:4504 --coordination=fdb1:4500 --class=coordination & - wait - " + healthcheck: + test: [ "CMD", "nc", "-z", "127.0.0.1", "4500" ] + interval: 5s + timeout: 5s + retries: 60 # Initialize and configure the database fdb-init: - image: foundationdb/foundationdb:7.1.61 + image: $FOUNDATIONDB_IMAGE platform: linux/amd64 - volumes: - - fdb_config:/var/fdb/config + configs: + - target: /var/fdb/config/fdb.cluster + source: fdb.cluster + environment: + - FDB_CLUSTER_FILE=/var/fdb/config/fdb.cluster networks: - fdb_network depends_on: - - fdb1 - - fdb2 - - fdb3 - command: | + fdb1: + condition: service_healthy + fdb2: + condition: service_healthy + fdb3: + condition: service_healthy + entrypoint: | bash -c " - # Wait for cluster file - while [ ! -f /var/fdb/config/fdb.cluster ]; do sleep 1; done - + set -o errexit # Wait for cluster to be ready sleep 10 # Configure database echo 'Initializing FoundationDB database...' - fdbcli --exec 'configure new single ssd' + if ! fdbcli --exec 'configure new single ssd' >/tmp/fdbcli.out 2>&1; then + if ! grep -qi 'ERROR: Database already exists!' /tmp/fdbcli.out >/dev/null 2>/dev/null; then + echo 'ERROR: Database initialization failed!' >&2 + cat /tmp/fdbcli.out >&2 + exit 1 + fi + fi # Wait for configuration to complete sleep 5 @@ -114,44 +86,43 @@ services: fdbcli --exec 'status' echo 'FoundationDB cluster initialization complete!' - - # Keep container running for debugging if needed - tail -f /dev/null " # SeaweedFS service with FoundationDB filer seaweedfs: - image: chrislusf/seaweedfs:local + image: $SEAWEEDFS_IMAGE + depends_on: + fdb-init: + condition: service_completed_successfully + networks: + - fdb_network ports: - "9333:9333" - "19333:19333" - "8888:8888" - "8333:8333" - "18888:18888" - command: "server -ip=seaweedfs -filer -master.volumeSizeLimitMB=16 -volume.max=0 -volume -volume.preStopSeconds=1 -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8333 -s3.allowEmptyFolder=false -s3.allowDeleteBucketNotEmpty=false" + configs: + - target: /var/fdb/config/fdb.cluster + source: fdb.cluster volumes: - ./s3.json:/etc/seaweedfs/s3.json - ./filer.toml:/etc/seaweedfs/filer.toml - - fdb_config:/var/fdb/config environment: - WEED_LEVELDB2_ENABLED: "false" - WEED_FOUNDATIONDB_ENABLED: "true" - WEED_FOUNDATIONDB_CLUSTER_FILE: "/var/fdb/config/fdb.cluster" - WEED_FOUNDATIONDB_API_VERSION: "720" - WEED_FOUNDATIONDB_TIMEOUT: "5s" - WEED_FOUNDATIONDB_MAX_RETRY_DELAY: "1s" - WEED_MASTER_VOLUME_GROWTH_COPY_1: 1 - WEED_MASTER_VOLUME_GROWTH_COPY_OTHER: 1 - networks: - - fdb_network - depends_on: - - fdb-init + - WEED_LEVELDB2_ENABLED + - WEED_FOUNDATIONDB_ENABLED + - WEED_FOUNDATIONDB_CLUSTER_FILE + - WEED_FOUNDATIONDB_API_VERSION + - WEED_FOUNDATIONDB_TIMEOUT + - WEED_FOUNDATIONDB_MAX_RETRY_DELAY + - WEED_MASTER_VOLUME_GROWTH_COPY_1=1 + - WEED_MASTER_VOLUME_GROWTH_COPY_OTHER=1 + command: "weed server -ip=seaweedfs -filer -master.volumeSizeLimitMB=16 -volume.max=0 -volume -volume.preStopSeconds=1 -s3 -s3.config=/etc/seaweedfs/s3.json -s3.port=8333 -s3.allowEmptyFolder=false -s3.allowDeleteBucketNotEmpty=false" -volumes: - fdb1_data: - fdb2_data: - fdb3_data: - fdb_config: +configs: + fdb.cluster: + content: | + $FDB_CLUSTER_FILE_CONTENTS networks: fdb_network: diff --git a/test/foundationdb/foundationdb_concurrent_test.go b/test/foundationdb/foundationdb_concurrent_test.go index f18a3fabb..aafc279bc 100644 --- a/test/foundationdb/foundationdb_concurrent_test.go +++ b/test/foundationdb/foundationdb_concurrent_test.go @@ -428,7 +428,7 @@ func createTestStore(t *testing.T) *foundationdb.FoundationDBStore { t.Skip("FoundationDB cluster file not found, skipping test") } - config := util.NewViper() + config := util.GetViper() config.Set("foundationdb.cluster_file", clusterFile) config.Set("foundationdb.api_version", 720) config.Set("foundationdb.timeout", "10s") diff --git a/test/foundationdb/foundationdb_integration_test.go b/test/foundationdb/foundationdb_integration_test.go index e6245050a..24084c61a 100644 --- a/test/foundationdb/foundationdb_integration_test.go +++ b/test/foundationdb/foundationdb_integration_test.go @@ -352,7 +352,7 @@ func createTestStore(t *testing.T) *foundationdb.FoundationDBStore { t.Skip("FoundationDB cluster file not found, skipping test") } - config := util.NewViper() + config := util.GetViper() config.Set("foundationdb.cluster_file", clusterFile) config.Set("foundationdb.api_version", 630) config.Set("foundationdb.timeout", "10s") diff --git a/test/foundationdb/test_fdb_s3.sh b/test/foundationdb/test_fdb_s3.sh index fb1e6cb74..95078ab10 100755 --- a/test/foundationdb/test_fdb_s3.sh +++ b/test/foundationdb/test_fdb_s3.sh @@ -97,7 +97,7 @@ fi echo -e "${BLUE}Test: FoundationDB backend verification${NC}" # Check that data is actually stored in FoundationDB -docker-compose exec -T fdb-init fdbcli --exec 'getrange seaweedfs seaweedfs\xFF' > fdb_keys.txt || true +docker-compose exec -T fdb1 fdbcli --exec 'getrange seaweedfs seaweedfs\xFF' > fdb_keys.txt || true if [ -s fdb_keys.txt ] && grep -q "seaweedfs" fdb_keys.txt; then echo -e "${GREEN}โœ… Data confirmed in FoundationDB backend${NC}" diff --git a/test/foundationdb/wait_for_services.sh b/test/foundationdb/wait_for_services.sh index 8653bf513..7904c401c 100755 --- a/test/foundationdb/wait_for_services.sh +++ b/test/foundationdb/wait_for_services.sh @@ -17,7 +17,7 @@ MAX_ATTEMPTS=30 ATTEMPT=0 while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do - if docker-compose exec -T fdb-init fdbcli --exec 'status' > /dev/null 2>&1; then + if docker-compose exec -T fdb1 fdbcli --exec 'status' > /dev/null 2>&1; then echo -e "${GREEN}โœ… FoundationDB cluster is ready${NC}" break fi @@ -103,7 +103,7 @@ echo -e "${GREEN}๐ŸŽ‰ All services are ready!${NC}" # Display final status echo -e "${BLUE}Final status check:${NC}" -docker-compose exec -T fdb-init fdbcli --exec 'status' +docker-compose exec -T fdb1 fdbcli --exec 'status' echo "" echo -e "${BLUE}SeaweedFS cluster info:${NC}" curl -s http://127.0.0.1:9333/cluster/status | head -20 diff --git a/weed/filer/foundationdb/foundationdb_store.go b/weed/filer/foundationdb/foundationdb_store.go index d8c17251c..d55cc192b 100644 --- a/weed/filer/foundationdb/foundationdb_store.go +++ b/weed/filer/foundationdb/foundationdb_store.go @@ -63,7 +63,6 @@ func init() { type FoundationDBStore struct { database fdb.Database - dirLayer directory.Directory seaweedfsDir directory.DirectorySubspace kvDir directory.DirectorySubspace directoryPrefix string @@ -135,17 +134,14 @@ func (store *FoundationDBStore) initialize(clusterFile string, apiVersion int) e return fmt.Errorf("failed to open FoundationDB database: %v", err) } - // Create directory layer - store.dirLayer = directory.NewDirectoryLayer(subspace.Sub(), subspace.Sub(), false) - // Create/open seaweedfs directory - store.seaweedfsDir, err = store.dirLayer.CreateOrOpen(store.database, []string{store.directoryPrefix}, nil) + store.seaweedfsDir, err = directory.CreateOrOpen(store.database, []string{store.directoryPrefix, "data"}, nil) if err != nil { return fmt.Errorf("failed to create/open seaweedfs directory: %v", err) } // Create/open kv subdirectory for key-value operations - store.kvDir, err = store.dirLayer.CreateOrOpen(store.database, []string{store.directoryPrefix, "kv"}, nil) + store.kvDir, err = directory.CreateOrOpen(store.database, []string{store.directoryPrefix, "kv"}, nil) if err != nil { return fmt.Errorf("failed to create/open kv directory: %v", err) } diff --git a/weed/filer/foundationdb/foundationdb_store_test.go b/weed/filer/foundationdb/foundationdb_store_test.go index 63f681956..044f12cdd 100644 --- a/weed/filer/foundationdb/foundationdb_store_test.go +++ b/weed/filer/foundationdb/foundationdb_store_test.go @@ -5,6 +5,7 @@ package foundationdb import ( "context" + "fmt" "os" "testing" "time" @@ -16,7 +17,7 @@ import ( func TestFoundationDBStore_Initialize(t *testing.T) { // Test with default configuration - config := util.NewViper() + config := util.GetViper() config.Set("foundationdb.cluster_file", getTestClusterFile()) config.Set("foundationdb.api_version", 630) @@ -38,7 +39,7 @@ func TestFoundationDBStore_Initialize(t *testing.T) { } func TestFoundationDBStore_InitializeWithCustomConfig(t *testing.T) { - config := util.NewViper() + config := util.GetViper() config.Set("foundationdb.cluster_file", getTestClusterFile()) config.Set("foundationdb.api_version", 630) config.Set("foundationdb.timeout", "10s") @@ -97,7 +98,7 @@ func TestFoundationDBStore_InitializeInvalidConfig(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - config := util.NewViper() + config := util.GetViper() for key, value := range tt.config { config.Set(key, value) } @@ -282,7 +283,7 @@ func BenchmarkFoundationDBStore_InsertEntry(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - entry.FullPath = util.NewFullPath("/benchmark", util.Uint64toHex(uint64(i))+".txt") + entry.FullPath = util.NewFullPath("/benchmark", fmt.Sprintf("%x", uint64(i))+".txt") err := store.InsertEntry(ctx, entry) if err != nil { b.Fatalf("InsertEntry failed: %v", err) @@ -300,7 +301,7 @@ func BenchmarkFoundationDBStore_FindEntry(b *testing.B) { numEntries := 1000 for i := 0; i < numEntries; i++ { entry := &filer.Entry{ - FullPath: util.NewFullPath("/benchmark", util.Uint64toHex(uint64(i))+".txt"), + FullPath: util.NewFullPath("/benchmark", fmt.Sprintf("%x", uint64(i))+".txt"), Attr: filer.Attr{ Mode: 0644, Uid: 1000, @@ -316,7 +317,7 @@ func BenchmarkFoundationDBStore_FindEntry(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - path := util.NewFullPath("/benchmark", util.Uint64toHex(uint64(i%numEntries))+".txt") + path := util.NewFullPath("/benchmark", fmt.Sprintf("%x", uint64(i%numEntries))+".txt") _, err := store.FindEntry(ctx, path) if err != nil { b.Fatalf("FindEntry failed: %v", err)