Fix incorrect defer usage

Problem:
Using defer inside a loop can lead to resource leaks

Solution:
Judge newer file in the separate function

Signed-off-by: iyear <ljyngup@gmail.com>
pull/6396/head
iyear 2 years ago committed by Brad Davidson
parent 86be784aa0
commit 3aae7b8783

@ -328,35 +328,15 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker,
}
logrus.Debugf("Reconciling %s at '%s'", pathKey, path)
f, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
logrus.Warn(path + " doesn't exist. continuing...")
updateDisk = true
continue
}
return errors.Wrapf(err, "reconcile failed to open %s", pathKey)
}
defer f.Close()
fData, err := io.ReadAll(f)
updated, newer, err := isNewerFile(path, fileData)
if err != nil {
return errors.Wrapf(err, "reconcile failed to read %s", pathKey)
return errors.Wrapf(err, "failed to get update status of %s", pathKey)
}
if !bytes.Equal(fileData.Content, fData) {
updateDisk = true
info, err := f.Stat()
if err != nil {
return errors.Wrapf(err, "reconcile failed to stat %s", pathKey)
}
if info.ModTime().Unix()-fileData.Timestamp.Unix() >= systemTimeSkew {
if newer {
newerOnDisk = append(newerOnDisk, path)
} else {
logrus.Warn(path + " will be updated from the datastore.")
}
}
updateDisk = updateDisk || updated
}
if c.config.ClusterReset {
@ -384,6 +364,41 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker,
return nil
}
// isNewerFile compares the file from disk and datastore, and returns
// update status.
func isNewerFile(path string, file bootstrap.File) (updated bool, newerOnDisk bool, _ error) {
f, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
logrus.Warn(path + " doesn't exist. continuing...")
return true, false, nil
}
return false, false, errors.Wrapf(err, "reconcile failed to open")
}
defer f.Close()
data, err := io.ReadAll(f)
if err != nil {
return false, false, errors.Wrapf(err, "reconcile failed to read")
}
if bytes.Equal(file.Content, data) {
return false, false, nil
}
info, err := f.Stat()
if err != nil {
return false, false, errors.Wrapf(err, "reconcile failed to stat")
}
if info.ModTime().Unix()-file.Timestamp.Unix() >= systemTimeSkew {
return true, true, nil
}
logrus.Warn(path + " will be updated from the datastore.")
return true, false, nil
}
// httpBootstrap retrieves bootstrap data (certs and keys, etc) from the remote server via HTTP
// and loads it into the ControlRuntimeBootstrap struct. Unlike the storage bootstrap path,
// this data does not need to be decrypted since it is generated on-demand by an existing server.

Loading…
Cancel
Save