forked from TrueCloudLab/rclone
azureblob: Implemented settier command support on azureblob remote, this supports to
change tier on objects. Added internal test to check if feature flags are set correctly
This commit is contained in:
parent
5716a58413
commit
aac84c554a
2 changed files with 93 additions and 19 deletions
|
@ -178,6 +178,32 @@ func parsePath(path string) (container, directory string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateAccessTier checks if azureblob supports user supplied tier
|
||||||
|
func validateAccessTier(tier string) bool {
|
||||||
|
switch tier {
|
||||||
|
case string(azblob.AccessTierHot),
|
||||||
|
string(azblob.AccessTierCool),
|
||||||
|
string(azblob.AccessTierArchive):
|
||||||
|
// valid cases
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validAccessTiers returns list of supported storage tiers on azureblob fs
|
||||||
|
func validAccessTiers() []string {
|
||||||
|
validTiers := [...]azblob.AccessTierType{azblob.AccessTierHot, azblob.AccessTierCool,
|
||||||
|
azblob.AccessTierArchive}
|
||||||
|
|
||||||
|
var tiers [len(validTiers)]string
|
||||||
|
|
||||||
|
for i, tier := range validTiers {
|
||||||
|
tiers[i] = string(tier)
|
||||||
|
}
|
||||||
|
return tiers[:]
|
||||||
|
}
|
||||||
|
|
||||||
// retryErrorCodes is a slice of error codes that we will retry
|
// retryErrorCodes is a slice of error codes that we will retry
|
||||||
var retryErrorCodes = []int{
|
var retryErrorCodes = []int{
|
||||||
401, // Unauthorized (eg "Token has expired")
|
401, // Unauthorized (eg "Token has expired")
|
||||||
|
@ -231,15 +257,9 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
|
|
||||||
if opt.AccessTier == "" {
|
if opt.AccessTier == "" {
|
||||||
opt.AccessTier = string(defaultAccessTier)
|
opt.AccessTier = string(defaultAccessTier)
|
||||||
} else {
|
} else if !validateAccessTier(opt.AccessTier) {
|
||||||
switch opt.AccessTier {
|
return nil, errors.Errorf("Azure Blob: Supported access tiers are %s, %s and %s",
|
||||||
case string(azblob.AccessTierHot):
|
string(azblob.AccessTierHot), string(azblob.AccessTierCool), string(azblob.AccessTierArchive))
|
||||||
case string(azblob.AccessTierCool):
|
|
||||||
case string(azblob.AccessTierArchive):
|
|
||||||
// valid cases
|
|
||||||
default:
|
|
||||||
return nil, errors.Errorf("azure: Supported access tiers are %s, %s and %s", string(azblob.AccessTierHot), string(azblob.AccessTierCool), azblob.AccessTierArchive)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -299,6 +319,9 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) {
|
||||||
ReadMimeType: true,
|
ReadMimeType: true,
|
||||||
WriteMimeType: true,
|
WriteMimeType: true,
|
||||||
BucketBased: true,
|
BucketBased: true,
|
||||||
|
SetTier: true,
|
||||||
|
GetTier: true,
|
||||||
|
ListTiers: true,
|
||||||
}).Fill(f)
|
}).Fill(f)
|
||||||
if f.root != "" {
|
if f.root != "" {
|
||||||
f.root += "/"
|
f.root += "/"
|
||||||
|
@ -1254,16 +1277,7 @@ func (o *Object) Update(in io.Reader, src fs.ObjectInfo, options ...fs.OpenOptio
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, set blob tier based on configured access tier
|
// Now, set blob tier based on configured access tier
|
||||||
desiredAccessTier := azblob.AccessTierType(o.fs.opt.AccessTier)
|
return o.SetTier(o.fs.opt.AccessTier)
|
||||||
err = o.fs.pacer.Call(func() (bool, error) {
|
|
||||||
_, err := blob.SetTier(ctx, desiredAccessTier)
|
|
||||||
return o.fs.shouldRetry(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "Failed to set Blob Tier")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove an object
|
// Remove an object
|
||||||
|
@ -1288,6 +1302,46 @@ func (o *Object) AccessTier() azblob.AccessTierType {
|
||||||
return o.accessTier
|
return o.accessTier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetTier performs changing object tier
|
||||||
|
func (o *Object) SetTier(tier string) error {
|
||||||
|
if !validateAccessTier(tier) {
|
||||||
|
return errors.Errorf("Tier %s not supported by Azure Blob Storage", tier)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if current tier already matches with desired tier
|
||||||
|
if o.GetTier() == tier {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
desiredAccessTier := azblob.AccessTierType(tier)
|
||||||
|
blob := o.getBlobReference()
|
||||||
|
ctx := context.Background()
|
||||||
|
err := o.fs.pacer.Call(func() (bool, error) {
|
||||||
|
_, err := blob.SetTier(ctx, desiredAccessTier)
|
||||||
|
return o.fs.shouldRetry(err)
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Failed to set Blob Tier")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set access tier on local object also, this typically
|
||||||
|
// gets updated on get blob properties
|
||||||
|
o.accessTier = desiredAccessTier
|
||||||
|
fs.Debugf(o, "Successfully changed object tier to %s", tier)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTier returns object tier in azure as string
|
||||||
|
func (o *Object) GetTier() string {
|
||||||
|
return string(o.accessTier)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListTiers returns list of storage tiers supported on this object
|
||||||
|
func (o *Object) ListTiers() []string {
|
||||||
|
return validAccessTiers()
|
||||||
|
}
|
||||||
|
|
||||||
// Check the interfaces are satisfied
|
// Check the interfaces are satisfied
|
||||||
var (
|
var (
|
||||||
_ fs.Fs = &Fs{}
|
_ fs.Fs = &Fs{}
|
||||||
|
|
20
backend/azureblob/azureblob_internal_test.go
Normal file
20
backend/azureblob/azureblob_internal_test.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// +build !freebsd,!netbsd,!openbsd,!plan9,!solaris,go1.8
|
||||||
|
|
||||||
|
package azureblob
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (f *Fs) InternalTest(t *testing.T) {
|
||||||
|
// Check first feature flags are set on this
|
||||||
|
// remote
|
||||||
|
enabled := f.Features().ListTiers
|
||||||
|
assert.True(t, enabled)
|
||||||
|
enabled = f.Features().SetTier
|
||||||
|
assert.True(t, enabled)
|
||||||
|
enabled = f.Features().GetTier
|
||||||
|
assert.True(t, enabled)
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue