4
4
"archive/tar"
5
5
"bytes"
6
6
"io"
7
+ "io/fs"
7
8
"os"
8
9
"path/filepath"
9
10
"strings"
@@ -31,43 +32,37 @@ func dirHasExt(dir string, ext string) (bool, error) {
31
32
return false , nil
32
33
}
33
34
34
- // Tar archives a Terraform directory.
35
- func Tar (directory string , limit int64 ) ([]byte , error ) {
36
- var buffer bytes.Buffer
37
- tarWriter := tar .NewWriter (& buffer )
38
- totalSize := int64 (0 )
39
35
40
- const tfExt = ".tf"
41
- hasTf , err := dirHasExt (directory , tfExt )
42
- if err != nil {
43
- return nil , err
44
- }
45
- if ! hasTf {
46
- absPath , err := filepath .Abs (directory )
47
- if err != nil {
48
- return nil , err
49
- }
36
+ type archiver struct {
50
37
51
- // Show absolute path to aid in debugging. E.g. showing "." is
52
- // useless.
53
- return nil , xerrors .Errorf (
54
- "%s is not a valid template since it has no %s files" ,
55
- absPath , tfExt ,
56
- )
57
- }
38
+ }
58
39
59
- err = filepath . Walk ( directory , func ( file string , fileInfo os.FileInfo , err error ) error {
40
+ func ( a * archiver ) walkFn ( path string , fileInfo os.FileInfo , err error ) error {
60
41
if err != nil {
61
42
return err
62
43
}
63
- var link string
64
44
if fileInfo .Mode ()& os .ModeSymlink == os .ModeSymlink {
65
- link , err = os .Readlink (file )
45
+ // Per https://github.com/coder/coder/issues/5677, we want to
46
+ // follow symlinks.
47
+ var linkDest string
48
+ linkDest , err = os .Readlink (file )
66
49
if err != nil {
67
50
return err
68
51
}
52
+
53
+ destInfo , err := os .Stat (linkDest )
54
+ if err != nil {
55
+ return err
56
+ }
57
+ if destInfo .IsDir () {
58
+ return filepath .Walk (linkDest , func (path string , info fs.FileInfo , err error ) error {
59
+ walkFn (path , info , err )
60
+ })
61
+ }
62
+ return nil
69
63
}
70
- header , err := tar .FileInfoHeader (fileInfo , link )
64
+
65
+ header , err := tar .FileInfoHeader (fileInfo , "" )
71
66
if err != nil {
72
67
return err
73
68
}
@@ -76,11 +71,10 @@ func Tar(directory string, limit int64) ([]byte, error) {
76
71
return err
77
72
}
78
73
if strings .HasPrefix (rel , "." ) || strings .HasPrefix (filepath .Base (rel ), "." ) {
74
+ // Don't archive hidden files!
79
75
if fileInfo .IsDir () && rel != "." {
80
- // Don't archive hidden files!
81
76
return filepath .SkipDir
82
77
}
83
- // Don't archive hidden files!
84
78
return nil
85
79
}
86
80
if strings .Contains (rel , ".tfstate" ) {
@@ -109,7 +103,35 @@ func Tar(directory string, limit int64) ([]byte, error) {
109
103
return xerrors .Errorf ("Archive too big. Must be <= %d bytes" , limit )
110
104
}
111
105
return data .Close ()
112
- })
106
+ }
107
+ }
108
+
109
+ // Tar archives a Terraform directory.
110
+ func Tar (directory string , limit int64 ) ([]byte , error ) {
111
+ var buffer bytes.Buffer
112
+ tarWriter := tar .NewWriter (& buffer )
113
+ totalSize := int64 (0 )
114
+
115
+ const tfExt = ".tf"
116
+ hasTf , err := dirHasExt (directory , tfExt )
117
+ if err != nil {
118
+ return nil , err
119
+ }
120
+ if ! hasTf {
121
+ absPath , err := filepath .Abs (directory )
122
+ if err != nil {
123
+ return nil , err
124
+ }
125
+
126
+ // Show absolute path to aid in debugging. E.g. showing "." is
127
+ // useless.
128
+ return nil , xerrors .Errorf (
129
+ "%s is not a valid template since it has no %s files" ,
130
+ absPath , tfExt ,
131
+ )
132
+ }
133
+
134
+ err = filepath .Walk (directory , tarWalkFn ())
113
135
if err != nil {
114
136
return nil , err
115
137
}
0 commit comments