From ad6e3be9b8a63dc40ae3176dfce0d97bb1f7a1f6 Mon Sep 17 00:00:00 2001 From: Chris Kim <30601846+Oats87@users.noreply.github.com> Date: Thu, 3 Mar 2022 12:39:43 -0700 Subject: [PATCH] Only write applied plan contents if the plan actually changes (#75) Signed-off-by: Chris Kim --- pkg/applyinator/applyinator.go | 69 +++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/pkg/applyinator/applyinator.go b/pkg/applyinator/applyinator.go index bd6a24bc..bfb2d065 100644 --- a/pkg/applyinator/applyinator.go +++ b/pkg/applyinator/applyinator.go @@ -9,6 +9,7 @@ import ( "encoding/json" "fmt" "io" + "io/ioutil" "os" "os/exec" "path/filepath" @@ -148,21 +149,13 @@ func (a *Applyinator) Apply(ctx context.Context, input ApplyInput) (ApplyOutput, now := time.Now() nowUnixTimeString := now.Format(time.UnixDate) nowString := now.Format(applyinatorDateCodeLayout) - appliedPlanFile := nowString + appliedPlanFileSuffix executionDir := filepath.Join(a.workDir, nowString) logrus.Tracef("[Applyinator] Applying calculated node plan contents %v", input.CalculatedPlan.Checksum) logrus.Tracef("[Applyinator] Using %s as execution directory", executionDir) if a.appliedPlanDir != "" { logrus.Debugf("[Applyinator] Writing applied calculated plan contents to historical plan directory %s", a.appliedPlanDir) - if err := os.MkdirAll(a.appliedPlanDir, 0700); err != nil { - return output, err - } - anpString, err := json.Marshal(input.CalculatedPlan) - if err != nil { - return output, err - } - if err := writeContentToFile(filepath.Join(a.appliedPlanDir, appliedPlanFile), os.Getuid(), os.Getgid(), 0600, anpString); err != nil { - return output, err + if err := a.writePlanToDisk(now, &input.CalculatedPlan); err != nil { + logrus.Errorf("error writing applied plan to disk: %v", err) } if err := a.appliedPlanRetentionPolicy(planRetentionPolicyCount); err != nil { logrus.Errorf("error while applying plan retention policy: %v", err) @@ -339,18 +332,11 @@ func generateByteBufferFromBytes(input []byte) (*bytes.Buffer, error) { } func (a *Applyinator) appliedPlanRetentionPolicy(retention int) error { - var planFiles []os.DirEntry - dirListedPlanFiles, err := os.ReadDir(a.appliedPlanDir) + planFiles, err := a.getAppliedPlanFiles() if err != nil { return err } - for _, f := range dirListedPlanFiles { - if strings.HasSuffix(f.Name(), appliedPlanFileSuffix) && !f.IsDir() { - planFiles = append(planFiles, f) - } - } - if len(planFiles) <= retention { return nil } @@ -370,6 +356,53 @@ func (a *Applyinator) appliedPlanRetentionPolicy(retention int) error { return nil } +func (a *Applyinator) getAppliedPlanFiles() ([]os.DirEntry, error) { + var planFiles []os.DirEntry + dirListedPlanFiles, err := os.ReadDir(a.appliedPlanDir) + if err != nil { + return nil, err + } + + for _, f := range dirListedPlanFiles { + if strings.HasSuffix(f.Name(), appliedPlanFileSuffix) && !f.IsDir() { + planFiles = append(planFiles, f) + } + } + return planFiles, nil +} + +func (a *Applyinator) writePlanToDisk(now time.Time, plan *CalculatedPlan) error { + planFiles, err := a.getAppliedPlanFiles() + if err != nil { + return err + } + + file := now.Format(applyinatorDateCodeLayout) + appliedPlanFileSuffix + if err := os.MkdirAll(a.appliedPlanDir, 0700); err != nil { + return err + } + anpString, err := json.Marshal(plan) + if err != nil { + return err + } + + if len(planFiles) != 0 { + sort.Slice(planFiles, func(i, j int) bool { + return planFiles[i].Name() > planFiles[j].Name() + }) + existingFileContent, err := ioutil.ReadFile(filepath.Join(a.appliedPlanDir, planFiles[0].Name())) + if err != nil { + return err + } + if bytes.Equal(existingFileContent, anpString) { + logrus.Debugf("[Applyinator] Not writing applied plan to file %s as the last file written (%s) had identical contents", file, planFiles[0].Name()) + return nil + } + } + + return writeContentToFile(filepath.Join(a.appliedPlanDir, file), os.Getuid(), os.Getgid(), 0600, anpString) +} + func (a *Applyinator) execute(ctx context.Context, prefix, executionDir string, instruction CommonInstruction, combinedOutput bool) ([]byte, []byte, int, error) { if instruction.Image == "" { logrus.Infof("[Applyinator] No image provided, creating empty working directory %s", executionDir)