package kopia import ( "backea/internal/logging" "context" "fmt" "os" "os/exec" "path/filepath" ) // SFTPProvider implements the Provider interface for SFTP remote storage type SFTPProvider struct { Host string BasePath string Username string KeyFile string logger *logging.Logger } // NewSFTPProvider creates a new SFTP provider func NewSFTPProvider(host, basePath, username, keyFile string) *SFTPProvider { return &SFTPProvider{ Host: host, BasePath: basePath, Username: username, KeyFile: keyFile, logger: logging.GetLogger(), } } func (p *SFTPProvider) Connect(ctx context.Context, serviceName string, password string, configPath string) error { repoPath := fmt.Sprintf("%s/%s", p.BasePath, serviceName) knownHostsPath := filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts") connectCmd := exec.CommandContext( ctx, "kopia", "--config-file", configPath, "repository", "connect", "sftp", "--path", repoPath, "--host", p.Host, "--username", p.Username, "--keyfile", p.KeyFile, "--known-hosts", knownHostsPath, "--password", password, ) err := connectCmd.Run() if err != nil { p.logger.Info("Creating new SFTP repository for %s at %s", serviceName, repoPath) createCmd := exec.CommandContext( ctx, "kopia", "--config-file", configPath, "repository", "create", "sftp", "--path", repoPath, "--host", p.Host, "--username", p.Username, "--keyfile", p.KeyFile, "--known-hosts", knownHostsPath, "--password", password, ) createOutput, err := createCmd.CombinedOutput() if err != nil { return NewKopiaError(fmt.Sprintf("failed to create SFTP repository: %s", string(createOutput)), err) } } return nil } // GetRepositoryParams returns parameters for SFTP operations func (p *SFTPProvider) GetRepositoryParams(serviceName string) ([]string, error) { repoPath := fmt.Sprintf("%s@%s:%s/%s", p.Username, p.Host, p.BasePath, serviceName) knownHostsPath := filepath.Join(os.Getenv("HOME"), ".ssh", "known_hosts") return []string{ "sftp", "--path", repoPath, "--keyfile", p.KeyFile, "--known-hosts", knownHostsPath, }, nil } // GetBucketName returns the path for a service func (p *SFTPProvider) GetBucketName(serviceName string) string { return fmt.Sprintf("%s/%s", p.BasePath, serviceName) } // GetProviderType returns the provider type identifier func (p *SFTPProvider) GetProviderType() string { return "sftp" }