@@ -273,27 +273,34 @@ func createCmdStrAndOpts(blockId string, blockMeta waveobj.MetaMapType) (string,
273273}
274274
275275func (bc * BlockController ) DoRunShellCommand (rc * RunShellOpts , blockMeta waveobj.MetaMapType ) error {
276+ shellProc , err := bc .setupAndStartShellProcess (rc , blockMeta )
277+ if err != nil {
278+ return err
279+ }
280+ return bc .manageRunningShellProcess (shellProc , rc , blockMeta )
281+ }
282+
283+ func (bc * BlockController ) setupAndStartShellProcess (rc * RunShellOpts , blockMeta waveobj.MetaMapType ) (* shellexec.ShellProc , error ) {
276284 // create a circular blockfile for the output
277285 ctx , cancelFn := context .WithTimeout (context .Background (), 2 * time .Second )
278286 defer cancelFn ()
279- err := filestore .WFS .MakeFile (ctx , bc .BlockId , BlockFile_Term , nil , filestore.FileOptsType {MaxSize : DefaultTermMaxFileSize , Circular : true })
280- if err != nil && err != fs .ErrExist {
281- err = fs .ErrExist
282- return fmt .Errorf ("error creating blockfile: %w" , err )
287+ fsErr := filestore .WFS .MakeFile (ctx , bc .BlockId , BlockFile_Term , nil , filestore.FileOptsType {MaxSize : DefaultTermMaxFileSize , Circular : true })
288+ if fsErr != nil && fsErr != fs .ErrExist {
289+ return nil , fmt .Errorf ("error creating blockfile: %w" , fsErr )
283290 }
284- if err == fs .ErrExist {
291+ if fsErr == fs .ErrExist {
285292 // reset the terminal state
286293 bc .resetTerminalState ()
287294 }
288- err = nil
289295 bcInitStatus := bc .GetRuntimeStatus ()
290296 if bcInitStatus .ShellProcStatus == Status_Running {
291- return nil
297+ return nil , nil
292298 }
293299 // TODO better sync here (don't let two starts happen at the same times)
294300 remoteName := blockMeta .GetString (waveobj .MetaKey_Connection , "" )
295301 var cmdStr string
296302 var cmdOpts shellexec.CommandOptsType
303+ var err error
297304 if bc .ControllerType == BlockController_Shell {
298305 cmdOpts .Env = make (map [string ]string )
299306 cmdOpts .Interactive = true
@@ -302,19 +309,19 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
302309 if cmdOpts .Cwd != "" {
303310 cwdPath , err := wavebase .ExpandHomeDir (cmdOpts .Cwd )
304311 if err != nil {
305- return err
312+ return nil , err
306313 }
307314 cmdOpts .Cwd = cwdPath
308315 }
309316 } else if bc .ControllerType == BlockController_Cmd {
310317 var cmdOptsPtr * shellexec.CommandOptsType
311318 cmdStr , cmdOptsPtr , err = createCmdStrAndOpts (bc .BlockId , blockMeta )
312319 if err != nil {
313- return err
320+ return nil , err
314321 }
315322 cmdOpts = * cmdOptsPtr
316323 } else {
317- return fmt .Errorf ("unknown controller type %q" , bc .ControllerType )
324+ return nil , fmt .Errorf ("unknown controller type %q" , bc .ControllerType )
318325 }
319326 var shellProc * shellexec.ShellProc
320327 if strings .HasPrefix (remoteName , "wsl://" ) {
@@ -325,45 +332,45 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
325332 wslConn := wsl .GetWslConn (credentialCtx , wslName , false )
326333 connStatus := wslConn .DeriveConnStatus ()
327334 if connStatus .Status != conncontroller .Status_Connected {
328- return fmt .Errorf ("not connected, cannot start shellproc" )
335+ return nil , fmt .Errorf ("not connected, cannot start shellproc" )
329336 }
330337
331338 // create jwt
332339 if ! blockMeta .GetBool (waveobj .MetaKey_CmdNoWsh , false ) {
333340 jwtStr , err := wshutil .MakeClientJWTToken (wshrpc.RpcContext {TabId : bc .TabId , BlockId : bc .BlockId , Conn : wslConn .GetName ()}, wslConn .GetDomainSocketName ())
334341 if err != nil {
335- return fmt .Errorf ("error making jwt token: %w" , err )
342+ return nil , fmt .Errorf ("error making jwt token: %w" , err )
336343 }
337344 cmdOpts .Env [wshutil .WaveJwtTokenVarName ] = jwtStr
338345 }
339346 shellProc , err = shellexec .StartWslShellProc (ctx , rc .TermSize , cmdStr , cmdOpts , wslConn )
340347 if err != nil {
341- return err
348+ return nil , err
342349 }
343350 } else if remoteName != "" {
344351 credentialCtx , cancelFunc := context .WithTimeout (context .Background (), 60 * time .Second )
345352 defer cancelFunc ()
346353
347354 opts , err := remote .ParseOpts (remoteName )
348355 if err != nil {
349- return err
356+ return nil , err
350357 }
351358 conn := conncontroller .GetConn (credentialCtx , opts , false , & wshrpc.ConnKeywords {})
352359 connStatus := conn .DeriveConnStatus ()
353360 if connStatus .Status != conncontroller .Status_Connected {
354- return fmt .Errorf ("not connected, cannot start shellproc" )
361+ return nil , fmt .Errorf ("not connected, cannot start shellproc" )
355362 }
356363 if ! blockMeta .GetBool (waveobj .MetaKey_CmdNoWsh , false ) {
357364 jwtStr , err := wshutil .MakeClientJWTToken (wshrpc.RpcContext {TabId : bc .TabId , BlockId : bc .BlockId , Conn : conn .Opts .String ()}, conn .GetDomainSocketName ())
358365 if err != nil {
359- return fmt .Errorf ("error making jwt token: %w" , err )
366+ return nil , fmt .Errorf ("error making jwt token: %w" , err )
360367 }
361368 cmdOpts .Env [wshutil .WaveJwtTokenVarName ] = jwtStr
362369 }
363370 if ! conn .WshEnabled .Load () {
364371 shellProc , err = shellexec .StartRemoteShellProcNoWsh (rc .TermSize , cmdStr , cmdOpts , conn )
365372 if err != nil {
366- return err
373+ return nil , err
367374 }
368375 } else {
369376 shellProc , err = shellexec .StartRemoteShellProc (rc .TermSize , cmdStr , cmdOpts , conn )
@@ -376,19 +383,16 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
376383 log .Print ("attempting install without wsh" )
377384 shellProc , err = shellexec .StartRemoteShellProcNoWsh (rc .TermSize , cmdStr , cmdOpts , conn )
378385 if err != nil {
379- return err
386+ return nil , err
380387 }
381388 }
382389 }
383- if err != nil {
384- return err
385- }
386390 } else {
387391 // local terminal
388392 if ! blockMeta .GetBool (waveobj .MetaKey_CmdNoWsh , false ) {
389393 jwtStr , err := wshutil .MakeClientJWTToken (wshrpc.RpcContext {TabId : bc .TabId , BlockId : bc .BlockId }, wavebase .GetDomainSocketName ())
390394 if err != nil {
391- return fmt .Errorf ("error making jwt token: %w" , err )
395+ return nil , fmt .Errorf ("error making jwt token: %w" , err )
392396 }
393397 cmdOpts .Env [wshutil .WaveJwtTokenVarName ] = jwtStr
394398 }
@@ -407,14 +411,18 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
407411 }
408412 shellProc , err = shellexec .StartShellProc (rc .TermSize , cmdStr , cmdOpts )
409413 if err != nil {
410- return err
414+ return nil , err
411415 }
412416 }
413417 bc .UpdateControllerAndSendUpdate (func () bool {
414418 bc .ShellProc = shellProc
415419 bc .ShellProcStatus = Status_Running
416420 return true
417421 })
422+ return shellProc , nil
423+ }
424+
425+ func (bc * BlockController ) manageRunningShellProcess (shellProc * shellexec.ShellProc , rc * RunShellOpts , blockMeta waveobj.MetaMapType ) error {
418426 shellInputCh := make (chan * BlockInputUnion , 32 )
419427 bc .ShellInputCh = shellInputCh
420428
@@ -473,14 +481,7 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
473481 shellProc .Cmd .Write (ic .InputData )
474482 }
475483 if ic .TermSize != nil {
476- err = setTermSize (ctx , bc .BlockId , * ic .TermSize )
477- if err != nil {
478- log .Printf ("error setting pty size: %v\n " , err )
479- }
480- err = shellProc .Cmd .SetSize (ic .TermSize .Rows , ic .TermSize .Cols )
481- if err != nil {
482- log .Printf ("error setting pty size: %v\n " , err )
483- }
484+ updateTermSize (shellProc , bc .BlockId , * ic .TermSize )
484485 }
485486 }
486487 }()
@@ -522,6 +523,17 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
522523 return nil
523524}
524525
526+ func updateTermSize (shellProc * shellexec.ShellProc , blockId string , termSize waveobj.TermSize ) {
527+ err := setTermSizeInDB (blockId , termSize )
528+ if err != nil {
529+ log .Printf ("error setting pty size: %v\n " , err )
530+ }
531+ err = shellProc .Cmd .SetSize (termSize .Rows , termSize .Cols )
532+ if err != nil {
533+ log .Printf ("error setting pty size: %v\n " , err )
534+ }
535+ }
536+
525537func checkCloseOnExit (blockId string , exitCode int ) {
526538 ctx , cancelFn := context .WithTimeout (context .Background (), DefaultTimeout )
527539 defer cancelFn ()
@@ -569,16 +581,22 @@ func getTermSize(bdata *waveobj.Block) waveobj.TermSize {
569581 }
570582}
571583
572- func setTermSize (ctx context.Context , blockId string , termSize waveobj.TermSize ) error {
584+ func setTermSizeInDB (blockId string , termSize waveobj.TermSize ) error {
585+ ctx , cancelFn := context .WithTimeout (context .Background (), 2 * time .Second )
586+ defer cancelFn ()
573587 ctx = waveobj .ContextWithUpdates (ctx )
574- bdata , err := wstore .DBMustGet [* waveobj.Block ](context . Background () , blockId )
588+ bdata , err := wstore .DBMustGet [* waveobj.Block ](ctx , blockId )
575589 if err != nil {
576590 return fmt .Errorf ("error getting block data: %v" , err )
577591 }
578592 if bdata .RuntimeOpts == nil {
579- return fmt . Errorf ( "error from nil RuntimeOpts: %v" , err )
593+ bdata . RuntimeOpts = & waveobj. RuntimeOpts {}
580594 }
581595 bdata .RuntimeOpts .TermSize = termSize
596+ err = wstore .DBUpdate (ctx , bdata )
597+ if err != nil {
598+ return fmt .Errorf ("error updating block data: %v" , err )
599+ }
582600 updates := waveobj .ContextGetUpdatesRtn (ctx )
583601 wps .Broker .SendUpdateEvents (updates )
584602 return nil
0 commit comments