Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add container attach/detach support - #259

Closed
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach
Closed

Add container attach/detach support#259
jacques-n wants to merge 1 commit into
apple:mainfrom
jacques-n:attach

Conversation

@jacques-n

@jacques-njacques-n commented Jun 26, 2025

Copy link
Copy Markdown

Closes#378.

Add container attach/detach support

This change introduces a new container attach command that allows users to attach
to running containers with terminal support.

Key changes:

  • Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
  • Update stdio to use a ring buffer so attach can get recent history.
  • Enable legacy (client driven stdio) and server stdio coexistence.

CLI Changes

  • Added container attach <id> subcommand for attaching to an existing session.
  • Added --legacy-stdio run flag to let newer clients talk to older servers.
  • Added --detach-keys option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)

Testing

  • Added integration tests for attach functionality
  • Added session management tests
  • Added fallback/legacy mode tests

Build changes

  • Added a couple of additional makefile flags to make it easier to target tests: INTEGRATION_TEST_FILTER, INTEGRATION_TEST_SKIP, TEST_FILTER
  • Removed the hand written TestCLI filter list and used a single filter with --no-parallel

@jacques-n
jacques-n marked this pull request as draft June 26, 2025 11:54
@jacques-n
jacques-n marked this pull request as ready for review June 28, 2025 01:27
@jacques-n

jacques-n commented Jul 7, 2025

Copy link
Copy Markdown
Author

Seeing some failures here. Moving back to draft until resolved. Will also rebase.

@jacques-n
jacques-n marked this pull request as draft July 7, 2025 23:52
This change introduces a new `container attach` command that allows users to attach
to running containers with terminal support.
- Move stdio management for interactive run from client to server so that sessions can exist beyond CLI lifetime.
- Update stdio to use a ring buffer so attach can get recent history.
- Enable legacy (client driven stdio) and server stdio coexistence.
- Added `container attach <id>` subcommand for attaching to an existing session.
- Added `--legacy-stdio` run flag to let newer clients talk to older servers.
- Added `--detach-keys` option to run and attach to set detachment keys (defaulted to ctrl-p,ctrl-q)
- Added integration tests for attach functionality
- Added session management tests
- Added fallback/legacy mode tests
@jacques-n

Copy link
Copy Markdown
Author

Simplified some things and rebased. Added more integration tests and confirmed passing integration and unit tests.

@jacques-n
jacques-n marked this pull request as ready for review July 10, 2025 04:01
@dcantahdcantah self-assigned this Jul 11, 2025
@dcantah

dcantah commented Jul 22, 2025

Copy link
Copy Markdown
Contributor

We haven't forgotten you 😄. Couple questions before I get started. What was the rationale behind needing to support sessions that exist past the lifetime of some attached client? Is that the entire reason behind swapping the direction that IO is established? The other thing I'm not sure of if we'd want to support as well is the ringbuffer of output before attaching. I haven't dug too far into it, but while the asking for the history is optional, it looks like if we ask for a pty we always fill the buffer? To me this feature is somewhat awkward as (and this is likely just me being used to other tools) I'd expect that if I was attaching I would solely be getting output from that point in time. We have logs today that can give you a breakdown/historical/last N lines view of IO already, so I'm hesitant to add in this extra logic.

@jacques-n

Copy link
Copy Markdown
Author

We haven't forgotten you 😄

😄

What was the rationale behind needing to support sessions that exist past the lifetime of some attached client?

It's pretty common to start a container with a disconnected interactive terminal. I think that is why it is supported in docker. It allows one to separate container creation from exposing that terminal. We use it for starting interactive applications from remote clients without having to guarantee continuous remote connectivity. Think old school client/server. Could one reproduce similar by creating this on top of container by creating a secondary long-lived daemon to hold the sessions? Yes, but it creates a lot of additional complexity and you're basically replicating a bunch of container functionality.

ring buffer.

Yeah, I considered both options. But the primary use case I think user expectation would be playback. Imagine starting an interactive detached container and then attaching to it a few seconds later. Do you expect to see what just happened? I suspect people would. The best analog would be screen. (I admit that It's nowhere near a perfect analog.) If you ran a command in screen and then detach then reattach, you don't lose context.

One alt impl would be to internally invoke the log infra. The concern was the complexity of trying to split the stream correctly--e.g. ensuring exactly once semantics. That's what the ring buffer provides that I think would be invasive to add to the logs.

@dcantah

Copy link
Copy Markdown
Contributor

It's pretty common to start a container with a disconnected interactive terminal.

I think I need to remember how IO was done here (I usually stay over in library land 😬) a tad more, but my remembrance was: We allocate 2 pipes (and 3 if -i was supplied) and send them to the daemon to use to send output to the client. However, the other bit I vaguely remember (you'd think I'd remember more as I added it..) output is always asked for from the process because we always write to a log file in addition to the pipes sent over by the client. This is how container log functions, we just tail/read(2) etc. this log file by having the daemon just send us the fd of it over xpc, and if any pipes were sent by the client we just multiplex the writes to the pipes as well. Every container is always ran in a separate process that the daemon spins up, so there should always be something holding open the IO for the lifetime of the container, that's the part that I wasn't super clear on if you found anything that falls over today. I'd imagine with the way IO is setup attach could basically be: send 2/3 new pipe fds to Sandbox process (the process running the container/VM), lock on some data structure that holds the current set of fds to multiplex to, and then continue writing.

@dcantah

Copy link
Copy Markdown
Contributor

After a reworking of some types locally, I'm somewhat convinced server initiated stdio may be a blessing. I'll be looking at this tomorrow morning

try ensureRunning(container: container)

// Check if container has terminal enabled
guard container.configuration.initProcess.terminal else {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why? If you just wanted to attach to see stdout/err really quick this shouldn't be required I'd imagine. Likewise even if you wanted to pipe some stdin I'd think you wouldn't need a pty

var noHistory = false

@Option(name: .customLong("detach-keys"), help: "Override the key sequence for detaching a container")
var detachKeys: String?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could not be happier about this 😆 I was honestly hoping someone would implement it.

@dcantah

dcantah commented Jul 23, 2025

Copy link
Copy Markdown
Contributor

One thing I can confidently say before reviewing the rest, I think we'd either want to move wholesale to server provided stdio or client and not a mix. I know you left in the old way so it's not an even bigger change/controversial, but we'd definitely just want one or the other. I'm honestly somewhat leaning towards the server end like I mentioned after trying to do a refactor the other day that was miserable, but I'll need to keep reading here and thinking about pitfalls

@egernstegernst added enhancement New feature or request next Must-have items for current and next milestone labels Aug 4, 2025
@egernstegernst added this to the 2025-09 milestone Sep 2, 2025
@jgloganjglogan removed this from the 2025-09 milestone Sep 10, 2025
@Mcrich23

Copy link
Copy Markdown
Contributor

Hey! So sorry, but in an effort to make plugin development more possible #603 and #635 have lead to the CLI folder being renamed to ContainerCommands and that will impact the merging of your pull request. Just an FYI, so you understand the issue when you are resolving conflicts.

@jacques-n

Copy link
Copy Markdown
Author

Closing as not a priority. Others are free to pick up this code and start again if it becomes a priority.

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

Labels

enhancementNew feature or requestnextMust-have items for current and next milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Request]: Attach the terminal to a running container.

7 participants

@jacques-n@dcantah@Mcrich23@crosbymichael@jglogan@adeebashraf@egernst