1
0
mirror of https://github.com/rclone/rclone.git synced 2025-11-23 21:44:49 +02:00

swift: If storage_policy isn't set, use the root containers policy

Ensure that if we need to create a segments container it uses the same
storage policy as the root container.

Fixes #8858
This commit is contained in:
Andrew Ruthven
2025-09-30 07:57:56 +00:00
committed by Nick Craig-Wood
parent 94829aaec5
commit 04e91838db
4 changed files with 106 additions and 1 deletions

View File

@@ -561,6 +561,21 @@ func (f *Fs) setRoot(root string) {
f.rootContainer, f.rootDirectory = bucket.Split(f.root) f.rootContainer, f.rootDirectory = bucket.Split(f.root)
} }
// Fetch the base container's policy to be used if/when we need to create a
// segments container to ensure we use the same policy.
func (f *Fs) fetchStoragePolicy(ctx context.Context, container string) (fs.Fs, error) {
err := f.pacer.Call(func() (bool, error) {
var rxHeaders swift.Headers
_, rxHeaders, err := f.c.Container(ctx, container)
f.opt.StoragePolicy = rxHeaders["X-Storage-Policy"]
fs.Debugf(f, "Auto set StoragePolicy to %s", f.opt.StoragePolicy)
return shouldRetryHeaders(ctx, rxHeaders, err)
})
return nil, err
}
// NewFsWithConnection constructs an Fs from the path, container:path // NewFsWithConnection constructs an Fs from the path, container:path
// and authenticated connection. // and authenticated connection.
// //
@@ -590,6 +605,7 @@ func NewFsWithConnection(ctx context.Context, opt *Options, name, root string, c
f.opt.UseSegmentsContainer.Valid = true f.opt.UseSegmentsContainer.Valid = true
fs.Debugf(f, "Auto set use_segments_container to %v", f.opt.UseSegmentsContainer.Value) fs.Debugf(f, "Auto set use_segments_container to %v", f.opt.UseSegmentsContainer.Value)
} }
if f.rootContainer != "" && f.rootDirectory != "" { if f.rootContainer != "" && f.rootDirectory != "" {
// Check to see if the object exists - ignoring directory markers // Check to see if the object exists - ignoring directory markers
var info swift.Object var info swift.Object
@@ -1132,6 +1148,13 @@ func (f *Fs) newSegmentedUpload(ctx context.Context, dstContainer string, dstPat
container: dstContainer, container: dstContainer,
} }
if f.opt.UseSegmentsContainer.Value { if f.opt.UseSegmentsContainer.Value {
if f.opt.StoragePolicy == "" {
_, err = f.fetchStoragePolicy(ctx, dstContainer)
if err != nil {
return nil, err
}
}
su.container += segmentsContainerSuffix su.container += segmentsContainerSuffix
err = f.makeContainer(ctx, su.container) err = f.makeContainer(ctx, su.container)
if err != nil { if err != nil {

View File

@@ -76,6 +76,7 @@ func (f *Fs) testNoChunk(t *testing.T) {
// Additional tests that aren't in the framework // Additional tests that aren't in the framework
func (f *Fs) InternalTest(t *testing.T) { func (f *Fs) InternalTest(t *testing.T) {
t.Run("PolicyDiscovery", f.testPolicyDiscovery)
t.Run("NoChunk", f.testNoChunk) t.Run("NoChunk", f.testNoChunk)
t.Run("WithChunk", f.testWithChunk) t.Run("WithChunk", f.testWithChunk)
t.Run("WithChunkFail", f.testWithChunkFail) t.Run("WithChunkFail", f.testWithChunkFail)
@@ -195,4 +196,50 @@ func (f *Fs) testCopyLargeObject(t *testing.T) {
require.Equal(t, obj.Size(), objTarget.Size()) require.Equal(t, obj.Size(), objTarget.Size())
} }
func (f *Fs) testPolicyDiscovery(t *testing.T) {
ctx := context.TODO()
container := "testPolicyDiscovery-1"
// Reset the policy so we can test if it is populated.
f.opt.StoragePolicy = ""
err := f.makeContainer(ctx, container)
require.NoError(t, err)
_, err = f.fetchStoragePolicy(ctx, container)
require.NoError(t, err)
// Default policy for Swift is Policy-0.
assert.Equal(t, "Policy-0", f.opt.StoragePolicy)
// Create a container using a non-default policy, and check to ensure
// that the created segments container uses the same non-default policy.
policy := "Policy-1"
container = "testPolicyDiscovery-2"
f.opt.StoragePolicy = policy
err = f.makeContainer(ctx, container)
require.NoError(t, err)
// Reset the policy so we can test if it is populated, and set to the
// non-default policy.
f.opt.StoragePolicy = ""
_, err = f.fetchStoragePolicy(ctx, container)
require.NoError(t, err)
assert.Equal(t, policy, f.opt.StoragePolicy)
// Test that when a segmented upload container is made, the newly
// created container inherits the non-default policy of the base
// container.
f.opt.StoragePolicy = ""
f.opt.UseSegmentsContainer.Value = true
su, err := f.newSegmentedUpload(ctx, container, "")
require.NoError(t, err)
// The container name we expected?
segmentsContainer := container + segmentsContainerSuffix
assert.Equal(t, segmentsContainer, su.container)
// The policy we expected?
f.opt.StoragePolicy = ""
_, err = f.fetchStoragePolicy(ctx, su.container)
require.NoError(t, err)
assert.Equal(t, policy, f.opt.StoragePolicy)
}
var _ fstests.InternalTester = (*Fs)(nil) var _ fstests.InternalTester = (*Fs)(nil)

View File

@@ -8,8 +8,10 @@ PORT=28628
. $(dirname "$0")/docker.bash . $(dirname "$0")/docker.bash
start() { start() {
# We need to replace the remakerings in the container to create Policy-1.
docker run --rm -d --name ${NAME} \ docker run --rm -d --name ${NAME} \
-p 127.0.0.1:${PORT}:8080 \ -p 127.0.0.1:${PORT}:8080 \
-v $(dirname "$0")/TestSwiftAIO.d/remakerings:/swift/bin/remakerings:ro \
bouncestorage/swift-aio bouncestorage/swift-aio
echo type=swift echo type=swift

View File

@@ -0,0 +1,33 @@
#!/bin/bash
cd /etc/swift
if ! grep storage-policy swift.conf; then
cat <<EOF >> swift.conf
# Policy-0 is the default, we need two policies to test policy inheritance.
[storage-policy:0]
name = Policy-0
default = true
[storage-policy:1]
name = Policy-1
EOF
fi
rm -f *.builder *.ring.gz backups/*.builder backups/*.ring.gz
swift-ring-builder object.builder create 10 1 1
swift-ring-builder object.builder add r1z1-127.0.0.1:6010/sdb1 1
swift-ring-builder object.builder rebalance
swift-ring-builder container.builder create 10 1 1
swift-ring-builder container.builder add r1z1-127.0.0.1:6011/sdb1 1
swift-ring-builder container.builder rebalance
swift-ring-builder account.builder create 10 1 1
swift-ring-builder account.builder add r1z1-127.0.0.1:6012/sdb1 1
swift-ring-builder account.builder rebalance
# For Policy-1:
swift-ring-builder object-1.builder create 10 1 1
swift-ring-builder object-1.builder add r1z1-127.0.0.1:6010/sdb1 1
swift-ring-builder object-1.builder rebalance