Made the list of archive classes configureable
This commit is contained in:
@@ -38,18 +38,55 @@ namespace Duplicati.Library.Backend
|
||||
/// </summary>
|
||||
public class S3AwsClient : IS3Client
|
||||
{
|
||||
private static readonly string LOGTAG = Logging.Log.LogTagFromType<S3AwsClient>();
|
||||
/// <summary>
|
||||
/// The maximum number of items to list in a single request
|
||||
/// </summary>
|
||||
private const int ITEM_LIST_LIMIT = 1000;
|
||||
|
||||
/// <summary>
|
||||
/// The prefix for extended options
|
||||
/// </summary>
|
||||
private const string EXT_OPTION_PREFIX = "s3-ext-";
|
||||
|
||||
/// <summary>
|
||||
/// The location constraint for the bucket
|
||||
/// </summary>
|
||||
private readonly string m_locationConstraint;
|
||||
/// <summary>
|
||||
/// The storage class for the bucket
|
||||
/// </summary>
|
||||
private readonly string m_storageClass;
|
||||
/// <summary>
|
||||
/// The S3 client
|
||||
/// </summary>
|
||||
private AmazonS3Client m_client;
|
||||
/// <summary>
|
||||
/// The option to specify if chunk encoding should be used
|
||||
/// </summary>
|
||||
private readonly bool m_useChunkEncoding;
|
||||
|
||||
/// <summary>
|
||||
/// The DNS host of the S3 server
|
||||
/// </summary>
|
||||
private readonly string m_dnsHost;
|
||||
|
||||
/// <summary>
|
||||
/// The archive classes that are considered archive classes
|
||||
/// </summary>
|
||||
private readonly IReadOnlySet<S3StorageClass> m_archiveClasses;
|
||||
|
||||
/// <summary>
|
||||
/// The option to specify the archive classes
|
||||
/// </summary>
|
||||
public const string S3_ARCHIVE_CLASSES_OPTION = "s3-archive-classes";
|
||||
|
||||
/// <summary>
|
||||
/// The default storage classes that are considered archive classes
|
||||
/// </summary>
|
||||
public static readonly IReadOnlySet<S3StorageClass> DEFAULT_ARCHIVE_CLASSES = new HashSet<S3StorageClass>([
|
||||
S3StorageClass.DeepArchive, S3StorageClass.Glacier, S3StorageClass.GlacierInstantRetrieval, S3StorageClass.Snow
|
||||
]);
|
||||
|
||||
public S3AwsClient(string awsID, string awsKey, string locationConstraint, string servername,
|
||||
string storageClass, bool useSSL, bool disableChunkEncoding, Dictionary<string, string> options)
|
||||
{
|
||||
@@ -65,6 +102,20 @@ namespace Duplicati.Library.Backend
|
||||
m_storageClass = storageClass;
|
||||
m_dnsHost = string.IsNullOrWhiteSpace(cfg.ServiceURL) ? null : new System.Uri(cfg.ServiceURL).Host;
|
||||
m_useChunkEncoding = !disableChunkEncoding;
|
||||
m_archiveClasses = ParseStorageClasses(options.GetValueOrDefault(S3_ARCHIVE_CLASSES_OPTION));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the storage classes from the string
|
||||
/// </summary>
|
||||
/// <param name="storageClass">The storage class string</param>
|
||||
/// <returns>The storage classes</returns>
|
||||
private static IReadOnlySet<S3StorageClass> ParseStorageClasses(string storageClass)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(storageClass))
|
||||
return DEFAULT_ARCHIVE_CLASSES;
|
||||
|
||||
return new HashSet<S3StorageClass>(storageClass.Split([','], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).Select(x => new S3StorageClass(x)));
|
||||
}
|
||||
|
||||
public Task AddBucketAsync(string bucketName, CancellationToken cancelToken)
|
||||
@@ -241,20 +292,12 @@ namespace Duplicati.Library.Backend
|
||||
obj.LastModified,
|
||||
obj.LastModified,
|
||||
false,
|
||||
IsStorageClassArchive(obj.StorageClass)
|
||||
m_archiveClasses.Contains(obj.StorageClass)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsStorageClassArchive(S3StorageClass storageClass)
|
||||
{
|
||||
return storageClass == S3StorageClass.DeepArchive
|
||||
|| storageClass == S3StorageClass.Glacier
|
||||
|| storageClass == S3StorageClass.GlacierInstantRetrieval
|
||||
|| storageClass == S3StorageClass.Snow;
|
||||
}
|
||||
|
||||
public async Task RenameFileAsync(string bucketName, string source, string target, CancellationToken cancelToken)
|
||||
{
|
||||
var copyObjectRequest = new CopyObjectRequest
|
||||
|
||||
@@ -333,6 +333,7 @@ namespace Duplicati.Library.Backend
|
||||
new CommandLineArgument(SSL_OPTION, CommandLineArgument.ArgumentType.Boolean, Strings.S3Backend.DescriptionUseSSLShort, Strings.S3Backend.DescriptionUseSSLLong),
|
||||
new CommandLineArgument(S3_CLIENT_OPTION, CommandLineArgument.ArgumentType.Enumeration, Strings.S3Backend.S3ClientDescriptionShort, Strings.S3Backend.S3ClientDescriptionLong, "aws", null, new string[] { "aws", "minio" }),
|
||||
new CommandLineArgument(S3_DISABLE_CHUNK_ENCODING_OPTION, CommandLineArgument.ArgumentType.Boolean, Strings.S3Backend.DescriptionDisableChunkEncodingShort, Strings.S3Backend.DescriptionDisableChunkEncodingLong, "false"),
|
||||
new CommandLineArgument(S3AwsClient.S3_ARCHIVE_CLASSES_OPTION, CommandLineArgument.ArgumentType.Flags, Strings.S3Backend.S3ArchiveClassesDescriptionShort, Strings.S3Backend.S3ArchiveClassesDescriptionLong, string.Join(",", S3AwsClient.DEFAULT_ARCHIVE_CLASSES.Select(x => x.Value)), null, S3AwsClient.DEFAULT_ARCHIVE_CLASSES.Select(x => x.Value).ToArray()),
|
||||
new CommandLineArgument("auth-password", CommandLineArgument.ArgumentType.Password, Strings.S3Backend.AuthPasswordDescriptionShort, Strings.S3Backend.AuthPasswordDescriptionLong),
|
||||
new CommandLineArgument("auth-username", CommandLineArgument.ArgumentType.String, Strings.S3Backend.AuthUsernameDescriptionShort, Strings.S3Backend.AuthUsernameDescriptionLong),
|
||||
};
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
// Copyright (C) 2025, The Duplicati Team
|
||||
// https://duplicati.com, hello@duplicati.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// Copyright (C) 2025, The Duplicati Team
|
||||
// https://duplicati.com, hello@duplicati.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
using Duplicati.Library.Localization.Short;
|
||||
namespace Duplicati.Library.Backend.Strings
|
||||
@@ -49,6 +49,8 @@ namespace Duplicati.Library.Backend.Strings
|
||||
public static string DescriptionDisableChunkEncodingShort { get { return LC.L(@"Disable chunk encoding (aws client only)"); } }
|
||||
public static string S3StorageclassDescriptionLong { get { return LC.L(@"Use this option to specify a storage class. If this option is not used, the server will choose a default storage class."); } }
|
||||
public static string S3StorageclassDescriptionShort { get { return LC.L(@"Specify storage class"); } }
|
||||
public static string S3ArchiveClassesDescriptionShort { get { return LC.L(@"Specify archive storage class"); } }
|
||||
public static string S3ArchiveClassesDescriptionLong { get { return LC.L(@"Use this option to specify what storage classes are considered archive storage classes. With this option it is possible to allow lifecycle policies to move data to cheaper storage classes and prevent Duplicati from accessing archived data. This option is only supported for the AWS client."); } }
|
||||
public static string UnknownS3ClientError(string client) { return LC.L(@"Unknown S3 client: {0}", client); }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user