mirror of
https://github.com/kopia/kopia.git
synced 2026-03-14 20:26:51 -04:00
124 lines
2.6 KiB
Go
124 lines
2.6 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/kopia/kopia/storage"
|
|
|
|
fsstorage "github.com/kopia/kopia/storage/filesystem"
|
|
gcsstorage "github.com/kopia/kopia/storage/gcs"
|
|
"github.com/kopia/kopia/storage/webdav"
|
|
)
|
|
|
|
func newStorageFromURL(ctx context.Context, urlString string) (storage.Storage, error) {
|
|
if strings.HasPrefix(urlString, "/") {
|
|
urlString = "file://" + urlString
|
|
}
|
|
|
|
u, err := url.Parse(urlString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch u.Scheme {
|
|
case "file":
|
|
var fso fsstorage.Options
|
|
if err := parseFilesystemURL(&fso, u); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return fsstorage.New(ctx, &fso)
|
|
|
|
case "gs", "gcs":
|
|
var gcso gcsstorage.Options
|
|
if err := parseGoogleCloudStorageURL(&gcso, u); err != nil {
|
|
return nil, err
|
|
}
|
|
return gcsstorage.New(ctx, &gcso)
|
|
|
|
case "http", "https":
|
|
var wdo webdav.Options
|
|
|
|
if err := parseWebDAVOptions(&wdo, u); err != nil {
|
|
return nil, err
|
|
}
|
|
return webdav.New(ctx, &wdo)
|
|
|
|
default:
|
|
return nil, fmt.Errorf("unrecognized storage type: %v", u.Scheme)
|
|
}
|
|
}
|
|
|
|
func parseFilesystemURL(fso *fsstorage.Options, u *url.URL) error {
|
|
if u.Opaque != "" {
|
|
fso.Path = u.Opaque
|
|
} else {
|
|
fso.Path = u.Path
|
|
}
|
|
if v := connectOwnerUID; v != "" {
|
|
fso.FileUID = getIntPtrValue(v, 10)
|
|
}
|
|
if v := connectOwnerGID; v != "" {
|
|
fso.FileGID = getIntPtrValue(v, 10)
|
|
}
|
|
if v := connectFileMode; v != "" {
|
|
fso.FileMode = getFileModeValue(v, 8)
|
|
}
|
|
if v := connectDirMode; v != "" {
|
|
fso.DirectoryMode = getFileModeValue(v, 8)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func parseGoogleCloudStorageURL(gcso *gcsstorage.Options, u *url.URL) error {
|
|
gcso.BucketName = u.Host
|
|
gcso.Prefix = u.Path
|
|
gcso.ServiceAccountCredentials = connectCredentialsFile
|
|
gcso.ReadOnly = connectReadOnly
|
|
gcso.MaxUploadSpeedBytesPerSecond = connectMaxUploadSpeedBytesPerSecond
|
|
gcso.MaxDownloadSpeedBytesPerSecond = connectMaxDownloadSpeedBytesPerSecond
|
|
|
|
return nil
|
|
}
|
|
|
|
func parseWebDAVOptions(wdo *webdav.Options, u *url.URL) error {
|
|
u2 := *u
|
|
u2.User = nil
|
|
wdo.URL = u2.String()
|
|
if ui := u.User; ui != nil {
|
|
wdo.Username = ui.Username()
|
|
if p, ok := ui.Password(); ok {
|
|
wdo.Password = p
|
|
} else {
|
|
pass, err := askPass("Enter WebDAV password: ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
wdo.Password = pass
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
func getIntPtrValue(value string, base int) *int {
|
|
if int64Val, err := strconv.ParseInt(value, base, 32); err == nil {
|
|
intVal := int(int64Val)
|
|
return &intVal
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getFileModeValue(value string, def os.FileMode) os.FileMode {
|
|
if uint32Val, err := strconv.ParseUint(value, 8, 32); err == nil {
|
|
return os.FileMode(uint32Val)
|
|
}
|
|
|
|
return def
|
|
}
|