From f5cb441a82973e906ade69523c6024d2ffdae293 Mon Sep 17 00:00:00 2001 From: Hidde Beydals Date: Fri, 23 Jul 2021 18:15:38 +0200 Subject: [PATCH] Take relative paths in account for Bucket revision This commit changes the checksum method which is used to calculate the revision of a Bucket source, so that the file paths are taken into account and directory structure changes can be observed. Signed-off-by: Hidde Beydals --- controllers/bucket_controller.go | 19 +++--- controllers/bucket_controller_test.go | 83 +++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 controllers/bucket_controller_test.go diff --git a/controllers/bucket_controller.go b/controllers/bucket_controller.go index daf3e21d9..9bd62c2d3 100644 --- a/controllers/bucket_controller.go +++ b/controllers/bucket_controller.go @@ -356,9 +356,12 @@ func (r *BucketReconciler) auth(ctx context.Context, bucket sourcev1.Bucket) (*m return minio.New(bucket.Spec.Endpoint, &opt) } +// checksum calculates the SHA1 checksum of the given root directory. +// It traverses the given root directory and calculates the checksum for any found file, and returns the SHA1 sum of the +// list with relative file paths and their checksums. func (r *BucketReconciler) checksum(root string) (string, error) { - checksum := "" - err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + sum := sha1.New() + if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err } @@ -369,14 +372,16 @@ func (r *BucketReconciler) checksum(root string) (string, error) { if err != nil { return err } - checksum += fmt.Sprintf("%x", sha1.Sum(data)) + relPath, err := filepath.Rel(root, path) + if err != nil { + return err + } + sum.Write([]byte(fmt.Sprintf("%x %s\n", sha1.Sum(data), relPath))) return nil - }) - if err != nil { + }); err != nil { return "", err } - - return fmt.Sprintf("%x", sha1.Sum([]byte(checksum))), nil + return fmt.Sprintf("%x", sum.Sum(nil)), nil } // resetStatus returns a modified v1beta1.Bucket and a boolean indicating diff --git a/controllers/bucket_controller_test.go b/controllers/bucket_controller_test.go new file mode 100644 index 000000000..963d1f729 --- /dev/null +++ b/controllers/bucket_controller_test.go @@ -0,0 +1,83 @@ +/* +Copyright 2021 The Flux authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestBucketReconciler_checksum(t *testing.T) { + tests := []struct { + name string + beforeFunc func(root string) + want string + wantErr bool + }{ + { + name: "empty root", + want: "da39a3ee5e6b4b0d3255bfef95601890afd80709", + }, + { + name: "with file", + beforeFunc: func(root string) { + mockFile(root, "a/b/c.txt", "a dummy string") + }, + want: "309a5e6e96b4a7eea0d1cfaabf1be8ec1c063fa0", + }, + { + name: "with file in different path", + beforeFunc: func(root string) { + mockFile(root, "a/b.txt", "a dummy string") + }, + want: "e28c62b5cc488849950c4355dddc5523712616d4", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + root, err := ioutil.TempDir("", "bucket-checksum-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(root) + if tt.beforeFunc != nil { + tt.beforeFunc(root) + } + got, err := (&BucketReconciler{}).checksum(root) + if (err != nil) != tt.wantErr { + t.Errorf("checksum() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("checksum() got = %v, want %v", got, tt.want) + } + }) + } +} + +func mockFile(root, path, content string) error { + filePath := filepath.Join(root, path) + if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { + panic(err) + } + if err := ioutil.WriteFile(filePath, []byte(content), 0644); err != nil { + panic(err) + } + return nil +}