@@ -27,6 +27,7 @@ import (
2727 "github.com/antmicro/rdfm/app"
2828 "github.com/antmicro/rdfm/conf"
2929 "github.com/antmicro/rdfm/serverws"
30+ "github.com/antmicro/rdfm/shell"
3031 "github.com/antmicro/rdfm/telemetry"
3132
3233 netUtils "github.com/antmicro/rdfm/daemon/net_utils"
@@ -48,6 +49,7 @@ type Device struct {
4849 logManager * telemetry.LogManager
4950 conn * serverws.DeviceManagementConnection
5051 actionRunner * actions.ActionRunner
52+ shellRunner * shell.ShellRunner
5153}
5254
5355func (d * Device ) handleRequest (msg []byte ) (serverws.Request , error ) {
@@ -107,8 +109,40 @@ func (d *Device) handleRequest(msg []byte) (serverws.Request, error) {
107109 Actions : reqActions ,
108110 }
109111 return response , nil
110- //case serverws.DeviceAttachToManager:
111- // TODO: Handle shell_attach
112+ case serverws.DeviceAttachToManager :
113+ tlsConf , err := d .getTlsConf ()
114+ if err != nil {
115+ log .Warnln ("Failed to get TLS configuration:" , err )
116+ return nil , nil
117+ }
118+
119+ go func () {
120+ token , err := d .getDeviceToken ()
121+ if err != nil {
122+ log .Warnln ("Failed to acquire device token:" , err )
123+ return
124+ }
125+
126+ session , err := d .shellRunner .Spawn (r .Uuid )
127+ if err != nil {
128+ log .Warnln ("Failed to spawn shell session:" , err )
129+ return
130+ }
131+ defer d .shellRunner .Terminate (session .Uuid ())
132+
133+ conn := serverws .NewShellConnection (d .rdfmCtx .RdfmConfig .ServerURL , tlsConf )
134+ err = conn .Connect (token , r .MacAddr , r .Uuid )
135+ if err != nil {
136+ log .Warnln ("Failed to connect to shell WebSocket:" , err )
137+ return
138+ }
139+ defer conn .Close ()
140+
141+ err = session .Run (conn )
142+ log .Debugf ("Shell session %s exited with err: %s" , session .Uuid (), err )
143+ }()
144+
145+ return nil , nil
112146 default :
113147 log .Warnf ("Request '%s' is unsupported" , requestName )
114148 response := serverws .CantHandleRequest ()
@@ -206,7 +240,7 @@ func (d *Device) setupConnection() error {
206240 // config file instead, but we don't have any configuration options that
207241 // determine whether action/shell should be enabled or not.
208242 d .conn .SetCapability ("action" , true )
209- d .conn .SetCapability ("shell" , false )
243+ d .conn .SetCapability ("shell" , true )
210244 return nil
211245}
212246
@@ -219,6 +253,15 @@ func (d *Device) setupActionRunner() error {
219253 return nil
220254}
221255
256+ func (d * Device ) setupShellRunner () error {
257+ sr , err := shell .NewShellRunner (1 )
258+ if err != nil {
259+ return err
260+ }
261+ d .shellRunner = sr
262+ return nil
263+ }
264+
222265func (d * Device ) actionResultCallback (result actions.ActionResult , cancelCtx context.Context ) bool {
223266 res := serverws.ActionExecResult {
224267 Method : "action_exec_result" ,
0 commit comments