mirror of
https://github.com/restic/restic.git
synced 2025-03-16 00:00:05 +01:00
Add unrelease issue and cleanup configs
Removed extra environment variables
This commit is contained in:
parent
8a7006d12c
commit
46c3dc618a
7 changed files with 41 additions and 84 deletions
7
changelog/unreleased/issue-4185
Normal file
7
changelog/unreleased/issue-4185
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Enhancement: SMB backend: Add SMB backend
|
||||||
|
|
||||||
|
Restic now supports SMB/CIFS backend. You can now add a SMB repository as `-r smb://<host>:<port>/<sharename>/<path>`.
|
||||||
|
|
||||||
|
You can configure the SMB user name (for NTLM authentication) via the environment variable `RESTIC_SMB_USER`, SMB password via the environment variable `RESTIC_SMB_PASSWORD` and optionally SMB domain via the environment variable `RESTIC_SMB_DOMAIN`(default:'WORKGROUP').
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/4185
|
|
@ -704,57 +704,6 @@ func parseConfig(loc location.Location, opts options.Options) (interface{}, erro
|
||||||
cfg.Domain = smb.DefaultDomain
|
cfg.Domain = smb.DefaultDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
//0 is an acceptable value for timeout, hence using -1 as the default unset value.
|
|
||||||
if cfg.IdleTimeout == nil {
|
|
||||||
it := os.Getenv("RESTIC_SMB_IDLETIMEOUTSECS")
|
|
||||||
if it == "" {
|
|
||||||
timeout := smb.DefaultIdleTimeout
|
|
||||||
cfg.IdleTimeout = &timeout
|
|
||||||
} else {
|
|
||||||
t, err := strconv.Atoi(it)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
timeout := (time.Duration(int64(t) * int64(time.Second)))
|
|
||||||
cfg.IdleTimeout = &timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Connections == 0 {
|
|
||||||
c := os.Getenv("RESTIC_SMB_CONNECTIONS")
|
|
||||||
if c == "" {
|
|
||||||
cfg.Connections = smb.DefaultConnections
|
|
||||||
} else {
|
|
||||||
con, err := strconv.Atoi(c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cfg.Connections = uint(con)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.RequireMessageSigning == nil {
|
|
||||||
v := os.Getenv("RESTIC_SMB_REQUIRE_MESSAGESIGNING")
|
|
||||||
rms := strings.ToLower(v) == "true"
|
|
||||||
cfg.RequireMessageSigning = &rms
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.ClientGuid == "" {
|
|
||||||
c := os.Getenv("RESTIC_SMB_CLIENTGUID")
|
|
||||||
cfg.ClientGuid = c
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.Dialect == 0 {
|
|
||||||
d := os.Getenv("RESTIC_SMB_DIALECT")
|
|
||||||
if d != "" {
|
|
||||||
v, err := strconv.Atoi(d)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cfg.Dialect = uint16(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debug.Log("opening smb repository at %#v", cfg)
|
debug.Log("opening smb repository at %#v", cfg)
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,16 @@ type Config struct {
|
||||||
ShareName string
|
ShareName string
|
||||||
Path string
|
Path string
|
||||||
|
|
||||||
Layout string `option:"layout" help:"use this backend directory layout (default: auto-detect)"`
|
User string `option:"user" help:"specify the SMB user for NTLM authentication."`
|
||||||
Connections uint `option:"connections" help:"set a limit for the number of concurrent operations (default: 2)"`
|
Password options.SecretString `option:"password" help:"specify the SMB password for NTLM authentication."`
|
||||||
IdleTimeout *time.Duration `option:"idle-timeout" help:"Max time in seconds before closing idle connections. If no connections have been returned to the connection pool in the time given, the connection pool will be emptied. Set to 0 to keep connections indefinitely.(default: 60)"`
|
Domain string `option:"domain" help:"specify the domain for authentication."`
|
||||||
RequireMessageSigning *bool `option:"require-message-signing" help:"Mandates message signing otherwise does not allow the connection. If this is false, messaging signing is just enabled and not enforced. (default: false)"`
|
|
||||||
Dialect uint16 `option:"dialect" help:"Force a specific dialect to be used. SMB311:785, SMB302:770, SMB300:768, SMB210:528, SMB202:514, SMB2:767. If unspecfied (0), following dialects are tried in order - SMB311, SMB302, SMB300, SMB210, SMB202 (default: 0)"`
|
|
||||||
ClientGuid string `option:"client-guid" help:"A 16-byte GUID to uniquely identify a client. If not specific a random GUID is used. (default: \"\")"`
|
|
||||||
|
|
||||||
User string `option:"user"`
|
Layout string `option:"layout" help:"use this backend directory layout (default: auto-detect)"`
|
||||||
Password options.SecretString `option:"password"`
|
Connections uint `option:"connections" help:"set a limit for the number of concurrent operations (default: 2)"`
|
||||||
Domain string `option:"domain"`
|
IdleTimeout time.Duration `option:"idle-timeout" help:"Max time in seconds before closing idle connections. If no connections have been returned to the connection pool in the time given, the connection pool will be emptied. Set to 0 to keep connections indefinitely.(default: 60)"`
|
||||||
|
RequireMessageSigning bool `option:"require-message-signing" help:"Mandates message signing otherwise does not allow the connection. If this is false, messaging signing is just enabled and not enforced. (default: false)"`
|
||||||
|
Dialect uint16 `option:"dialect" help:"Force a specific dialect to be used. SMB311:785, SMB302:770, SMB300:768, SMB210:528, SMB202:514, SMB2:767. If unspecfied (0), following dialects are tried in order - SMB311, SMB302, SMB300, SMB210, SMB202 (default: 0)"`
|
||||||
|
ClientGuid string `option:"client-guid" help:"A 16-byte GUID to uniquely identify a client. If not specific a random GUID is used. (default: \"\")"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -39,7 +39,10 @@ const (
|
||||||
// NewConfig returns a new Config with the default values filled in.
|
// NewConfig returns a new Config with the default values filled in.
|
||||||
func NewConfig() Config {
|
func NewConfig() Config {
|
||||||
return Config{
|
return Config{
|
||||||
Port: DefaultSmbPort,
|
Port: DefaultSmbPort,
|
||||||
|
Domain: DefaultDomain,
|
||||||
|
IdleTimeout: DefaultIdleTimeout,
|
||||||
|
Connections: DefaultConnections,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,16 +10,22 @@ var configTests = []struct {
|
||||||
cfg Config
|
cfg Config
|
||||||
}{
|
}{
|
||||||
{"smb://shareaddress/sharename/directory", Config{
|
{"smb://shareaddress/sharename/directory", Config{
|
||||||
Address: "shareaddress",
|
Address: "shareaddress",
|
||||||
Port: DefaultSmbPort,
|
Port: DefaultSmbPort,
|
||||||
ShareName: "sharename",
|
ShareName: "sharename",
|
||||||
Path: "directory",
|
Path: "directory",
|
||||||
|
Domain: DefaultDomain,
|
||||||
|
Connections: DefaultConnections,
|
||||||
|
IdleTimeout: DefaultIdleTimeout,
|
||||||
}},
|
}},
|
||||||
{"smb://shareaddress:456/sharename/directory", Config{
|
{"smb://shareaddress:456/sharename/directory", Config{
|
||||||
Address: "shareaddress",
|
Address: "shareaddress",
|
||||||
Port: 456,
|
Port: 456,
|
||||||
ShareName: "sharename",
|
ShareName: "sharename",
|
||||||
Path: "directory",
|
Path: "directory",
|
||||||
|
Domain: DefaultDomain,
|
||||||
|
Connections: DefaultConnections,
|
||||||
|
IdleTimeout: DefaultIdleTimeout,
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,13 +75,9 @@ func (b *Backend) dial(ctx context.Context, network, addr string) (*conn, error)
|
||||||
copy(clientId[:], []byte(b.ClientGuid))
|
copy(clientId[:], []byte(b.ClientGuid))
|
||||||
}
|
}
|
||||||
|
|
||||||
rms := b.RequireMessageSigning != nil
|
|
||||||
if rms {
|
|
||||||
rms = *b.RequireMessageSigning
|
|
||||||
}
|
|
||||||
d := &smb2.Dialer{
|
d := &smb2.Dialer{
|
||||||
Negotiator: smb2.Negotiator{
|
Negotiator: smb2.Negotiator{
|
||||||
RequireMessageSigning: rms,
|
RequireMessageSigning: b.RequireMessageSigning,
|
||||||
SpecifiedDialect: b.Dialect,
|
SpecifiedDialect: b.Dialect,
|
||||||
ClientGuid: clientId,
|
ClientGuid: clientId,
|
||||||
},
|
},
|
||||||
|
@ -193,9 +189,7 @@ func (b *Backend) putConnection(pc **conn) {
|
||||||
|
|
||||||
b.poolMu.Lock()
|
b.poolMu.Lock()
|
||||||
b.pool = append(b.pool, c)
|
b.pool = append(b.pool, c)
|
||||||
if b.Config.IdleTimeout != nil && *b.Config.IdleTimeout > 0 {
|
b.drain.Reset(b.Config.IdleTimeout) // nudge on the pool emptying timer
|
||||||
b.drain.Reset(*b.Config.IdleTimeout) // nudge on the pool emptying timer
|
|
||||||
}
|
|
||||||
b.poolMu.Unlock()
|
b.poolMu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,12 +199,10 @@ func (b *Backend) drainPool() (err error) {
|
||||||
defer b.poolMu.Unlock()
|
defer b.poolMu.Unlock()
|
||||||
if sessions := b.getSessions(); sessions != 0 {
|
if sessions := b.getSessions(); sessions != 0 {
|
||||||
debug.Log("Not closing %d unused connections as %d sessions active", len(b.pool), sessions)
|
debug.Log("Not closing %d unused connections as %d sessions active", len(b.pool), sessions)
|
||||||
if b.Config.IdleTimeout != nil && *b.Config.IdleTimeout > 0 {
|
b.drain.Reset(b.Config.IdleTimeout) // nudge on the pool emptying timer
|
||||||
b.drain.Reset(*b.Config.IdleTimeout) // nudge on the pool emptying timer
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if b.Config.IdleTimeout != nil && *b.Config.IdleTimeout > 0 {
|
if b.Config.IdleTimeout > 0 {
|
||||||
b.drain.Stop()
|
b.drain.Stop()
|
||||||
}
|
}
|
||||||
if len(b.pool) != 0 {
|
if len(b.pool) != 0 {
|
||||||
|
|
|
@ -66,8 +66,8 @@ func open(ctx context.Context, cfg Config) (*Backend, error) {
|
||||||
debug.Log("open, config %#v", cfg)
|
debug.Log("open, config %#v", cfg)
|
||||||
|
|
||||||
// set the pool drainer timer going
|
// set the pool drainer timer going
|
||||||
if b.Config.IdleTimeout != nil && *b.Config.IdleTimeout > 0 {
|
if b.Config.IdleTimeout > 0 {
|
||||||
b.drain = time.AfterFunc(*b.Config.IdleTimeout, func() { _ = b.drainPool() })
|
b.drain = time.AfterFunc(b.Config.IdleTimeout, func() { _ = b.drainPool() })
|
||||||
}
|
}
|
||||||
|
|
||||||
cn, err := b.getConnection(ctx, b.ShareName)
|
cn, err := b.getConnection(ctx, b.ShareName)
|
||||||
|
|
|
@ -25,7 +25,7 @@ func newTestSuite(t testing.TB) *test.Suite {
|
||||||
cfg.Password = options.NewSecretString("mGoWwqvgdnwtmh07")
|
cfg.Password = options.NewSecretString("mGoWwqvgdnwtmh07")
|
||||||
cfg.Connections = smb.DefaultConnections
|
cfg.Connections = smb.DefaultConnections
|
||||||
timeout := smb.DefaultIdleTimeout
|
timeout := smb.DefaultIdleTimeout
|
||||||
cfg.IdleTimeout = &timeout
|
cfg.IdleTimeout = timeout
|
||||||
cfg.Domain = smb.DefaultDomain
|
cfg.Domain = smb.DefaultDomain
|
||||||
|
|
||||||
t.Logf("create new backend at %v", cfg.Address+"/"+cfg.ShareName)
|
t.Logf("create new backend at %v", cfg.Address+"/"+cfg.ShareName)
|
||||||
|
|
Loading…
Add table
Reference in a new issue