#Connect to Dagger Shell websocket?
1 messages · Page 1 of 1 (latest)
I was thinking about building a specific dagger utility function for this.
It's not straightforward since you need to supply your own Dialer to target the engine graphql endpoint to be able to access it
Ah gotcha ok
a bit of a bummer I can't access the engineconn package or the conn from the Client so I can construct the WS the client myself from the SDK to actually be able to use that for the ssh access. cc @timber chasm @median lily
If we want to support this, we can add a session attachable for it, that way it will work with any SDK since the functionality will be in the CLI
I was waiting to see if anyone would actually ever end up wanting this before implementing it, I guess so 🙂
that'd be nice. Didn't think about cross SDK which makes total sense. So the session attachable would be a new method on the client object?
the attachable itself would be an internal detail, I think the change would just include adding a field to Terminal like Attach that results in the caller's TTY (if it exists) being hooked up to the container shell (internally using the same websocket protocol as today). So from an SDK it'd be like c.Container().From("foo").Terminal().Attach(ctx)
oh, I see. Even better.
I guess the benefit of being able to access this outside the SDK functions could be to plug some other non-tty implementations like i.e: adding a websocket based term like https://xtermjs.org/docs/api/addons/attach/
The attach addon provides methods for attaching a terminal to a WebSocket stream, such as Docker’s WebSocket attach endpoint.
Yeah that was my thinking too, start with just websocketEndpoint which is super generic and layer attach on later if desired
yes, the thing is that websocketEndpoint returns the internal URL of where this lives but I don't have an easy way to connect to that via the SDK
at least not in Go since the underlying conn or engineconn packages are private and I can't use the dialer to make my WS request
You can do what the CLI does, which is directly connect to the engine (i.e. call this https://github.com/sipsma/dagger/blob/2097db77def7dfb12fdc6b6f0f00d3680df5809a/engine/client/client.go#L110-L110). That Client has a .Dagger() method that returns a dagger go sdk hooked up to the engine: https://github.com/sipsma/dagger/blob/2097db77def7dfb12fdc6b6f0f00d3680df5809a/engine/client/client.go#L675-L675
ohh, ok. I need to pull a package from the engine as a dep for this then, correct?
Yeah engine/client
👍 .
was trying to see if I could highjack the connection from the GraphQLClient SDK client somehow but all the graphql types are also private 😬
Yeah I think I prefer to leave that as is since I don't want to make the Go SDK itself overly special and different from other SDKs. There's still the backdoor of engine/client if you really really want to do something like this, but that's outside the Go SDK module
makes sense! it feels a bit weird to have a public WithConn opt in the Go SDK at least which receives an engineconn which is in an internal package though 🤔
Yeah agree it's a bit weird and the one place where the go sdk diverges slightly from the rest of the sdks, but we needed some way for engine/client/the cli to do all this, was the least worst way I could think of at the time 🤷♂️
awesome thx! at least I have a way to prototype it. Community call demo happening maybe? cc @granite shore 😛
Cool I'll keep an eye out thanks!
Sorry for bumping this. I'm also trying to connect to a shell but from the PHP SDK. I guess this is not possible yet ? My use case is getting a stream of stdout from a long running task
yes, there's no straightforward way to do this for the moment
you can use the SDK's Shell().WebsocketEndpoint for this but it will give you the internal WS endpoint you need to use through the existing connection the SDK has to achieve that. So there's some fiddling you need to do on your end to get it working 😬
Alright I managed to connect to the websocket endpoint. Here is the code :
public function getWebsocketConnection(string $webSocketEndpoint): PromiseInterface
{
$endpoint = str_replace('dagger', '127.0.0.1:'.$this->port, $webSocketEndpoint);
return WebsocketClient\connect($endpoint, headers: [
'Origin' => 'http://dagger',
'Authorization' => 'Basic '.base64_encode($this->sessionToken.':'),
]);
}
that's great! that's the good thing about dynamic languages like php, python and node that you can access pretty much anything 🙌
@drifting elbow - where did you get your session token? I see I can get this from a call to dagger session - but not sure which api to use internally to get it
hmm I think I'm past the auth token, but still having issues finding how I can connect to the websocket endpoint - it doesn't appear exposed anywhere I can access
using engine/client package and .Dagger() call on client seems to work, but then I get stuck connecting ot websocket
Oh and worth mentioning I'm on 11.4 now and using .Terminal() - which seems to do the same thing
eyyoooooo got it working. certainly no niceties of a real terminal, but works.jpg.
Thanks for coming to my ted talk (or more accurately - rubber duck session)
@granite shore how did you end up doing it?
I looked at the code but terminalSession is no where to be found, checking dagger source code I see its part of shell.go here https://github.com/dagger/dagger/blob/main/cmd/dagger/shell.go which is a private struct as it appears right now