diff --git a/changelog/unreleased/issue-4583 b/changelog/unreleased/issue-4583 index 6af8ab475..97b0e6ba7 100644 --- a/changelog/unreleased/issue-4583 +++ b/changelog/unreleased/issue-4583 @@ -1,9 +1,12 @@ -Bugfix: Ignoring the s3.storage-class option for metadata when archive tier is specified +Enhancement: Ignore s3.storage-class for metadata if archive tier is specified -Restic now will save snapshot metadata to non-archive storage tier whatsoever, -this will help avoid issues when data is being saved to archive storage class. -It is not providing any support for cold storages in restic, -only saving users from making backups unusable. +There is no official cold storage support in restic, use this option at your +own risk. + +Restic always stored all files on s3 using the specified `s3.storage-class`. +Now, restic will store metadata using a non-archive storage tier to avoid +problems when accessing a repository. To restore any data, it is still +necessary to manually warm up the required data beforehand. https://github.com/restic/restic/issues/4583 -https://github.com/restic/restic/issues/3202 \ No newline at end of file +https://github.com/restic/restic/pull/4584 diff --git a/internal/backend/s3/s3.go b/internal/backend/s3/s3.go index f9947b3a4..d41f4479d 100644 --- a/internal/backend/s3/s3.go +++ b/internal/backend/s3/s3.go @@ -326,8 +326,10 @@ func (be *Backend) Path() string { } // useStorageClass returns whether file should be saved in the provided Storage Class +// For archive storage classes, only data files are stored using that class; metadata +// must remain instantly accessible. func (be *Backend) useStorageClass(h backend.Handle) bool { - var notArchiveClass bool = be.cfg.StorageClass != "GLACIER" && be.cfg.StorageClass != "DEEP_ARCHIVE" + notArchiveClass := be.cfg.StorageClass != "GLACIER" && be.cfg.StorageClass != "DEEP_ARCHIVE" isDataFile := h.Type == backend.PackFile && !h.IsMetadata return isDataFile || notArchiveClass } @@ -336,15 +338,16 @@ func (be *Backend) useStorageClass(h backend.Handle) bool { func (be *Backend) Save(ctx context.Context, h backend.Handle, rd backend.RewindReader) error { objName := be.Filename(h) - opts := minio.PutObjectOptions{ContentType: "application/octet-stream"} - + opts := minio.PutObjectOptions{ + ContentType: "application/octet-stream", + // the only option with the high-level api is to let the library handle the checksum computation + SendContentMd5: true, + // only use multipart uploads for very large files + PartSize: 200 * 1024 * 1024, + } if be.useStorageClass(h) { opts.StorageClass = be.cfg.StorageClass } - // the only option with the high-level api is to let the library handle the checksum computation - opts.SendContentMd5 = true - // only use multipart uploads for very large files - opts.PartSize = 200 * 1024 * 1024 info, err := be.client.PutObject(ctx, be.cfg.Bucket, objName, io.NopCloser(rd), int64(rd.Length()), opts)