@@ -273,27 +273,34 @@ func createCmdStrAndOpts(blockId string, blockMeta waveobj.MetaMapType) (string,
273
273
}
274
274
275
275
func (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 ) {
276
284
// create a circular blockfile for the output
277
285
ctx , cancelFn := context .WithTimeout (context .Background (), 2 * time .Second )
278
286
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 )
283
290
}
284
- if err == fs .ErrExist {
291
+ if fsErr == fs .ErrExist {
285
292
// reset the terminal state
286
293
bc .resetTerminalState ()
287
294
}
288
- err = nil
289
295
bcInitStatus := bc .GetRuntimeStatus ()
290
296
if bcInitStatus .ShellProcStatus == Status_Running {
291
- return nil
297
+ return nil , nil
292
298
}
293
299
// TODO better sync here (don't let two starts happen at the same times)
294
300
remoteName := blockMeta .GetString (waveobj .MetaKey_Connection , "" )
295
301
var cmdStr string
296
302
var cmdOpts shellexec.CommandOptsType
303
+ var err error
297
304
if bc .ControllerType == BlockController_Shell {
298
305
cmdOpts .Env = make (map [string ]string )
299
306
cmdOpts .Interactive = true
@@ -302,19 +309,19 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
302
309
if cmdOpts .Cwd != "" {
303
310
cwdPath , err := wavebase .ExpandHomeDir (cmdOpts .Cwd )
304
311
if err != nil {
305
- return err
312
+ return nil , err
306
313
}
307
314
cmdOpts .Cwd = cwdPath
308
315
}
309
316
} else if bc .ControllerType == BlockController_Cmd {
310
317
var cmdOptsPtr * shellexec.CommandOptsType
311
318
cmdStr , cmdOptsPtr , err = createCmdStrAndOpts (bc .BlockId , blockMeta )
312
319
if err != nil {
313
- return err
320
+ return nil , err
314
321
}
315
322
cmdOpts = * cmdOptsPtr
316
323
} else {
317
- return fmt .Errorf ("unknown controller type %q" , bc .ControllerType )
324
+ return nil , fmt .Errorf ("unknown controller type %q" , bc .ControllerType )
318
325
}
319
326
var shellProc * shellexec.ShellProc
320
327
if strings .HasPrefix (remoteName , "wsl://" ) {
@@ -325,45 +332,45 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
325
332
wslConn := wsl .GetWslConn (credentialCtx , wslName , false )
326
333
connStatus := wslConn .DeriveConnStatus ()
327
334
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" )
329
336
}
330
337
331
338
// create jwt
332
339
if ! blockMeta .GetBool (waveobj .MetaKey_CmdNoWsh , false ) {
333
340
jwtStr , err := wshutil .MakeClientJWTToken (wshrpc.RpcContext {TabId : bc .TabId , BlockId : bc .BlockId , Conn : wslConn .GetName ()}, wslConn .GetDomainSocketName ())
334
341
if err != nil {
335
- return fmt .Errorf ("error making jwt token: %w" , err )
342
+ return nil , fmt .Errorf ("error making jwt token: %w" , err )
336
343
}
337
344
cmdOpts .Env [wshutil .WaveJwtTokenVarName ] = jwtStr
338
345
}
339
346
shellProc , err = shellexec .StartWslShellProc (ctx , rc .TermSize , cmdStr , cmdOpts , wslConn )
340
347
if err != nil {
341
- return err
348
+ return nil , err
342
349
}
343
350
} else if remoteName != "" {
344
351
credentialCtx , cancelFunc := context .WithTimeout (context .Background (), 60 * time .Second )
345
352
defer cancelFunc ()
346
353
347
354
opts , err := remote .ParseOpts (remoteName )
348
355
if err != nil {
349
- return err
356
+ return nil , err
350
357
}
351
358
conn := conncontroller .GetConn (credentialCtx , opts , false , & wshrpc.ConnKeywords {})
352
359
connStatus := conn .DeriveConnStatus ()
353
360
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" )
355
362
}
356
363
if ! blockMeta .GetBool (waveobj .MetaKey_CmdNoWsh , false ) {
357
364
jwtStr , err := wshutil .MakeClientJWTToken (wshrpc.RpcContext {TabId : bc .TabId , BlockId : bc .BlockId , Conn : conn .Opts .String ()}, conn .GetDomainSocketName ())
358
365
if err != nil {
359
- return fmt .Errorf ("error making jwt token: %w" , err )
366
+ return nil , fmt .Errorf ("error making jwt token: %w" , err )
360
367
}
361
368
cmdOpts .Env [wshutil .WaveJwtTokenVarName ] = jwtStr
362
369
}
363
370
if ! conn .WshEnabled .Load () {
364
371
shellProc , err = shellexec .StartRemoteShellProcNoWsh (rc .TermSize , cmdStr , cmdOpts , conn )
365
372
if err != nil {
366
- return err
373
+ return nil , err
367
374
}
368
375
} else {
369
376
shellProc , err = shellexec .StartRemoteShellProc (rc .TermSize , cmdStr , cmdOpts , conn )
@@ -376,19 +383,16 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
376
383
log .Print ("attempting install without wsh" )
377
384
shellProc , err = shellexec .StartRemoteShellProcNoWsh (rc .TermSize , cmdStr , cmdOpts , conn )
378
385
if err != nil {
379
- return err
386
+ return nil , err
380
387
}
381
388
}
382
389
}
383
- if err != nil {
384
- return err
385
- }
386
390
} else {
387
391
// local terminal
388
392
if ! blockMeta .GetBool (waveobj .MetaKey_CmdNoWsh , false ) {
389
393
jwtStr , err := wshutil .MakeClientJWTToken (wshrpc.RpcContext {TabId : bc .TabId , BlockId : bc .BlockId }, wavebase .GetDomainSocketName ())
390
394
if err != nil {
391
- return fmt .Errorf ("error making jwt token: %w" , err )
395
+ return nil , fmt .Errorf ("error making jwt token: %w" , err )
392
396
}
393
397
cmdOpts .Env [wshutil .WaveJwtTokenVarName ] = jwtStr
394
398
}
@@ -407,14 +411,18 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
407
411
}
408
412
shellProc , err = shellexec .StartShellProc (rc .TermSize , cmdStr , cmdOpts )
409
413
if err != nil {
410
- return err
414
+ return nil , err
411
415
}
412
416
}
413
417
bc .UpdateControllerAndSendUpdate (func () bool {
414
418
bc .ShellProc = shellProc
415
419
bc .ShellProcStatus = Status_Running
416
420
return true
417
421
})
422
+ return shellProc , nil
423
+ }
424
+
425
+ func (bc * BlockController ) manageRunningShellProcess (shellProc * shellexec.ShellProc , rc * RunShellOpts , blockMeta waveobj.MetaMapType ) error {
418
426
shellInputCh := make (chan * BlockInputUnion , 32 )
419
427
bc .ShellInputCh = shellInputCh
420
428
@@ -473,14 +481,7 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
473
481
shellProc .Cmd .Write (ic .InputData )
474
482
}
475
483
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 )
484
485
}
485
486
}
486
487
}()
@@ -522,6 +523,17 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts, blockMeta waveobj
522
523
return nil
523
524
}
524
525
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
+
525
537
func checkCloseOnExit (blockId string , exitCode int ) {
526
538
ctx , cancelFn := context .WithTimeout (context .Background (), DefaultTimeout )
527
539
defer cancelFn ()
@@ -569,16 +581,22 @@ func getTermSize(bdata *waveobj.Block) waveobj.TermSize {
569
581
}
570
582
}
571
583
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 ()
573
587
ctx = waveobj .ContextWithUpdates (ctx )
574
- bdata , err := wstore .DBMustGet [* waveobj.Block ](context . Background () , blockId )
588
+ bdata , err := wstore .DBMustGet [* waveobj.Block ](ctx , blockId )
575
589
if err != nil {
576
590
return fmt .Errorf ("error getting block data: %v" , err )
577
591
}
578
592
if bdata .RuntimeOpts == nil {
579
- return fmt . Errorf ( "error from nil RuntimeOpts: %v" , err )
593
+ bdata . RuntimeOpts = & waveobj. RuntimeOpts {}
580
594
}
581
595
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
+ }
582
600
updates := waveobj .ContextGetUpdatesRtn (ctx )
583
601
wps .Broker .SendUpdateEvents (updates )
584
602
return nil
0 commit comments