feat: [WIP] implement scp by bgo

This commit is contained in:
2026-06-12 14:12:11 +08:00
parent 3cd92945ac
commit 250ba269f5
5 changed files with 278 additions and 21 deletions
+31 -17
View File
@@ -10,12 +10,12 @@ package domain
// endpoint, etc.).
//
// Field design notes:
// - PathPrefix supports object name templating so users can group screenshots
// by date.
// - PublicURLBase is optional to support CDN-fronted buckets; otherwise the
// adapter falls back to "{Endpoint}/{Bucket}/{Key}" (path-style).
// - UsePathStyle defaults to true because many self-hosted MinIO / R2
// deployments do not support virtual-hosted-style addressing.
// - PathPrefix supports object name templating so users can group screenshots
// by date.
// - PublicURLBase is optional to support CDN-fronted buckets; otherwise the
// adapter falls back to "{Endpoint}/{Bucket}/{Key}" (path-style).
// - UsePathStyle defaults to true because many self-hosted MinIO / R2
// deployments do not support virtual-hosted-style addressing.
type S3Config struct {
Endpoint string `json:"endpoint"`
Region string `json:"region"`
@@ -34,17 +34,22 @@ type S3Config struct {
// - Host / Port form the destination endpoint. Port defaults to 22 when 0.
// - User is the SSH login name.
// - AuthMethod selects how the connection authenticates:
// "password" → password only, via the in-process Go SSH client.
// "key" → ssh-agent + ~/.ssh/id_* key files (no password),
// via the in-process Go SSH client.
// "kerberos" → delegate to the system /usr/bin/ssh binary so the
// existing Kerberos (GSSAPI) credential cache from
// `kinit` is reused. Native GSSAPI is required here
// because macOS stores tickets in an API: ccache
// that pure-Go SSH libraries cannot read.
// "" / "builtin" → legacy combined behaviour (password → agent → key
// files) kept only for backward compatibility with
// configs written before the method was split.
// "password" → password only, via the in-process Go SSH client.
// "key" → ssh-agent + ~/.ssh/id_* key files (no password),
// via the in-process Go SSH client.
// "kerberos" → delegate to the system /usr/bin/ssh binary so the
// existing Kerberos (GSSAPI) credential cache from
// `kinit` is reused. Native GSSAPI is required here
// because macOS stores tickets in an API: ccache
// that pure-Go SSH libraries cannot read.
// "bgo" delegate to the internal `bgo scp` client which
// handles its own auth/credential management. bgo
// must run under a PTY and cannot create remote
// directories, so this mode uploads to the user's
// remote $HOME with a flat, timestamped filename.
// "" / "builtin" → legacy combined behaviour (password → agent → key
// files) kept only for backward compatibility with
// configs written before the method was split.
// - Password is optional; when empty the implementation falls back to the
// local SSH agent or ~/.ssh/id_* keys (i.e. the user is responsible for
// having password-less access already configured on this machine).
@@ -85,6 +90,10 @@ const (
// SSHAuthKerberos delegates to the system ssh binary so an existing
// Kerberos credential cache (populated by `kinit`) is reused via GSSAPI.
SSHAuthKerberos = "kerberos"
// SSHAuthBgo delegates to the internal `bgo scp` client, which manages
// its own authentication. bgo requires a PTY and cannot create remote
// directories, so uploads land flat in the remote $HOME.
SSHAuthBgo = "bgo"
)
// IsKerberos reports whether this config requests Kerberos/GSSAPI auth.
@@ -92,6 +101,11 @@ func (c SSHConfig) IsKerberos() bool {
return c.AuthMethod == SSHAuthKerberos
}
// IsBgo reports whether this config requests the internal bgo client.
func (c SSHConfig) IsBgo() bool {
return c.AuthMethod == SSHAuthBgo
}
// AppConfig is the top-level on-disk configuration document.
//
// We keep S3 / SSH nested so that adding more providers later (e.g. AliyunOSS,