Skip to content

Add Podman container support for Attach to Process#1582

Open
WardenGnaw wants to merge 1 commit into
feature/podmanfrom
dev/waan/podman-pr2
Open

Add Podman container support for Attach to Process#1582
WardenGnaw wants to merge 1 commit into
feature/podmanfrom
dev/waan/podman-pr2

Conversation

@WardenGnaw

Copy link
Copy Markdown
Member

Adds Podman as a option in the Attach to Process dialog, enabling developers to discover and debug processes inside Podman containers.

TODO:

  • The Podman port supplier also needs to be registered in vsdbg's VsIntegration.pkgdef for .NET debugging.

Adds Podman as a container runtime option in the Attach to Process dialog,
enabling developers to discover and debug processes inside Podman containers.

- New PodmanConnection, PodmanContainerInstance, PodmanDiscoveryStrategy,
  PodmanExecutionManager, PodmanHelper, PodmanPortPicker, PodmanPortSupplier,
  and PodmanTransportSettings classes
- Renamed DockerContainerInstance to ContainerInstance (shared by both runtimes)
- Renamed DockerHostPrefixRegex/DockerHostPrefix to HostPrefixRegex/HostPrefix
- Registered Podman port supplier and CLSID in pkgdef files
- Added ContainerRuntimeType.Podman enum value
- Added Podman case in ContainerPickerViewModel and ConnectionManager

NOTE: The Podman port supplier also needs to be registered in vsdbg's
VsIntegration.pkgdef for full VS integration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds Podman as an additional container runtime for the “Attach to Process” container picker/port supplier flow in SSHDebugPS, enabling discovery and debugging of processes inside Podman containers (local and remote/SSH).

Changes:

  • Introduces a Podman port supplier/port picker/connection stack and registers it via .pkgdef.
  • Adds a Podman container discovery strategy and UI resources for Podman-specific labels/tooltips.
  • Refactors container discovery/types to use a runtime-agnostic ContainerInstance rather than Docker-specific types.
Show a summary per file
File Description
src/SSHDebugPS/UI/ViewModels/ContainerViewModel.cs Adjusts container VM to bind to the generalized ContainerInstance type.
src/SSHDebugPS/UI/ViewModels/ContainerPickerViewModel.cs Adds Podman discovery strategy selection and uses generalized container list types.
src/SSHDebugPS/UI/UIResources.resx Adds Podman UI strings (labels/tooltips/automation names).
src/SSHDebugPS/UI/UIResources.Designer.cs Generated accessors for new Podman UI strings.
src/SSHDebugPS/UI/ContainerInstance.cs Simplifies to only the IContainerInstance interface (base class moved/reshaped).
src/SSHDebugPS/StringResources.resx Adds Podman port supplier strings and Podman-specific error strings.
src/SSHDebugPS/StringResources.Designer.cs Generated accessors for new Podman string resources.
src/SSHDebugPS/Podman/PodmanTransportSettings.cs Adds Podman transport settings for exec/cp/commands.
src/SSHDebugPS/Podman/PodmanPortSupplier.cs Implements Podman AD7 port supplier.
src/SSHDebugPS/Podman/PodmanPortPicker.cs Implements Podman port picker (DockerPortPickerBase-derived).
src/SSHDebugPS/Podman/PodmanPort.cs Implements Podman AD7 port and connection acquisition.
src/SSHDebugPS/Podman/PodmanJsonConverter.cs Adds converter for Podman ps JSON fields with variant shapes.
src/SSHDebugPS/Podman/PodmanHelper.cs Implements Podman container enumeration (local/remote) and running checks.
src/SSHDebugPS/Podman/PodmanExecutionManager.cs Reuses Docker execution manager pipeline for Podman exec settings.
src/SSHDebugPS/Podman/PodmanDiscoveryStrategy.cs Wires Podman container discovery into the shared picker interface.
src/SSHDebugPS/Podman/PodmanContainerInstance.cs Defines podman ps JSON model and parsing for Podman containers.
src/SSHDebugPS/Podman/PodmanConnection.cs Implements container connection (exec/copy/home dir) for Podman targets.
src/SSHDebugPS/Microsoft.SSHDebugPS.pkgdef Registers Podman port supplier and picker COM CLSIDs + AD7 metrics.
src/SSHDebugPS/IContainerDiscoveryStrategy.cs Generalizes discovery interface to return ContainerInstance.
src/SSHDebugPS/Docker/DockerHelper.cs Generalizes Docker helper APIs to return ContainerInstance.
src/SSHDebugPS/Docker/DockerDiscoveryStrategy.cs Updates Docker strategy to use generalized container types.
src/SSHDebugPS/Docker/DockerConnection.cs Renames host prefix constants to runtime-agnostic names.
src/SSHDebugPS/Docker/ContainerInstance.cs Renames/generalizes Docker container instance to ContainerInstance.
src/SSHDebugPS/ContainerRuntimeType.cs Adds Podman runtime type.
src/SSHDebugPS/ConnectionManager.cs Adds GetPodmanConnection and hooks it into connection flow.
src/MIDebugEngine/Microsoft.MIDebugEngine.pkgdef Adds Podman port supplier GUID to MI engine port supplier list.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Files not reviewed (2)
  • src/SSHDebugPS/StringResources.Designer.cs: Generated file
  • src/SSHDebugPS/UI/UIResources.Designer.cs: Generated file
Comments suppressed due to low confidence (1)

src/SSHDebugPS/Docker/DockerHelper.cs:308

  • GetRemoteDockerContainers adds non-JSON output lines to outputLines (treating them as error text) and then still parses all collected lines as JSON, incrementing totalContainers for error lines. This can yield spurious parse failures and incorrect counts when docker ps outputs warnings/errors.
                foreach (var item in outputLines)
                {
                    if (ContainerInstance.TryCreate(item, out ContainerInstance containerInstance))
                    {
                        containers.Add(containerInstance);
                    }
                    totalContainers++;
                }
  • Files reviewed: 24/26 changed files
  • Comments generated: 5

Comment on lines +142 to +149
foreach (var item in outputLines)
{
if (PodmanContainerInstance.TryCreate(item, out PodmanContainerInstance containerInstance))
{
containers.Add(containerInstance);
}
totalContainers++;
}
Comment on lines +148 to +150
<data name="Error_PodmanPSParseFailed" xml:space="preserve">
<value>Failed to parse output of '{0}'</value>
</data>
Comment on lines +249 to +251
<data name="Podman_HostnameTip" xml:space="preserve">
<value>Specify a URL for connecting to a different Podman host. </value>
</data>
Comment on lines 133 to 137
public class DockerContainerViewModel
: ContainerViewModel<DockerContainerInstance>
: ContainerViewModel<ContainerInstance>
{
public DockerContainerViewModel(DockerContainerInstance instance)
public DockerContainerViewModel(ContainerInstance instance)
: base(instance)
Comment on lines +28 to +34
HostTelemetry.SendEvent(TelemetryHelper.Event_DockerPSParseFailure, new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>(TelemetryHelper.Property_ExceptionName, e.GetType().Name)
});

string error = e.ToString();
VsOutputWindowWrapper.WriteLine(StringResources.Error_PodmanPSParseFailed.FormatCurrentCultureWithArgs(json, error), StringResources.Podman_PSName);
Debug.Fail(error);
@gregg-miskelly

Copy link
Copy Markdown
Member

"1"="{267B1341-AC92-44DC-94DF-2EE4205DD17E}"

Did you want to register LLDB also?


Refers to: src/MIDebugEngine/Microsoft.MIDebugEngine.pkgdef:87 in 18945f6. [](commit_id = 18945f6, deletion_comment = False)

@@ -9,6 +9,7 @@ namespace Microsoft.SSHDebugPS
public enum ContainerRuntimeType
{
Unknown,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unknown

Can we remove Unknown or is it used?

public bool Equals(IContainerInstance instance)
{
if (instance is DockerContainerInstance other)
if (!ReferenceEquals(null, instance) && instance is ContainerInstance container)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

!ReferenceEquals(null, instance) && i

nit: this is redundant with the is check

if (instance is ContainerInstance other)
{
// the id can be a partial on a container
return String.Equals(Id, other.Id, StringComparison.Ordinal) ||

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

return

Since this type isn't sealed, should we also verify the types are equal?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like we could also make this method non-virtual if we did that.

Feels like we should either add the type check, or just make this method abstract and move this check into all the implementations.


namespace Microsoft.SSHDebugPS.Podman
{
internal class PodmanConnection : PipeConnection

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

class

nit: sealed where we can

remoteConnection = null;
settings = null;

string containerName = string.Empty;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

string

nit: Should we just call the Docker one and then convert the DockerTransportSettings to the podman version? Or are there side effects in the constructor?

@gregg-miskelly gregg-miskelly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Otherwise LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants