Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,9 @@ jobs:
exit 1

- name: Test (${{ matrix.docker.name }})
run: >-
dotnet test
--configuration Release
--framework ${{ matrix.dotnet.tfm }}
--no-restore
--no-build
--logger console
run: |
./test/Docker.DotNet.Tests/bin/Release/${{ matrix.dotnet.tfm }}/linux-x64/publish/Docker.DotNet.Tests
./test/Docker.DotNet.TestsV2/bin/Release/${{ matrix.dotnet.tfm }}/linux-x64/publish/Docker.DotNet.TestsV2
env:
DOCKER_HOST: ${{ matrix.docker.docker_host }}
DOCKER_TLS_VERIFY: ${{ matrix.docker.tls_verify }}
Expand Down
5 changes: 2 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
<PackageVersion Include="System.Text.Json" Version="8.0.5" />
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.5.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.v3.mtp-v2" Version="4.0.0-pre.81" />
<PackageVersion Include="xunit.v3.aot.mtp-v2" Version="4.0.0-pre.81" />
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
1 change: 1 addition & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<PropertyGroup>
<IsAotCompatible>true</IsAotCompatible>
<IsPackable>true</IsPackable>
<TargetFrameworks>net8.0;net9.0;net10.0;netstandard2.0;netstandard2.1</TargetFrameworks>
<Copyright>Copyright (c) .NET Foundation and Contributors; Andre Hofmeister</Copyright>
Expand Down
6 changes: 3 additions & 3 deletions src/Docker.DotNet.NPipe/DockerHandlerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ public ResolvedTransport CreateHandler(NPipeTransportOptions transportOptions, C

var dockerStream = new DockerPipeStream(clientStream);

#if NETSTANDARD
var namedPipeConnectTimeout = (int)transportOptions.ConnectTimeout.TotalMilliseconds;
#else
#if NET
var namedPipeConnectTimeout = transportOptions.ConnectTimeout;
#else
var namedPipeConnectTimeout = (int)transportOptions.ConnectTimeout.TotalMilliseconds;
#endif

await clientStream.ConnectAsync(namedPipeConnectTimeout, cancellationToken)
Expand Down
2 changes: 1 addition & 1 deletion src/Docker.DotNet.NativeHttp/DockerHandlerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ResolvedTransport CreateHandler(NativeHttpTransportOptions transportOptio
var scheme = clientOptions.AuthProvider.TlsEnabled ? Uri.UriSchemeHttps : Uri.UriSchemeHttp;
var uri = new UriBuilder(clientOptions.Endpoint) { Scheme = scheme }.Uri;

#if NET6_0_OR_GREATER
#if NET
var handler = new SocketsHttpHandler
{
MaxConnectionsPerServer = MaxConnectionsPerServer,
Expand Down
2 changes: 1 addition & 1 deletion src/Docker.DotNet.NativeHttp/NativeHttpTransportOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Docker.DotNet.NativeHttp;
/// </summary>
public sealed record NativeHttpTransportOptions
{
#if NET6_0_OR_GREATER
#if NET
/// <summary>
/// Gets a callback that configures the created <see cref="SocketsHttpHandler"/> instance.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Docker.DotNet.X509/CertificateCredentials.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public CertificateCredentials(X509Certificate2? certificate)

public HttpMessageHandler ConfigureHandler(HttpMessageHandler handler)
{
#if NET6_0_OR_GREATER
#if NET
if (handler is SocketsHttpHandler socketsHandler)
{
if (_certificate != null)
Expand Down
8 changes: 3 additions & 5 deletions src/Docker.DotNet.X509/DockerTlsCertificates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public static X509Certificate2 LoadCertificateFromPemFiles(string certPemPath, s
}

return certificate;
#elif NET6_0_OR_GREATER
#elif NET
var certificate = X509Certificate2.CreateFromPemFile(certPemPath, keyPemPath);

if (OperatingSystem.IsWindows())
Expand All @@ -75,10 +75,8 @@ public static X509Certificate2 LoadCertificateFromPemFiles(string certPemPath, s
}

return certificate;
#elif NETSTANDARD
return Polyfills.X509Certificate2.CreateFromPemFile(certPemPath, keyPemPath);
#else
return X509Certificate2.CreateFromPemFile(certPemPath, keyPemPath);
return Polyfills.X509Certificate2.CreateFromPemFile(certPemPath, keyPemPath);
#endif
}

Expand Down Expand Up @@ -141,7 +139,7 @@ public static RemoteCertificateValidationCallback CreateCertificateAuthorityVali
using var chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

#if NET5_0_OR_GREATER
#if NET
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.CustomTrustStore.Add(certificateAuthorityCertificate);
return chain.Build(serverCertificate2);
Expand Down
2 changes: 2 additions & 0 deletions src/Docker.DotNet/Docker.DotNet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<Using Include="System.Collections.Concurrent" />
<Using Include="System.Collections.Generic" />
<Using Include="System.Diagnostics" />
<Using Include="System.Diagnostics.CodeAnalysis" />
<Using Include="System.Globalization" />
<Using Include="System.IO" />
<Using Include="System.IO.Pipelines" />
Expand All @@ -49,6 +50,7 @@
<Using Include="System.Text" />
<Using Include="System.Text.Json" />
<Using Include="System.Text.Json.Serialization" />
<Using Include="System.Text.Json.Serialization.Metadata" />
<Using Include="System.Threading" />
<Using Include="System.Threading.Tasks" />
<Using Include="Docker.DotNet" />
Expand Down
4 changes: 1 addition & 3 deletions src/Docker.DotNet/DockerClient.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
namespace Docker.DotNet;

using System;

public sealed class DockerClient : IDockerClient
{
internal readonly IEnumerable<ApiResponseErrorHandlingDelegate> NoErrorHandlers = Enumerable.Empty<ApiResponseErrorHandlingDelegate>();
Expand Down Expand Up @@ -370,7 +368,7 @@ private async Task<HttpResponseMessage> PrivateMakeRequestAsync(

if (Timeout.InfiniteTimeSpan == timeout)
{
#if NET6_0_OR_GREATER
#if NET
return await _client.SendAsync(request, completionOption, cancellationToken)
.ConfigureAwait(false);
#else
Expand Down
2 changes: 1 addition & 1 deletion src/Docker.DotNet/Endpoints/ConfigsOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ internal ConfigOperations(DockerClient client)

public async Task<IList<SwarmConfig>> ListConfigsAsync(CancellationToken cancellationToken = default)
{
return await _client.MakeRequestAsync<IList<SwarmConfig>>(_client.NoErrorHandlers, HttpMethod.Get, "configs", cancellationToken)
return await _client.MakeRequestAsync<SwarmConfig[]>(_client.NoErrorHandlers, HttpMethod.Get, "configs", cancellationToken)
.ConfigureAwait(false);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Docker.DotNet/Endpoints/ISwarmOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public interface ISwarmOperations
/// 500 - Server error.
/// 503 - Node is not part of a swarm.
/// </remarks>
Task<IEnumerable<SwarmService>> ListServicesAsync(ServiceListParameters? parameters = null, CancellationToken cancellationToken = default);
Task<IList<SwarmService>> ListServicesAsync(ServiceListParameters? parameters = null, CancellationToken cancellationToken = default);
Comment thread
HofmeisterAn marked this conversation as resolved.

/// <summary>
/// Update a service.
Expand Down Expand Up @@ -198,7 +198,7 @@ public interface ISwarmOperations
/// 503 - Node is not part of a swarm.
/// </remarks>
/// <returns></returns>
Task<IEnumerable<NodeListResponse>> ListNodesAsync(CancellationToken cancellationToken = default);
Task<IList<NodeListResponse>> ListNodesAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Inspect a node.
Expand Down
4 changes: 2 additions & 2 deletions src/Docker.DotNet/Endpoints/SwarmOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ await _client.MakeRequestAsync([NotInSwarmResponseHandler], HttpMethod.Post, "sw
.ConfigureAwait(false);
}

public async Task<IEnumerable<SwarmService>> ListServicesAsync(ServiceListParameters? parameters = null, CancellationToken cancellationToken = default)
public async Task<IList<SwarmService>> ListServicesAsync(ServiceListParameters? parameters = null, CancellationToken cancellationToken = default)
{
var queryParameters = parameters == null ? null : new QueryString<ServiceListParameters>(parameters);

Expand Down Expand Up @@ -193,7 +193,7 @@ private static Dictionary<string, string> RegistryAuthHeaders(AuthConfig? authCo
};
}

public async Task<IEnumerable<NodeListResponse>> ListNodesAsync(CancellationToken cancellationToken = default)
public async Task<IList<NodeListResponse>> ListNodesAsync(CancellationToken cancellationToken = default)
{
return await _client.MakeRequestAsync<NodeListResponse[]>([NotInSwarmResponseHandler], HttpMethod.Get, "nodes", cancellationToken)
.ConfigureAwait(false);
Expand Down
6 changes: 0 additions & 6 deletions src/Docker.DotNet/IQueryStringConverterInstanceFactory.cs

This file was deleted.

52 changes: 46 additions & 6 deletions src/Docker.DotNet/JsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ static JsonSerializer()

private JsonSerializer()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the following is slightly better, although the improvements compared to network I/O are probably negligible. WDYT?

Subject: [PATCH] f
---
Index: src/Docker.DotNet/JsonSerializer.cs
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/Docker.DotNet/JsonSerializer.cs b/src/Docker.DotNet/JsonSerializer.cs
--- a/src/Docker.DotNet/JsonSerializer.cs	(revision e4cc73fdd8371f3dd6110684f6e7a705b55941c4)
+++ b/src/Docker.DotNet/JsonSerializer.cs	(date 1776437559579)
@@ -42,26 +42,27 @@
 
     public string Serialize<T>(T value)
     {
-        return System.Text.Json.JsonSerializer.Serialize(value, (JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)));
+        return System.Text.Json.JsonSerializer.Serialize(value, TypeInfoCache<T>.Value);
     }
 
     public byte[] SerializeToUtf8Bytes<T>(T value)
     {
-        return System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(value, (JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)));
+        return System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(value, TypeInfoCache<T>.Value);
     }
 
     public T Deserialize<T>(byte[] json)
     {
-        return System.Text.Json.JsonSerializer.Deserialize(json, (JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)))!;
+        return System.Text.Json.JsonSerializer.Deserialize(json, TypeInfoCache<T>.Value)!;
     }
 
     public Task<T> DeserializeAsync<T>(HttpContent content, CancellationToken cancellationToken)
     {
-        return content.ReadFromJsonAsync((JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)), cancellationToken)!;
+        return content.ReadFromJsonAsync(TypeInfoCache<T>.Value, cancellationToken)!;
     }
 
     public async IAsyncEnumerable<T> DeserializeAsync<T>(Stream stream, [EnumeratorCancellation] CancellationToken cancellationToken)
     {
+        var typeInfo = TypeInfoCache<T>.Value;
         var reader = PipeReader.Create(stream);
 
         while (true)
@@ -73,7 +74,7 @@
 
             while (!buffer.IsEmpty && TryParseJson(ref buffer, out var jsonDocument))
             {
-                yield return jsonDocument!.Deserialize((JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)))!;
+                yield return jsonDocument!.Deserialize(typeInfo)!;
             }
 
             if (result.IsCompleted)
@@ -99,6 +100,11 @@
 
         return false;
     }
+
+    private static class TypeInfoCache<T>
+    {
+        public static readonly JsonTypeInfo<T> Value = (JsonTypeInfo<T>)Instance._options.GetTypeInfo(typeof(T));
+    }
 }
 
 // Additional source-generated metadata for collections and dictionaries used by operations.

{
_options.TypeInfoResolver = JsonTypeInfoResolver.Combine(
DockerModelsJsonSerializerContext.Default,
DockerExtendedJsonSerializerContext.Default);
_options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
_options.Converters.Add(new JsonEnumMemberConverter<RestartPolicyKind>());
_options.Converters.Add(new JsonEnumMemberConverter<TaskState>());
_options.Converters.Add(new JsonDateTimeConverter());
_options.Converters.Add(new JsonNullableDateTimeConverter());
_options.MakeReadOnly();
}

public static JsonSerializer Instance { get; }
Expand All @@ -38,22 +42,22 @@ public HttpContent GetHttpContent<T>(T value)

public string Serialize<T>(T value)
{
return System.Text.Json.JsonSerializer.Serialize(value, _options);
return System.Text.Json.JsonSerializer.Serialize(value, (JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)));
}

public byte[] SerializeToUtf8Bytes<T>(T value)
{
return System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(value, _options);
return System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(value, (JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)));
}

public T Deserialize<T>(byte[] json)
{
return System.Text.Json.JsonSerializer.Deserialize<T>(json, _options)!;
return System.Text.Json.JsonSerializer.Deserialize(json, (JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)))!;
}

public Task<T> DeserializeAsync<T>(HttpContent content, CancellationToken cancellationToken)
{
return content.ReadFromJsonAsync<T>(_options, cancellationToken)!;
return content.ReadFromJsonAsync((JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)), cancellationToken)!;
}

public async IAsyncEnumerable<T> DeserializeAsync<T>(Stream stream, [EnumeratorCancellation] CancellationToken cancellationToken)
Expand All @@ -69,7 +73,7 @@ public async IAsyncEnumerable<T> DeserializeAsync<T>(Stream stream, [EnumeratorC

while (!buffer.IsEmpty && TryParseJson(ref buffer, out var jsonDocument))
{
yield return jsonDocument!.Deserialize<T>(_options)!;
yield return jsonDocument!.Deserialize((JsonTypeInfo<T>)_options.GetTypeInfo(typeof(T)))!;
}

if (result.IsCompleted)
Expand All @@ -95,4 +99,40 @@ private static bool TryParseJson(ref ReadOnlySequence<byte> buffer, out JsonDocu

return false;
}
}
}

// Additional source-generated metadata for collections and dictionaries used by operations.

// Filters
[JsonSerializable(typeof(IDictionary<string, IDictionary<string, bool>>))]

// ConfigOperations.ListConfigsAsync
[JsonSerializable(typeof(SwarmConfig[]))]

// ContainerOperations.ListContainersAsync
[JsonSerializable(typeof(ContainerListResponse[]))]
// ContainerOperations.InspectChangesAsync
[JsonSerializable(typeof(ContainerFileSystemChangeResponse[]))]

// ImageOperations.ListImagesAsync
[JsonSerializable(typeof(ImagesListResponse[]))]
// ImageOperations.GetImageHistoryAsync
[JsonSerializable(typeof(ImageHistoryResponse[]))]
// ImageOperations.DeleteImageAsync
[JsonSerializable(typeof(Dictionary<string, string>[]))]
// ImageOperations.SearchImagesAsync
[JsonSerializable(typeof(ImageSearchResponse[]))]

// NetworkOperations.ListNetworksAsync
[JsonSerializable(typeof(NetworkResponse[]))]

// PluginOperations.ListPluginsAsync
[JsonSerializable(typeof(Plugin[]))]
// PluginOperations.GetPrivilegesAsync
[JsonSerializable(typeof(PluginPrivilege[]))]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have one more topic, but aside from the open discussions, the PR looks good. We can also address some of those in a follow-up PR if you prefer.

PluginPrivilege[] covers the array response, but InstallPluginAsync and UpgradePluginAsync serialize an IList<PluginPrivilege>.

IList<PluginPrivilege> is a different closed type from PluginPrivilege[], so it needs its own JsonSerializable entry in the combined serializer context, right?

I belive the analyzer is a good idea 💡.

I think these are missing too (or we change them to arrays too):

// PluginOperations.InstallPluginAsync, UpgradePluginAsync
[JsonSerializable(typeof(IList<PluginPrivilege>))]
// PluginOperations.ConfigurePluginAsync
[JsonSerializable(typeof(IList<string>))]

// SecretsOperations.ListAsync
[JsonSerializable(typeof(IList<Secret>))]

// TasksOperations.ListAsync
[JsonSerializable(typeof(IList<TaskResponse>))]


// SwarmOperations.ListServicesAsync
[JsonSerializable(typeof(SwarmService[]))]
// SwarmOperations.ListNodesAsync
[JsonSerializable(typeof(NodeListResponse[]))]
internal sealed partial class DockerExtendedJsonSerializerContext : JsonSerializerContext { }
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ public CommitContainerChangesParameters(ContainerConfig Config)
[QueryStringParameter("author", false)]
public string? Author { get; set; }

[QueryStringParameter("changes", false, typeof(EnumerableQueryStringConverter))]
[QueryStringParameter<EnumerableQueryStringConverter>("changes", false)]
public IList<string>? Changes { get; set; }

[QueryStringParameter("pause", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("pause", false)]
public bool? Pause { get; set; }

[JsonPropertyName("Hostname")]
Expand Down
10 changes: 5 additions & 5 deletions src/Docker.DotNet/Models/ContainerAttachParameters.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,22 @@ namespace Docker.DotNet.Models
{
public class ContainerAttachParameters // (main.ContainerAttachParameters)
{
[QueryStringParameter("stream", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("stream", false)]
public bool? Stream { get; set; }

[QueryStringParameter("stdin", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("stdin", false)]
public bool? Stdin { get; set; }

[QueryStringParameter("stdout", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("stdout", false)]
public bool? Stdout { get; set; }

[QueryStringParameter("stderr", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("stderr", false)]
public bool? Stderr { get; set; }

[QueryStringParameter("detachKeys", false)]
public string? DetachKeys { get; set; }

[QueryStringParameter("logs", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("logs", false)]
public bool? Logs { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class ContainerEventsParameters // (main.ContainerEventsParameters)
[QueryStringParameter("until", false)]
public string? Until { get; set; }

[QueryStringParameter("filters", false, typeof(MapQueryStringConverter))]
[QueryStringParameter<MapQueryStringConverter>("filters", false)]
public IDictionary<string, IDictionary<string, bool>>? Filters { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace Docker.DotNet.Models
{
public class ContainerInspectParameters // (main.ContainerInspectParameters)
{
[QueryStringParameter("size", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("size", false)]
public bool? IncludeSize { get; set; }
}
}
8 changes: 4 additions & 4 deletions src/Docker.DotNet/Models/ContainerLogsParameters.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ namespace Docker.DotNet.Models
{
public class ContainerLogsParameters // (main.ContainerLogsParameters)
{
[QueryStringParameter("stdout", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("stdout", false)]
public bool? ShowStdout { get; set; }

[QueryStringParameter("stderr", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("stderr", false)]
public bool? ShowStderr { get; set; }

[QueryStringParameter("since", false)]
Expand All @@ -15,10 +15,10 @@ public class ContainerLogsParameters // (main.ContainerLogsParameters)
[QueryStringParameter("until", false)]
public string? Until { get; set; }

[QueryStringParameter("timestamps", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("timestamps", false)]
public bool? Timestamps { get; set; }

[QueryStringParameter("follow", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("follow", false)]
public bool? Follow { get; set; }

[QueryStringParameter("tail", false)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ namespace Docker.DotNet.Models
{
public class ContainerRemoveParameters // (main.ContainerRemoveParameters)
{
[QueryStringParameter("v", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("v", false)]
public bool? RemoveVolumes { get; set; }

[QueryStringParameter("link", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("link", false)]
public bool? RemoveLinks { get; set; }

[QueryStringParameter("force", false, typeof(BoolQueryStringConverter))]
[QueryStringParameter<BoolQueryStringConverter>("force", false)]
public bool? Force { get; set; }
}
}
Loading