@@ -21,7 +21,6 @@ import (
21
21
"github.com/creack/pty"
22
22
"github.com/wavetermdev/waveterm/pkg/blocklogger"
23
23
"github.com/wavetermdev/waveterm/pkg/panichandler"
24
- "github.com/wavetermdev/waveterm/pkg/remote"
25
24
"github.com/wavetermdev/waveterm/pkg/remote/conncontroller"
26
25
"github.com/wavetermdev/waveterm/pkg/util/pamparse"
27
26
"github.com/wavetermdev/waveterm/pkg/util/shellutil"
@@ -30,7 +29,7 @@ import (
30
29
"github.com/wavetermdev/waveterm/pkg/wshrpc"
31
30
"github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient"
32
31
"github.com/wavetermdev/waveterm/pkg/wshutil"
33
- "github.com/wavetermdev/waveterm/pkg/wsl "
32
+ "github.com/wavetermdev/waveterm/pkg/wslconn "
34
33
)
35
34
36
35
const DefaultGracefulKillWait = 400 * time .Millisecond
@@ -151,92 +150,108 @@ func (pp *PipePty) WriteString(s string) (n int, err error) {
151
150
return pp .Write ([]byte (s ))
152
151
}
153
152
154
- func StartWslShellProc (ctx context.Context , termSize waveobj.TermSize , cmdStr string , cmdOpts CommandOptsType , conn * wsl.WslConn ) (* ShellProc , error ) {
155
- utilCtx , cancelFn := context .WithTimeout (ctx , 2 * time .Second )
156
- defer cancelFn ()
153
+ func StartWslShellProc (ctx context.Context , termSize waveobj.TermSize , cmdStr string , cmdOpts CommandOptsType , conn * wslconn.WslConn ) (* ShellProc , error ) {
157
154
client := conn .GetClient ()
158
- shellPath := cmdOpts .ShellPath
155
+ conn .Infof (ctx , "WSL-NEWSESSION (StartWslShellProc)" )
156
+ connRoute := wshutil .MakeConnectionRouteId (conn .GetName ())
157
+ rpcClient := wshclient .GetBareRpcClient ()
158
+ remoteInfo , err := wshclient .RemoteGetInfoCommand (rpcClient , & wshrpc.RpcOpts {Route : connRoute , Timeout : 2000 })
159
+ if err != nil {
160
+ return nil , fmt .Errorf ("unable to obtain client info: %w" , err )
161
+ }
162
+ log .Printf ("client info collected: %+#v" , remoteInfo )
163
+ var shellPath string
164
+ if cmdOpts .ShellPath != "" {
165
+ conn .Infof (ctx , "using shell path from command opts: %s\n " , cmdOpts .ShellPath )
166
+ shellPath = cmdOpts .ShellPath
167
+ }
168
+ configShellPath := conn .GetConfigShellPath ()
169
+ if shellPath == "" && configShellPath != "" {
170
+ conn .Infof (ctx , "using shell path from config (conn:shellpath): %s\n " , configShellPath )
171
+ shellPath = configShellPath
172
+ }
173
+ if shellPath == "" && remoteInfo .Shell != "" {
174
+ conn .Infof (ctx , "using shell path detected on remote machine: %s\n " , remoteInfo .Shell )
175
+ shellPath = remoteInfo .Shell
176
+ }
159
177
if shellPath == "" {
160
- remoteShellPath , err := wsl .DetectShell (utilCtx , client )
161
- if err != nil {
162
- return nil , err
163
- }
164
- shellPath = remoteShellPath
178
+ conn .Infof (ctx , "no shell path detected, using default (/bin/bash)\n " )
179
+ shellPath = "/bin/bash"
165
180
}
166
181
var shellOpts []string
167
- log .Printf ("detected shell: %s" , shellPath )
182
+ var cmdCombined string
183
+ log .Printf ("detected shell %q for conn %q\n " , shellPath , conn .GetName ())
168
184
169
- err := wsl . InstallClientRcFiles ( utilCtx , client )
185
+ err = wshclient . RemoteInstallRcFilesCommand ( rpcClient , & wshrpc. RpcOpts { Route : connRoute , Timeout : 2000 } )
170
186
if err != nil {
171
187
log .Printf ("error installing rc files: %v" , err )
172
188
return nil , err
173
189
}
174
-
175
- homeDir := wsl .GetHomeDir (utilCtx , client )
176
- shellOpts = append (shellOpts , "~" , "-d" , client .Name ())
177
-
178
- var subShellOpts []string
190
+ shellOpts = append (shellOpts , cmdOpts .ShellOpts ... )
191
+ shellType := shellutil .GetShellTypeFromShellPath (shellPath )
192
+ conn .Infof (ctx , "detected shell type: %s\n " , shellType )
179
193
180
194
if cmdStr == "" {
181
195
/* transform command in order to inject environment vars */
182
- if isBashShell (shellPath ) {
183
- log .Printf ("recognized as bash shell" )
196
+ if shellType == shellutil .ShellType_bash {
184
197
// add --rcfile
185
198
// cant set -l or -i with --rcfile
186
- subShellOpts = append (subShellOpts , "--rcfile" , fmt .Sprintf (`%s/.waveterm/%s/.bashrc` , homeDir , shellutil .BashIntegrationDir ))
187
- } else if isFishShell (shellPath ) {
188
- carg := fmt .Sprintf (`"set -x PATH \"%s\"/.waveterm/%s $PATH"` , homeDir , shellutil .WaveHomeBinDir )
189
- subShellOpts = append (subShellOpts , "-C" , carg )
190
- } else if wsl .IsPowershell (shellPath ) {
199
+ bashPath := fmt .Sprintf ("~/.waveterm/%s/.bashrc" , shellutil .BashIntegrationDir )
200
+ shellOpts = append (shellOpts , "--rcfile" , bashPath )
201
+ } else if shellType == shellutil .ShellType_fish {
202
+ if cmdOpts .Login {
203
+ shellOpts = append (shellOpts , "-l" )
204
+ }
205
+ // source the wave.fish file
206
+ waveFishPath := fmt .Sprintf ("~/.waveterm/%s/wave.fish" , shellutil .FishIntegrationDir )
207
+ carg := fmt .Sprintf (`"source %s"` , waveFishPath )
208
+ shellOpts = append (shellOpts , "-C" , carg )
209
+ } else if shellType == shellutil .ShellType_pwsh {
210
+ pwshPath := fmt .Sprintf ("~/.waveterm/%s/wavepwsh.ps1" , shellutil .PwshIntegrationDir )
191
211
// powershell is weird about quoted path executables and requires an ampersand first
192
212
shellPath = "& " + shellPath
193
- subShellOpts = append (subShellOpts , "-ExecutionPolicy" , "Bypass" , "-NoExit" , "-File" , fmt . Sprintf ( "%s/.waveterm/%s/wavepwsh.ps1" , homeDir , shellutil . PwshIntegrationDir ) )
213
+ shellOpts = append (shellOpts , "-ExecutionPolicy" , "Bypass" , "-NoExit" , "-File" , pwshPath )
194
214
} else {
195
215
if cmdOpts .Login {
196
- subShellOpts = append (subShellOpts , "-l" )
216
+ shellOpts = append (shellOpts , "-l" )
197
217
}
198
218
if cmdOpts .Interactive {
199
- subShellOpts = append (subShellOpts , "-i" )
219
+ shellOpts = append (shellOpts , "-i" )
200
220
}
201
- // can't set environment vars this way
202
- // will try to do later if possible
221
+ // zdotdir setting moved to after session is created
203
222
}
223
+ cmdCombined = fmt .Sprintf ("%s %s" , shellPath , strings .Join (shellOpts , " " ))
204
224
} else {
225
+ // TODO check quoting of cmdStr
205
226
shellPath = cmdStr
206
- if cmdOpts .Login {
207
- subShellOpts = append (subShellOpts , "-l" )
208
- }
209
- if cmdOpts .Interactive {
210
- subShellOpts = append (subShellOpts , "-i" )
211
- }
212
- subShellOpts = append (subShellOpts , "-c" , cmdStr )
227
+ shellOpts = append (shellOpts , "-c" , cmdStr )
228
+ cmdCombined = fmt .Sprintf ("%s %s" , shellPath , strings .Join (shellOpts , " " ))
229
+ }
230
+ conn .Infof (ctx , "starting shell, using command: %s\n " , cmdCombined )
231
+ conn .Infof (ctx , "WSL-NEWSESSION (StartWslShellProc)\n " )
232
+
233
+ if shellType == shellutil .ShellType_zsh {
234
+ zshDir := fmt .Sprintf ("~/.waveterm/%s" , shellutil .ZshIntegrationDir )
235
+ conn .Infof (ctx , "setting ZDOTDIR to %s\n " , zshDir )
236
+ cmdCombined = fmt .Sprintf (`ZDOTDIR=%s %s` , zshDir , cmdCombined )
213
237
}
214
238
215
239
jwtToken , ok := cmdOpts .Env [wshutil .WaveJwtTokenVarName ]
216
240
if ! ok {
217
241
return nil , fmt .Errorf ("no jwt token provided to connection" )
218
242
}
219
- if remote .IsPowershell (shellPath ) {
220
- shellOpts = append (shellOpts , "--" , fmt .Sprintf (`$env:%s=%s;` , wshutil .WaveJwtTokenVarName , jwtToken ))
221
- } else {
222
- shellOpts = append (shellOpts , "--" , fmt .Sprintf (`%s=%s` , wshutil .WaveJwtTokenVarName , jwtToken ))
223
- }
243
+ cmdCombined = fmt .Sprintf (`%s=%s %s` , wshutil .WaveJwtTokenVarName , jwtToken , cmdCombined )
224
244
225
- if isZshShell (shellPath ) {
226
- shellOpts = append (shellOpts , fmt .Sprintf (`ZDOTDIR=%s/.waveterm/%s` , homeDir , shellutil .ZshIntegrationDir ))
227
- }
228
- shellOpts = append (shellOpts , shellPath )
229
- shellOpts = append (shellOpts , subShellOpts ... )
230
- log .Printf ("full cmd is: %s %s" , "wsl.exe" , strings .Join (shellOpts , " " ))
231
-
232
- ecmd := exec .Command ("wsl.exe" , shellOpts ... )
245
+ log .Printf ("full combined command: %s" , cmdCombined )
246
+ ecmd := exec .Command ("wsl.exe" , "~" , "-d" , client .Name (), "--" , "sh" , "-c" , cmdCombined )
233
247
if termSize .Rows == 0 || termSize .Cols == 0 {
234
248
termSize .Rows = shellutil .DefaultTermRows
235
249
termSize .Cols = shellutil .DefaultTermCols
236
250
}
237
251
if termSize .Rows <= 0 || termSize .Cols <= 0 {
238
252
return nil , fmt .Errorf ("invalid term size: %v" , termSize )
239
253
}
254
+ shellutil .AddTokenSwapEntry (cmdOpts .SwapToken )
240
255
cmdPty , err := pty .StartWithSize (ecmd , & pty.Winsize {Rows : uint16 (termSize .Rows ), Cols : uint16 (termSize .Cols )})
241
256
if err != nil {
242
257
return nil , err
0 commit comments