mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-03-12 13:29:15 +01:00
205 lines
7.4 KiB
Go
205 lines
7.4 KiB
Go
package fileshare
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/wavetermdev/waveterm/pkg/remote/awsconn"
|
|
"github.com/wavetermdev/waveterm/pkg/remote/connparse"
|
|
"github.com/wavetermdev/waveterm/pkg/remote/fileshare/fstype"
|
|
"github.com/wavetermdev/waveterm/pkg/remote/fileshare/s3fs"
|
|
"github.com/wavetermdev/waveterm/pkg/remote/fileshare/wavefs"
|
|
"github.com/wavetermdev/waveterm/pkg/remote/fileshare/wshfs"
|
|
"github.com/wavetermdev/waveterm/pkg/util/iochan/iochantypes"
|
|
"github.com/wavetermdev/waveterm/pkg/wshrpc"
|
|
"github.com/wavetermdev/waveterm/pkg/wshutil"
|
|
)
|
|
|
|
const (
|
|
ErrorParsingConnection = "error creating fileshare client, could not parse connection %s"
|
|
)
|
|
|
|
// CreateFileShareClient creates a fileshare client based on the connection string
|
|
// Returns the client and the parsed connection
|
|
func CreateFileShareClient(ctx context.Context, connection string) (fstype.FileShareClient, *connparse.Connection) {
|
|
conn, err := connparse.ParseURIAndReplaceCurrentHost(ctx, connection)
|
|
if err != nil {
|
|
log.Printf("error parsing connection: %v", err)
|
|
return nil, nil
|
|
}
|
|
conntype := conn.GetType()
|
|
if conntype == connparse.ConnectionTypeS3 {
|
|
config, err := awsconn.GetConfig(ctx, connection)
|
|
if err != nil {
|
|
log.Printf("error getting aws config: %v", err)
|
|
return nil, nil
|
|
}
|
|
return s3fs.NewS3Client(config), conn
|
|
} else if conntype == connparse.ConnectionTypeWave {
|
|
return wavefs.NewWaveClient(), conn
|
|
} else if conntype == connparse.ConnectionTypeWsh {
|
|
return wshfs.NewWshClient(), conn
|
|
} else {
|
|
log.Printf("unsupported connection type: %s", conntype)
|
|
return nil, nil
|
|
}
|
|
}
|
|
|
|
func Read(ctx context.Context, data wshrpc.FileData) (*wshrpc.FileData, error) {
|
|
log.Printf("Read: %v", data.Info.Path)
|
|
client, conn := CreateFileShareClient(ctx, data.Info.Path)
|
|
if conn == nil || client == nil {
|
|
return nil, fmt.Errorf(ErrorParsingConnection, data.Info.Path)
|
|
}
|
|
return client.Read(ctx, conn, data)
|
|
}
|
|
|
|
func ReadStream(ctx context.Context, data wshrpc.FileData) <-chan wshrpc.RespOrErrorUnion[wshrpc.FileData] {
|
|
log.Printf("ReadStream: %v", data.Info.Path)
|
|
client, conn := CreateFileShareClient(ctx, data.Info.Path)
|
|
if conn == nil || client == nil {
|
|
return wshutil.SendErrCh[wshrpc.FileData](fmt.Errorf(ErrorParsingConnection, data.Info.Path))
|
|
}
|
|
return client.ReadStream(ctx, conn, data)
|
|
}
|
|
|
|
func ReadTarStream(ctx context.Context, data wshrpc.CommandRemoteStreamTarData) <-chan wshrpc.RespOrErrorUnion[iochantypes.Packet] {
|
|
log.Printf("ReadTarStream: %v", data.Path)
|
|
client, conn := CreateFileShareClient(ctx, data.Path)
|
|
if conn == nil || client == nil {
|
|
return wshutil.SendErrCh[iochantypes.Packet](fmt.Errorf(ErrorParsingConnection, data.Path))
|
|
}
|
|
return client.ReadTarStream(ctx, conn, data.Opts)
|
|
}
|
|
|
|
func ListEntries(ctx context.Context, path string, opts *wshrpc.FileListOpts) ([]*wshrpc.FileInfo, error) {
|
|
log.Printf("ListEntries: %v", path)
|
|
client, conn := CreateFileShareClient(ctx, path)
|
|
if conn == nil || client == nil {
|
|
return nil, fmt.Errorf(ErrorParsingConnection, path)
|
|
}
|
|
return client.ListEntries(ctx, conn, opts)
|
|
}
|
|
|
|
func ListEntriesStream(ctx context.Context, path string, opts *wshrpc.FileListOpts) <-chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteListEntriesRtnData] {
|
|
log.Printf("ListEntriesStream: %v", path)
|
|
client, conn := CreateFileShareClient(ctx, path)
|
|
if conn == nil || client == nil {
|
|
return wshutil.SendErrCh[wshrpc.CommandRemoteListEntriesRtnData](fmt.Errorf(ErrorParsingConnection, path))
|
|
}
|
|
return client.ListEntriesStream(ctx, conn, opts)
|
|
}
|
|
|
|
func Stat(ctx context.Context, path string) (*wshrpc.FileInfo, error) {
|
|
log.Printf("Stat: %v", path)
|
|
client, conn := CreateFileShareClient(ctx, path)
|
|
if conn == nil || client == nil {
|
|
return nil, fmt.Errorf(ErrorParsingConnection, path)
|
|
}
|
|
return client.Stat(ctx, conn)
|
|
}
|
|
|
|
func PutFile(ctx context.Context, data wshrpc.FileData) error {
|
|
log.Printf("PutFile: %v", data.Info.Path)
|
|
client, conn := CreateFileShareClient(ctx, data.Info.Path)
|
|
if conn == nil || client == nil {
|
|
return fmt.Errorf(ErrorParsingConnection, data.Info.Path)
|
|
}
|
|
return client.PutFile(ctx, conn, data)
|
|
}
|
|
|
|
func Mkdir(ctx context.Context, path string) error {
|
|
log.Printf("Mkdir: %v", path)
|
|
client, conn := CreateFileShareClient(ctx, path)
|
|
if conn == nil || client == nil {
|
|
return fmt.Errorf(ErrorParsingConnection, path)
|
|
}
|
|
return client.Mkdir(ctx, conn)
|
|
}
|
|
|
|
func Move(ctx context.Context, data wshrpc.CommandFileCopyData) error {
|
|
opts := data.Opts
|
|
if opts == nil {
|
|
opts = &wshrpc.FileCopyOpts{}
|
|
}
|
|
log.Printf("Move: srcuri: %v, desturi: %v, opts: %v", data.SrcUri, data.DestUri, opts)
|
|
srcClient, srcConn := CreateFileShareClient(ctx, data.SrcUri)
|
|
if srcConn == nil || srcClient == nil {
|
|
return fmt.Errorf("error creating fileshare client, could not parse source connection %s", data.SrcUri)
|
|
}
|
|
destClient, destConn := CreateFileShareClient(ctx, data.DestUri)
|
|
if destConn == nil || destClient == nil {
|
|
return fmt.Errorf("error creating fileshare client, could not parse destination connection %s", data.DestUri)
|
|
}
|
|
if srcConn.Host != destConn.Host {
|
|
isDir, err := destClient.CopyRemote(ctx, srcConn, destConn, srcClient, opts)
|
|
if err != nil {
|
|
return fmt.Errorf("cannot copy %q to %q: %w", data.SrcUri, data.DestUri, err)
|
|
}
|
|
return srcClient.Delete(ctx, srcConn, opts.Recursive && isDir)
|
|
} else {
|
|
return srcClient.MoveInternal(ctx, srcConn, destConn, opts)
|
|
}
|
|
}
|
|
|
|
func Copy(ctx context.Context, data wshrpc.CommandFileCopyData) error {
|
|
opts := data.Opts
|
|
if opts == nil {
|
|
opts = &wshrpc.FileCopyOpts{}
|
|
}
|
|
opts.Recursive = true
|
|
log.Printf("Copy: srcuri: %v, desturi: %v, opts: %v", data.SrcUri, data.DestUri, opts)
|
|
srcClient, srcConn := CreateFileShareClient(ctx, data.SrcUri)
|
|
if srcConn == nil || srcClient == nil {
|
|
return fmt.Errorf("error creating fileshare client, could not parse source connection %s", data.SrcUri)
|
|
}
|
|
destClient, destConn := CreateFileShareClient(ctx, data.DestUri)
|
|
if destConn == nil || destClient == nil {
|
|
return fmt.Errorf("error creating fileshare client, could not parse destination connection %s", data.DestUri)
|
|
}
|
|
if srcConn.Host != destConn.Host {
|
|
_, err := destClient.CopyRemote(ctx, srcConn, destConn, srcClient, opts)
|
|
return err
|
|
} else {
|
|
_, err := srcClient.CopyInternal(ctx, srcConn, destConn, opts)
|
|
return err
|
|
}
|
|
}
|
|
|
|
func Delete(ctx context.Context, data wshrpc.CommandDeleteFileData) error {
|
|
log.Printf("Delete: %v", data)
|
|
client, conn := CreateFileShareClient(ctx, data.Path)
|
|
if conn == nil || client == nil {
|
|
return fmt.Errorf(ErrorParsingConnection, data.Path)
|
|
}
|
|
return client.Delete(ctx, conn, data.Recursive)
|
|
}
|
|
|
|
func Join(ctx context.Context, path string, parts ...string) (*wshrpc.FileInfo, error) {
|
|
log.Printf("Join: %v", path)
|
|
client, conn := CreateFileShareClient(ctx, path)
|
|
if conn == nil || client == nil {
|
|
return nil, fmt.Errorf(ErrorParsingConnection, path)
|
|
}
|
|
return client.Join(ctx, conn, parts...)
|
|
}
|
|
|
|
func Append(ctx context.Context, data wshrpc.FileData) error {
|
|
log.Printf("Append: %v", data.Info.Path)
|
|
client, conn := CreateFileShareClient(ctx, data.Info.Path)
|
|
if conn == nil || client == nil {
|
|
return fmt.Errorf(ErrorParsingConnection, data.Info.Path)
|
|
}
|
|
return client.AppendFile(ctx, conn, data)
|
|
}
|
|
|
|
func GetCapability(ctx context.Context, path string) (wshrpc.FileShareCapability, error) {
|
|
log.Printf("GetCapability: %v", path)
|
|
client, conn := CreateFileShareClient(ctx, path)
|
|
if conn == nil || client == nil {
|
|
return wshrpc.FileShareCapability{}, fmt.Errorf(ErrorParsingConnection, path)
|
|
}
|
|
return client.GetCapability(), nil
|
|
}
|