diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fa6015e..bd10cddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ IMPROVEMENTS: * The provider is now compatible with Terraform v0.12, while retaining compatibility with prior versions. +BUG FIXES: + +* Fix file permissions affecting zip contents and causing spurious diffs ([#34](https://github.com/terraform-providers/terraform-provider-archive/issues/34)) + ## 1.1.0 (July 30, 2018) ENHANCEMENTS: diff --git a/archive/zip_archiver.go b/archive/zip_archiver.go index 1ed341f9..127f3a98 100644 --- a/archive/zip_archiver.go +++ b/archive/zip_archiver.go @@ -62,6 +62,18 @@ func (a *ZipArchiver) ArchiveFile(infilename string) error { // fh.Modified alone isn't enough when using a zero value fh.SetModTime(time.Time{}) + // check if file is executable + info, err := os.Stat(infilename) + if err != nil { + return err + } + mode := info.Mode().Perm() + if mode&0100 == 0100 { + fh.SetMode(0555) + } else { + fh.SetMode(0444) + } + f, err := a.writer.CreateHeader(fh) if err != nil { return fmt.Errorf("error creating file inside archive: %s", err) diff --git a/archive/zip_archiver_test.go b/archive/zip_archiver_test.go index 5429096c..e1ce8069 100644 --- a/archive/zip_archiver_test.go +++ b/archive/zip_archiver_test.go @@ -33,7 +33,92 @@ func TestZipArchiver_File(t *testing.T) { "test-file.txt": []byte("This is test content"), }) } -func TestZipArchiver_FileModified(t *testing.T) { + +func TestZipArchiver_FilePermissionsModified(t *testing.T) { + var ( + zipFilePath = filepath.FromSlash("archive-file.zip") + toZipPath = filepath.FromSlash("./test-fixtures/test-file.txt") + ) + + var zip = func() { + archiver := NewZipArchiver(zipFilePath) + if err := archiver.ArchiveFile(toZipPath); err != nil { + t.Fatalf("unexpected error: %s", err) + } + } + + //set initial file permissions + if err := os.Chmod(toZipPath, 0600); err != nil { + t.Fatalf("unexpected error: %s", err) + } + + zip() + + expectedContents, err := ioutil.ReadFile(zipFilePath) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + //change file permissions + if err := os.Chmod(toZipPath, 0666); err != nil { + t.Fatalf("unexpected error: %s", err) + } + + zip() + + actualContents, err := ioutil.ReadFile(zipFilePath) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + if !bytes.Equal(expectedContents, actualContents) { + t.Fatalf("zip contents do not match, potentially a permission issue") + } +} + +func TestZipArchiver_FileExecutablePermissionsModified(t *testing.T) { + var ( + zipFilePath = filepath.FromSlash("archive-file.zip") + toZipPath = filepath.FromSlash("./test-fixtures/test-file.txt") + ) + + var zip = func() { + archiver := NewZipArchiver(zipFilePath) + if err := archiver.ArchiveFile(toZipPath); err != nil { + t.Fatalf("unexpected error: %s", err) + } + } + + //set initial file permissions + if err := os.Chmod(toZipPath, 0700); err != nil { + t.Fatalf("unexpected error: %s", err) + } + + zip() + + expectedContents, err := ioutil.ReadFile(zipFilePath) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + //make file executable + if err := os.Chmod(toZipPath, 0644); err != nil { + t.Fatalf("unexpected error: %s", err) + } + + zip() + + actualContents, err := ioutil.ReadFile(zipFilePath) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + if bytes.Equal(expectedContents, actualContents) { + t.Fatalf("zip contents match, potentially a permission issue") + } +} + +func TestZipArchiver_FileTimeModified(t *testing.T) { var ( zipFilePath = filepath.FromSlash("archive-file.zip") toZipPath = filepath.FromSlash("./test-fixtures/test-file.txt") @@ -63,7 +148,7 @@ func TestZipArchiver_FileModified(t *testing.T) { actualContents, err := ioutil.ReadFile(zipFilePath) if err != nil { - t.Fatalf("unexpecte error: %s", err) + t.Fatalf("unexpected error: %s", err) } if !bytes.Equal(expectedContents, actualContents) {