diff --git a/cmd/croc/croc.go b/cmd/croc/croc.go index 906431e..ea1029c 100644 --- a/cmd/croc/croc.go +++ b/cmd/croc/croc.go @@ -449,7 +449,7 @@ func (c *Client) setupLocalRelay() { func (c *Client) broadcastOnLocalNetwork(useipv6 bool) { var timeLimit time.Duration - //if we don't use an external relay, the broadcast messages need to be sent continuously + // if we don't use an external relay, the broadcast messages need to be sent continuously if c.Options.OnlyLocal { timeLimit = -1 * time.Second } else { @@ -515,7 +515,6 @@ func (c *Client) Send(filesInfo []FileInfo, emptyFoldersToTransfer []FileInfo, t c.TotalNumberFolders = totalNumberFolders c.TotalNumberOfContents = len(filesInfo) err = c.sendCollectFiles(filesInfo) - if err != nil { return } @@ -1120,7 +1119,7 @@ func (c *Client) processMessagePake(m message.Message) (err error) { Type: message.TypePAKE, Bytes: c.Pake.Bytes(), Bytes2: salt, - }) + }) // TODO: check me } else { err = c.Pake.Update(m.Bytes) if err != nil { @@ -1350,7 +1349,7 @@ func (c *Client) recipientInitializeFile() (err error) { var errOpen error c.CurrentFile, errOpen = os.OpenFile( pathToFile, - os.O_WRONLY, 0666) + os.O_WRONLY, 0o666) var truncate bool // default false c.CurrentFileChunks = []int64{} c.CurrentFileChunkRanges = []int64{} diff --git a/cmd/croc/receive.go b/cmd/croc/receive.go index 7051351..7baa0d4 100644 --- a/cmd/croc/receive.go +++ b/cmd/croc/receive.go @@ -2,19 +2,24 @@ package croc import ( "encoding/json" - "fmt" + "log" "net/http" - "strings" + "os" "strconv" + "strings" + "time" "github.com/schollz/croc/v9/src/croc" "github.com/schollz/croc/v9/src/models" "github.com/spf13/cobra" ) -func GetRelays() ([]Relay, error) { +func getRelays() ([]Relay, error) { // Make a GET request to the URL - res, err := http.Get(relayUrl) + client := &http.Client{ + Timeout: 2 * time.Minute, + } + res, err := client.Get(relayUrl) if err != nil { return nil, err } @@ -36,20 +41,20 @@ var ReceiveCmd = &cobra.Command{ Short: "receive file(s), or folder", Long: "receive file(s), or folder from pod or any computer", Run: func(cmd *cobra.Command, args []string) { - relays, err := GetRelays() + log := log.New(os.Stderr, "runpodctl-receive: ", 0) + relays, err := getRelays() if err != nil { - fmt.Println("There was an issue getting the relay list. Please try again.") - return + log.Fatal("There was an issue getting the relay list. Please try again.") + } + sharedSecretCode := args[0] + split := strings.Split(sharedSecretCode, "-") + if len(split) < 5 { + log.Fatalf("Malformed code %q: expected 5 parts separated by dashes, but got %v", sharedSecretCode, len(split)) } - SharedSecret := args[0] - split := strings.Split(SharedSecret, "-") - relayIndexString := split[4] - relayIndex, err := strconv.Atoi(relayIndexString) - + relayIndex, err := strconv.Atoi(split[4]) // relay index if err != nil { - fmt.Println("Malformed relay, please try again.") - return + log.Fatalf("Malformed relay, please try again.") } relay := relays[relayIndex] @@ -62,7 +67,7 @@ var ReceiveCmd = &cobra.Command{ Overwrite: true, RelayAddress: relay.Address, RelayPassword: relay.Password, - SharedSecret: SharedSecret, + SharedSecret: sharedSecretCode, } if crocOptions.RelayAddress != models.DEFAULT_RELAY { @@ -72,18 +77,12 @@ var ReceiveCmd = &cobra.Command{ } cr, err := croc.New(crocOptions) - if err != nil { - fmt.Println(err) - return + log.Fatalf("croc: %v", err) } if err = cr.Receive(); err != nil { - fmt.Println(err) - return - } - + log.Fatalf("croc: receive: %v", err) + } }, } - - diff --git a/cmd/croc/send-ssh.go b/cmd/croc/send-ssh.go new file mode 100644 index 0000000..5d33a2a --- /dev/null +++ b/cmd/croc/send-ssh.go @@ -0,0 +1,62 @@ +package croc + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +const scpHelp = ` +----Summary---- +The built-in scp command, available as part of the POSIX standard, can be used to securely copy files between your local machine +and a runpod instance you already have SSH access to. + +This is not part of runpodctl - we provide this documentation for your convenience only. + +Linux, MacOS, and Windows 10 all come with scp pre-installed. + +--- Quick Start ----- +The following quick-start guide: obtained via the tldr.sh project under the MIT license, provides a brief overview of how to use scp. https://tldr.sh/ + +Secure copy. +Copy files between hosts using Secure Copy Protocol over SSH. +More information: . + +Copy a local file to a remote host: + + scp path/to/local_file remote_host:path/to/remote_file + +Use a specific port when connecting to the remote host: + + scp -P port path/to/local_file remote_host:path/to/remote_file + +Copy a file from a remote host to a local directory: + + scp remote_host:path/to/remote_file path/to/local_directory + +Recursively copy the contents of a directory from a remote host to a local directory: + + scp -r remote_host:path/to/remote_directory path/to/local_directory + +Copy a file between two remote hosts transferring through the local host: + + scp -3 host1:path/to/remote_file host2:path/to/remote_directory + +Use a specific username when connecting to the remote host: + + scp path/to/local_file remote_username@remote_host:path/to/remote_directory + +Use a specific SSH private key for authentication with the remote host: + + scp -i ~/.ssh/private_key path/to/local_file remote_host:path/to/remote_file + +Use a specific proxy when connecting to the remote host: + + scp -J proxy_username@proxy_host path/to/local_file remote_host:path/to/remote_file` + +var SCPHelp = &cobra.Command{ + Use: "scp-help", + Short: "help for using scp (secure copy over SSH)", + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { fmt.Println(scpHelp) }, +} diff --git a/cmd/croc/send.go b/cmd/croc/send.go index 32a4424..21aea13 100644 --- a/cmd/croc/send.go +++ b/cmd/croc/send.go @@ -1,11 +1,14 @@ package croc import ( + "errors" "fmt" + "log" "math/rand" + "os" + "path/filepath" "strconv" "strings" - "time" "github.com/schollz/croc/v9/src/models" "github.com/schollz/croc/v9/src/utils" @@ -27,20 +30,27 @@ var code string var relayUrl = "https://raw.githubusercontent.com/runpod/runpodctl/main/cmd/croc/relays.json" var SendCmd = &cobra.Command{ - Use: "send [filename(s) or folder]", - Args: cobra.ExactArgs(1), + Use: "send [file0] [file1] ...", + Args: cobra.MinimumNArgs(1), Short: "send file(s), or folder", Long: "send file(s), or folder to pod or any computer", - Run: func(cmd *cobra.Command, args []string) { - - rand.Seed(time.Now().UnixNano()) - + Run: func(_ *cobra.Command, args []string) { + log := log.New(os.Stderr, "runpodctl-send: ", 0) + src, err := filepath.Abs(args[0]) + if err != nil { + log.Fatalf("error getting absolute path of %s: %v", args[0], err) + } + switch _, err := os.Stat(src); { + case errors.Is(err, os.ErrNotExist): + log.Fatalf("file or folder %q does not exist", src) + case err != nil: + log.Fatalf("error reading file or folder %q: %v", src, err) + } // Make a GET request to the URL - relays, err := GetRelays() + relays, err := getRelays() if err != nil { - fmt.Println(err) - fmt.Println("Could not get list of relays. Please contact support for help!") - return + log.Print(err) + log.Fatal("Could not get list of relays. Please contact support for help!") } // Choose a random relay from the array @@ -67,20 +77,15 @@ var SendCmd = &cobra.Command{ crocOptions.RelayAddress = "" } - fnames := args - if len(fnames) == 0 { - fmt.Println("must specify file: croc send [filename(s) or folder]") - return - } - if len(crocOptions.SharedSecret) == 0 { // generate code phrase crocOptions.SharedSecret = utils.GetRandomName() } crocOptions.SharedSecret = crocOptions.SharedSecret + "-" + strconv.Itoa(randomIndex) + fmt.Println(crocOptions.SharedSecret) // output to stdout so user or send-ssh can see it - minimalFileInfos, emptyFoldersToTransfer, totalNumberFolders, err := GetFilesInfo(fnames, crocOptions.ZipFolder) + minimalFileInfos, emptyFoldersToTransfer, totalNumberFolders, err := GetFilesInfo(args, crocOptions.ZipFolder) if err != nil { return } diff --git a/cmd/root.go b/cmd/root.go index 4214898..e6de136 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -50,6 +50,7 @@ func registerCommands() { // file transfer via croc rootCmd.AddCommand(croc.ReceiveCmd) rootCmd.AddCommand(croc.SendCmd) + rootCmd.AddCommand(croc.SCPHelp) // Version rootCmd.Version = version