2016-09-21 8:31 GMT+09:00 Paul Borman <bor...@google.com>: > For cancellation you run the actual operation in a goroutine and return > results on a channel. You can then select on the Deadline from the context > and the returned result. If the deadline hits, you just shut down the SSH > session. Does that make sense?
Yes, thank you for your explanation! I'll try to implement it in my spare time. Thanks Hiroaki Nakamura > > -Paul > > On Tue, Sep 20, 2016 at 3:36 PM, Hiroaki Nakamura <hnaka...@gmail.com> > wrote: >> >> 2016-09-21 0:59 GMT+09:00 Paul Borman <bor...@google.com>: >> > I would suggest just putting your package out there and see how it is >> > received. At some point, if it becomes the defacto package, moving it >> > might >> > make sense. >> >> OK, I understood. >> >> > >> > I actually wrote an internal SCP package that works with a ssh >> > multiplexer >> > built on top of crypto/ssh. For various reasons, I am not in a position >> > to >> > OpenSource the package. >> >> I hope your SCP package will be released as an OpenSource. >> >> > >> > It provides a NewSCP that returns an SCP object. You provide NewSCP >> > with a >> > configuration structure that specifies optional default timestamps, >> > mode, if >> > -p should be used, and if Start or Shell should be used to make the >> > session >> > (some SSH servers do not support exec mode (Start)). >> > >> > The SCP type only has 3 methods (and one is actually a convenience >> > wrapper): >> > >> > func (*SCP) Send(ctx context.Context, dst string, srcs ...string) error >> > >> > Send sends the srcs to dst. If srcs has a length greater than 1, or any >> > of >> > the srcs is a Directory, dst must reference a directory on the remote >> > host. >> > Send returns any errors encountered. If an error is returned, it may >> > contain >> > multiple errors. User Errors(err) to retrieve the list of errors. >> > >> > func (*SCP) Receive(ctx context.Context, src string, f func(*Incoming) >> > error) error >> > >> > Receive requests the directory or file src from the remote host. For >> > each >> > directory and file in src, f is called with a populated Incoming >> > structure. >> > If IsDir is not set then f must either populate W or return an error. In >> > any >> > event, if f returns an error then that file or directory's transfer is >> > stopped. If the returned error is wrapped by Fatal{}, the entire SCP >> > session >> > is shutdown. >> > >> > type Incoming struct { >> > Path string // Name of file on remote host >> > Mode os.FileMode // Mode of the file on the remote host >> > MTime time.Time // Last modified time from the remote host >> > ATime time.Time // Last access time from the remote host >> > Length int64 // Length of incoming file >> > IsDir bool // Set if receiving a directory >> > WErr error // Error encountered during write, if any >> > W io.Writer // Destination for read data >> > NoClose bool // Do not close W when finished. >> > } >> > >> > Incoming is where to send information about a file or directory. When an >> > Incoming is provided to ReceiveFile, W must be set and IsDir must not be >> > set. If the set W also implements io.Closer, W.Close is called after the >> > fimal write to W, unless NoClose is set. NoClose is normally only set >> > when >> > using a single io.Writer for all data (such as os.Stdout). >> > >> > The convenience function is: >> > >> > func (*SCP) ReceiveFile(ctx context.Context, in *Incoming, src string) >> > error >> > >> > ReceiveFile requests the remote host send the file named src. >> > ReceiveFile >> > writes the received contents to in.W. Path, Mode, MTime and ATime are >> > set >> > prior to the first write to in.W. MTime and ATime may be the zero value >> > for >> > time.Time if not provided by the remote host. >> > >> > If there is an error writing to in.W, in.WErr is set to the error. >> > in.WErr >> > is only valid after ReceiveFile returns. If there is an error receiving >> > the >> > file from the remote host, it is returned. >> > >> > You could easily imagine a wrapper that called Receive and provided an >> > internal function that did whatever needed to be done, or even a stock >> > function that can be passed to Receive. >> > >> > I hope this is helpful. >> >> Thanks for the spec about your SCP package. >> I think it is more general than mine. >> >> However most of my cases are copy a single file or a directory, >> so I think I'd keep my APIs for the moment. >> >> I added NewSCP and SCP >> >> https://github.com/hnakamur/go-scp/commit/b43795fc10ef52b02a76653b643fa5aabb7b85a7 >> >> One thing I would like to add is the cancellation support using >> context.Context. >> However ssh.Run does not take a context.Context as an argument, >> so I don't know how to achieve that. >> https://godoc.org/golang.org/x/crypto/ssh#Session.Run >> >> Could you tell me how you implement the cancellation? >> >> Thanks, >> Hiroaki Nakamura >> >> > >> > -Paul >> > >> > On Tue, Sep 20, 2016 at 6:47 AM, Hiroaki Nakamura <hnaka...@gmail.com> >> > wrote: >> >> >> >> Hi Paul, >> >> Thanks for your feedback! >> >> >> >> 2016-09-20 0:02 GMT+09:00 Paul Borman <bor...@google.com>: >> >> > Adding an scp package is a nice addition. >> >> >> >> I agree. >> >> Should I send a pull request to https://github.com/golang/crypto? >> >> If yes, what package? golang.org/x/crypto/scp or >> >> golang.org/x/crypto/ssh/scp? >> >> >> >> > You might want to consider simple names like: >> >> > >> >> > Send - Sends from []byte to file on remote host >> >> > SendDir - Send files in dir to a remote host >> >> > SendFile - Sends the contents of a file to the remote host >> >> > Fetch - Fetches the contents of a file on remote host into memory >> >> > FetchFile - Fetches a file from remote host into file on local host >> >> > FetchDir - Fetches the files in a directory from the remote host >> >> > >> >> > These would translate in code to names like scp.SendFile, which is >> >> > pretty >> >> > descriptive all by itself. >> >> >> >> Thanks for simple and descriptive function names. >> >> I renamed functions. >> >> >> >> >> >> https://github.com/hnakamur/go-scp/commit/8cd6d9e5ab17187556e5efc3a666d29b4b561c78 >> >> >> >> > >> >> > For the directory copy, it might be better to have a function return >> >> > the >> >> > io.Writer to write the file to, rather than force the files into a >> >> > directory. This would make it easy to keep the contents in memory, >> >> > change >> >> > file names, or whatever. >> >> >> >> Yes, I agree it might be better not to force the files in a directory. >> >> However I don't think having a function return the io.Writer will do >> >> since we need to read a reply for each scp protocol header or body. >> >> >> >> I had read the article below and the openssh source code and >> >> implemented my scp package https://github.com/hnakamur/go-scp. >> >> >> >> "How the SCP protocol works (Jan Pechanec's weblog)" >> >> https://blogs.oracle.com/janp/entry/how_the_scp_protocol_works >> >> >> >> I built two structs sourceProtocol and sinkProtocol >> >> https://github.com/hnakamur/go-scp/blob/master/protocol.go >> >> >> >> I had thought to export these structs or make interfaces for that. >> >> However the implementation of two functions SendDir and FetchDir >> >> which using these structs become somewhat complex. >> >> >> >> >> >> >> >> https://github.com/hnakamur/go-scp/blob/8cd6d9e5ab17187556e5efc3a666d29b4b561c78/source.go#L81-L175 >> >> >> >> >> >> https://github.com/hnakamur/go-scp/blob/8cd6d9e5ab17187556e5efc3a666d29b4b561c78/sink.go#L111-L223 >> >> >> >> So I was not confident about exporting sourceProtocol and sinkProtocol, >> >> and I did not export them at the time. >> >> >> >> If we can define structs, functions or interfaces which are easy to >> >> use, >> >> I'm glad to export them. >> >> >> >> Do you have an idea about such structs, functions or interfaces? >> >> Thanks! >> >> >> >> Hiroaki Nakamura >> >> >> >> > >> >> > On Fri, Sep 16, 2016 at 9:41 AM, Hiroaki Nakamura >> >> > <hnaka...@gmail.com> >> >> > wrote: >> >> >> >> >> >> Hi all, >> >> >> >> >> >> I noticed the golang.org/x/crypto/ssh package exists, but the scp >> >> >> package does not. >> >> >> So I wrote a scp client library in go. >> >> >> https://github.com/hnakamur/go-scp >> >> >> >> >> >> I also wrote a sshd server just usable for testing go-scp. >> >> >> https://github.com/hnakamur/go-sshd >> >> >> >> >> >> Right now, go-scp only exports high level functions which are >> >> >> supposed >> >> >> to be easy to use. >> >> >> https://godoc.org/github.com/hnakamur/go-scp >> >> >> >> >> >> However I wonder if there APIs can be improved. For example, >> >> >> better function names and better arguments. >> >> >> >> >> >> Could you tell me what you think? >> >> >> Thanks! >> >> >> >> >> >> Hiroaki Nakamura >> >> >> >> >> >> -- >> >> >> You received this message because you are subscribed to the Google >> >> >> Groups >> >> >> "golang-nuts" group. >> >> >> To unsubscribe from this group and stop receiving emails from it, >> >> >> send >> >> >> an >> >> >> email to golang-nuts+unsubscr...@googlegroups.com. >> >> >> For more options, visit https://groups.google.com/d/optout. >> >> > >> >> > >> > >> > > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.