mirror of
https://github.com/kopia/kopia.git
synced 2026-05-11 00:04:46 -04:00
Remove unused-parameter exclusion for `ctx` in revive linter. --------- Signed-off-by: Matthieu MOREL <matthieu.morel35@gmail.com> Co-authored-by: Matthieu MOREL <matthieu.morel35@gmail.com>
164 lines
4.4 KiB
Go
164 lines
4.4 KiB
Go
package format
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/kopia/kopia/internal/gather"
|
|
"github.com/kopia/kopia/repo/content/index"
|
|
"github.com/kopia/kopia/repo/ecc"
|
|
"github.com/kopia/kopia/repo/encryption"
|
|
"github.com/kopia/kopia/repo/hashing"
|
|
)
|
|
|
|
const (
|
|
minValidPackSize = 10 << 20
|
|
maxValidPackSize = 120 << 20
|
|
|
|
// CurrentWriteVersion is the version of the repository applied to new repositories.
|
|
CurrentWriteVersion = FormatVersion3
|
|
|
|
// MinSupportedWriteVersion is the minimum version that this kopia client can write.
|
|
MinSupportedWriteVersion = FormatVersion1
|
|
|
|
// MaxSupportedWriteVersion is the maximum version that this kopia client can write.
|
|
MaxSupportedWriteVersion = FormatVersion3
|
|
|
|
// MinSupportedReadVersion is the minimum version that this kopia client can read.
|
|
MinSupportedReadVersion = FormatVersion1
|
|
|
|
// MaxSupportedReadVersion is the maximum version that this kopia client can read.
|
|
MaxSupportedReadVersion = FormatVersion3
|
|
|
|
legacyIndexVersion = index.Version1
|
|
)
|
|
|
|
// Version denotes content format version.
|
|
type Version int
|
|
|
|
// Supported format versions.
|
|
const (
|
|
FormatVersion1 Version = 1
|
|
FormatVersion2 Version = 2 // new in v0.9
|
|
FormatVersion3 Version = 3 // new in v0.11
|
|
|
|
MaxFormatVersion = FormatVersion3
|
|
)
|
|
|
|
// Provider provides current formatting options. The options returned
|
|
// should not be cached for more than a few seconds as they are subject to change.
|
|
type Provider interface {
|
|
encryption.Parameters
|
|
hashing.Parameters
|
|
ecc.Parameters
|
|
|
|
HashFunc() hashing.HashFunc
|
|
Encryptor() encryption.Encryptor
|
|
|
|
// this is typically cached, but sometimes refreshes MutableParameters from
|
|
// the repository so the results should not be cached.
|
|
GetMutableParameters(ctx context.Context) (MutableParameters, error)
|
|
GetCachedMutableParameters() MutableParameters
|
|
SupportsPasswordChange() bool
|
|
GetMasterKey() []byte
|
|
|
|
RepositoryFormatBytes(ctx context.Context) ([]byte, error)
|
|
}
|
|
|
|
type formattingOptionsProvider struct {
|
|
*ContentFormat
|
|
|
|
h hashing.HashFunc
|
|
e encryption.Encryptor
|
|
formatBytes []byte
|
|
}
|
|
|
|
// NewFormattingOptionsProvider validates the provided formatting options and returns static
|
|
// FormattingOptionsProvider based on them.
|
|
func NewFormattingOptionsProvider(f0 *ContentFormat, formatBytes []byte) (Provider, error) {
|
|
clone := *f0
|
|
f := &clone
|
|
formatVersion := f.Version
|
|
|
|
if formatVersion < MinSupportedReadVersion || formatVersion > CurrentWriteVersion {
|
|
return nil, errors.Errorf("can't handle repositories created using version %v (min supported %v, max supported %v)", formatVersion, MinSupportedReadVersion, MaxSupportedReadVersion)
|
|
}
|
|
|
|
if formatVersion < MinSupportedWriteVersion || formatVersion > CurrentWriteVersion {
|
|
return nil, errors.Errorf("can't handle repositories created using version %v (min supported %v, max supported %v)", formatVersion, MinSupportedWriteVersion, MaxSupportedWriteVersion)
|
|
}
|
|
|
|
if f.IndexVersion == 0 {
|
|
f.IndexVersion = legacyIndexVersion
|
|
}
|
|
|
|
if f.IndexVersion < index.Version1 || f.IndexVersion > index.Version2 {
|
|
return nil, errors.Errorf("index version %v is not supported", f.IndexVersion)
|
|
}
|
|
|
|
// apply default
|
|
if f.MaxPackSize == 0 {
|
|
// legacy only, apply default
|
|
f.MaxPackSize = 20 << 20 //nolint:mnd
|
|
}
|
|
|
|
h, err := hashing.CreateHashFunc(f)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "unable to create hash")
|
|
}
|
|
|
|
e, err := encryption.CreateEncryptor(f)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "unable to create encryptor")
|
|
}
|
|
|
|
if f.GetECCAlgorithm() != "" && f.GetECCOverheadPercent() > 0 {
|
|
eccEncryptor, err := ecc.CreateEncryptor(f)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "unable to create ECC")
|
|
}
|
|
|
|
e = &encryptorWrapper{
|
|
impl: e,
|
|
next: eccEncryptor,
|
|
}
|
|
}
|
|
|
|
contentID := h(nil, gather.FromSlice(nil))
|
|
|
|
var tmp gather.WriteBuffer
|
|
defer tmp.Close()
|
|
|
|
err = e.Encrypt(gather.FromSlice(nil), contentID, &tmp)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "invalid encryptor")
|
|
}
|
|
|
|
return &formattingOptionsProvider{
|
|
ContentFormat: f,
|
|
|
|
h: h,
|
|
e: e,
|
|
formatBytes: formatBytes,
|
|
}, nil
|
|
}
|
|
|
|
func (f *formattingOptionsProvider) Encryptor() encryption.Encryptor {
|
|
return f.e
|
|
}
|
|
|
|
func (f *formattingOptionsProvider) HashFunc() hashing.HashFunc {
|
|
return f.h
|
|
}
|
|
|
|
func (f *formattingOptionsProvider) RepositoryFormatBytes(_ context.Context) ([]byte, error) {
|
|
if f.SupportsPasswordChange() {
|
|
return nil, nil
|
|
}
|
|
|
|
return f.formatBytes, nil
|
|
}
|
|
|
|
var _ Provider = (*formattingOptionsProvider)(nil)
|