mirror of https://github.com/k3s-io/k3s
Consistently set snapshotFile timestamp
Attempt to use timestamp from creation or filename instead of file/object modification times
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
(cherry picked from commit 8d47645312
)
Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
pull/8644/head
parent
a89645dfb4
commit
514bcade78
|
@ -98,9 +98,11 @@ func (s *S3) upload(ctx context.Context, snapshot string, extraMetadata *v1.Conf
|
||||||
logrus.Infof("Uploading snapshot %s to S3", snapshot)
|
logrus.Infof("Uploading snapshot %s to S3", snapshot)
|
||||||
basename := filepath.Base(snapshot)
|
basename := filepath.Base(snapshot)
|
||||||
sf := &snapshotFile{
|
sf := &snapshotFile{
|
||||||
Name: basename,
|
Name: basename,
|
||||||
NodeName: "s3",
|
NodeName: "s3",
|
||||||
CreatedAt: &metav1.Time{},
|
CreatedAt: &metav1.Time{
|
||||||
|
Time: now,
|
||||||
|
},
|
||||||
S3: &s3Config{
|
S3: &s3Config{
|
||||||
Endpoint: s.config.EtcdS3Endpoint,
|
Endpoint: s.config.EtcdS3Endpoint,
|
||||||
EndpointCA: s.config.EtcdS3EndpointCA,
|
EndpointCA: s.config.EtcdS3EndpointCA,
|
||||||
|
@ -126,11 +128,9 @@ func (s *S3) upload(ctx context.Context, snapshot string, extraMetadata *v1.Conf
|
||||||
}
|
}
|
||||||
uploadInfo, err := s.client.FPutObject(toCtx, s.config.EtcdS3BucketName, snapshotKey, snapshot, opts)
|
uploadInfo, err := s.client.FPutObject(toCtx, s.config.EtcdS3BucketName, snapshotKey, snapshot, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sf.CreatedAt.Time = now
|
|
||||||
sf.Status = failedSnapshotStatus
|
sf.Status = failedSnapshotStatus
|
||||||
sf.Message = base64.StdEncoding.EncodeToString([]byte(err.Error()))
|
sf.Message = base64.StdEncoding.EncodeToString([]byte(err.Error()))
|
||||||
} else {
|
} else {
|
||||||
sf.CreatedAt.Time = uploadInfo.LastModified
|
|
||||||
sf.Status = successfulSnapshotStatus
|
sf.Status = successfulSnapshotStatus
|
||||||
sf.Size = uploadInfo.Size
|
sf.Size = uploadInfo.Size
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -93,7 +94,7 @@ func (e *ETCD) preSnapshotSetup(ctx context.Context) error {
|
||||||
|
|
||||||
// compressSnapshot compresses the given snapshot and provides the
|
// compressSnapshot compresses the given snapshot and provides the
|
||||||
// caller with the path to the file.
|
// caller with the path to the file.
|
||||||
func (e *ETCD) compressSnapshot(snapshotDir, snapshotName, snapshotPath string) (string, error) {
|
func (e *ETCD) compressSnapshot(snapshotDir, snapshotName, snapshotPath string, now time.Time) (string, error) {
|
||||||
logrus.Info("Compressing etcd snapshot file: " + snapshotName)
|
logrus.Info("Compressing etcd snapshot file: " + snapshotName)
|
||||||
|
|
||||||
zippedSnapshotName := snapshotName + compressedExtension
|
zippedSnapshotName := snapshotName + compressedExtension
|
||||||
|
@ -130,7 +131,7 @@ func (e *ETCD) compressSnapshot(snapshotDir, snapshotName, snapshotPath string)
|
||||||
|
|
||||||
header.Name = snapshotName
|
header.Name = snapshotName
|
||||||
header.Method = zip.Deflate
|
header.Method = zip.Deflate
|
||||||
header.Modified = time.Now()
|
header.Modified = now
|
||||||
|
|
||||||
writer, err := zipWriter.CreateHeader(header)
|
writer, err := zipWriter.CreateHeader(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -239,7 +240,7 @@ func (e *ETCD) Snapshot(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeName := os.Getenv("NODE_NAME")
|
nodeName := os.Getenv("NODE_NAME")
|
||||||
now := time.Now()
|
now := time.Now().Round(time.Second)
|
||||||
snapshotName := fmt.Sprintf("%s-%s-%d", e.config.EtcdSnapshotName, nodeName, now.Unix())
|
snapshotName := fmt.Sprintf("%s-%s-%d", e.config.EtcdSnapshotName, nodeName, now.Unix())
|
||||||
snapshotPath := filepath.Join(snapshotDir, snapshotName)
|
snapshotPath := filepath.Join(snapshotDir, snapshotName)
|
||||||
|
|
||||||
|
@ -273,7 +274,7 @@ func (e *ETCD) Snapshot(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.config.EtcdSnapshotCompress {
|
if e.config.EtcdSnapshotCompress {
|
||||||
zipPath, err := e.compressSnapshot(snapshotDir, snapshotName, snapshotPath)
|
zipPath, err := e.compressSnapshot(snapshotDir, snapshotName, snapshotPath, now)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -295,7 +296,7 @@ func (e *ETCD) Snapshot(ctx context.Context) error {
|
||||||
Location: "file://" + snapshotPath,
|
Location: "file://" + snapshotPath,
|
||||||
NodeName: nodeName,
|
NodeName: nodeName,
|
||||||
CreatedAt: &metav1.Time{
|
CreatedAt: &metav1.Time{
|
||||||
Time: f.ModTime(),
|
Time: now,
|
||||||
},
|
},
|
||||||
Status: successfulSnapshotStatus,
|
Status: successfulSnapshotStatus,
|
||||||
Size: f.Size(),
|
Size: f.Size(),
|
||||||
|
@ -397,36 +398,39 @@ type snapshotFile struct {
|
||||||
// snapshots on disk along with their relevant
|
// snapshots on disk along with their relevant
|
||||||
// metadata.
|
// metadata.
|
||||||
func (e *ETCD) listLocalSnapshots() (map[string]snapshotFile, error) {
|
func (e *ETCD) listLocalSnapshots() (map[string]snapshotFile, error) {
|
||||||
|
nodeName := os.Getenv("NODE_NAME")
|
||||||
snapshots := make(map[string]snapshotFile)
|
snapshots := make(map[string]snapshotFile)
|
||||||
snapshotDir, err := snapshotDir(e.config, true)
|
snapshotDir, err := snapshotDir(e.config, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return snapshots, errors.Wrap(err, "failed to get the snapshot dir")
|
return snapshots, errors.Wrap(err, "failed to get the snapshot dir")
|
||||||
}
|
}
|
||||||
|
|
||||||
dirEntries, err := os.ReadDir(snapshotDir)
|
if err := filepath.Walk(snapshotDir, func(path string, file os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if file.IsDir() || err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeName := os.Getenv("NODE_NAME")
|
basename, compressed := strings.CutSuffix(file.Name(), compressedExtension)
|
||||||
|
ts, err := strconv.ParseInt(basename[strings.LastIndexByte(basename, '-')+1:], 10, 64)
|
||||||
for _, de := range dirEntries {
|
|
||||||
file, err := de.Info()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
ts = file.ModTime().Unix()
|
||||||
}
|
}
|
||||||
sf := snapshotFile{
|
sf := snapshotFile{
|
||||||
Name: file.Name(),
|
Name: file.Name(),
|
||||||
Location: "file://" + filepath.Join(snapshotDir, file.Name()),
|
Location: "file://" + filepath.Join(snapshotDir, file.Name()),
|
||||||
NodeName: nodeName,
|
NodeName: nodeName,
|
||||||
CreatedAt: &metav1.Time{
|
CreatedAt: &metav1.Time{
|
||||||
Time: file.ModTime(),
|
Time: time.Unix(ts, 0),
|
||||||
},
|
},
|
||||||
Size: file.Size(),
|
Size: file.Size(),
|
||||||
Status: successfulSnapshotStatus,
|
Status: successfulSnapshotStatus,
|
||||||
|
Compressed: compressed,
|
||||||
}
|
}
|
||||||
sfKey := generateSnapshotConfigMapKey(sf)
|
sfKey := generateSnapshotConfigMapKey(sf)
|
||||||
snapshots[sfKey] = sf
|
snapshots[sfKey] = sf
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return snapshots, nil
|
return snapshots, nil
|
||||||
|
@ -463,11 +467,19 @@ func (e *ETCD) listS3Snapshots(ctx context.Context) (map[string]snapshotFile, er
|
||||||
if obj.Size == 0 {
|
if obj.Size == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filename := path.Base(obj.Key)
|
||||||
|
basename, compressed := strings.CutSuffix(filename, compressedExtension)
|
||||||
|
ts, err := strconv.ParseInt(basename[strings.LastIndexByte(basename, '-')+1:], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
ts = obj.LastModified.Unix()
|
||||||
|
}
|
||||||
|
|
||||||
sf := snapshotFile{
|
sf := snapshotFile{
|
||||||
Name: filepath.Base(obj.Key),
|
Name: filename,
|
||||||
NodeName: "s3",
|
NodeName: "s3",
|
||||||
CreatedAt: &metav1.Time{
|
CreatedAt: &metav1.Time{
|
||||||
Time: obj.LastModified,
|
Time: time.Unix(ts, 0),
|
||||||
},
|
},
|
||||||
Size: obj.Size,
|
Size: obj.Size,
|
||||||
S3: &s3Config{
|
S3: &s3Config{
|
||||||
|
@ -479,7 +491,8 @@ func (e *ETCD) listS3Snapshots(ctx context.Context) (map[string]snapshotFile, er
|
||||||
Folder: e.config.EtcdS3Folder,
|
Folder: e.config.EtcdS3Folder,
|
||||||
Insecure: e.config.EtcdS3Insecure,
|
Insecure: e.config.EtcdS3Insecure,
|
||||||
},
|
},
|
||||||
Status: successfulSnapshotStatus,
|
Status: successfulSnapshotStatus,
|
||||||
|
Compressed: compressed,
|
||||||
}
|
}
|
||||||
sfKey := generateSnapshotConfigMapKey(sf)
|
sfKey := generateSnapshotConfigMapKey(sf)
|
||||||
snapshots[sfKey] = sf
|
snapshots[sfKey] = sf
|
||||||
|
@ -917,12 +930,15 @@ func snapshotRetention(retention int, snapshotPrefix string, snapshotDir string)
|
||||||
|
|
||||||
var snapshotFiles []snapshotFile
|
var snapshotFiles []snapshotFile
|
||||||
if err := filepath.Walk(snapshotDir, func(path string, info os.FileInfo, err error) error {
|
if err := filepath.Walk(snapshotDir, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if info.IsDir() || err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(info.Name(), snapshotPrefix) {
|
if strings.HasPrefix(info.Name(), snapshotPrefix) {
|
||||||
basename, compressed := strings.CutSuffix(info.Name(), compressedExtension)
|
basename, compressed := strings.CutSuffix(info.Name(), compressedExtension)
|
||||||
ts, _ := strconv.ParseInt(basename[strings.LastIndexByte(basename, '-')+1:], 10, 64)
|
ts, err := strconv.ParseInt(basename[strings.LastIndexByte(basename, '-')+1:], 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
ts = info.ModTime().Unix()
|
||||||
|
}
|
||||||
snapshotFiles = append(snapshotFiles, snapshotFile{Name: info.Name(), CreatedAt: &metav1.Time{Time: time.Unix(ts, 0)}, Compressed: compressed})
|
snapshotFiles = append(snapshotFiles, snapshotFile{Name: info.Name(), CreatedAt: &metav1.Time{Time: time.Unix(ts, 0)}, Compressed: compressed})
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue