add:partial functionality
This commit is contained in:
53
internal/services/commands.go
Normal file
53
internal/services/commands.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
const defaultPort = "22"
|
||||
const defaultStoragePath = "~/.filepass_storage"
|
||||
|
||||
func serverPort(s Server) string {
|
||||
if s.Port == "" {
|
||||
return defaultPort
|
||||
}
|
||||
return s.Port
|
||||
}
|
||||
|
||||
// SSHCmd returns an exec.Cmd for running a single command on the server.
|
||||
func SSHCmd(s Server, remoteCmd string) *exec.Cmd {
|
||||
return exec.Command(
|
||||
"ssh",
|
||||
"-i", s.PrivateKey,
|
||||
"-p", serverPort(s),
|
||||
"-o", "StrictHostKeyChecking=no",
|
||||
"-o", "BatchMode=yes",
|
||||
s.User+"@"+s.Host,
|
||||
remoteCmd,
|
||||
)
|
||||
}
|
||||
|
||||
// RsyncCmd returns an exec.Cmd for an rsync transfer.
|
||||
// src and dst follow standard rsync syntax (local path or user@host:path).
|
||||
func RsyncCmd(s Server, src, dst string) *exec.Cmd {
|
||||
sshFlag := "ssh -i " + s.PrivateKey + " -p " + serverPort(s) +
|
||||
" -o StrictHostKeyChecking=no -o BatchMode=yes"
|
||||
return exec.Command(
|
||||
"rsync",
|
||||
"-avz",
|
||||
"--partial",
|
||||
"-e", sshFlag,
|
||||
src,
|
||||
dst,
|
||||
)
|
||||
}
|
||||
|
||||
// RemotePath returns the full remote path for a filename inside storage.
|
||||
func RemotePath(s Server, filename string) string {
|
||||
return s.User + "@" + s.Host + ":" + defaultStoragePath + "/" + filename
|
||||
}
|
||||
|
||||
// RemoteStorageRoot returns the remote storage root for rsync operations.
|
||||
func RemoteStorageRoot(s Server) string {
|
||||
return s.User + "@" + s.Host + ":" + defaultStoragePath + "/"
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package services
|
||||
|
||||
import "fmt"
|
||||
|
||||
type ServicesStore struct {
|
||||
Config *ConfigService
|
||||
}
|
||||
@@ -11,3 +13,11 @@ func NewServicesStore() (*ServicesStore, error) {
|
||||
}
|
||||
return &ServicesStore{Config: cfg}, nil
|
||||
}
|
||||
|
||||
func (s *ServicesStore) NewStorageService(serverName string) (*StorageService, error) {
|
||||
srv, ok := s.Config.servers[serverName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("server %q not found", serverName)
|
||||
}
|
||||
return NewStorageService(srv), nil
|
||||
}
|
||||
|
||||
52
internal/services/storage.go
Normal file
52
internal/services/storage.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// StorageService executes file operations against a single server's storage.
|
||||
type StorageService struct {
|
||||
server Server
|
||||
}
|
||||
|
||||
func NewStorageService(s Server) *StorageService {
|
||||
return &StorageService{server: s}
|
||||
}
|
||||
|
||||
// Check returns the list of files currently in the remote storage directory.
|
||||
func (s *StorageService) Check() ([]string, error) {
|
||||
cmd := SSHCmd(s.server,
|
||||
"find "+defaultStoragePath+" -type f -printf '%f\n' 2>/dev/null",
|
||||
)
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("check failed: %w", err)
|
||||
}
|
||||
raw := strings.TrimSpace(string(out))
|
||||
if raw == "" {
|
||||
return []string{}, nil
|
||||
}
|
||||
return strings.Split(raw, "\n"), nil
|
||||
}
|
||||
|
||||
// Send transfers one or more local files to the remote storage.
|
||||
// Multiple files are archived into a temp tarball first.
|
||||
func (s *StorageService) Send(localPaths []string) error {
|
||||
// TODO: implement
|
||||
return fmt.Errorf("send: not yet implemented")
|
||||
}
|
||||
|
||||
// Get downloads one or more files from remote storage to destDir.
|
||||
// Multiple files are archived server-side, transferred, then extracted.
|
||||
func (s *StorageService) Get(remoteFiles []string, destDir string) error {
|
||||
// TODO: implement
|
||||
return fmt.Errorf("get: not yet implemented")
|
||||
}
|
||||
|
||||
// Clean removes specific files from remote storage.
|
||||
// Pass a nil or empty slice to remove all files.
|
||||
func (s *StorageService) Clean(remoteFiles []string) error {
|
||||
// TODO: implement
|
||||
return fmt.Errorf("clean: not yet implemented")
|
||||
}
|
||||
Reference in New Issue
Block a user