From e136c302668d9afdfc229fe217b190b92f4e6365 Mon Sep 17 00:00:00 2001 From: Menno van Leeuwen Date: Fri, 23 May 2025 15:19:59 +0200 Subject: [PATCH] Fix module import path and installation instructions --- README.md | 2 +- cmd/start.go | 186 +++++++++++++++++++++++++-------------------------- cmd/stats.go | 10 +-- cmd/stop.go | 6 +- go.mod | 2 +- main.go | 2 +- 6 files changed, 104 insertions(+), 104 deletions(-) diff --git a/README.md b/README.md index 46dce74..f5e3e2b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ A Go-based command-line tool to manage SSH tunnels. This tool allows you to: ## Installation ``` -go install git.mvl.sh/vleeuwenmenno/sshtunnel/cmd@latest +go install git.mvl.sh/vleeuwenmenno/sshtunnel@latest ``` Or clone this repository and build it yourself: diff --git a/cmd/start.go b/cmd/start.go index 329273f..e3c001c 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -8,8 +8,8 @@ import ( "strings" "time" + "git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/stats" "github.com/spf13/cobra" - "sshtunnel/pkg/stats" ) var ( @@ -28,106 +28,106 @@ var startCmd = &cobra.Command{ The tunnel will run in the background and can be managed using the list and stop commands.`, Run: func(cmd *cobra.Command, args []string) { // Check required flags - // Generate the SSH command with appropriate flags for reliable background operation - sshArgs := []string{ - "-N", // Don't execute remote command - "-f", // Run in background - "-L", fmt.Sprintf("%d:%s:%d", localPort, remoteHost, remotePort), + // Generate the SSH command with appropriate flags for reliable background operation + sshArgs := []string{ + "-N", // Don't execute remote command + "-f", // Run in background + "-L", fmt.Sprintf("%d:%s:%d", localPort, remoteHost, remotePort), + } + + if identity != "" { + sshArgs = append(sshArgs, "-i", identity) + } + + sshArgs = append(sshArgs, sshServer) + sshCmd := exec.Command("ssh", sshArgs...) + + // Capture output for debugging + var outputBuffer strings.Builder + sshCmd.Stdout = &outputBuffer + sshCmd.Stderr = &outputBuffer + + // Run the command (not just Start) - the -f flag means it will return immediately + // after going to the background + if err := sshCmd.Run(); err != nil { + fmt.Printf("Error starting SSH tunnel: %v\n", err) + fmt.Printf("SSH output: %s\n", outputBuffer.String()) + os.Exit(1) + } + + // The PID from cmd.Process is no longer valid since ssh -f forks + // We need to find the actual SSH process PID + actualPID, err := findSSHTunnelPID(localPort) + if err != nil { + fmt.Printf("Warning: Could not determine tunnel PID: %v\n", err) + } + + // Store tunnel information + id := generateTunnelID() + pid := 0 + + if actualPID > 0 { + pid = actualPID + } + + tunnel := Tunnel{ + ID: id, + LocalPort: localPort, + RemotePort: remotePort, + RemoteHost: remoteHost, + SSHServer: sshServer, + PID: pid, + } + + if err := saveTunnel(tunnel); err != nil { + fmt.Printf("Error saving tunnel information: %v\n", err) + if pid > 0 { + // Try to kill the process + process, _ := os.FindProcess(pid) + if process != nil { + process.Kill() + } } + os.Exit(1) + } - if identity != "" { - sshArgs = append(sshArgs, "-i", identity) - } - - sshArgs = append(sshArgs, sshServer) - sshCmd := exec.Command("ssh", sshArgs...) - - // Capture output for debugging - var outputBuffer strings.Builder - sshCmd.Stdout = &outputBuffer - sshCmd.Stderr = &outputBuffer - - // Run the command (not just Start) - the -f flag means it will return immediately - // after going to the background - if err := sshCmd.Run(); err != nil { - fmt.Printf("Error starting SSH tunnel: %v\n", err) - fmt.Printf("SSH output: %s\n", outputBuffer.String()) - os.Exit(1) - } - - // The PID from cmd.Process is no longer valid since ssh -f forks - // We need to find the actual SSH process PID - actualPID, err := findSSHTunnelPID(localPort) + // Initialize statistics for this tunnel + statsManager, err := stats.NewStatsManager() + if err == nil { + err = statsManager.InitStats(id, localPort) if err != nil { - fmt.Printf("Warning: Could not determine tunnel PID: %v\n", err) + fmt.Printf("Warning: Failed to initialize statistics: %v\n", err) } + } - // Store tunnel information - id := generateTunnelID() - pid := 0 - - if actualPID > 0 { - pid = actualPID - } - - tunnel := Tunnel{ - ID: id, - LocalPort: localPort, - RemotePort: remotePort, - RemoteHost: remoteHost, - SSHServer: sshServer, - PID: pid, - } + // Verify tunnel is actually working + time.Sleep(500 * time.Millisecond) + active := verifyTunnelActive(localPort) + status := "ACTIVE" + if !active { + status = "UNKNOWN" + } - if err := saveTunnel(tunnel); err != nil { - fmt.Printf("Error saving tunnel information: %v\n", err) - if pid > 0 { - // Try to kill the process - process, _ := os.FindProcess(pid) - if process != nil { - process.Kill() - } - } - os.Exit(1) - } - - // Initialize statistics for this tunnel - statsManager, err := stats.NewStatsManager() - if err == nil { - err = statsManager.InitStats(id, localPort) - if err != nil { - fmt.Printf("Warning: Failed to initialize statistics: %v\n", err) - } - } + fmt.Printf("Started SSH tunnel (ID: %d): localhost:%d -> %s:%d (%s) [PID: %d] [Status: %s]\n", + id, localPort, remoteHost, remotePort, sshServer, pid, status) + }, +} - // Verify tunnel is actually working - time.Sleep(500 * time.Millisecond) - active := verifyTunnelActive(localPort) - status := "ACTIVE" - if !active { - status = "UNKNOWN" - } +func init() { + rootCmd.AddCommand(startCmd) - fmt.Printf("Started SSH tunnel (ID: %d): localhost:%d -> %s:%d (%s) [PID: %d] [Status: %s]\n", - id, localPort, remoteHost, remotePort, sshServer, pid, status) - }, - } + // Add flags for the start command + startCmd.Flags().IntVarP(&localPort, "local", "l", 0, "Local port to forward") + startCmd.Flags().IntVarP(&remotePort, "remote", "r", 0, "Remote port to forward to") + startCmd.Flags().StringVarP(&remoteHost, "host", "H", "localhost", "Remote host to forward to") + startCmd.Flags().StringVarP(&sshServer, "server", "s", "", "SSH server address (user@host)") + startCmd.Flags().StringVarP(&identity, "identity", "i", "", "Path to SSH identity file") - func init() { - rootCmd.AddCommand(startCmd) - - // Add flags for the start command - startCmd.Flags().IntVarP(&localPort, "local", "l", 0, "Local port to forward") - startCmd.Flags().IntVarP(&remotePort, "remote", "r", 0, "Remote port to forward to") - startCmd.Flags().StringVarP(&remoteHost, "host", "H", "localhost", "Remote host to forward to") - startCmd.Flags().StringVarP(&sshServer, "server", "s", "", "SSH server address (user@host)") - startCmd.Flags().StringVarP(&identity, "identity", "i", "", "Path to SSH identity file") - - // Mark required flags - startCmd.MarkFlagRequired("local") - startCmd.MarkFlagRequired("remote") - startCmd.MarkFlagRequired("server") - } + // Mark required flags + startCmd.MarkFlagRequired("local") + startCmd.MarkFlagRequired("remote") + startCmd.MarkFlagRequired("server") +} // verifyTunnelActive checks if the tunnel is actually working func verifyTunnelActive(port int) bool { @@ -138,4 +138,4 @@ func verifyTunnelActive(port int) bool { } conn.Close() return true -} \ No newline at end of file +} diff --git a/cmd/stats.go b/cmd/stats.go index 9f8a2c5..54cdaf5 100644 --- a/cmd/stats.go +++ b/cmd/stats.go @@ -5,8 +5,8 @@ import ( "os" "time" - "sshtunnel/pkg/monitor" - "sshtunnel/pkg/stats" + "git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/monitor" + "git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/stats" "github.com/spf13/cobra" ) @@ -181,7 +181,7 @@ func watchTunnelStats(tunnelID int, interval int) { if err != nil { fmt.Printf("Warning: Tunnel #%d may not be active: %v\n", tunnelID, err) fmt.Println("Attempting to monitor anyway...") - + // Try to get port from stats statsManager, _ := stats.NewStatsManager() s, err := statsManager.GetStats(tunnelID) @@ -226,7 +226,7 @@ func watchTunnelStats(tunnelID int, interval int) { if err != nil { fmt.Printf("Warning: %v\n", err) fmt.Println("Displaying minimal statistics...") - statsStr = fmt.Sprintf("Monitoring tunnel #%d on port %d...", + statsStr = fmt.Sprintf("Monitoring tunnel #%d on port %d...", tunnelID, tunnel.LocalPort) } fmt.Println(statsStr) @@ -241,7 +241,7 @@ func watchTunnelStats(tunnelID int, interval int) { statsStr, err := mon.FormatStats() if err != nil { - statsStr = fmt.Sprintf("Warning: %v\n\nStill monitoring tunnel #%d on port %d...", + statsStr = fmt.Sprintf("Warning: %v\n\nStill monitoring tunnel #%d on port %d...", err, tunnelID, tunnel.LocalPort) } diff --git a/cmd/stop.go b/cmd/stop.go index e37aba5..ed5e157 100644 --- a/cmd/stop.go +++ b/cmd/stop.go @@ -5,8 +5,8 @@ import ( "os" "syscall" + "git.mvl.sh/vleeuwenmenno/sshtunnel/pkg/stats" "github.com/spf13/cobra" - "sshtunnel/pkg/stats" ) var ( @@ -86,7 +86,7 @@ func killTunnel(t Tunnel) { removeFile(t.ID) cleanupStats(t.ID) - fmt.Printf("Stopped SSH tunnel (ID: %d): localhost:%d -> %s:%d\n", + fmt.Printf("Stopped SSH tunnel (ID: %d): localhost:%d -> %s:%d\n", t.ID, t.LocalPort, t.RemoteHost, t.RemotePort) } @@ -102,4 +102,4 @@ func cleanupStats(tunnelID int) { if err != nil { fmt.Printf("Warning: Failed to delete statistics for tunnel %d: %v\n", tunnelID, err) } -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index 3588e2f..f243b0a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module sshtunnel +module git.mvl.sh/vleeuwenmenno/sshtunnel go 1.22.2 diff --git a/main.go b/main.go index cf6aff2..ebac3be 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,7 @@ import ( "fmt" "os" - "sshtunnel/cmd" + "git.mvl.sh/vleeuwenmenno/sshtunnel/cmd" ) func main() {