Commit b1c61373 authored by iyear's avatar iyear Committed by Brad Davidson

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: 's avatariyear <ljyngup@gmail.com> Signed-off-by: 's avatarBrad Davidson <brad.davidson@rancher.com>
parent 0b19c2b7
...@@ -328,35 +328,15 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker, ...@@ -328,35 +328,15 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker,
} }
logrus.Debugf("Reconciling %s at '%s'", pathKey, path) logrus.Debugf("Reconciling %s at '%s'", pathKey, path)
f, err := os.Open(path) updated, newer, err := isNewerFile(path, fileData)
if err != nil { if err != nil {
if os.IsNotExist(err) { return errors.Wrapf(err, "failed to get update status of %s", pathKey)
logrus.Warn(path + " doesn't exist. continuing...")
updateDisk = true
continue
}
return errors.Wrapf(err, "reconcile failed to open %s", pathKey)
} }
defer f.Close() if newer {
newerOnDisk = append(newerOnDisk, path)
fData, err := io.ReadAll(f)
if err != nil {
return errors.Wrapf(err, "reconcile failed to read %s", pathKey)
} }
if !bytes.Equal(fileData.Content, fData) { updateDisk = updateDisk || updated
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 {
newerOnDisk = append(newerOnDisk, path)
} else {
logrus.Warn(path + " will be updated from the datastore.")
}
}
} }
if c.config.ClusterReset { if c.config.ClusterReset {
...@@ -384,6 +364,41 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker, ...@@ -384,6 +364,41 @@ func (c *Cluster) ReconcileBootstrapData(ctx context.Context, buf io.ReadSeeker,
return nil 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 // 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, // 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. // this data does not need to be decrypted since it is generated on-demand by an existing server.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment