Skip to content

Commit a92e371

Browse files
committed
stabilize hashes
1 parent acdc8df commit a92e371

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

provisioner/terraform/modules.go

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"path/filepath"
1111
"strings"
12+
"time"
1213

1314
"golang.org/x/xerrors"
1415

@@ -94,33 +95,28 @@ func GetModulesArchive(root fs.FS) ([]byte, error) {
9495
continue
9596
}
9697

97-
err := fs.WalkDir(root, it.Dir, func(filePath string, info fs.DirEntry, err error) error {
98+
err := fs.WalkDir(root, it.Dir, func(filePath string, d fs.DirEntry, err error) error {
9899
if err != nil {
99100
return xerrors.Errorf("failed to create modules archive: %w", err)
100101
}
101-
fileType := info.Type()
102-
if !fileType.IsRegular() && !fileType.IsDir() {
102+
fileMode := d.Type()
103+
if !fileMode.IsRegular() && !fileMode.IsDir() {
103104
return nil
104105
}
105-
fileInfo, err := info.Info()
106+
fileInfo, err := d.Info()
106107
if err != nil {
107108
return xerrors.Errorf("failed to archive module file %q: %w", filePath, err)
108109
}
109-
header, err := tar.FileInfoHeader(fileInfo, "")
110+
header, err := fileHeader(filePath, fileMode, fileInfo)
110111
if err != nil {
111112
return xerrors.Errorf("failed to archive module file %q: %w", filePath, err)
112113
}
113-
header.Name = filePath
114-
if fileType.IsDir() {
115-
header.Name += "/"
116-
}
117-
118114
err = w.WriteHeader(header)
119115
if err != nil {
120116
return xerrors.Errorf("failed to add module file %q to archive: %w", filePath, err)
121117
}
122118

123-
if !fileType.IsRegular() {
119+
if !fileMode.IsRegular() {
124120
return nil
125121
}
126122
empty = false
@@ -140,13 +136,7 @@ func GetModulesArchive(root fs.FS) ([]byte, error) {
140136
}
141137
}
142138

143-
err = w.WriteHeader(&tar.Header{
144-
Name: ".terraform/modules/modules.json",
145-
Size: int64(len(modulesFileContent)),
146-
Mode: 0o644,
147-
Uid: 1000,
148-
Gid: 1000,
149-
})
139+
err = w.WriteHeader(defaultFileHeader(".terraform/modules/modules.json", len(modulesFileContent)))
150140
if err != nil {
151141
return nil, xerrors.Errorf("failed to write modules.json to archive: %w", err)
152142
}
@@ -163,3 +153,33 @@ func GetModulesArchive(root fs.FS) ([]byte, error) {
163153
}
164154
return b.Bytes(), nil
165155
}
156+
157+
func fileHeader(filePath string, fileMode fs.FileMode, fileInfo fs.FileInfo) (*tar.Header, error) {
158+
header, err := tar.FileInfoHeader(fileInfo, "")
159+
if err != nil {
160+
return nil, xerrors.Errorf("failed to archive module file %q: %w", filePath, err)
161+
}
162+
header.Name = filePath
163+
if fileMode.IsDir() {
164+
header.Name += "/"
165+
}
166+
// Erase a bunch of metadata that we don't need so that we get more consistent
167+
// hashes from the resulting archive.
168+
header.AccessTime = time.Time{}
169+
header.ChangeTime = time.Time{}
170+
header.ModTime = time.Time{}
171+
header.Uname = ""
172+
header.Gname = ""
173+
174+
return header, nil
175+
}
176+
177+
func defaultFileHeader(filePath string, length int) *tar.Header {
178+
return &tar.Header{
179+
Name: filePath,
180+
Size: int64(length),
181+
Mode: 0o644,
182+
Uid: 1000,
183+
Gid: 1000,
184+
}
185+
}

provisioner/terraform/modules_internal_test.go

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
package terraform
22

33
import (
4-
"archive/tar"
54
"bytes"
65
"crypto/sha256"
76
"encoding/hex"
8-
"errors"
9-
"fmt"
10-
"io"
117
"io/fs"
128
"os"
139
"path/filepath"
@@ -58,20 +54,11 @@ func TestGetModulesArchive(t *testing.T) {
5854
_, err = fs.ReadFile(tarfs, ".terraform/modules/stuff_that_should_not_be_included/nothing.txt")
5955
require.Error(t, err)
6056

61-
r := tar.NewReader(bytes.NewBuffer(archive))
62-
for {
63-
h, err := r.Next()
64-
if errors.Is(err, io.EOF) {
65-
break
66-
}
67-
fmt.Printf("- %v (%v) [%v:%v] %#v\n", h.Name, h.Size, h.Uid, h.Gid, h)
68-
}
69-
7057
// It should always be byte-identical to optimize storage
7158
hashBytes := sha256.Sum256(archive)
7259
hash := hex.EncodeToString(hashBytes[:])
7360
if runtime.GOOS != "windows" {
74-
require.Equal(t, "b956016b8ddc50a0fe107f5f0e1d6a21e936df828e484be456969329dae0afe0", hash)
61+
require.Equal(t, "8491a8ab368f00a7eb0e927a957a3b0e4bf5df322c5b330d7b92b8b043a3d1d9", hash)
7562
} else {
7663
require.Equal(t, "c219943913051e4637527cd03ae2b7303f6945005a262cdd420f9c2af490d572", hash)
7764
}

0 commit comments

Comments
 (0)