From b37342cda179b47c29ac2d908f7857c74862f0f3 Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sat, 17 Aug 2024 22:11:46 +0200 Subject: [PATCH] (feature): init --- .gitattributes | 63 +++ .gitignore | 266 +++++++++ LICENSE.md | 21 + README.md | 3 + .../Extensions/ObjectExtensions.cs | 36 ++ .../Extensions/StringExtensions.cs | 35 ++ src/PodmanClient/Models/AutoUserNsOptions.cs | 18 + src/PodmanClient/Models/BindOptions.cs | 16 + src/PodmanClient/Models/BlockIO.cs | 18 + src/PodmanClient/Models/CPU.cs | 20 + .../Container/CreateContainerRequest.cs | 129 +++++ .../Container/CreateContainerResponse.cs | 13 + .../Container/DeleteContainerResponse.cs | 12 + src/PodmanClient/Models/DriverConfig.cs | 13 + src/PodmanClient/Models/ErrorResponse.cs | 13 + .../Models/Exec/CreateExecRequest.cs | 22 + .../Models/Exec/CreateExecResponse.cs | 12 + .../Models/Exec/InspectExecResponse.cs | 13 + .../Models/Exec/StartExecRequest.cs | 14 + src/PodmanClient/Models/HugepageLimit.cs | 12 + src/PodmanClient/Models/IDMapping.cs | 14 + src/PodmanClient/Models/IDMappingOptions.cs | 18 + .../Models/Image/ImagePullStatusResponse.cs | 14 + .../Models/Image/ImagePullStreamResponse.cs | 11 + src/PodmanClient/Models/ImageVolume.cs | 15 + src/PodmanClient/Models/IntelRdt.cs | 16 + src/PodmanClient/Models/LinuxDevice.cs | 18 + src/PodmanClient/Models/LinuxDeviceCgroup.cs | 16 + src/PodmanClient/Models/LinuxIntelRdt.cs | 16 + src/PodmanClient/Models/LinuxPersonality.cs | 13 + src/PodmanClient/Models/LinuxResources.cs | 21 + src/PodmanClient/Models/LogConfigLibpod.cs | 15 + src/PodmanClient/Models/Memory.cs | 20 + src/PodmanClient/Models/Mount.cs | 20 + src/PodmanClient/Models/NamedVolume.cs | 16 + src/PodmanClient/Models/Namespace.cs | 13 + src/PodmanClient/Models/Network.cs | 13 + src/PodmanClient/Models/NetworkPriority.cs | 13 + src/PodmanClient/Models/NetworkSettings.cs | 15 + src/PodmanClient/Models/OverlayVolume.cs | 14 + src/PodmanClient/Models/POSIXRlimit.cs | 14 + src/PodmanClient/Models/Pids.cs | 12 + src/PodmanClient/Models/PortMapping.cs | 16 + src/PodmanClient/Models/ProgressDetail.cs | 12 + src/PodmanClient/Models/RdmaResource.cs | 13 + .../Models/Schema2HealthConfig.cs | 17 + src/PodmanClient/Models/SecretProp.cs | 13 + .../Models/StartupHealthConfig.cs | 18 + src/PodmanClient/Models/ThrottleDevice.cs | 14 + src/PodmanClient/Models/TmpfsOptions.cs | 14 + src/PodmanClient/Models/VolumeOptions.cs | 15 + src/PodmanClient/Models/WeightDevice.cs | 15 + src/PodmanClient/PodmanClientDotNet.csproj | 10 + src/PodmanClient/PodmanConnector.cs | 19 + src/PodmanClient/PodmanConnectorContainer.cs | 503 ++++++++++++++++++ src/PodmanClient/PodmanConnectorExec.cs | 170 ++++++ src/PodmanClient/PodmanConnectorImage.cs | 107 ++++ src/PodmanClientDotNet.sln | 25 + 58 files changed, 2067 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 src/PodmanClient/Extensions/ObjectExtensions.cs create mode 100644 src/PodmanClient/Extensions/StringExtensions.cs create mode 100644 src/PodmanClient/Models/AutoUserNsOptions.cs create mode 100644 src/PodmanClient/Models/BindOptions.cs create mode 100644 src/PodmanClient/Models/BlockIO.cs create mode 100644 src/PodmanClient/Models/CPU.cs create mode 100644 src/PodmanClient/Models/Container/CreateContainerRequest.cs create mode 100644 src/PodmanClient/Models/Container/CreateContainerResponse.cs create mode 100644 src/PodmanClient/Models/Container/DeleteContainerResponse.cs create mode 100644 src/PodmanClient/Models/DriverConfig.cs create mode 100644 src/PodmanClient/Models/ErrorResponse.cs create mode 100644 src/PodmanClient/Models/Exec/CreateExecRequest.cs create mode 100644 src/PodmanClient/Models/Exec/CreateExecResponse.cs create mode 100644 src/PodmanClient/Models/Exec/InspectExecResponse.cs create mode 100644 src/PodmanClient/Models/Exec/StartExecRequest.cs create mode 100644 src/PodmanClient/Models/HugepageLimit.cs create mode 100644 src/PodmanClient/Models/IDMapping.cs create mode 100644 src/PodmanClient/Models/IDMappingOptions.cs create mode 100644 src/PodmanClient/Models/Image/ImagePullStatusResponse.cs create mode 100644 src/PodmanClient/Models/Image/ImagePullStreamResponse.cs create mode 100644 src/PodmanClient/Models/ImageVolume.cs create mode 100644 src/PodmanClient/Models/IntelRdt.cs create mode 100644 src/PodmanClient/Models/LinuxDevice.cs create mode 100644 src/PodmanClient/Models/LinuxDeviceCgroup.cs create mode 100644 src/PodmanClient/Models/LinuxIntelRdt.cs create mode 100644 src/PodmanClient/Models/LinuxPersonality.cs create mode 100644 src/PodmanClient/Models/LinuxResources.cs create mode 100644 src/PodmanClient/Models/LogConfigLibpod.cs create mode 100644 src/PodmanClient/Models/Memory.cs create mode 100644 src/PodmanClient/Models/Mount.cs create mode 100644 src/PodmanClient/Models/NamedVolume.cs create mode 100644 src/PodmanClient/Models/Namespace.cs create mode 100644 src/PodmanClient/Models/Network.cs create mode 100644 src/PodmanClient/Models/NetworkPriority.cs create mode 100644 src/PodmanClient/Models/NetworkSettings.cs create mode 100644 src/PodmanClient/Models/OverlayVolume.cs create mode 100644 src/PodmanClient/Models/POSIXRlimit.cs create mode 100644 src/PodmanClient/Models/Pids.cs create mode 100644 src/PodmanClient/Models/PortMapping.cs create mode 100644 src/PodmanClient/Models/ProgressDetail.cs create mode 100644 src/PodmanClient/Models/RdmaResource.cs create mode 100644 src/PodmanClient/Models/Schema2HealthConfig.cs create mode 100644 src/PodmanClient/Models/SecretProp.cs create mode 100644 src/PodmanClient/Models/StartupHealthConfig.cs create mode 100644 src/PodmanClient/Models/ThrottleDevice.cs create mode 100644 src/PodmanClient/Models/TmpfsOptions.cs create mode 100644 src/PodmanClient/Models/VolumeOptions.cs create mode 100644 src/PodmanClient/Models/WeightDevice.cs create mode 100644 src/PodmanClient/PodmanClientDotNet.csproj create mode 100644 src/PodmanClient/PodmanConnector.cs create mode 100644 src/PodmanClient/PodmanConnectorContainer.cs create mode 100644 src/PodmanClient/PodmanConnectorExec.cs create mode 100644 src/PodmanClient/PodmanConnectorImage.cs create mode 100644 src/PodmanClientDotNet.sln diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f09bf8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,266 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs +.directory + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + + +**/*docker-compose/LetsEncryptServer/acme +**/*docker-compose/LetsEncryptServer/cache \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..3af1574 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Maksym Sadovnychyy (MAKS-IT) + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..040fa93 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Podman Client DotNet + +Podman API .NET cilent implementation based on podman latest [documentation](https://docs.podman.io/en/latest/) \ No newline at end of file diff --git a/src/PodmanClient/Extensions/ObjectExtensions.cs b/src/PodmanClient/Extensions/ObjectExtensions.cs new file mode 100644 index 0000000..df68c2c --- /dev/null +++ b/src/PodmanClient/Extensions/ObjectExtensions.cs @@ -0,0 +1,36 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MaksIT.PodmanClientDotNet.Extensions; + +public static class ObjectExtensions { + + /// + /// Converts object to json string + /// + /// + /// + /// + public static string ToJson(this T? obj) => ToJson(obj, null); + + /// + /// Converts object to json string + /// + /// + /// + /// + /// + public static string ToJson(T? obj, List? converters) { + if (obj == null) + return "{}"; + + var options = new JsonSerializerOptions { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + }; + + converters?.ForEach(x => options.Converters.Add(x)); + + return JsonSerializer.Serialize(obj, options); + } +} \ No newline at end of file diff --git a/src/PodmanClient/Extensions/StringExtensions.cs b/src/PodmanClient/Extensions/StringExtensions.cs new file mode 100644 index 0000000..d05a08b --- /dev/null +++ b/src/PodmanClient/Extensions/StringExtensions.cs @@ -0,0 +1,35 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MaksIT.PodmanClientDotNet.Extensions; + +public static partial class StringExtensions { + + + /// + /// Converts JSON string to object + /// + /// + /// + /// + public static T? ToObject(this string s) => ToObjectCore(s, null); + + /// + /// + /// + /// + /// + /// + /// + public static T? ToObject(this string s, List converters) => ToObjectCore(s, converters); + + private static T? ToObjectCore(string s, List? converters) { + var options = new JsonSerializerOptions { + PropertyNameCaseInsensitive = true + }; + + converters?.ForEach(x => options.Converters.Add(x)); + + return JsonSerializer.Deserialize(s, options); + } +} \ No newline at end of file diff --git a/src/PodmanClient/Models/AutoUserNsOptions.cs b/src/PodmanClient/Models/AutoUserNsOptions.cs new file mode 100644 index 0000000..6cad328 --- /dev/null +++ b/src/PodmanClient/Models/AutoUserNsOptions.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class AutoUserNsOptions { + public List AdditionalGIDMappings { get; set; } + public List AdditionalUIDMappings { get; set; } + public string GroupFile { get; set; } + public int InitialSize { get; set; } + public string PasswdFile { get; set; } + public int Size { get; set; } + } + +} diff --git a/src/PodmanClient/Models/BindOptions.cs b/src/PodmanClient/Models/BindOptions.cs new file mode 100644 index 0000000..5dfa213 --- /dev/null +++ b/src/PodmanClient/Models/BindOptions.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class BindOptions { + public bool CreateMountpoint { get; set; } + public bool NonRecursive { get; set; } + public string Propagation { get; set; } + public bool ReadOnlyForceRecursive { get; set; } + public bool ReadOnlyNonRecursive { get; set; } + } + +} diff --git a/src/PodmanClient/Models/BlockIO.cs b/src/PodmanClient/Models/BlockIO.cs new file mode 100644 index 0000000..3f211be --- /dev/null +++ b/src/PodmanClient/Models/BlockIO.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class BlockIO { + public int LeafWeight { get; set; } + public List ThrottleReadBpsDevice { get; set; } + public List ThrottleReadIopsDevice { get; set; } + public List ThrottleWriteBpsDevice { get; set; } + public List ThrottleWriteIopsDevice { get; set; } + public int Weight { get; set; } + public List WeightDevice { get; set; } + } + +} diff --git a/src/PodmanClient/Models/CPU.cs b/src/PodmanClient/Models/CPU.cs new file mode 100644 index 0000000..79e2757 --- /dev/null +++ b/src/PodmanClient/Models/CPU.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class CPU { + public int Burst { get; set; } + public string Cpus { get; set; } + public int Idle { get; set; } + public string Mems { get; set; } + public int Period { get; set; } + public int Quota { get; set; } + public int RealtimePeriod { get; set; } + public int RealtimeRuntime { get; set; } + public int Shares { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Container/CreateContainerRequest.cs b/src/PodmanClient/Models/Container/CreateContainerRequest.cs new file mode 100644 index 0000000..927d63a --- /dev/null +++ b/src/PodmanClient/Models/Container/CreateContainerRequest.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Container { + public class CreateContainerRequest { + public Dictionary Annotations { get; set; } + public string ApparmorProfile { get; set; } + public string BaseHostsFile { get; set; } + public List CapAdd { get; set; } + public List CapDrop { get; set; } + public string CgroupParent { get; set; } + public Namespace Cgroupns { get; set; } + public string CgroupsMode { get; set; } + public List ChrootDirectories { get; set; } + public List CNINetworks { get; set; } + public List Command { get; set; } + public string ConmonPidFile { get; set; } + public List ContainerCreateCommand { get; set; } + public bool? CreateWorkingDir { get; set; } + public List DependencyContainers { get; set; } + public List DeviceCgroupRule { get; set; } + public List Devices { get; set; } + public List DevicesFrom { get; set; } + public List DNSOption { get; set; } + public List DNSSearch { get; set; } + public List DNSServer { get; set; } + public List Entrypoint { get; set; } + public Dictionary Env { get; set; } + public bool? EnvHost { get; set; } + public List EnvMerge { get; set; } + public Dictionary Expose { get; set; } + public string GroupEntry { get; set; } + public List Groups { get; set; } + public long? HealthCheckOnFailureAction { get; set; } + public Schema2HealthConfig HealthConfig { get; set; } + public List HostDeviceList { get; set; } + public List HostAdd { get; set; } + public string Hostname { get; set; } + public List HostUsers { get; set; } + public bool? EnvHTTPProxy { get; set; } + public IDMappingOptions IDMappings { get; set; } + public string Image { get; set; } + public string ImageArch { get; set; } + public string ImageOS { get; set; } + public string ImageVariant { get; set; } + public string ImageVolumeMode { get; set; } + public List ImageVolumes { get; set; } + public bool? Init { get; set; } + public string InitContainerType { get; set; } + public string InitPath { get; set; } + public LinuxIntelRdt IntelRdt { get; set; } + public Namespace Ipcns { get; set; } + public bool? LabelNested { get; set; } + public Dictionary Labels { get; set; } + public LogConfigLibpod LogConfiguration { get; set; } + public bool? ManagePassword { get; set; } + public List Mask { get; set; } + public List Mounts { get; set; } + public string Name { get; set; } + public Namespace Netns { get; set; } + public Dictionary NetworkOptions { get; set; } + public Dictionary Networks { get; set; } + public bool? NoNewPrivileges { get; set; } + public string OciRuntime { get; set; } + public long? OomScoreAdj { get; set; } + public List OverlayVolumes { get; set; } + public string PasswdEntry { get; set; } + public LinuxPersonality Personality { get; set; } + public Namespace Pidns { get; set; } + public string Pod { get; set; } + public List Portmappings { get; set; } + public bool? Privileged { get; set; } + public List ProcfsOpts { get; set; } + public bool? PublishImagePorts { get; set; } + public List RLimits { get; set; } + public string RawImageName { get; set; } + public bool? ReadOnlyFilesystem { get; set; } + public bool? ReadWriteTmpfs { get; set; } + public bool? Remove { get; set; } + public LinuxResources ResourceLimits { get; set; } + public string RestartPolicy { get; set; } + public ulong? RestartTries { get; set; } + public string Rootfs { get; set; } + public string RootfsMapping { get; set; } + public bool? RootfsOverlay { get; set; } + public string RootfsPropagation { get; set; } + public string SdnotifyMode { get; set; } + public string SeccompPolicy { get; set; } + public string SeccompProfilePath { get; set; } + public Dictionary SecretEnv { get; set; } + public List Secrets { get; set; } + public List SelinuxOpts { get; set; } + public long? ShmSize { get; set; } + public long? ShmSizeSystemd { get; set; } + public StartupHealthConfig StartupHealthConfig { get; set; } + public bool? Stdin { get; set; } + public long? StopSignal { get; set; } + public ulong? StopTimeout { get; set; } + public Dictionary StorageOpts { get; set; } + public Dictionary Sysctl { get; set; } + public string Systemd { get; set; } + public bool? Terminal { get; set; } + public Dictionary ThrottleReadBpsDevice { get; set; } + public Dictionary ThrottleReadIopsDevice { get; set; } + public Dictionary ThrottleWriteBpsDevice { get; set; } + public Dictionary ThrottleWriteIopsDevice { get; set; } + public ulong? Timeout { get; set; } + public string Timezone { get; set; } + public string Umask { get; set; } + public Dictionary Unified { get; set; } + public List Unmask { get; set; } + public List Unsetenv { get; set; } + public bool? Unsetenvall { get; set; } + public bool? UseImageHosts { get; set; } + public bool? UseImageResolvConf { get; set; } + public string User { get; set; } + public Namespace Userns { get; set; } + public Namespace Utsns { get; set; } + public bool? Volatile { get; set; } + public List Volumes { get; set; } + public List VolumesFrom { get; set; } + public Dictionary WeightDevice { get; set; } + public string WorkDir { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Container/CreateContainerResponse.cs b/src/PodmanClient/Models/Container/CreateContainerResponse.cs new file mode 100644 index 0000000..6842ccf --- /dev/null +++ b/src/PodmanClient/Models/Container/CreateContainerResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Container { + public class CreateContainerResponse { + public string Id { get; set; } + + public string[] Warnings { get; set; } + } +} diff --git a/src/PodmanClient/Models/Container/DeleteContainerResponse.cs b/src/PodmanClient/Models/Container/DeleteContainerResponse.cs new file mode 100644 index 0000000..962f4ee --- /dev/null +++ b/src/PodmanClient/Models/Container/DeleteContainerResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Container { + public class DeleteContainerResponse { + public string Err { get; set; } + public string Id { get; set; } + } +} diff --git a/src/PodmanClient/Models/DriverConfig.cs b/src/PodmanClient/Models/DriverConfig.cs new file mode 100644 index 0000000..06ffb10 --- /dev/null +++ b/src/PodmanClient/Models/DriverConfig.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class DriverConfig { + public string Name { get; set; } + public Dictionary Options { get; set; } + } + +} diff --git a/src/PodmanClient/Models/ErrorResponse.cs b/src/PodmanClient/Models/ErrorResponse.cs new file mode 100644 index 0000000..9abda48 --- /dev/null +++ b/src/PodmanClient/Models/ErrorResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class ErrorResponse { + public string Cause { get; set; } + public string Message { get; set; } + public int Response { get; set; } + } +} diff --git a/src/PodmanClient/Models/Exec/CreateExecRequest.cs b/src/PodmanClient/Models/Exec/CreateExecRequest.cs new file mode 100644 index 0000000..c445061 --- /dev/null +++ b/src/PodmanClient/Models/Exec/CreateExecRequest.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Exec +{ + public class CreateExecRequest + { + public bool AttachStderr { get; set; } + public bool AttachStdin { get; set; } + public bool AttachStdout { get; set; } + public string[] Cmd { get; set; } + public string DetachKeys { get; set; } + public string[] Env { get; set; } + public bool Privileged { get; set; } + public bool Tty { get; set; } + public string User { get; set; } + public string WorkingDir { get; set; } + } +} diff --git a/src/PodmanClient/Models/Exec/CreateExecResponse.cs b/src/PodmanClient/Models/Exec/CreateExecResponse.cs new file mode 100644 index 0000000..c28c8e7 --- /dev/null +++ b/src/PodmanClient/Models/Exec/CreateExecResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Exec { + public class CreateExecResponse { + public string Id { get; set; } // The ID of the exec instance + } + +} diff --git a/src/PodmanClient/Models/Exec/InspectExecResponse.cs b/src/PodmanClient/Models/Exec/InspectExecResponse.cs new file mode 100644 index 0000000..d9eb876 --- /dev/null +++ b/src/PodmanClient/Models/Exec/InspectExecResponse.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Exec { + public class InspectExecResponse { + public bool Running { get; set; } + public int ExitCode { get; set; } + public string ProcessConfig { get; set; } // Additional fields can be added based on your needs + } +} diff --git a/src/PodmanClient/Models/Exec/StartExecRequest.cs b/src/PodmanClient/Models/Exec/StartExecRequest.cs new file mode 100644 index 0000000..0dacefe --- /dev/null +++ b/src/PodmanClient/Models/Exec/StartExecRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Exec { + public class StartExecRequest { + public bool Detach { get; set; } + public bool Tty { get; set; } + public int? Height { get; set; } // Optional, nullable if not provided + public int? Width { get; set; } // Optional, nullable if not provided + } +} diff --git a/src/PodmanClient/Models/HugepageLimit.cs b/src/PodmanClient/Models/HugepageLimit.cs new file mode 100644 index 0000000..a1f748a --- /dev/null +++ b/src/PodmanClient/Models/HugepageLimit.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class HugepageLimit { + public long Limit { get; set; } + public string PageSize { get; set; } + } +} diff --git a/src/PodmanClient/Models/IDMapping.cs b/src/PodmanClient/Models/IDMapping.cs new file mode 100644 index 0000000..25107da --- /dev/null +++ b/src/PodmanClient/Models/IDMapping.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class IDMapping { + public int ContainerId { get; set; } + public int HostId { get; set; } + public int Size { get; set; } + } + +} diff --git a/src/PodmanClient/Models/IDMappingOptions.cs b/src/PodmanClient/Models/IDMappingOptions.cs new file mode 100644 index 0000000..d640ac6 --- /dev/null +++ b/src/PodmanClient/Models/IDMappingOptions.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class IDMappingOptions { + public bool AutoUserNs { get; set; } + public AutoUserNsOptions AutoUserNsOpts { get; set; } + public List GIDMap { get; set; } + public bool HostGIDMapping { get; set; } + public bool HostUIDMapping { get; set; } + public List UIDMap { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Image/ImagePullStatusResponse.cs b/src/PodmanClient/Models/Image/ImagePullStatusResponse.cs new file mode 100644 index 0000000..7ebccb8 --- /dev/null +++ b/src/PodmanClient/Models/Image/ImagePullStatusResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Image { + public class ImagePullStatusResponse { + public string Status { get; set; } + public string Id { get; set; } + public string Progress { get; set; } + public ProgressDetail ProgressDetail { get; set; } + } +} diff --git a/src/PodmanClient/Models/Image/ImagePullStreamResponse.cs b/src/PodmanClient/Models/Image/ImagePullStreamResponse.cs new file mode 100644 index 0000000..9f4ff21 --- /dev/null +++ b/src/PodmanClient/Models/Image/ImagePullStreamResponse.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models.Image { + public class ImagePullStreamResponse { + public string Stream { get; set; } + } +} diff --git a/src/PodmanClient/Models/ImageVolume.cs b/src/PodmanClient/Models/ImageVolume.cs new file mode 100644 index 0000000..eb9d0c6 --- /dev/null +++ b/src/PodmanClient/Models/ImageVolume.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class ImageVolume { + public string Destination { get; set; } + public bool ReadWrite { get; set; } + public string Source { get; set; } + public string SubPath { get; set; } + } + +} diff --git a/src/PodmanClient/Models/IntelRdt.cs b/src/PodmanClient/Models/IntelRdt.cs new file mode 100644 index 0000000..fcb9ff0 --- /dev/null +++ b/src/PodmanClient/Models/IntelRdt.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class IntelRdt { + public string ClosId { get; set; } + public bool EnableCMT { get; set; } + public bool EnableMBM { get; set; } + public string L3CacheSchema { get; set; } + public string MemBwSchema { get; set; } + } + +} diff --git a/src/PodmanClient/Models/LinuxDevice.cs b/src/PodmanClient/Models/LinuxDevice.cs new file mode 100644 index 0000000..86e40c5 --- /dev/null +++ b/src/PodmanClient/Models/LinuxDevice.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class LinuxDevice { + public int FileMode { get; set; } + public int Gid { get; set; } + public int Major { get; set; } + public int Minor { get; set; } + public string Path { get; set; } + public string Type { get; set; } + public int Uid { get; set; } + } + +} diff --git a/src/PodmanClient/Models/LinuxDeviceCgroup.cs b/src/PodmanClient/Models/LinuxDeviceCgroup.cs new file mode 100644 index 0000000..14b44bd --- /dev/null +++ b/src/PodmanClient/Models/LinuxDeviceCgroup.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class LinuxDeviceCgroup { + public string Access { get; set; } + public bool Allow { get; set; } + public int Major { get; set; } + public int Minor { get; set; } + public string Type { get; set; } + } + +} diff --git a/src/PodmanClient/Models/LinuxIntelRdt.cs b/src/PodmanClient/Models/LinuxIntelRdt.cs new file mode 100644 index 0000000..b5652bc --- /dev/null +++ b/src/PodmanClient/Models/LinuxIntelRdt.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class LinuxIntelRdt { + public string ClosID { get; set; } + public bool EnableCMT { get; set; } + public bool EnableMBM { get; set; } + public string L3CacheSchema { get; set; } + public string MemBwSchema { get; set; } + } + +} diff --git a/src/PodmanClient/Models/LinuxPersonality.cs b/src/PodmanClient/Models/LinuxPersonality.cs new file mode 100644 index 0000000..ebf4389 --- /dev/null +++ b/src/PodmanClient/Models/LinuxPersonality.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class LinuxPersonality { + public string Domain { get; set; } + public List Flags { get; set; } + } + +} diff --git a/src/PodmanClient/Models/LinuxResources.cs b/src/PodmanClient/Models/LinuxResources.cs new file mode 100644 index 0000000..c51daa1 --- /dev/null +++ b/src/PodmanClient/Models/LinuxResources.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class LinuxResources { + public BlockIO BlockIO { get; set; } + public CPU CPU { get; set; } + public List Devices { get; set; } + public List HugepageLimits { get; set; } + public Memory Memory { get; set; } + public Network Network { get; set; } + public Pids Pids { get; set; } + public Dictionary Rdma { get; set; } + public Dictionary Unified { get; set; } + } + +} diff --git a/src/PodmanClient/Models/LogConfigLibpod.cs b/src/PodmanClient/Models/LogConfigLibpod.cs new file mode 100644 index 0000000..4ebdfbc --- /dev/null +++ b/src/PodmanClient/Models/LogConfigLibpod.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class LogConfigLibpod { + public string Driver { get; set; } + public Dictionary Options { get; set; } + public string Path { get; set; } + public long Size { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Memory.cs b/src/PodmanClient/Models/Memory.cs new file mode 100644 index 0000000..e152041 --- /dev/null +++ b/src/PodmanClient/Models/Memory.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class Memory { + public bool CheckBeforeUpdate { get; set; } + public bool DisableOOMKiller { get; set; } + public long Kernel { get; set; } + public long KernelTCP { get; set; } + public long Limit { get; set; } + public long Reservation { get; set; } + public long Swap { get; set; } + public int Swappiness { get; set; } + public bool UseHierarchy { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Mount.cs b/src/PodmanClient/Models/Mount.cs new file mode 100644 index 0000000..ce78199 --- /dev/null +++ b/src/PodmanClient/Models/Mount.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.NetworkInformation; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class Mount { + public BindOptions BindOptions { get; set; } + public string Consistency { get; set; } + public bool ReadOnly { get; set; } + public string Source { get; set; } + public string Target { get; set; } + public TmpfsOptions TmpfsOptions { get; set; } + public string Type { get; set; } + public VolumeOptions VolumeOptions { get; set; } + } + +} diff --git a/src/PodmanClient/Models/NamedVolume.cs b/src/PodmanClient/Models/NamedVolume.cs new file mode 100644 index 0000000..91835f6 --- /dev/null +++ b/src/PodmanClient/Models/NamedVolume.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class NamedVolume { + public string Dest { get; set; } + public bool IsAnonymous { get; set; } + public string Name { get; set; } + public List Options { get; set; } + public string SubPath { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Namespace.cs b/src/PodmanClient/Models/Namespace.cs new file mode 100644 index 0000000..1b038db --- /dev/null +++ b/src/PodmanClient/Models/Namespace.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class Namespace { + public string Nsmode { get; set; } + public string Value { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Network.cs b/src/PodmanClient/Models/Network.cs new file mode 100644 index 0000000..a631ff9 --- /dev/null +++ b/src/PodmanClient/Models/Network.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class Network { + public int ClassID { get; set; } + public List Priorities { get; set; } + } + +} diff --git a/src/PodmanClient/Models/NetworkPriority.cs b/src/PodmanClient/Models/NetworkPriority.cs new file mode 100644 index 0000000..9724ede --- /dev/null +++ b/src/PodmanClient/Models/NetworkPriority.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class NetworkPriority { + public string Name { get; set; } + public int Priority { get; set; } + } + +} diff --git a/src/PodmanClient/Models/NetworkSettings.cs b/src/PodmanClient/Models/NetworkSettings.cs new file mode 100644 index 0000000..b8ae788 --- /dev/null +++ b/src/PodmanClient/Models/NetworkSettings.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class NetworkSettings { + public List Aliases { get; set; } + public string InterfaceName { get; set; } + public List StaticIps { get; set; } + public string StaticMac { get; set; } + } + +} diff --git a/src/PodmanClient/Models/OverlayVolume.cs b/src/PodmanClient/Models/OverlayVolume.cs new file mode 100644 index 0000000..34f9b45 --- /dev/null +++ b/src/PodmanClient/Models/OverlayVolume.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class OverlayVolume { + public string Destination { get; set; } + public List Options { get; set; } + public string Source { get; set; } + } + +} diff --git a/src/PodmanClient/Models/POSIXRlimit.cs b/src/PodmanClient/Models/POSIXRlimit.cs new file mode 100644 index 0000000..160d5a6 --- /dev/null +++ b/src/PodmanClient/Models/POSIXRlimit.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class POSIXRlimit { + public long Hard { get; set; } + public long Soft { get; set; } + public string Type { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Pids.cs b/src/PodmanClient/Models/Pids.cs new file mode 100644 index 0000000..3b8eb3f --- /dev/null +++ b/src/PodmanClient/Models/Pids.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class Pids { + public int Limit { get; set; } + } + +} diff --git a/src/PodmanClient/Models/PortMapping.cs b/src/PodmanClient/Models/PortMapping.cs new file mode 100644 index 0000000..a59c47a --- /dev/null +++ b/src/PodmanClient/Models/PortMapping.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class PortMapping { + public int ContainerPort { get; set; } + public string HostIp { get; set; } + public int HostPort { get; set; } + public string Protocol { get; set; } + public int Range { get; set; } + } + +} diff --git a/src/PodmanClient/Models/ProgressDetail.cs b/src/PodmanClient/Models/ProgressDetail.cs new file mode 100644 index 0000000..1947611 --- /dev/null +++ b/src/PodmanClient/Models/ProgressDetail.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class ProgressDetail { + public long? Current { get; set; } + public long? Total { get; set; } + } +} diff --git a/src/PodmanClient/Models/RdmaResource.cs b/src/PodmanClient/Models/RdmaResource.cs new file mode 100644 index 0000000..832c384 --- /dev/null +++ b/src/PodmanClient/Models/RdmaResource.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class RdmaResource { + public int HcaHandles { get; set; } + public int HcaObjects { get; set; } + } + +} diff --git a/src/PodmanClient/Models/Schema2HealthConfig.cs b/src/PodmanClient/Models/Schema2HealthConfig.cs new file mode 100644 index 0000000..6fc2391 --- /dev/null +++ b/src/PodmanClient/Models/Schema2HealthConfig.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class Schema2HealthConfig { + public long Interval { get; set; } + public int Retries { get; set; } + public long StartInterval { get; set; } + public long StartPeriod { get; set; } + public List Test { get; set; } + public long Timeout { get; set; } + } + +} diff --git a/src/PodmanClient/Models/SecretProp.cs b/src/PodmanClient/Models/SecretProp.cs new file mode 100644 index 0000000..4360fa4 --- /dev/null +++ b/src/PodmanClient/Models/SecretProp.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class SecretProp { + public string Key { get; set; } + public string Secret { get; set; } + } + +} diff --git a/src/PodmanClient/Models/StartupHealthConfig.cs b/src/PodmanClient/Models/StartupHealthConfig.cs new file mode 100644 index 0000000..550d195 --- /dev/null +++ b/src/PodmanClient/Models/StartupHealthConfig.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class StartupHealthConfig { + public long Interval { get; set; } + public int Retries { get; set; } + public long StartInterval { get; set; } + public long StartPeriod { get; set; } + public int Successes { get; set; } + public List Test { get; set; } + public long Timeout { get; set; } + } + +} diff --git a/src/PodmanClient/Models/ThrottleDevice.cs b/src/PodmanClient/Models/ThrottleDevice.cs new file mode 100644 index 0000000..757119c --- /dev/null +++ b/src/PodmanClient/Models/ThrottleDevice.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class ThrottleDevice { + public int Major { get; set; } + public int Minor { get; set; } + public long Rate { get; set; } + } + +} diff --git a/src/PodmanClient/Models/TmpfsOptions.cs b/src/PodmanClient/Models/TmpfsOptions.cs new file mode 100644 index 0000000..8b095d0 --- /dev/null +++ b/src/PodmanClient/Models/TmpfsOptions.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class TmpfsOptions { + public int Mode { get; set; } + public List Options { get; set; } + public long SizeBytes { get; set; } + } + +} diff --git a/src/PodmanClient/Models/VolumeOptions.cs b/src/PodmanClient/Models/VolumeOptions.cs new file mode 100644 index 0000000..5683d1a --- /dev/null +++ b/src/PodmanClient/Models/VolumeOptions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class VolumeOptions { + public DriverConfig DriverConfig { get; set; } + public Dictionary Labels { get; set; } + public bool NoCopy { get; set; } + public string Subpath { get; set; } + } + +} diff --git a/src/PodmanClient/Models/WeightDevice.cs b/src/PodmanClient/Models/WeightDevice.cs new file mode 100644 index 0000000..3997b37 --- /dev/null +++ b/src/PodmanClient/Models/WeightDevice.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MaksIT.PodmanClientDotNet.Models { + public class WeightDevice { + public int LeafWeight { get; set; } + public int Major { get; set; } + public int Minor { get; set; } + public int Weight { get; set; } + } + +} diff --git a/src/PodmanClient/PodmanClientDotNet.csproj b/src/PodmanClient/PodmanClientDotNet.csproj new file mode 100644 index 0000000..3502635 --- /dev/null +++ b/src/PodmanClient/PodmanClientDotNet.csproj @@ -0,0 +1,10 @@ + + + + net8.0 + enable + enable + MaksIT.$(MSBuildProjectName.Replace(" ", "_")) + + + diff --git a/src/PodmanClient/PodmanConnector.cs b/src/PodmanClient/PodmanConnector.cs new file mode 100644 index 0000000..ed4e554 --- /dev/null +++ b/src/PodmanClient/PodmanConnector.cs @@ -0,0 +1,19 @@ +namespace MaksIT.PodmanClientDotNet { + public partial class PodmanClient { + private readonly HttpClient _httpClient; + + public PodmanClient(string baseAddress, int timeOut) { + _httpClient = new HttpClient(); + _httpClient.BaseAddress = new Uri(baseAddress); + _httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); + _httpClient.Timeout = TimeSpan.FromMinutes(timeOut); + } + + public PodmanClient(HttpClient httpClient) { + _httpClient = httpClient; + _httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); + _httpClient.Timeout = TimeSpan.FromMinutes(60); + } + + } +} diff --git a/src/PodmanClient/PodmanConnectorContainer.cs b/src/PodmanClient/PodmanConnectorContainer.cs new file mode 100644 index 0000000..80e7890 --- /dev/null +++ b/src/PodmanClient/PodmanConnectorContainer.cs @@ -0,0 +1,503 @@ +using System.Text; +using System.Text.Json; + +using MaksIT.PodmanClientDotNet.Extensions; + +using MaksIT.PodmanClientDotNet.Models; +using MaksIT.PodmanClientDotNet.Models.Container; + +namespace MaksIT.PodmanClientDotNet { + public partial class PodmanClient { + public async Task CreateContainerAsync( + string name, + string image, + List command = null, + Dictionary env = null, + bool? remove = null, + bool? stdin = null, + bool? terminal = null, + List mounts = null, + bool? privileged = null, + string hostname = null, + Namespace netns = null, + List portMappings = null, + string restartPolicy = null, + ulong? stopTimeout = null, + List capAdd = null, + List capDrop = null, + List dnsServers = null, + List dnsSearch = null, + List dnsOptions = null, + bool? publishImagePorts = null, + List cniNetworks = null, + Dictionary labels = null, + bool? readOnlyFilesystem = null, + List rLimits = null, + List devices = null, + string ociRuntime = null, + string pod = null, + bool? noNewPrivileges = null, + string cgroupsMode = null, + Dictionary storageOpts = null, + bool? unsetenvall = null, + Dictionary secretEnv = null, + string timezone = null, + Dictionary sysctl = null, + string seccompProfilePath = null, + string seccompPolicy = null, + Dictionary annotations = null, + string apparmorProfile = null, + string baseHostsFile = null, + string cgroupParent = null, + Namespace cgroupns = null, + List chrootDirectories = null, + string conmonPidFile = null, + List containerCreateCommand = null, + bool? createWorkingDir = null, + List dependencyContainers = null, + List deviceCgroupRule = null, + List devicesFrom = null, + List entrypoint = null, + bool? envHost = null, + List envMerge = null, + Dictionary expose = null, + string groupEntry = null, + List groups = null, + long? healthCheckOnFailureAction = null, + Schema2HealthConfig healthConfig = null, + List hostDeviceList = null, + List hostAdd = null, + List hostUsers = null, + bool? envHTTPProxy = null, + IDMappingOptions idMappings = null, + string imageArch = null, + string imageOS = null, + string imageVariant = null, + string imageVolumeMode = null, + List imageVolumes = null, + bool? init = null, + string initContainerType = null, + string initPath = null, + LinuxIntelRdt intelRdt = null, + Namespace ipcns = null, + bool? labelNested = null, + LogConfigLibpod logConfiguration = null, + bool? managePassword = null, + List mask = null, + Dictionary networkOptions = null, + Dictionary networks = null, + long? oomScoreAdj = null, + List overlayVolumes = null, + string passwdEntry = null, + LinuxPersonality personality = null, + Namespace pidns = null, + string rawImageName = null, + bool? readWriteTmpfs = null, + LinuxResources resourceLimits = null, + ulong? restartTries = null, + string rootfs = null, + string rootfsMapping = null, + bool? rootfsOverlay = null, + string rootfsPropagation = null, + string sdnotifyMode = null, + List secrets = null, + List selinuxOpts = null, + long? shmSize = null, + long? shmSizeSystemd = null, + StartupHealthConfig startupHealthConfig = null, + long? stopSignal = null, + string systemd = null, + Dictionary throttleReadBpsDevice = null, + Dictionary throttleReadIopsDevice = null, + Dictionary throttleWriteBpsDevice = null, + Dictionary throttleWriteIopsDevice = null, + ulong? timeout = null, + string umask = null, + Dictionary unified = null, + List unmask = null, + bool? useImageHosts = null, + bool? useImageResolvConf = null, + string user = null, + Namespace userns = null, + Namespace utsns = null, + bool? volatileFlag = null, + List volumes = null, + List volumesFrom = null, + Dictionary weightDevice = null, + string workDir = null + ) { + var createContainerParameters = new CreateContainerRequest { + Name = name, + Image = image, + Command = command, + Env = env, + WorkDir = workDir, + Remove = remove, + Stdin = stdin, + Terminal = terminal, + Mounts = mounts, + Privileged = privileged, + Hostname = hostname, + Netns = netns, + Portmappings = portMappings, + RestartPolicy = restartPolicy, + StopTimeout = stopTimeout, + CapAdd = capAdd, + CapDrop = capDrop, + DNSServer = dnsServers, + DNSSearch = dnsSearch, + DNSOption = dnsOptions, + PublishImagePorts = publishImagePorts, + CNINetworks = cniNetworks, + Labels = labels, + ReadOnlyFilesystem = readOnlyFilesystem, + RLimits = rLimits, + Devices = devices, + OciRuntime = ociRuntime, + Pod = pod, + NoNewPrivileges = noNewPrivileges, + CgroupsMode = cgroupsMode, + StorageOpts = storageOpts, + Unmask = unmask, + Unsetenvall = unsetenvall, + SecretEnv = secretEnv, + Timezone = timezone, + Sysctl = sysctl, + SeccompProfilePath = seccompProfilePath, + SeccompPolicy = seccompPolicy, + Annotations = annotations, + ApparmorProfile = apparmorProfile, + BaseHostsFile = baseHostsFile, + CgroupParent = cgroupParent, + Cgroupns = cgroupns, + ChrootDirectories = chrootDirectories, + ConmonPidFile = conmonPidFile, + ContainerCreateCommand = containerCreateCommand, + CreateWorkingDir = createWorkingDir, + DependencyContainers = dependencyContainers, + DeviceCgroupRule = deviceCgroupRule, + DevicesFrom = devicesFrom, + Entrypoint = entrypoint, + EnvHost = envHost, + EnvMerge = envMerge, + Expose = expose, + GroupEntry = groupEntry, + Groups = groups, + HealthCheckOnFailureAction = healthCheckOnFailureAction, + HealthConfig = healthConfig, + HostDeviceList = hostDeviceList, + HostAdd = hostAdd, + HostUsers = hostUsers, + EnvHTTPProxy = envHTTPProxy, + IDMappings = idMappings, + ImageArch = imageArch, + ImageOS = imageOS, + ImageVariant = imageVariant, + ImageVolumeMode = imageVolumeMode, + ImageVolumes = imageVolumes, + Init = init, + InitContainerType = initContainerType, + InitPath = initPath, + IntelRdt = intelRdt, + Ipcns = ipcns, + LabelNested = labelNested, + LogConfiguration = logConfiguration, + ManagePassword = managePassword, + Mask = mask, + NetworkOptions = networkOptions, + Networks = networks, + OomScoreAdj = oomScoreAdj, + OverlayVolumes = overlayVolumes, + PasswdEntry = passwdEntry, + Personality = personality, + Pidns = pidns, + RawImageName = rawImageName, + ReadWriteTmpfs = readWriteTmpfs, + ResourceLimits = resourceLimits, + RestartTries = restartTries, + Rootfs = rootfs, + RootfsMapping = rootfsMapping, + RootfsOverlay = rootfsOverlay, + RootfsPropagation = rootfsPropagation, + SdnotifyMode = sdnotifyMode, + Secrets = secrets, + SelinuxOpts = selinuxOpts, + ShmSize = shmSize, + ShmSizeSystemd = shmSizeSystemd, + StartupHealthConfig = startupHealthConfig, + StopSignal = stopSignal, + Systemd = systemd, + ThrottleReadBpsDevice = throttleReadBpsDevice, + ThrottleReadIopsDevice = throttleReadIopsDevice, + ThrottleWriteBpsDevice = throttleWriteBpsDevice, + ThrottleWriteIopsDevice = throttleWriteIopsDevice, + Timeout = timeout, + Umask = umask, + Unified = unified, + UseImageHosts = useImageHosts, + UseImageResolvConf = useImageResolvConf, + User = user, + Userns = userns, + Utsns = utsns, + Volatile = volatileFlag, + Volumes = volumes, + VolumesFrom = volumesFrom, + WeightDevice = weightDevice + }; + + var jsonContent = new StringContent(JsonSerializer.Serialize(createContainerParameters), Encoding.UTF8, "application/json"); + var response = await _httpClient.PostAsync("/v1.41/libpod/containers/create", jsonContent); + + if (response.IsSuccessStatusCode) { + var jsonResponse = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize(jsonResponse); + } + else { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = JsonSerializer.Deserialize(errorContent); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.BadRequest: + Console.WriteLine($"Bad parameter in request: {errorDetails?.Message}"); + break; + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such container: {errorDetails?.Message}"); + break; + case System.Net.HttpStatusCode.Conflict: + Console.WriteLine($"Conflict error in operation: {errorDetails?.Message}"); + break; + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorDetails?.Message}"); + break; + default: + Console.WriteLine($"Error creating container: {errorDetails?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); + + return null; + } + } + + + + public async Task StartContainerAsync(string containerId, string detachKeys = "ctrl-p,ctrl-q") { + var response = await _httpClient.PostAsync( + $"/v1.41/libpod/containers/{containerId}/start?detachKeys={Uri.EscapeDataString(detachKeys)}", null); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.NoContent: + Console.WriteLine("Container started successfully."); + break; + + case System.Net.HttpStatusCode.NotModified: + Console.WriteLine("Container was already started."); + break; + + case System.Net.HttpStatusCode.NotFound: + var errorContent404 = await response.Content.ReadAsStringAsync(); + var errorDetails404 = errorContent404.ToObject(); + Console.WriteLine($"Container not found: {errorDetails404?.Message}"); + break; + + case System.Net.HttpStatusCode.InternalServerError: + var errorContent500 = await response.Content.ReadAsStringAsync(); + var errorDetails500 = errorContent500.ToObject(); + Console.WriteLine($"Internal server error: {errorDetails500?.Message}"); + break; + + default: + if ((int)response.StatusCode >= 400) { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = errorContent.ToObject(); + Console.WriteLine($"Error starting container: {errorDetails?.Message}"); + } + break; + } + + response.EnsureSuccessStatusCode(); + } + + public async Task StopContainerAsync(string containerId, int timeout = 10, bool ignoreAlreadyStopped = false) { + var queryParams = $"?timeout={timeout}&Ignore={ignoreAlreadyStopped.ToString().ToLower()}"; + var response = await _httpClient.PostAsync($"/v1.41/libpod/containers/{containerId}/stop{queryParams}", null); + + if (response.IsSuccessStatusCode) { + if (response.StatusCode == System.Net.HttpStatusCode.NoContent) { + Console.WriteLine("Container stopped successfully."); + } + else if (response.StatusCode == System.Net.HttpStatusCode.NotModified) { + Console.WriteLine("Container was already stopped."); + } + } + else { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = JsonSerializer.Deserialize(errorContent); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such container: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorDetails?.Message}"); + break; + + default: + Console.WriteLine($"Error stopping container: {errorDetails?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); + } + } + + public async Task ForceDeleteContainerAsync(string containerId, bool deleteVolumes = false, int timeout = 10) { + var queryParams = $"?force=true&v={deleteVolumes.ToString().ToLower()}&timeout={timeout}"; + var response = await _httpClient.DeleteAsync($"/v1.41/libpod/containers/{containerId}{queryParams}"); + + if (response.IsSuccessStatusCode) { + if (response.StatusCode == System.Net.HttpStatusCode.NoContent) { + Console.WriteLine("Container force deleted successfully."); + } + else if (response.StatusCode == System.Net.HttpStatusCode.OK) { + var responseContent = await response.Content.ReadAsStringAsync(); + var deleteResponses = JsonSerializer.Deserialize(responseContent); + + foreach (var deleteResponse in deleteResponses) { + if (string.IsNullOrEmpty(deleteResponse.Err)) { + Console.WriteLine($"Container {deleteResponse.Id} deleted successfully."); + } + else { + Console.WriteLine($"Error deleting container {deleteResponse.Id}: {deleteResponse.Err}"); + } + } + } + } + else { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = JsonSerializer.Deserialize(errorContent); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.BadRequest: + Console.WriteLine($"Bad parameter in request: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such container: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.Conflict: + Console.WriteLine($"Conflict error: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorDetails?.Message}"); + break; + + default: + Console.WriteLine($"Error deleting container: {errorDetails?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); + } + } + + public async Task DeleteContainerAsync(string containerId, bool depend = false, bool ignore = false, int timeout = 10) { + var queryParams = $"?depend={depend.ToString().ToLower()}&ignore={ignore.ToString().ToLower()}&timeout={timeout}"; + var response = await _httpClient.DeleteAsync($"/v1.41/libpod/containers/{containerId}{queryParams}"); + + if (response.IsSuccessStatusCode) { + if (response.StatusCode == System.Net.HttpStatusCode.NoContent) { + Console.WriteLine("Container deleted successfully."); + } + else if (response.StatusCode == System.Net.HttpStatusCode.OK) { + var responseContent = await response.Content.ReadAsStringAsync(); + var deleteResponses = JsonSerializer.Deserialize(responseContent); + + foreach (var deleteResponse in deleteResponses) { + if (string.IsNullOrEmpty(deleteResponse.Err)) { + Console.WriteLine($"Container {deleteResponse.Id} deleted successfully."); + } + else { + Console.WriteLine($"Error deleting container {deleteResponse.Id}: {deleteResponse.Err}"); + } + } + } + } + else { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = JsonSerializer.Deserialize(errorContent); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.BadRequest: + Console.WriteLine($"Bad parameter in request: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such container: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.Conflict: + Console.WriteLine($"Conflict error: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorDetails?.Message}"); + break; + + default: + Console.WriteLine($"Error deleting container: {errorDetails?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); // Throws an exception if the response indicates an error + } + + } + + + public async Task ExtractArchiveToContainerAsync(string containerId, Stream tarStream, string path, bool pause = true) { + var content = new StreamContent(tarStream); + content.Headers.Add("Content-Type", "application/x-tar"); + + var queryParams = $"?path={Uri.EscapeDataString(path)}&pause={pause.ToString().ToLower()}"; + var response = await _httpClient.PutAsync($"/v1.41/libpod/containers/{containerId}/archive{queryParams}", content); + + if (response.IsSuccessStatusCode) { + Console.WriteLine("Files copied successfully to the container."); + } + else { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = JsonSerializer.Deserialize(errorContent); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.BadRequest: + Console.WriteLine($"Bad parameter in request: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.Forbidden: + Console.WriteLine($"The container root filesystem is read-only: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such container: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorDetails?.Message}"); + break; + + default: + Console.WriteLine($"Error copying files: {errorDetails?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); + } + } + + } +} diff --git a/src/PodmanClient/PodmanConnectorExec.cs b/src/PodmanClient/PodmanConnectorExec.cs new file mode 100644 index 0000000..caa82ee --- /dev/null +++ b/src/PodmanClient/PodmanConnectorExec.cs @@ -0,0 +1,170 @@ +using System.Text; +using System.Text.Json; + +using MaksIT.PodmanClientDotNet.Extensions; +using MaksIT.PodmanClientDotNet.Models.Exec; +using MaksIT.PodmanClientDotNet.Models; + +namespace MaksIT.PodmanClientDotNet { + public partial class PodmanClient { + + public async Task CreateExecAsync( + string containerName, + string[] cmd, + bool attachStderr = true, + bool attachStdin = false, + bool attachStdout = true, + string detachKeys = null, + string[] env = null, + bool privileged = false, + bool tty = false, + string user = null, + string workingDir = null + ) { + // Construct the request object + var execRequest = new CreateExecRequest { + AttachStderr = attachStderr, + AttachStdin = attachStdin, + AttachStdout = attachStdout, + Cmd = cmd, + DetachKeys = detachKeys, + Env = env, + Privileged = privileged, + Tty = tty, + User = user, + WorkingDir = workingDir + }; + + // Serialize the request object to JSON + var jsonRequest = execRequest.ToJson(); + var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); + + // Create the request URL + var requestUrl = $"/containers/{Uri.EscapeDataString(containerName)}/exec"; + + // Send the POST request + var response = await _httpClient.PostAsync(requestUrl, content); + + if (response.IsSuccessStatusCode) { + var jsonResponse = await response.Content.ReadAsStringAsync(); + return jsonResponse.ToObject(); + } + else { + var jsonResponse = await response.Content.ReadAsStringAsync(); + var errorResponse = JsonSerializer.Deserialize(jsonResponse); + + // Handle different response codes + switch (response.StatusCode) { + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such container: {errorResponse?.Message}"); + break; + case System.Net.HttpStatusCode.Conflict: + Console.WriteLine($"Conflict error: {errorResponse?.Message}"); + break; + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorResponse?.Message}"); + break; + default: + Console.WriteLine($"Error creating exec instance: {errorResponse?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); + return null; + } + } + + public async Task StartExecAsync( + string execId, + bool detach = false, + bool tty = false, + int? height = null, + int? width = null, + string outputFilePath = "exec_output.log" + ) { + + outputFilePath = Path.Combine(Path.GetTempPath(), outputFilePath); + + // Construct the request object + var startExecRequest = new StartExecRequest { + Detach = detach, + Tty = tty, + Height = height, + Width = width + }; + + // Serialize the request object to JSON + var jsonRequest = JsonSerializer.Serialize(startExecRequest); + var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); + + // Create the request URL + var requestUrl = $"/exec/{Uri.EscapeDataString(execId)}/start"; + + // Send the POST request + var response = await _httpClient.PostAsync(requestUrl, content); + + if (response.IsSuccessStatusCode) { + // Write the response stream directly to a file + using (var responseStream = await response.Content.ReadAsStreamAsync()) + using (var fileStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write)) { + await responseStream.CopyToAsync(fileStream); + } + var test = File.ReadAllText(outputFilePath); + Console.WriteLine($"Exec instance started and output written to {outputFilePath}"); + } + else { + var jsonResponse = await response.Content.ReadAsStringAsync(); + var errorResponse = JsonSerializer.Deserialize(jsonResponse); + + // Handle different response codes + switch (response.StatusCode) { + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such exec instance: {errorResponse?.Message}"); + break; + case System.Net.HttpStatusCode.Conflict: + Console.WriteLine($"Conflict error: {errorResponse?.Message}"); + break; + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorResponse?.Message}"); + break; + default: + Console.WriteLine($"Error starting exec instance: {errorResponse?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); // Throws an exception if the response indicates an error + } + } + + public async Task InspectExecAsync(string execId) { + var requestUrl = $"/exec/{Uri.EscapeDataString(execId)}/json"; + var response = await _httpClient.GetAsync(requestUrl); + + if (response.IsSuccessStatusCode) { + var jsonResponse = await response.Content.ReadAsStringAsync(); + return jsonResponse.ToObject(); + } + else { + var jsonResponse = await response.Content.ReadAsStringAsync(); + var errorResponse = JsonSerializer.Deserialize(jsonResponse); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such exec instance: {errorResponse?.Message}"); + return null; + + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorResponse?.Message}"); + break; + + default: + Console.WriteLine($"Error inspecting exec instance: {errorResponse?.Message}"); + break; + } + + return null; + } + } + + } +} diff --git a/src/PodmanClient/PodmanConnectorImage.cs b/src/PodmanClient/PodmanConnectorImage.cs new file mode 100644 index 0000000..294b574 --- /dev/null +++ b/src/PodmanClient/PodmanConnectorImage.cs @@ -0,0 +1,107 @@ +using System.Text.Json; + +using MaksIT.PodmanClientDotNet.Models.Image; +using MaksIT.PodmanClientDotNet.Models; + +namespace MaksIT.PodmanClientDotNet { + public partial class PodmanClient { + + public async Task> PullImageAsync(string reference, bool tlsVerify = true, bool quiet = false, string policy = "always", string arch = null, string os = null, string variant = null, bool allTags = false, string authHeader = null) { + var query = $"reference={Uri.EscapeDataString(reference)}&tlsVerify={tlsVerify}&quiet={quiet}&policy={Uri.EscapeDataString(policy)}"; + if (!string.IsNullOrEmpty(arch)) query += $"&Arch={Uri.EscapeDataString(arch)}"; + if (!string.IsNullOrEmpty(os)) query += $"&OS={Uri.EscapeDataString(os)}"; + if (!string.IsNullOrEmpty(variant)) query += $"&Variant={Uri.EscapeDataString(variant)}"; + if (allTags) query += "&allTags=true"; + + if (!string.IsNullOrEmpty(authHeader)) { + _httpClient.DefaultRequestHeaders.Add("X-Registry-Auth", authHeader); + } + + var response = await _httpClient.PostAsync($"/v1.41/libpod/images/pull?{query}", null); + var imagePullResponses = new List(); + + if (response.IsSuccessStatusCode) { + using var responseStream = await response.Content.ReadAsStreamAsync(); + using var reader = new StreamReader(responseStream); + string line; + + while ((line = await reader.ReadLineAsync()) != null) { + if (line.Contains("\"status\"")) { + // The line contains status information + var statusResponse = JsonSerializer.Deserialize(line); + Console.WriteLine($"Status: {statusResponse.Status}"); + } + else if (line.Contains("\"id\"") || line.Contains("\"images\"")) { + // The line contains image ID information + var imageResponse = JsonSerializer.Deserialize(line); + if (imageResponse != null) { + imagePullResponses.Add(imageResponse); + } + } + } + + return imagePullResponses; + } + else { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = JsonSerializer.Deserialize(errorContent); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.BadRequest: + Console.WriteLine($"Bad request: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorDetails?.Message}"); + break; + + default: + Console.WriteLine($"Error pulling image: {errorDetails?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); + return null; + } + } + + + public async Task TagImageAsync(string image, string repo, string tag) { + var response = await _httpClient.PostAsync($"/v1.41/libpod/images/{image}/tag?repo={Uri.EscapeDataString(repo)}&tag={Uri.EscapeDataString(tag)}", null); + + if (response.IsSuccessStatusCode) { + if (response.StatusCode == System.Net.HttpStatusCode.Created) { + Console.WriteLine("Image tagged successfully."); + } + } + else { + var errorContent = await response.Content.ReadAsStringAsync(); + var errorDetails = JsonSerializer.Deserialize(errorContent); + + switch (response.StatusCode) { + case System.Net.HttpStatusCode.BadRequest: + Console.WriteLine($"Bad parameter in request: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.NotFound: + Console.WriteLine($"No such image: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.Conflict: + Console.WriteLine($"Conflict error in operation: {errorDetails?.Message}"); + break; + + case System.Net.HttpStatusCode.InternalServerError: + Console.WriteLine($"Internal server error: {errorDetails?.Message}"); + break; + + default: + Console.WriteLine($"Error tagging image: {errorDetails?.Message}"); + break; + } + + response.EnsureSuccessStatusCode(); + } + } + } +} diff --git a/src/PodmanClientDotNet.sln b/src/PodmanClientDotNet.sln new file mode 100644 index 0000000..fc4a0ef --- /dev/null +++ b/src/PodmanClientDotNet.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34902.65 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PodmanClientDotNet", "PodmanClient\PodmanClientDotNet.csproj", "{0833C90F-6BF3-40E4-A035-B6D6C81DB9D7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0833C90F-6BF3-40E4-A035-B6D6C81DB9D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0833C90F-6BF3-40E4-A035-B6D6C81DB9D7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0833C90F-6BF3-40E4-A035-B6D6C81DB9D7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0833C90F-6BF3-40E4-A035-B6D6C81DB9D7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CFC10A81-CC42-4585-B549-1C2214AC18DA} + EndGlobalSection +EndGlobal