From 6313471ffa3031c7c5999dc8f808fa4b0198ec0f Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Fri, 12 Jun 2026 13:47:49 +0200 Subject: [PATCH] Fix minor issues with remote sources This updates some minor issues that would cause warnings or make things appear to not work, even though they would work fine when actually running a backup. --- .../DynamicLoader/SourceProviderLoader.cs | 28 ++----------------- .../Endpoints/Shared/SharedRemoteOperation.cs | 4 ++- .../WebserverCore/Endpoints/V1/WebModules.cs | 19 +++++++++---- proprietary/GoogleWorkspace/APIHelper.cs | 4 +-- .../GoogleWorkspace/WebModule/WebModule.cs | 2 +- 5 files changed, 22 insertions(+), 35 deletions(-) diff --git a/Duplicati/Library/DynamicLoader/SourceProviderLoader.cs b/Duplicati/Library/DynamicLoader/SourceProviderLoader.cs index 26382353f..d7667b325 100644 --- a/Duplicati/Library/DynamicLoader/SourceProviderLoader.cs +++ b/Duplicati/Library/DynamicLoader/SourceProviderLoader.cs @@ -168,28 +168,6 @@ namespace Duplicati.Library.DynamicLoader return commands; } - /// - /// Instanciates a specific SourceProvider, given the url and options - /// - /// The url to create the instance for - /// The mount point to use - /// The options to pass to the instance constructor - /// The cancellation token - /// The instanciated SourceProvider or null if the url is not supported - public static Task GetSourceProvider(string url, string mountPoint, Dictionary options, CancellationToken cancellationToken) - => GetSourceProvider(url, mountPoint, options, false, cancellationToken); - - /// - /// Instanciates a specific SourceProvider for testing, given the url and options - /// - /// The url to create the instance for - /// The mount point to use - /// The options to pass to the instance constructor - /// The cancellation token - /// The instanciated SourceProvider or null if the url is not supported - public static Task GetSourceProviderForTesting(string url, string mountPoint, Dictionary options, CancellationToken cancellationToken) - => GetSourceProvider(url, mountPoint, options, true, cancellationToken); - /// /// Instanciates a specific SourceProvider, given the url and options /// @@ -199,7 +177,7 @@ namespace Duplicati.Library.DynamicLoader /// Whether the SourceProvider is requested for testing purposes /// The cancellation token /// The instanciated SourceProvider or null if the url is not supported - private static async Task GetSourceProvider(string url, string mountPoint, Dictionary options, bool getForTesting, CancellationToken cancellationToken) + public static async Task GetSourceProvider(string url, string mountPoint, Dictionary options, CancellationToken cancellationToken) { // Source providers are preferred over backends var provider = _SourceProviderLoader.GetSourceProvider(url, mountPoint, options); @@ -218,9 +196,7 @@ namespace Duplicati.Library.DynamicLoader try { - // In test mode, we do not initialize the provider - if (!getForTesting) - await provider.InitializeAsync(cancellationToken).ConfigureAwait(false); + await provider.InitializeAsync(cancellationToken).ConfigureAwait(false); return provider; } catch diff --git a/Duplicati/WebserverCore/Endpoints/Shared/SharedRemoteOperation.cs b/Duplicati/WebserverCore/Endpoints/Shared/SharedRemoteOperation.cs index 0fea5b909..5460b60ba 100644 --- a/Duplicati/WebserverCore/Endpoints/Shared/SharedRemoteOperation.cs +++ b/Duplicati/WebserverCore/Endpoints/Shared/SharedRemoteOperation.cs @@ -127,8 +127,10 @@ public class SharedRemoteOperation public static async Task GetSourceProviderForTestingAsync(Connection connection, IApplicationSettings applicationSettings, string url, string? additionalPath, string? backupId, long connectionStringId, string? sourcePrefix, CancellationToken cancelToken) { (url, var opts) = await ExpandUrlAsync(connection, applicationSettings, url, backupId, connectionStringId, sourcePrefix, cancelToken); + // Prevent the source provider from rejecting requests when we are simply testing + opts["store-metadata-content-in-database"] = "true"; var modules = ConfigureModules(opts); - var sourceProvider = await Library.DynamicLoader.SourceProviderLoader.GetSourceProviderForTesting(AppendAdditionalPath(url, additionalPath), "", opts, cancelToken); + var sourceProvider = await Library.DynamicLoader.SourceProviderLoader.GetSourceProvider(AppendAdditionalPath(url, additionalPath), "", opts, cancelToken); return new SourceProviderTupleDisposeWrapper(sourceProvider, modules); } diff --git a/Duplicati/WebserverCore/Endpoints/V1/WebModules.cs b/Duplicati/WebserverCore/Endpoints/V1/WebModules.cs index 763949b8d..154fdf937 100644 --- a/Duplicati/WebserverCore/Endpoints/V1/WebModules.cs +++ b/Duplicati/WebserverCore/Endpoints/V1/WebModules.cs @@ -19,7 +19,6 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. using Duplicati.Library.Interface; -using Duplicati.Library.Main; using Duplicati.Server; using Duplicati.Server.Database; using Duplicati.WebserverCore.Abstractions; @@ -61,10 +60,20 @@ public record WebModules : IEndpointV1 options[k] = opts[k]; } - return new Dto.WebModuleOutputDto( - Status: "OK", - Result: await m.Execute(options, cancellationToken).ConfigureAwait(false) - ); + try + { + return new Dto.WebModuleOutputDto( + Status: "OK", + Result: await m.Execute(options, cancellationToken).ConfigureAwait(false) + ); + } + catch (Exception ex) + { + return new Dto.WebModuleOutputDto( + Status: "FAILED", + Result: new Dictionary { { "error", ex.Message } } + ); + } } } diff --git a/proprietary/GoogleWorkspace/APIHelper.cs b/proprietary/GoogleWorkspace/APIHelper.cs index 034ede472..73b09fdf5 100644 --- a/proprietary/GoogleWorkspace/APIHelper.cs +++ b/proprietary/GoogleWorkspace/APIHelper.cs @@ -99,8 +99,8 @@ public class APIHelper else { // Test connection by getting the Gmail service - var gmailService = GetGmailService("me"); - gmailService.Users.GetProfile("me").Execute(); + var gmailService = GetGmailService(_adminEmail ?? "me"); + gmailService.Users.GetProfile(_adminEmail ?? "me").Execute(); } } public GmailService GetGmailService(string userId) diff --git a/proprietary/GoogleWorkspace/WebModule/WebModule.cs b/proprietary/GoogleWorkspace/WebModule/WebModule.cs index 2cba7fd31..0ef5e7a45 100644 --- a/proprietary/GoogleWorkspace/WebModule/WebModule.cs +++ b/proprietary/GoogleWorkspace/WebModule/WebModule.cs @@ -94,7 +94,7 @@ public class WebModule : IWebModule foreach (var key in uri.QueryParameters.AllKeys) forwardoptions[key!] = uri.QueryParameters[key]; - using var client = new SourceProvider(url, "", forwardoptions, true); + using var client = new SourceProvider(url, "", forwardoptions, false); await client.InitializeAsync(cancellationToken); var targetEntry = await client.GetEntryAsync((path ?? "").TrimStart('/'), isFolder: true, cancellationToken).ConfigureAwait(false);