Updater update

This commit is contained in:
2025-05-06 10:15:04 +03:00
parent 3330006c3f
commit 26ac96bdda
6 changed files with 339 additions and 42 deletions

View File

@ -8,19 +8,21 @@ import (
// UpdaterConfig holds the configuration for the updater application
type UpdaterConfig struct {
IP string `json:"ip"`
Port string `json:"port"`
Login string `json:"login"`
Password string `json:"password"`
IP string `json:"ip"`
Port string `json:"port"`
Login string `json:"login"`
Password string `json:"password"`
DownloadURL string `json:"downloadUrl"`
}
// NewUpdaterConfig creates a new updater configuration with default values
func NewUpdaterConfig() *UpdaterConfig {
return &UpdaterConfig{
IP: "127.0.0.1",
Port: "22",
Login: "root",
Password: "",
IP: "127.0.0.1",
Port: "22",
Login: "root",
Password: "",
DownloadURL: "http://example.com/fema/build",
}
}
@ -69,5 +71,5 @@ func SaveUpdaterConfig(config *UpdaterConfig, filePath string) error {
// String returns a string representation of the updater configuration
func (c *UpdaterConfig) String() string {
return fmt.Sprintf("IP: %s\nПорт: %s\nЛогин: %s\nПароль: %s", c.IP, c.Port, c.Login, c.Password)
}
return fmt.Sprintf("IP: %s\nПорт: %s\nЛогин: %s\nПароль: %s\nURL загрузки: %s", c.IP, c.Port, c.Login, c.Password, c.DownloadURL)
}

View File

@ -4,12 +4,21 @@ import (
"fmt"
"io"
"os"
"time"
"github.com/pkg/sftp"
)
// ProgressCallback is a function that reports upload progress
type ProgressCallback func(percentage float64, estimatedTimeRemaining time.Duration)
// UploadFile uploads a local file to a remote server using SFTP
func UploadFile(client *sftp.Client, localPath, remotePath string) error {
return UploadFileWithProgress(client, localPath, remotePath, nil)
}
// UploadFileWithProgress uploads a local file to a remote server using SFTP and reports progress
func UploadFileWithProgress(client *sftp.Client, localPath, remotePath string, progressCallback ProgressCallback) error {
// Open the local file
localFile, err := os.Open(localPath)
if err != nil {
@ -17,6 +26,13 @@ func UploadFile(client *sftp.Client, localPath, remotePath string) error {
}
defer localFile.Close()
// Get file size
fileInfo, err := localFile.Stat()
if err != nil {
return fmt.Errorf("failed to get file info: %w", err)
}
fileSize := fileInfo.Size()
// Create the remote file
remoteFile, err := client.Create(remotePath)
if err != nil {
@ -24,10 +40,54 @@ func UploadFile(client *sftp.Client, localPath, remotePath string) error {
}
defer remoteFile.Close()
// Copy from the local file to the remote file
if _, err = io.Copy(remoteFile, localFile); err != nil {
return fmt.Errorf("failed to upload file: %w", err)
// If no progress callback is provided, just copy the file
if progressCallback == nil {
if _, err = io.Copy(remoteFile, localFile); err != nil {
return fmt.Errorf("failed to upload file: %w", err)
}
return nil
}
// Copy with progress reporting
buffer := make([]byte, 32*1024) // 32KB buffer
var totalBytesWritten int64
startTime := time.Now()
for {
bytesRead, readErr := localFile.Read(buffer)
if bytesRead > 0 {
bytesWritten, writeErr := remoteFile.Write(buffer[:bytesRead])
if writeErr != nil {
return fmt.Errorf("failed to write to remote file: %w", writeErr)
}
totalBytesWritten += int64(bytesWritten)
// Calculate progress percentage
percentage := float64(totalBytesWritten) / float64(fileSize) * 100
// Calculate estimated time remaining
elapsed := time.Since(startTime)
var estimatedTimeRemaining time.Duration
if totalBytesWritten > 0 {
bytesPerSecond := float64(totalBytesWritten) / elapsed.Seconds()
if bytesPerSecond > 0 {
remainingBytes := fileSize - totalBytesWritten
estimatedSeconds := float64(remainingBytes) / bytesPerSecond
estimatedTimeRemaining = time.Duration(estimatedSeconds * float64(time.Second))
}
}
// Report progress
progressCallback(percentage, estimatedTimeRemaining)
}
if readErr != nil {
if readErr == io.EOF {
break
}
return fmt.Errorf("failed to read from local file: %w", readErr)
}
}
return nil
}
}