Skip to content

Instantly share code, notes, and snippets.

@lynsei
Last active February 10, 2025 19:36
Show Gist options
  • Select an option

  • Save lynsei/a14954fcc5674714c570c3f0cef45d2f to your computer and use it in GitHub Desktop.

Select an option

Save lynsei/a14954fcc5674714c570c3f0cef45d2f to your computer and use it in GitHub Desktop.
[deno-duplex] command
deno run --allow-read --allow-write --allow-net --allow-run --allow-env --allow-sys run.ts child -i fish -- fish
Date: Mon Feb 10 2025 13:21:24 GMT-0500 (Eastern Standard Time)
System: darwin Home: /Users/lynseihogan Shell: /bin/zsh User: lynseihogan Platform: OXHPMV6XJ72H Memory: 169951232 Arch: arm64
User Commands: fish
Container Name: XL0LTCUneppgeh4jjdFQ
Socket: /var/run/docker.sock
Config Location: /Users/lynseihogan/Documents/gh/lotsofthoughts/install/.config.yaml
linux/arm64
POST /containers/create?name=XL0LTCUneppgeh4jjdFQ&platform=linux%2Farm64 HTTP/1.1
Host: docker
Accept: application/json
X-Registry-Auth: eyJ1c2VybmFtZSI6Imx5bnNlaSIsInBhc3N3b3JkIjoiUFZQcyY0Xk5ZJTlwXjY4ZCIsImVtYWlsIjoiIiwic2VydmVyYWRkcmVzcyI6ImRvY2tlci5pbyJ9
Content-Length: 822
Content-Type: application/json
{"Image":"lynsei/run.child.fish:arm64","User":"root","AttachStdin":true,"AttachStdout":true,"AttachStderr":true,"OpenStdin":true,"StdinOnce":false,"Tty":true,"Labels":{"com.container.author":"lynsei"},"Env":["__platform=linux/arm64","__config=/root/.config.yaml"],"HostConfig":{"AutoRemove":true,"LogConfig":{"Type":"json-file"},"Tmpfs":{"/secrets":"rw,noexec,nosuid,size=64m"},"Privileged":true,"Binds":["/Users/lynseihogan/Documents/gh/lotsofthoughts/install/.cache.parent:/root/.cache.parent","/Users/lynseihogan/Documents/gh/lotsofthoughts/install/.cache.child:/root/.cache.child","/Users/lynseihogan/Documents/gh/lotsofthoughts/install/.sha:/root/.sha","/Users/lynseihogan/Documents/gh/lotsofthoughts/install/.enc:/root/.enc","/Users/lynseihogan/Documents/gh/lotsofthoughts/install/.config.yaml:/root/.config.yaml"]}}
Started: dd52e13716efff20315d7929389693bb792e89943172c6ed6cdf44f52200dc77
πŸ”— Attaching to container: dd52e13716efff20315d7929389693bb792e89943172c6ed6cdf44f52200dc77
POST /containers/dd52e13716efff20315d7929389693bb792e89943172c6ed6cdf44f52200dc77/attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
Host: localhost
Connection: Upgrade
Upgrade: tcp
βœ… Detached from container: dd52e13716efff20315d7929389693bb792e89943172c6ed6cdf44f52200dc77
HTTP/1.1 101 UPGRADED
Connection: Upgrade
Content-Type: application/vnd.docker.raw-stream
Upgrade: tcp
πŸ”— Attaching to container: dd52e13716efff20315d7929389693bb792e89943172c6ed6cdf44f52200dc77
POST /containers/dd52e13716efff20315d7929389693bb792e89943172c6ed6cdf44f52200dc77/attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1
Host: localhost
Connection: Upgrade
Upgrade: tcp
βœ… Detached from container: dd52e13716efff20315d7929389693bb792e89943172c6ed6cdf44f52200dc77
error: Uncaught (in promise) TypeError: The stream is already locked
const writer = Deno.stdout.writable.getWriter();
^
at setUpWritableStreamDefaultWriter (ext:deno_web/06_streams.js:3972:11)
at new WritableStreamDefaultWriter (ext:deno_web/06_streams.js:6476:5)
at acquireWritableStreamDefaultWriter (ext:deno_web/06_streams.js:430:10)
at WritableStream.getWriter (ext:deno_web/06_streams.js:6436:12)
at file:///Users/lynseihogan/Documents/gh/lotsofthoughts/install/lib/runner.ts:198:53
at Runner.containerAttachment (file:///Users/lynseihogan/Documents/gh/lotsofthoughts/install/lib/runner.ts:208:14)
at eventLoopTick (ext:core/01_core.js:177:7)
at async Runner.createContainer (file:///Users/lynseihogan/Documents/gh/lotsofthoughts/install/lib/runner.ts:377:13)
at async Command.actionHandler (file:///Users/lynseihogan/Documents/gh/lotsofthoughts/install/lib/runner.ts:461:9)
at async Command.execute (https://jsr.io/@cliffy/command/1.0.0-rc.7/command.ts:1940:7)
private async containerAttachment(containerId: string) {
try {
log(bgBlue(`πŸ”— Attaching to container: ${containerId}`));
// Check if already attached to avoid duplicate locks
if (this.isAttached) {
log(yellow(`⚠️ Already attached to container: ${containerId}`));
return;
}
this.isAttached = true; // Set flag to prevent duplicate attach calls
// Connect to Docker socket
const socket = await Deno.connect({
transport: "unix",
path: "/var/run/docker.sock"
});
// Send the attach request
const attachRequest =
`POST /containers/${containerId}/attach?stream=1&stdin=1&stdout=1&stderr=1 HTTP/1.1\r\n` +
`Host: localhost\r\n` +
`Connection: Upgrade\r\n` +
`Upgrade: tcp\r\n\r\n`;
await socket.write(new TextEncoder().encode(attachRequest));
// Wait for Docker to upgrade connection
const reader = socket.readable.getReader();
let response = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
response += new TextDecoder().decode(value);
if (response.includes("HTTP/1.1 101 UPGRADED")) break;
}
log(green(`βœ… Attached successfully to container: ${containerId}`));
// **Stream container output to terminal (stdout)**
(async () => {
const stdoutWriter = Deno.stdout.writable.getWriter();
while (true) {
const { done, value } = await reader.read();
if (done) break;
await stdoutWriter.write(value);
}
stdoutWriter.releaseLock(); // Ensure the writer is released
})();
// **Stream user input to container (stdin)**
(async () => {
const stdinReader = Deno.stdin.readable;
await stdinReader.pipeTo(socket.writable);
})();
// **Keep the process open**
await new Promise(() => {});
} catch (error) {
log(red(`❌ Attach Error: ${error.message}`));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment