-
Notifications
You must be signed in to change notification settings - Fork 301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
conn updates 2 #1660
conn updates 2 #1660
Conversation
WalkthroughThis pull request introduces several significant enhancements to the Wave Terminal's codebase, focusing on connection management, shell command execution, and infrastructure improvements. The changes span multiple packages and introduce new functionality for handling SSH and WSL connections, implementing generic connection utilities, and improving error handling across various components. Key additions include a new Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
…ric RunSimple. create a new SyncBuffer struct.
… in the CpWsh func
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (8)
pkg/genconn/wsl-impl.go (1)
18-24
: ConstructingWSLShellClient
This constructor is straightforward and correctly assigns the incoming distribution. Consider logging or validating thedistro
argument if there's any chance it might be nil or invalid at runtime.pkg/remote/conncontroller/conncontroller.go (1)
319-321
: Version check logic
Usingsemver.Compare(clientVersion, expectedVersion) >= 0
means the installation is skipped if the installed version is the same or newer. If it’s intentional to let a newer version stand, this is correct. Otherwise, consider using a strictly-greater check (> 0
) to prompt upgrades if needed.cmd/wsh/cmd/wshcmd-conn.go (2)
90-103
: Separate concerns between SSH and WSL retrievalThe consolidated approach of fetching SSH and WSL statuses in one function is clear and maintainable. However, consider logging errors where they occur before returning them, to provide visibility into which connection type failed.
153-165
: Validate concurrency safety when disconnecting multiple connectionsLooping through all connections and disconnecting each individually is generally fine. However, in environments with numerous connections, consider whether concurrent disconnections might be beneficial. Should you later decide on asynchronous disconnect calls, ensure concurrency safety on shared resources.
pkg/wavebase/wavebase.go (2)
55-63
: Add documentation for supported binariesThe map-based approach is effective for quick membership lookups. Consider adding a brief comment explaining the purpose of each supported key and how new platform keys can be added or removed. This can reduce confusion for future maintainers.
278-283
: Include case normalization on inputsIf there is any chance the OS or architecture might be passed with varied casing (e.g., "Linux" vs. "linux"), consider normalizing case before lookup to avoid false negatives. Otherwise, looks good.
pkg/wsl/wsl.go (1)
332-335
: Surface more context for debuggingWhen returning the error from
shellutil.GetWshBinaryPath
, consider wrapping it with contextual information (e.g., which OS or architecture) to aid debugging. For instance:- return err + return fmt.Errorf("failed to get wsh binary path for %s-%s: %w", clientOs, clientArch, err)ROADMAP.md (1)
32-32
: Status update aligns with ongoing connection improvements.The status change from Planned to In Progress accurately reflects the current work on connection-related improvements, which is consistent with this PR's objectives.
Consider updating the v0.11 release timeline since we're past January 13th, 2024.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sum
is excluded by!**/*.sum
📒 Files selected for processing (17)
ROADMAP.md
(1 hunks)cmd/wsh/cmd/wshcmd-conn.go
(2 hunks)frontend/app/store/keymodel.ts
(0 hunks)go.mod
(1 hunks)pkg/blockcontroller/blockcontroller.go
(8 hunks)pkg/genconn/genconn.go
(1 hunks)pkg/genconn/quote.go
(1 hunks)pkg/genconn/quote_test.go
(1 hunks)pkg/genconn/ssh-impl.go
(1 hunks)pkg/genconn/wsl-impl.go
(1 hunks)pkg/remote/conncontroller/conncontroller.go
(4 hunks)pkg/remote/connutil.go
(4 hunks)pkg/util/shellutil/shellutil.go
(5 hunks)pkg/util/syncbuf/syncbuf.go
(1 hunks)pkg/wavebase/wavebase.go
(2 hunks)pkg/wsl/wsl-util.go
(1 hunks)pkg/wsl/wsl.go
(1 hunks)
💤 Files with no reviewable changes (1)
- frontend/app/store/keymodel.ts
🔇 Additional comments (38)
pkg/genconn/wsl-impl.go (5)
1-5
: Build Constraint and License Notice
These lines establish the Windows-only build constraint and the license. Everything here looks properly defined.
43-61
:MakeWSLProcessController
Error Handling
The function correctly handles potential errors fromBuildShellCommand
. Usingfmt.Errorf()
with"%w"
to wrap the underlying error is a good practice for better context. Also, returning early on error is clean. Nice work.
63-77
: Safe Start Sequence
Lock usage and the check forw.started
effectively prevent starting the same command multiple times. The error messages are clear.
79-93
: Single Wait Execution & Graceful Kill
Usingsync.Once
inWait()
avoids multiple waits. TheKill()
method is straightforward. However, note thatProcess.Kill()
does not provide an error return; we rely on the process to terminate properly. This is acceptable if partial knowledge of kill success is acceptable.
95-146
: Pipe Management
Stdin, Stdout, and Stderr pipe methods properly guard against calling afterStart()
, preventing usage conflicts. Also, the checks for multiple calls on the same pipe are good. Overall, concurrency handling here looks solid.pkg/genconn/genconn.go (4)
1-17
: Package Introduction
The file sets up a sound foundation for generic shell execution, definingCommandSpec
,ShellClient
, andShellProcessController
. The design seems flexible for different backends (e.g., SSH, WSL).
39-57
:RunSimpleCommand
Pipeline Setup
Creates a process, retrieves stdout/stderr pipes, and starts the command. Good use of aWaitGroup
to handle concurrent copying from output streams. The error wrapping adds clarity when diagnosing failures.
58-77
: Concurrent Stream Copy & Context Wait
io.Copy
from stdout/stderr intosyncbuf
is a straightforward approach.ProcessContextWait
is an elegant way to combine process waiting with a context cancellation. The final returns of combined outputs are neatly done.
110-128
:BuildShellCommand
and Environment Handling
Building shell commands with environment variables is properly validated. TheHardQuote
usage ensures safer command construction. Be mindful that quoting logic must be carefully tested to avoid edge cases with special characters.pkg/genconn/ssh-impl.go (5)
16-22
:SSHShellClient
Construction
Simple structure wraps anssh.Client
. Building around an existing SSH client is a nice approach for modularity. No issues here.
42-55
:MakeSSHCmdClient
Session Initialization
The creation of anssh.Session
is properly checked for errors, returning a wrapped error if session creation fails. This approach is clear and easy to maintain.
57-80
:Start
Method
Locks ensure that the command isn’t started more than once. The fallback logic for unpiped input/output is a nice detail, avoiding corner cases. This is well-executed.
82-98
:Wait
andKill
Methods
Similar to the WSL version,sync.Once
ensures a consistent wait. TheKill()
method (session.Close()
) is safe, though you might consider clarifying in docstrings that closing the session terminates the remote process.
100-145
: Pipe Setup
Each pipe method checksstarted
and whether the pipe was already created. This prevents race conditions and pipe misuse. Error messages are clear, and concurrency is properly managed with the lock.pkg/util/shellutil/shellutil.go (3)
96-101
: Windows Shell Detection
Here,exec.LookPath("pwsh")
and thenexec.LookPath("powershell")
is a sensible fallback chain, returning"powershell.exe"
if neither is found. This logic ensures a best-effort approach for Windows environments.
Line range hint
222-237
:GetWshBinaryPath
The function normalizes architecture names, checks for unsupported platforms, then constructs a filename. This is a good pattern. Just ensure calls towavebase.SupportedWshBinaries
remain updated for newly supported OS/arch combos.
Line range hint
311-327
: Graceful Handling of Missing Binaries
initCustomShellStartupFilesInternal()
logs a non-fatal error if the WSH binary path is missing, then returns early. This approach avoids halting the entire initialization. This is user-friendly and robust.pkg/remote/connutil.go (6)
8-8
: Context-Based Refactor
Introducingcontext
is a great move toward graceful cancellation and timeouts.
Line range hint
58-81
:GetWshVersion
Validates that thewsh version
output has exactly two fields and performs semver checks. The explicit error for unexpected output is helpful for debugging.
155-158
:normalizeOs
Lowercasing and trimming OS strings ensures consistent comparisons. This is a simple but important detail to avoid subtle mismatches.
160-168
:normalizeArch
Maps known architecture synonyms (x86_64
,amd64
→x64
;arm64
,aarch64
→arm64
). This is straightforward, but stay in sync if new arch naming arises.
171-190
:GetClientPlatform
Runsuname -sm
remotely, splitting the result into OS and arch. Checkingwavebase.ValidateWshSupportedArch
is a good integration that ensures the rest of the code doesn’t proceed on unsupported platforms.
200-255
:CpWshToRemote
Flow
- Retrieves the local WSH path using
GetWshBinaryPath
.- Streams the binary to the remote host using an install template with final naming and permissions.
- Uses concurrency (
copyDone
channel) to track data copying.- Properly checks both the process error and the copy error.
This is cleanly structured code with robust error handling.
pkg/remote/conncontroller/conncontroller.go (3)
23-23
: New import forgenconn
The newly added import forgithub.looper.workers.dev/wavetermdev/waveterm/pkg/genconn
indicates integration with generic connection utilities. This looks appropriate given the usage ofgenconn.MakeSSHShellClient
later in the file.
36-36
: Usinggolang.org/x/mod/semver
Introducing semver comparison is beneficial for flexible and robust version checks. This import nicely aligns with the updated logic inCheckAndInstallWsh
.
373-379
: Installation flow for Wsh
After callingCpWshToRemote
, the code returns an error if the operation fails. If partial installation could leave the remote target in an inconsistent state, consider adding optional cleanup or rollback steps. Otherwise, this error handling is sufficient.
[approve]pkg/blockcontroller/blockcontroller.go (5)
276-281
: Sequential shell command orchestration
This newDoRunShellCommand
method cleanly delegates shell process setup tosetupAndStartShellProcess
and lifecycle management tomanageRunningShellProcess
, improving clarity and separation of concerns.
Line range hint
283-423
: Refactored shell process initialization
- Block file creation (lines 287-291): Good approach using a circular buffer to limit log size. Resetting terminal state upon
fs.ErrExist
ensures a fresh environment.- Status check (line 297): Early return if already running helps avoid duplicate processes.
- Command resolution (lines 303-324): Separates logic for shell-based vs. command-based controllers. Clear error returns for unknown controllers.
- Remote vs. local logic (lines 335-414): The branching structure is clean and explicit for WSL, SSH, or local execution. Encouraging clarifying logs or metrics for each path might aid debugging.
- Handling Wsh fallback (lines 373-386): If Wsh fails, you gracefully disable it and attempt a no-Wsh scenario, increasing resilience.
- Final update and status assignment (lines 414-422): Attaching the new
ShellProc
to the controller with a running state is neat.Overall, this function is well-structured. A minor note: consider factoring out helper functions or sub-blocks if it grows larger in the future.
Line range hint
425-525
: Shell process lifecycle management
- Concurrent read/write loops (lines ~439-482): Each goroutine handles a distinct data flow path. Carefully performed defers ensure cleanup in error conditions.
- Input channel usage (lines ~444-455): The
shellInputCh
design is logical. You guard references by storing it locally within the goroutine.- Final wait and exit code handling (lines ~494-515): Storing the exit code and updating status to
Status_Done
is consistent. Unregistering the route to avoid stale references is also a plus.This method is a robust approach to orchestrating the shell I/O. Good job.
526-535
: NewupdateTermSize
utility
The function sets term size in the database, then updates the shell’s PTY dimensions. Good abstraction that ensures both the DB model and the shell environment remain synchronized.
584-599
: Persisting terminal dimensions
SettingtermSize
in the DB (lines 584–599) is concise and has appropriate error handling. If partial updates are a concern, you already store changes inRuntimeOpts
and send broker updates on success. This is coherent.pkg/util/syncbuf/syncbuf.go (1)
1-41
: Thread-safe buffer implementation
- Structure & Locking (lines 12-16): Straightforward design with a mutex-protected
bytes.Buffer
.- Instantiation (lines 17-22):
MakeSyncBuffer
correctly returns a pointer, and re-initializes a freshbytes.Buffer
.- Async copying (lines 24-29):
MakeSyncBufferFromReader
elegantly streams data into the buffer, ensuring concurrency safety.- Write and String methods (lines 31-41): Both hold the lock during operations, maintaining concurrency safety.
This is a clear and usable concurrency utility.
pkg/genconn/quote.go (1)
1-78
: String quoting helpers
HardQuote
(lines 19-40): Simple, direct solution. Good check of empty strings. Proper escaping of special characters ensures safe shell usage.SoftQuote
(lines 42-78): The special handling for~
expansions is a thoughtful addition, letting certain paths remain unquoted. Skipping$
escaping fosters environment variable expansion.The approach is consistent with typical shell quoting practices. Watch for corner cases (e.g., multi-byte unicode). Otherwise, it’s well done.
pkg/genconn/quote_test.go (1)
1-110
: Comprehensive quote testing
The test table covers various edge cases (empty strings, tilde patterns, variables, embedded quotes/backslashes, etc.). This breadth of coverage is commendable. Consider adding a test for multi-byte characters (e.g., Unicode) if that’s relevant to your user base.cmd/wsh/cmd/wshcmd-conn.go (1)
105-109
: Graceful handling of no connection scenarioThe logic is straightforward and gracefully handles the “no connections” case. This looks good.
pkg/wsl/wsl-util.go (1)
16-16
: Switch to text-based templatingSwitching from HTML-based templates to
text/template
is sensible for command generation. Ensure any previously relied-upon escaping or sanitization logic is still enforced where needed.go.mod (2)
66-66
: New indirect dependency looks good.The addition of
golang.org/x/mod v0.22.0
as an indirect dependency is appropriate as it's a well-maintained part of the Go ecosystem.
Line range hint
77-79
: Verify the security implications of using forked dependencies.The use of forked versions of
ssh_config
andpty
packages requires careful consideration:
- Please document the rationale for using these specific forks in the codebase.
- Ensure there's a process to keep track of upstream security fixes.
Let's verify the changes in these forks:
No description provided.