Container filters can't be negated
JonathanBout opened this issue · comments
Output of dotnet --info
:
Output
.NET SDK: Version: 8.0.202 Commit: 25674bb2f4 Workload version: 8.0.200-manifests.fe7a266eRuntime Environment:
OS Name: Windows
OS Version: 10.0.22631
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\8.0.202\.NET workloads installed:
[android]
Installation Source: VS 17.10.34607.79, VS 17.9.34701.34
Manifest Version: 34.0.79/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.79\WorkloadManifest.json
Install Type: Msi[maui-windows]
Installation Source: VS 17.10.34607.79, VS 17.9.34701.34
Manifest Version: 8.0.7/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.7\WorkloadManifest.json
Install Type: Msi[maccatalyst]
Installation Source: VS 17.10.34607.79, VS 17.9.34701.34
Manifest Version: 17.2.8022/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\17.2.8022\WorkloadManifest.json
Install Type: Msi[ios]
Installation Source: VS 17.10.34607.79, VS 17.9.34701.34
Manifest Version: 17.2.8022/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\17.2.8022\WorkloadManifest.json
Install Type: Msi[wasm-tools]
Installation Source: VS 17.9.34701.34
Manifest Version: 8.0.3/8.0.100
Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.workload.mono.toolchain.current\8.0.3\WorkloadManifest.json
Install Type: MsiHost:
Version: 8.0.3
Architecture: x64
Commit: 9f4b1f5d66.NET SDKs installed:
8.0.101 [C:\Program Files\dotnet\sdk]
8.0.200 [C:\Program Files\dotnet\sdk]
8.0.202 [C:\Program Files\dotnet\sdk].NET runtimes installed:
Microsoft.AspNetCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.28 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 7.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.3 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]Other architectures found:
x86 [C:\Program Files (x86)\dotnet]
registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]Environment variables:
Not setglobal.json file:
Not foundLearn more:
https://aka.ms/dotnet/infoDownload .NET:
https://aka.ms/dotnet/download
What version of Docker.DotNet?:
3.125.15
Steps to reproduce the issue:
- Create a default client
- List the containers and add a filter with
false
:
var containers = await docker.Containers.ListContainersAsync(new ContainersListParameters
{
Filters = new Dictionary<string, IDictionary<string, bool>>() { { "status", new Dictionary<string, bool>() { { "exited", false } } } },
All = true,
Limit = 20,
});
What actually happened?:
I got a list of all exited containers
What did you expect to happen?:
I get a list of all not exited containers
Additional information:
I use ASP.NET Core with dependency injection. The Docker client is registered as a singleton:
builder.Services
.AddSingleton<IDockerClient>(dockerConfig.CreateClient());
I am curious and interested in which language feature (syntax sugar) I missed. I am unable to compile your provided example. Can you share the docs for the language feature that introduces the syntax you are using (initializing the dictionary)? My test runs fine:
var containersListParameters = new ContainersListParameters();
containersListParameters.Filters = new Dictionary<string, IDictionary<string, bool>> { { "status", new Dictionary<string, bool> { { "exited", true } } } };
The filter only returns exited containers.
Oh my example indeed doesn't compile 😅 I'll update it.
But it does correctly return all exited containers, yes. But it also returns exited containers when I use { "exited", false }
AFAIK the bool flag does nothing. I have 4 container (3 exited, 1 running). I get the following results, which look Ok:
Returns 4:
var containersListParameters = new ContainersListParameters();
// containersListParameters.Filters = new Dictionary<string, IDictionary<string, bool>> { { "status", new Dictionary<string, bool> { { "exited", true } } } };
containersListParameters.All = true;
Returns 1:
var containersListParameters = new ContainersListParameters();
// containersListParameters.Filters = new Dictionary<string, IDictionary<string, bool>> { { "status", new Dictionary<string, bool> { { "exited", true } } } };
containersListParameters.All = false;
Returns 3:
var containersListParameters = new ContainersListParameters();
containersListParameters.Filters = new Dictionary<string, IDictionary<string, bool>> { { "status", new Dictionary<string, bool> { { "exited", true } } } };
// containersListParameters.All = false;
But why was it added then? It's a bit confusing your 3rd example returns the same as this:
var containersListParameters = new ContainersListParameters();
containersListParameters.Filters = new Dictionary<string, IDictionary<string, bool>> { { "status", new Dictionary<string, bool> { { "exited", false} } } };
your 3rd example returns the same as this
I know, but I do not know why there is the additional bool
value, if you look into the Docker Engine API, it says:
Filters to process on the container list, encoded as JSON (a map[string][]string). For example, {"status": ["paused"]} will only return paused containers.
Maybe it was necessary in a previous API version? If you want to know the exact details, you probably need to look at QueryString and its history. I am using this library a lot and never noticed any differences whether true
or false
is used. And according to the API docs, I do not expect them to be necessary at all. Sorry, I cannot help more.
Does any main developer of this project know what the bool
flag is supposed to do in a filter?
It definitely does something with the formatting, see this example:
var images1 = await client.Images.ListImagesAsync(
new ImagesListParameters()
{
Filters = new Dictionary<string, IDictionary<string, bool>>()
{
{"dangling", new Dictionary<string, bool>() {{"true", true}}}
}
});
// Success
Changing the bool
flag to false {"dangling", new Dictionary<string, bool>() {{"true", FALSE}}}
resulted in:
Unhandled exception. Docker.DotNet.DockerApiException: Docker API responded with status code=BadRequest, response={"message":"invalid filter 'dangling=[true]'"}
at Docker.DotNet.DockerClient.HandleIfErrorResponseAsync(HttpStatusCode statusCode, HttpResponseMessage response, IEnumerable
1 handlers) at Docker.DotNet.DockerClient.MakeRequestAsync(IEnumerable
1 errorHandlers, HttpMethod method, String path, IQueryString queryString, IRequestContent body, IDictionary`2 headers, TimeSpan timeout, CancellationToken token)
at Docker.DotNet.ImageOperations.ListImagesAsync(ImagesListParameters parameters, CancellationToken cancellationToken)
The brackets dangling=[true]
are added in case the bool
is set to false
. In case true
it is dangling=true
.