mirror of
https://github.com/MAKS-IT-COM/podman-client-dotnet.git
synced 2026-08-15 14:48:11 +02:00
feat: add System.Text.Json source generation for AOT/trim compatibility
- Add PodmanJsonContext (JsonSerializerContext) covering all ~70 DTOs and request models used by the library with PropertyNameCaseInsensitive=true - Replace MaksIT.Core ToJson()/ToObject<T>() with explicit JsonTypeInfo<T> parameters threaded through all internal HTTP helper methods - Update all call sites in PodmanClient partial classes - Update PodmanProgressSession<T> constructor to accept JsonTypeInfo<T> - Remove MaksIT.Core package reference (no longer needed) - Enable IsAotCompatible=true in project file to activate trim/AOT analyzers - All 13 unit tests pass, 0 build warnings
This commit is contained in:
parent
1553524cbc
commit
bbba014602
@ -1,8 +1,8 @@
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MaksIT.Core.Extensions;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Common;
|
||||
using MaksIT.Results;
|
||||
|
||||
@ -13,7 +13,7 @@ internal static class PodmanHttpResults {
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
return "Podman API request failed.";
|
||||
|
||||
var error = content.ToObject<ErrorResponseDto>();
|
||||
var error = JsonSerializer.Deserialize(content, PodmanJsonContext.Default.ErrorResponseDto);
|
||||
return string.IsNullOrWhiteSpace(error?.Message) ? content : error.Message;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MaksIT.Core.Extensions;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Build;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Image;
|
||||
using MaksIT.Results;
|
||||
@ -24,7 +25,7 @@ internal static class PodmanNdjsonStreams {
|
||||
if (!line.Contains("\"error\"", StringComparison.Ordinal))
|
||||
continue;
|
||||
|
||||
var errorDetails = line.ToObject<PullImageResponseDto>();
|
||||
var errorDetails = JsonSerializer.Deserialize(line, PodmanJsonContext.Default.PullImageResponseDto);
|
||||
var message = errorDetails?.Error ?? $"{operation} failed.";
|
||||
logger.LogError("{Operation} failed: {Message}", operation, message);
|
||||
return Result.BadRequest(message);
|
||||
@ -46,7 +47,7 @@ internal static class PodmanNdjsonStreams {
|
||||
if (string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
var progress = line.ToObject<BuildProgressLineDto>();
|
||||
var progress = JsonSerializer.Deserialize(line, PodmanJsonContext.Default.BuildProgressLineDto);
|
||||
if (progress is null)
|
||||
continue;
|
||||
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MaksIT.Core.Extensions;
|
||||
using MaksIT.PodmanClientDotNet.Internal;
|
||||
using MaksIT.PodmanClientDotNet.Models;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Container;
|
||||
@ -251,7 +252,9 @@ public partial class PodmanClient {
|
||||
return await PostJsonAsync<CreateContainerRequest, CreateContainerResponseDto>(
|
||||
"/libpod/containers/create",
|
||||
"Create container",
|
||||
createContainerParameters
|
||||
createContainerParameters,
|
||||
PodmanJsonContext.Default.CreateContainerRequest,
|
||||
PodmanJsonContext.Default.CreateContainerResponseDto
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@ -314,7 +317,7 @@ public partial class PodmanClient {
|
||||
|
||||
if (response.IsSuccessStatusCode) {
|
||||
var value = !string.IsNullOrWhiteSpace(jsonResponse)
|
||||
? jsonResponse.ToObject<DeleteContainerResponseDto[]>()
|
||||
? JsonSerializer.Deserialize(jsonResponse, PodmanJsonContext.Default.DeleteContainerResponseDtoArray)
|
||||
: null;
|
||||
return PodmanHttpResults.Success(response.StatusCode, value);
|
||||
}
|
||||
@ -336,7 +339,7 @@ public partial class PodmanClient {
|
||||
|
||||
if (response.IsSuccessStatusCode) {
|
||||
var value = !string.IsNullOrWhiteSpace(jsonResponse)
|
||||
? jsonResponse.ToObject<DeleteContainerResponseDto[]>()
|
||||
? JsonSerializer.Deserialize(jsonResponse, PodmanJsonContext.Default.DeleteContainerResponseDtoArray)
|
||||
: null;
|
||||
return PodmanHttpResults.Success(response.StatusCode, value);
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Common;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Container;
|
||||
using MaksIT.Results;
|
||||
@ -16,6 +17,7 @@ public partial class PodmanClient {
|
||||
GetJsonAsync<List<ContainerListEntryDto>>(
|
||||
"/libpod/containers/json",
|
||||
"List containers",
|
||||
PodmanJsonContext.Default.ListContainerListEntryDto,
|
||||
[
|
||||
("all", all.ToString().ToLowerInvariant()),
|
||||
("limit", limit?.ToString()),
|
||||
@ -27,7 +29,7 @@ public partial class PodmanClient {
|
||||
);
|
||||
|
||||
public Task<Result<ContainerInspectDto?>> InspectContainerAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<ContainerInspectDto>($"{ContainerPath(name)}/json", "Inspect container", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<ContainerInspectDto>($"{ContainerPath(name)}/json", "Inspect container", PodmanJsonContext.Default.ContainerInspectDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> ContainerExistsAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetWithoutBodyAsync($"{ContainerPath(name)}/exists", "Container exists", cancellationToken: cancellationToken);
|
||||
@ -58,6 +60,7 @@ public partial class PodmanClient {
|
||||
PostLibpodAsync<ContainerWaitDto>(
|
||||
$"{ContainerPath(name)}/wait",
|
||||
"Wait container",
|
||||
PodmanJsonContext.Default.ContainerWaitDto,
|
||||
query: condition is null ? null : [("condition", condition)],
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
@ -92,6 +95,7 @@ public partial class PodmanClient {
|
||||
GetJsonAsync<ContainerStatsDto>(
|
||||
$"{ContainerPath(name)}/stats",
|
||||
"Get container stats",
|
||||
PodmanJsonContext.Default.ContainerStatsDto,
|
||||
[("stream", stream.ToString().ToLowerInvariant())],
|
||||
cancellationToken
|
||||
);
|
||||
@ -107,13 +111,14 @@ public partial class PodmanClient {
|
||||
query.Add(("containers", c));
|
||||
}
|
||||
|
||||
return GetJsonAsync<Dictionary<string, ContainerStatsDto>>("/libpod/containers/stats", "Get containers stats", query, cancellationToken);
|
||||
return GetJsonAsync<Dictionary<string, ContainerStatsDto>>("/libpod/containers/stats", "Get containers stats", PodmanJsonContext.Default.DictionaryStringContainerStatsDto, query, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<Result<PruneReportDto?>> PruneContainersAsync(string? filters = null, CancellationToken cancellationToken = default) =>
|
||||
PostLibpodAsync<PruneReportDto>(
|
||||
"/libpod/containers/prune",
|
||||
"Prune containers",
|
||||
PodmanJsonContext.Default.PruneReportDto,
|
||||
query: filters is null ? null : [("filters", filters)],
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
@ -178,7 +183,7 @@ public partial class PodmanClient {
|
||||
);
|
||||
|
||||
public Task<Result<ContainerMountDto?>> MountContainerAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
PostLibpodAsync<ContainerMountDto>($"{ContainerPath(name)}/mount", "Mount container", cancellationToken: cancellationToken);
|
||||
PostLibpodAsync<ContainerMountDto>($"{ContainerPath(name)}/mount", "Mount container", PodmanJsonContext.Default.ContainerMountDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> UnmountContainerAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
PostWithoutBodyAsync($"{ContainerPath(name)}/unmount", "Unmount container", cancellationToken: cancellationToken);
|
||||
@ -228,7 +233,7 @@ public partial class PodmanClient {
|
||||
);
|
||||
|
||||
public Task<Result<ContainerChangesDto?>> GetContainerChangesAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<ContainerChangesDto>($"{ContainerPath(name)}/changes", "Get container changes", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<ContainerChangesDto>($"{ContainerPath(name)}/changes", "Get container changes", PodmanJsonContext.Default.ContainerChangesDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<ContainerCommitDto?>> CommitContainerAsync(
|
||||
string container,
|
||||
@ -255,14 +260,14 @@ public partial class PodmanClient {
|
||||
query.Add(("changes", change));
|
||||
}
|
||||
|
||||
return PostLibpodAsync<ContainerCommitDto>("/libpod/commit", "Commit container", query: query, cancellationToken: cancellationToken);
|
||||
return PostLibpodAsync<ContainerCommitDto>("/libpod/commit", "Commit container", PodmanJsonContext.Default.ContainerCommitDto, query: query, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public Task<Result<ContainerHealthCheckDto?>> HealthCheckContainerAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<ContainerHealthCheckDto>($"{ContainerPath(name)}/healthcheck", "Health check container", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<ContainerHealthCheckDto>($"{ContainerPath(name)}/healthcheck", "Health check container", PodmanJsonContext.Default.ContainerHealthCheckDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<MountedContainersResponseDto?>> GetMountedContainersAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<MountedContainersResponseDto>("/libpod/containers/showmounted", "Get mounted containers", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<MountedContainersResponseDto>("/libpod/containers/showmounted", "Get mounted containers", PodmanJsonContext.Default.MountedContainersResponseDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<ContainerTopDto?>> TopContainerAsync(
|
||||
string name,
|
||||
@ -273,6 +278,7 @@ public partial class PodmanClient {
|
||||
GetJsonAsync<ContainerTopDto>(
|
||||
$"{ContainerPath(name)}/top",
|
||||
"Top container",
|
||||
PodmanJsonContext.Default.ContainerTopDto,
|
||||
[
|
||||
("ps_args", psArgs),
|
||||
("stream", stream.ToString().ToLowerInvariant()),
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
using System.Text;
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MaksIT.Core.Extensions;
|
||||
using MaksIT.PodmanClientDotNet.Internal;
|
||||
using MaksIT.PodmanClientDotNet.Models;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Exec;
|
||||
@ -39,7 +39,9 @@ public partial class PodmanClient {
|
||||
return await PostJsonAsync<CreateExecRequest, CreateExecResponseDto>(
|
||||
$"/libpod/containers/{Uri.EscapeDataString(containerName)}/exec",
|
||||
"Create exec",
|
||||
execRequest
|
||||
execRequest,
|
||||
PodmanJsonContext.Default.CreateExecRequest,
|
||||
PodmanJsonContext.Default.CreateExecResponseDto
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@ -60,7 +62,8 @@ public partial class PodmanClient {
|
||||
var result = await PostJsonWithoutBodyAsync<StartExecRequest>(
|
||||
$"/libpod/exec/{Uri.EscapeDataString(execId)}/start",
|
||||
"Start exec",
|
||||
startExecRequest
|
||||
startExecRequest,
|
||||
PodmanJsonContext.Default.StartExecRequest
|
||||
).ConfigureAwait(false);
|
||||
|
||||
if (result.IsSuccess)
|
||||
@ -72,7 +75,8 @@ public partial class PodmanClient {
|
||||
public Task<Result<InspectExecResponseDto?>> InspectExecAsync(string execId) =>
|
||||
GetJsonAsync<InspectExecResponseDto>(
|
||||
$"/libpod/exec/{Uri.EscapeDataString(execId)}/json",
|
||||
"Inspect exec"
|
||||
"Inspect exec",
|
||||
PodmanJsonContext.Default.InspectExecResponseDto
|
||||
);
|
||||
|
||||
public Task<Result> ResizeExecAsync(string execId, int height, int width, CancellationToken cancellationToken = default) =>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Generate;
|
||||
@ -18,6 +19,7 @@ public partial class PodmanClient {
|
||||
GetJsonAsync<GenerateSystemdDto>(
|
||||
$"/libpod/generate/{Uri.EscapeDataString(name)}/systemd",
|
||||
"Generate systemd",
|
||||
PodmanJsonContext.Default.GenerateSystemdDto,
|
||||
[
|
||||
("useName", useName.ToString().ToLowerInvariant()),
|
||||
("new", createNew.ToString().ToLowerInvariant()),
|
||||
@ -62,6 +64,7 @@ public partial class PodmanClient {
|
||||
return PostLibpodAsync<PlayKubeReportDto>(
|
||||
"/libpod/play/kube",
|
||||
"Play kube",
|
||||
PodmanJsonContext.Default.PlayKubeReportDto,
|
||||
content,
|
||||
[
|
||||
("network", network),
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
|
||||
using MaksIT.Core.Extensions;
|
||||
using MaksIT.PodmanClientDotNet.Internal;
|
||||
using MaksIT.Results;
|
||||
|
||||
@ -55,13 +56,14 @@ public partial class PodmanClient {
|
||||
internal Task<Result<T?>> GetJsonAsync<T>(
|
||||
string libpodPath,
|
||||
string operation,
|
||||
JsonTypeInfo<T> typeInfo,
|
||||
IEnumerable<(string Key, string? Value)>? query = null,
|
||||
CancellationToken cancellationToken = default
|
||||
) =>
|
||||
SendAsync<T>(
|
||||
() => _httpClient.GetAsync(LibpodPath(libpodPath) + BuildQuery(query ?? []), cancellationToken),
|
||||
operation,
|
||||
body => body.ToObject<T>(),
|
||||
body => JsonSerializer.Deserialize(body, typeInfo),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
@ -81,17 +83,19 @@ public partial class PodmanClient {
|
||||
string libpodPath,
|
||||
string operation,
|
||||
TRequest? requestBody,
|
||||
JsonTypeInfo<TRequest> requestTypeInfo,
|
||||
JsonTypeInfo<TResponse> responseTypeInfo,
|
||||
IEnumerable<(string Key, string? Value)>? query = null,
|
||||
CancellationToken cancellationToken = default
|
||||
) {
|
||||
var content = requestBody is null
|
||||
? null
|
||||
: new StringContent(requestBody.ToJson(), Encoding.UTF8, "application/json");
|
||||
: new StringContent(JsonSerializer.Serialize(requestBody, requestTypeInfo), Encoding.UTF8, "application/json");
|
||||
|
||||
return SendAsync<TResponse>(
|
||||
() => _httpClient.PostAsync(LibpodPath(libpodPath) + BuildQuery(query ?? []), content, cancellationToken),
|
||||
operation,
|
||||
body => string.IsNullOrWhiteSpace(body) ? default : body.ToObject<TResponse>(),
|
||||
body => string.IsNullOrWhiteSpace(body) ? default : JsonSerializer.Deserialize(body, responseTypeInfo),
|
||||
cancellationToken
|
||||
);
|
||||
}
|
||||
@ -100,12 +104,13 @@ public partial class PodmanClient {
|
||||
string libpodPath,
|
||||
string operation,
|
||||
TRequest? requestBody,
|
||||
JsonTypeInfo<TRequest> requestTypeInfo,
|
||||
IEnumerable<(string Key, string? Value)>? query = null,
|
||||
CancellationToken cancellationToken = default
|
||||
) {
|
||||
var content = requestBody is null
|
||||
? null
|
||||
: new StringContent(requestBody.ToJson(), Encoding.UTF8, "application/json");
|
||||
: new StringContent(JsonSerializer.Serialize(requestBody, requestTypeInfo), Encoding.UTF8, "application/json");
|
||||
|
||||
return SendWithoutBodyAsync(
|
||||
() => _httpClient.PostAsync(LibpodPath(libpodPath) + BuildQuery(query ?? []), content, cancellationToken),
|
||||
@ -155,6 +160,7 @@ public partial class PodmanClient {
|
||||
internal Task<Result<TResponse?>> PostLibpodAsync<TResponse>(
|
||||
string libpodPath,
|
||||
string operation,
|
||||
JsonTypeInfo<TResponse> responseTypeInfo,
|
||||
HttpContent? content = null,
|
||||
IEnumerable<(string Key, string? Value)>? query = null,
|
||||
CancellationToken cancellationToken = default
|
||||
@ -162,20 +168,21 @@ public partial class PodmanClient {
|
||||
SendAsync<TResponse>(
|
||||
() => _httpClient.PostAsync(LibpodPath(libpodPath) + BuildQuery(query ?? []), content, cancellationToken),
|
||||
operation,
|
||||
body => string.IsNullOrWhiteSpace(body) ? default : body.ToObject<TResponse>(),
|
||||
body => string.IsNullOrWhiteSpace(body) ? default : JsonSerializer.Deserialize(body, responseTypeInfo),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
internal Task<Result<T?>> DeleteJsonAsync<T>(
|
||||
string libpodPath,
|
||||
string operation,
|
||||
JsonTypeInfo<T> typeInfo,
|
||||
IEnumerable<(string Key, string? Value)>? query = null,
|
||||
CancellationToken cancellationToken = default
|
||||
) =>
|
||||
SendAsync<T>(
|
||||
() => _httpClient.DeleteAsync(LibpodPath(libpodPath) + BuildQuery(query ?? []), cancellationToken),
|
||||
operation,
|
||||
body => string.IsNullOrWhiteSpace(body) ? default : body.ToObject<T>(),
|
||||
body => string.IsNullOrWhiteSpace(body) ? default : JsonSerializer.Deserialize(body, typeInfo),
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Common;
|
||||
@ -16,6 +17,7 @@ public partial class PodmanClient {
|
||||
GetJsonAsync<List<ImageListEntryDto>>(
|
||||
"/libpod/images/json",
|
||||
"List images",
|
||||
PodmanJsonContext.Default.ListImageListEntryDto,
|
||||
[
|
||||
("all", all.ToString().ToLowerInvariant()),
|
||||
("filters", filters),
|
||||
@ -24,7 +26,7 @@ public partial class PodmanClient {
|
||||
);
|
||||
|
||||
public Task<Result<ImageInspectDto?>> InspectImageAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<ImageInspectDto>($"{ImagePath(name)}/json", "Inspect image", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<ImageInspectDto>($"{ImagePath(name)}/json", "Inspect image", PodmanJsonContext.Default.ImageInspectDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> ImageExistsAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetWithoutBodyAsync($"{ImagePath(name)}/exists", "Image exists", cancellationToken: cancellationToken);
|
||||
@ -33,6 +35,7 @@ public partial class PodmanClient {
|
||||
DeleteJsonAsync<ImageDeleteDto[]>(
|
||||
ImagePath(name),
|
||||
"Delete image",
|
||||
PodmanJsonContext.Default.ImageDeleteDtoArray,
|
||||
[("force", force.ToString().ToLowerInvariant())],
|
||||
cancellationToken
|
||||
);
|
||||
@ -50,11 +53,11 @@ public partial class PodmanClient {
|
||||
foreach (var image in images)
|
||||
query.Add(("images", image));
|
||||
|
||||
return DeleteJsonAsync<ImageDeleteDto[]>("/libpod/images/remove", "Remove images", query, cancellationToken);
|
||||
return DeleteJsonAsync<ImageDeleteDto[]>("/libpod/images/remove", "Remove images", PodmanJsonContext.Default.ImageDeleteDtoArray, query, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<Result<PruneReportDto?>> PruneImagesAsync(CancellationToken cancellationToken = default) =>
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/images/prune", "Prune images", cancellationToken: cancellationToken);
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/images/prune", "Prune images", PodmanJsonContext.Default.PruneReportDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<List<ImageSearchResultDto>?>> SearchImagesAsync(
|
||||
string term,
|
||||
@ -64,6 +67,7 @@ public partial class PodmanClient {
|
||||
GetJsonAsync<List<ImageSearchResultDto>>(
|
||||
"/libpod/images/search",
|
||||
"Search images",
|
||||
PodmanJsonContext.Default.ListImageSearchResultDto,
|
||||
[
|
||||
("term", term),
|
||||
("limit", limit?.ToString()),
|
||||
@ -115,13 +119,13 @@ public partial class PodmanClient {
|
||||
);
|
||||
|
||||
public Task<Result<List<ImageHistoryEntryDto>?>> GetImageHistoryAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<List<ImageHistoryEntryDto>>($"{ImagePath(name)}/history", "Get image history", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<List<ImageHistoryEntryDto>>($"{ImagePath(name)}/history", "Get image history", PodmanJsonContext.Default.ListImageHistoryEntryDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<ImageTreeDto?>> GetImageTreeAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<ImageTreeDto>($"{ImagePath(name)}/tree", "Get image tree", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<ImageTreeDto>($"{ImagePath(name)}/tree", "Get image tree", PodmanJsonContext.Default.ImageTreeDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<ImageChangesDto?>> GetImageChangesAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<ImageChangesDto>($"{ImagePath(name)}/changes", "Get image changes", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<ImageChangesDto>($"{ImagePath(name)}/changes", "Get image changes", PodmanJsonContext.Default.ImageChangesDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<ImageImportDto?>> ImportImageAsync(
|
||||
Stream? tarball = null,
|
||||
@ -140,6 +144,7 @@ public partial class PodmanClient {
|
||||
return PostLibpodAsync<ImageImportDto>(
|
||||
"/libpod/images/import",
|
||||
"Import image",
|
||||
PodmanJsonContext.Default.ImageImportDto,
|
||||
content,
|
||||
[
|
||||
("changes", changes),
|
||||
@ -154,7 +159,7 @@ public partial class PodmanClient {
|
||||
public Task<Result<ImageLoadDto?>> LoadImageAsync(Stream tarball, CancellationToken cancellationToken = default) {
|
||||
var content = new StreamContent(tarball);
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-tar");
|
||||
return PostLibpodAsync<ImageLoadDto>("/libpod/images/load", "Load image", content, cancellationToken: cancellationToken);
|
||||
return PostLibpodAsync<ImageLoadDto>("/libpod/images/load", "Load image", PodmanJsonContext.Default.ImageLoadDto, content, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public Task<Result<Stream?>> ExportImagesAsync(
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Manifest;
|
||||
using MaksIT.Results;
|
||||
|
||||
@ -13,6 +14,7 @@ public partial class PodmanClient {
|
||||
PostLibpodAsync<ManifestCreateDto>(
|
||||
"/libpod/manifests/create",
|
||||
"Create manifest",
|
||||
PodmanJsonContext.Default.ManifestCreateDto,
|
||||
query: [
|
||||
("name", name),
|
||||
("image", image),
|
||||
@ -30,10 +32,10 @@ public partial class PodmanClient {
|
||||
);
|
||||
|
||||
public Task<Result<ManifestInspectDto?>> InspectManifestAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<ManifestInspectDto>($"{ManifestPath(name)}/json", "Inspect manifest", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<ManifestInspectDto>($"{ManifestPath(name)}/json", "Inspect manifest", PodmanJsonContext.Default.ManifestInspectDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> AddToManifestAsync(string name, ManifestAddRequestDto request, CancellationToken cancellationToken = default) =>
|
||||
PostJsonWithoutBodyAsync($"{ManifestPath(name)}/add", "Add to manifest", request, cancellationToken: cancellationToken);
|
||||
PostJsonWithoutBodyAsync($"{ManifestPath(name)}/add", "Add to manifest", request, PodmanJsonContext.Default.ManifestAddRequestDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> PushManifestAsync(
|
||||
string name,
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Network;
|
||||
using MaksIT.PodmanClientDotNet.Models.Network;
|
||||
using MaksIT.Results;
|
||||
@ -11,14 +12,16 @@ public partial class PodmanClient {
|
||||
"/libpod/networks/create",
|
||||
"Create network",
|
||||
request,
|
||||
PodmanJsonContext.Default.NetworkCreateRequest,
|
||||
PodmanJsonContext.Default.NetworkListEntryDto,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
public Task<Result<List<NetworkListEntryDto>?>> ListNetworksAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<List<NetworkListEntryDto>>("/libpod/networks/json", "List networks", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<List<NetworkListEntryDto>>("/libpod/networks/json", "List networks", PodmanJsonContext.Default.ListNetworkListEntryDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<NetworkInspectDto?>> InspectNetworkAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<NetworkInspectDto>($"/libpod/networks/{Uri.EscapeDataString(name)}/json", "Inspect network", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<NetworkInspectDto>($"/libpod/networks/{Uri.EscapeDataString(name)}/json", "Inspect network", PodmanJsonContext.Default.NetworkInspectDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> DeleteNetworkAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
DeleteWithoutBodyAsync($"/libpod/networks/{Uri.EscapeDataString(name)}", "Delete network", cancellationToken: cancellationToken);
|
||||
@ -32,6 +35,7 @@ public partial class PodmanClient {
|
||||
$"/libpod/networks/{Uri.EscapeDataString(name)}/connect",
|
||||
"Connect network",
|
||||
request,
|
||||
PodmanJsonContext.Default.NetworkConnectRequest,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
@ -44,6 +48,7 @@ public partial class PodmanClient {
|
||||
$"/libpod/networks/{Uri.EscapeDataString(name)}/disconnect",
|
||||
"Disconnect network",
|
||||
request,
|
||||
PodmanJsonContext.Default.NetworkDisconnectRequest,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Common;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Pod;
|
||||
using MaksIT.PodmanClientDotNet.Models.Pod;
|
||||
@ -5,18 +6,19 @@ using MaksIT.Results;
|
||||
|
||||
public partial class PodmanClient {
|
||||
public Task<Result<PodListEntryDto?>> CreatePodAsync(PodCreateRequest request, CancellationToken cancellationToken = default) =>
|
||||
PostJsonAsync<PodCreateRequest, PodListEntryDto>("/libpod/pods/create", "Create pod", request, cancellationToken: cancellationToken);
|
||||
PostJsonAsync<PodCreateRequest, PodListEntryDto>("/libpod/pods/create", "Create pod", request, PodmanJsonContext.Default.PodCreateRequest, PodmanJsonContext.Default.PodListEntryDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<List<PodListEntryDto>?>> ListPodsAsync(bool all = false, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<List<PodListEntryDto>>(
|
||||
"/libpod/pods/json",
|
||||
"List pods",
|
||||
PodmanJsonContext.Default.ListPodListEntryDto,
|
||||
[("all", all.ToString().ToLowerInvariant())],
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
public Task<Result<PodInspectDto?>> InspectPodAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<PodInspectDto>($"/libpod/pods/{Uri.EscapeDataString(name)}/json", "Inspect pod", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<PodInspectDto>($"/libpod/pods/{Uri.EscapeDataString(name)}/json", "Inspect pod", PodmanJsonContext.Default.PodInspectDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> PodExistsAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetWithoutBodyAsync($"/libpod/pods/{Uri.EscapeDataString(name)}/exists", "Pod exists", cancellationToken: cancellationToken);
|
||||
@ -63,11 +65,11 @@ public partial class PodmanClient {
|
||||
PostWithoutBodyAsync($"/libpod/pods/{Uri.EscapeDataString(name)}/unpause", "Unpause pod", cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<PruneReportDto?>> PrunePodsAsync(CancellationToken cancellationToken = default) =>
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/pods/prune", "Prune pods", cancellationToken: cancellationToken);
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/pods/prune", "Prune pods", PodmanJsonContext.Default.PruneReportDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<PodTopDto?>> TopPodAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<PodTopDto>($"/libpod/pods/{Uri.EscapeDataString(name)}/top", "Top pod", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<PodTopDto>($"/libpod/pods/{Uri.EscapeDataString(name)}/top", "Top pod", PodmanJsonContext.Default.PodTopDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<PodStatsResponseDto?>> GetPodsStatsAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<PodStatsResponseDto>("/libpod/pods/stats", "Get pods stats", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<PodStatsResponseDto>("/libpod/pods/stats", "Get pods stats", PodmanJsonContext.Default.PodStatsResponseDto, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using MaksIT.Core.Extensions;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Build;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Image;
|
||||
using MaksIT.PodmanClientDotNet.Internal;
|
||||
@ -65,7 +66,7 @@ public partial class PodmanClient {
|
||||
Height = height,
|
||||
Width = width,
|
||||
};
|
||||
var body = Encoding.UTF8.GetBytes(startExecRequest.ToJson());
|
||||
var body = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(startExecRequest, PodmanJsonContext.Default.StartExecRequest));
|
||||
var query = BuildQuery([]);
|
||||
|
||||
var hijack = await PodmanHijackConnection.ConnectAsync(
|
||||
@ -122,7 +123,7 @@ public partial class PodmanClient {
|
||||
return streamResult.ToResultOfType<IPodmanProgressSession<PullImageResponseDto>>(null!);
|
||||
|
||||
return Result<IPodmanProgressSession<PullImageResponseDto>?>.Ok(
|
||||
new PodmanProgressSession<PullImageResponseDto>(streamResult.Value!)
|
||||
new PodmanProgressSession<PullImageResponseDto>(streamResult.Value!, PodmanJsonContext.Default.PullImageResponseDto)
|
||||
);
|
||||
}
|
||||
|
||||
@ -169,7 +170,7 @@ public partial class PodmanClient {
|
||||
return streamResult.ToResultOfType<IPodmanProgressSession<BuildProgressLineDto>>(null!);
|
||||
|
||||
return Result<IPodmanProgressSession<BuildProgressLineDto>?>.Ok(
|
||||
new PodmanProgressSession<BuildProgressLineDto>(streamResult.Value!)
|
||||
new PodmanProgressSession<BuildProgressLineDto>(streamResult.Value!, PodmanJsonContext.Default.BuildProgressLineDto)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,22 +1,23 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Common;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.System;
|
||||
using MaksIT.Results;
|
||||
|
||||
public partial class PodmanClient {
|
||||
public Task<Result<LibpodPingDto?>> PingAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<LibpodPingDto>("/libpod/_ping", "Ping", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<LibpodPingDto>("/libpod/_ping", "Ping", PodmanJsonContext.Default.LibpodPingDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<LibpodVersionDto?>> GetVersionAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<LibpodVersionDto>("/libpod/version", "Get version", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<LibpodVersionDto>("/libpod/version", "Get version", PodmanJsonContext.Default.LibpodVersionDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<InfoDto?>> GetInfoAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<InfoDto>("/libpod/info", "Get info", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<InfoDto>("/libpod/info", "Get info", PodmanJsonContext.Default.InfoDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<SystemDfDto?>> GetSystemDiskUsageAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<SystemDfDto>("/libpod/system/df", "Get system disk usage", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<SystemDfDto>("/libpod/system/df", "Get system disk usage", PodmanJsonContext.Default.SystemDfDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<PruneReportDto?>> PruneSystemAsync(CancellationToken cancellationToken = default) =>
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/system/prune", "Prune system", cancellationToken: cancellationToken);
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/system/prune", "Prune system", PodmanJsonContext.Default.PruneReportDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<Stream?>> GetEventsAsync(CancellationToken cancellationToken = default) =>
|
||||
GetStreamAsync("/libpod/events", "Get events", cancellationToken: cancellationToken);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
using MaksIT.PodmanClientDotNet;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Common;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Volume;
|
||||
using MaksIT.PodmanClientDotNet.Models.Volume;
|
||||
@ -12,14 +13,16 @@ public partial class PodmanClient {
|
||||
"/libpod/volumes/create",
|
||||
"Create volume",
|
||||
request,
|
||||
PodmanJsonContext.Default.CreateVolumeRequest,
|
||||
PodmanJsonContext.Default.VolumeInspectResponseDto,
|
||||
cancellationToken: cancellationToken
|
||||
);
|
||||
|
||||
public Task<Result<List<VolumeListEntryDto>?>> ListVolumesAsync(CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<List<VolumeListEntryDto>>("/libpod/volumes/json", "List volumes", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<List<VolumeListEntryDto>>("/libpod/volumes/json", "List volumes", PodmanJsonContext.Default.ListVolumeListEntryDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result<VolumeInspectResponseDto?>> InspectVolumeAsync(string name, CancellationToken cancellationToken = default) =>
|
||||
GetJsonAsync<VolumeInspectResponseDto>($"/libpod/volumes/{Uri.EscapeDataString(name)}/json", "Inspect volume", cancellationToken: cancellationToken);
|
||||
GetJsonAsync<VolumeInspectResponseDto>($"/libpod/volumes/{Uri.EscapeDataString(name)}/json", "Inspect volume", PodmanJsonContext.Default.VolumeInspectResponseDto, cancellationToken: cancellationToken);
|
||||
|
||||
public Task<Result> DeleteVolumeAsync(string name, bool force = false, CancellationToken cancellationToken = default) =>
|
||||
DeleteWithoutBodyAsync(
|
||||
@ -30,5 +33,5 @@ public partial class PodmanClient {
|
||||
);
|
||||
|
||||
public Task<Result<PruneReportDto?>> PruneVolumesAsync(CancellationToken cancellationToken = default) =>
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/volumes/prune", "Prune volumes", cancellationToken: cancellationToken);
|
||||
PostLibpodAsync<PruneReportDto>("/libpod/volumes/prune", "Prune volumes", PodmanJsonContext.Default.PruneReportDto, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
@ -39,6 +39,9 @@
|
||||
<!-- Deterministic builds for reproducibility -->
|
||||
<Deterministic>true</Deterministic>
|
||||
<ContinuousIntegrationBuild Condition="'$(CI)' == 'true'">true</ContinuousIntegrationBuild>
|
||||
|
||||
<!-- AOT / trimming compatibility -->
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -46,7 +49,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MaksIT.Core" Version="1.6.8" />
|
||||
<PackageReference Include="MaksIT.Results" Version="2.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.9" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.9" />
|
||||
|
||||
116
src/PodmanClient/PodmanJsonContext.cs
Normal file
116
src/PodmanClient/PodmanJsonContext.cs
Normal file
@ -0,0 +1,116 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Build;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Common;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Container;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Exec;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Generate;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Image;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Manifest;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Network;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Pod;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.System;
|
||||
using MaksIT.PodmanClientDotNet.Dtos.Volume;
|
||||
using MaksIT.PodmanClientDotNet.Models.Container;
|
||||
using MaksIT.PodmanClientDotNet.Models.Exec;
|
||||
using MaksIT.PodmanClientDotNet.Models.Network;
|
||||
using MaksIT.PodmanClientDotNet.Models.Pod;
|
||||
using MaksIT.PodmanClientDotNet.Models.Volume;
|
||||
|
||||
namespace MaksIT.PodmanClientDotNet;
|
||||
|
||||
// ----- Response / DTO types -----
|
||||
|
||||
// Common
|
||||
[JsonSerializable(typeof(ErrorResponseDto))]
|
||||
[JsonSerializable(typeof(IdResponseDto))]
|
||||
[JsonSerializable(typeof(PruneReportDto))]
|
||||
[JsonSerializable(typeof(ReportDto))]
|
||||
|
||||
// Build
|
||||
[JsonSerializable(typeof(BuildProgressLineDto))]
|
||||
[JsonSerializable(typeof(BuildReportDto))]
|
||||
|
||||
// Container
|
||||
[JsonSerializable(typeof(ContainerChangesDto))]
|
||||
[JsonSerializable(typeof(ContainerCommitDto))]
|
||||
[JsonSerializable(typeof(ContainerHealthCheckDto))]
|
||||
[JsonSerializable(typeof(ContainerInspectDto))]
|
||||
[JsonSerializable(typeof(ContainerListEntryDto))]
|
||||
[JsonSerializable(typeof(List<ContainerListEntryDto>))]
|
||||
[JsonSerializable(typeof(ContainerMountDto))]
|
||||
[JsonSerializable(typeof(ContainerStatsDto))]
|
||||
[JsonSerializable(typeof(Dictionary<string, ContainerStatsDto>))]
|
||||
[JsonSerializable(typeof(ContainerTopDto))]
|
||||
[JsonSerializable(typeof(ContainerWaitDto))]
|
||||
[JsonSerializable(typeof(CreateContainerResponseDto))]
|
||||
[JsonSerializable(typeof(DeleteContainerResponseDto))]
|
||||
[JsonSerializable(typeof(DeleteContainerResponseDto[]))]
|
||||
[JsonSerializable(typeof(MountedContainersResponseDto))]
|
||||
|
||||
// Exec
|
||||
[JsonSerializable(typeof(CreateExecResponseDto))]
|
||||
[JsonSerializable(typeof(InspectExecResponseDto))]
|
||||
|
||||
// Generate
|
||||
[JsonSerializable(typeof(GenerateSystemdDto))]
|
||||
[JsonSerializable(typeof(PlayKubeReportDto))]
|
||||
|
||||
// Image
|
||||
[JsonSerializable(typeof(ImageChangesDto))]
|
||||
[JsonSerializable(typeof(ImageDeleteDto))]
|
||||
[JsonSerializable(typeof(ImageDeleteDto[]))]
|
||||
[JsonSerializable(typeof(ImageHistoryEntryDto))]
|
||||
[JsonSerializable(typeof(List<ImageHistoryEntryDto>))]
|
||||
[JsonSerializable(typeof(ImageImportDto))]
|
||||
[JsonSerializable(typeof(ImageInspectDto))]
|
||||
[JsonSerializable(typeof(ImageListEntryDto))]
|
||||
[JsonSerializable(typeof(List<ImageListEntryDto>))]
|
||||
[JsonSerializable(typeof(ImageLoadDto))]
|
||||
[JsonSerializable(typeof(ImageRemoveResponseDto))]
|
||||
[JsonSerializable(typeof(ImageSearchResultDto))]
|
||||
[JsonSerializable(typeof(List<ImageSearchResultDto>))]
|
||||
[JsonSerializable(typeof(ImageTreeDto))]
|
||||
[JsonSerializable(typeof(PullImageResponseDto))]
|
||||
|
||||
// Manifest
|
||||
[JsonSerializable(typeof(ManifestCreateDto))]
|
||||
[JsonSerializable(typeof(ManifestInspectDto))]
|
||||
|
||||
// Network
|
||||
[JsonSerializable(typeof(NetworkInspectDto))]
|
||||
[JsonSerializable(typeof(NetworkListEntryDto))]
|
||||
[JsonSerializable(typeof(List<NetworkListEntryDto>))]
|
||||
|
||||
// Pod
|
||||
[JsonSerializable(typeof(PodInspectDto))]
|
||||
[JsonSerializable(typeof(PodListEntryDto))]
|
||||
[JsonSerializable(typeof(List<PodListEntryDto>))]
|
||||
[JsonSerializable(typeof(PodTopDto))]
|
||||
[JsonSerializable(typeof(PodStatsResponseDto))]
|
||||
|
||||
// System
|
||||
[JsonSerializable(typeof(InfoDto))]
|
||||
[JsonSerializable(typeof(LibpodPingDto))]
|
||||
[JsonSerializable(typeof(LibpodVersionDto))]
|
||||
[JsonSerializable(typeof(SystemDfDto))]
|
||||
|
||||
// Volume
|
||||
[JsonSerializable(typeof(VolumeInspectResponseDto))]
|
||||
[JsonSerializable(typeof(VolumeListEntryDto))]
|
||||
[JsonSerializable(typeof(List<VolumeListEntryDto>))]
|
||||
|
||||
// ----- Request / model types -----
|
||||
[JsonSerializable(typeof(CreateContainerRequest))]
|
||||
[JsonSerializable(typeof(CreateExecRequest))]
|
||||
[JsonSerializable(typeof(StartExecRequest))]
|
||||
[JsonSerializable(typeof(NetworkCreateRequest))]
|
||||
[JsonSerializable(typeof(NetworkConnectRequest))]
|
||||
[JsonSerializable(typeof(NetworkDisconnectRequest))]
|
||||
[JsonSerializable(typeof(PodCreateRequest))]
|
||||
[JsonSerializable(typeof(CreateVolumeRequest))]
|
||||
[JsonSerializable(typeof(ManifestAddRequestDto))]
|
||||
|
||||
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, PropertyNameCaseInsensitive = true)]
|
||||
internal sealed partial class PodmanJsonContext : JsonSerializerContext {
|
||||
}
|
||||
@ -1,15 +1,16 @@
|
||||
using System.Text.Json;
|
||||
|
||||
using MaksIT.Core.Extensions;
|
||||
using System.Text.Json.Serialization.Metadata;
|
||||
|
||||
namespace MaksIT.PodmanClientDotNet.Streaming;
|
||||
|
||||
internal sealed class PodmanProgressSession<T> : IPodmanProgressSession<T> {
|
||||
private readonly Stream _stream;
|
||||
private readonly bool _ownsStream;
|
||||
private readonly JsonTypeInfo<T> _typeInfo;
|
||||
|
||||
internal PodmanProgressSession(Stream stream, bool ownsStream = true) {
|
||||
internal PodmanProgressSession(Stream stream, JsonTypeInfo<T> typeInfo, bool ownsStream = true) {
|
||||
_stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||
_typeInfo = typeInfo ?? throw new ArgumentNullException(nameof(typeInfo));
|
||||
_ownsStream = ownsStream;
|
||||
}
|
||||
|
||||
@ -24,7 +25,7 @@ internal sealed class PodmanProgressSession<T> : IPodmanProgressSession<T> {
|
||||
|
||||
T? item;
|
||||
try {
|
||||
item = line.ToObject<T>();
|
||||
item = JsonSerializer.Deserialize(line, _typeInfo);
|
||||
}
|
||||
catch (JsonException) {
|
||||
continue;
|
||||
|
||||
@ -10,7 +10,7 @@ public class PodmanProgressSessionTests {
|
||||
public async Task ReadProgressAsync_ParsesNdjsonLines() {
|
||||
var json = "{\"status\":\"Pulling fs layer\"}\n{\"id\":\"abc\"}\n";
|
||||
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
|
||||
await using var session = new PodmanProgressSession<PullImageResponseDto>(stream, ownsStream: false);
|
||||
await using var session = new PodmanProgressSession<PullImageResponseDto>(stream, PodmanJsonContext.Default.PullImageResponseDto, ownsStream: false);
|
||||
|
||||
var items = new List<PullImageResponseDto>();
|
||||
await foreach (var item in session.ReadProgressAsync(TestContext.Current.CancellationToken))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user