@@ -18,13 +18,18 @@ package util
18
18
19
19
import (
20
20
"archive/tar"
21
+ "fmt"
22
+ "github.com/pkg/errors"
21
23
"github.com/sirupsen/logrus"
22
24
"io"
23
25
"os"
24
26
"path/filepath"
25
27
"strings"
26
28
)
27
29
30
+ // Map of target:linkname
31
+ var hardlinks = make (map [string ]string )
32
+
28
33
func unpackTar (tr * tar.Reader , path string , whitelist []string ) error {
29
34
for {
30
35
header , err := tr .Next ()
@@ -119,11 +124,38 @@ func unpackTar(tr *tar.Reader, path string, whitelist []string) error {
119
124
if err = os .Symlink (header .Linkname , target ); err != nil {
120
125
logrus .Errorf ("Failed to create symlink between %s and %s: %s" , header .Linkname , target , err )
121
126
}
127
+ case tar .TypeLink :
128
+ linkname := filepath .Join (path , header .Linkname )
129
+ // Check if the linkname already exists
130
+ if _ , err := os .Stat (linkname ); ! os .IsNotExist (err ) {
131
+ // If it exists, create the hard link
132
+ resolveHardlink (linkname , target )
133
+ } else {
134
+ hardlinks [target ] = linkname
135
+ }
136
+ }
137
+ }
138
+
139
+ for target , linkname := range hardlinks {
140
+ logrus .Info ("Resolving hard links." )
141
+ if _ , err := os .Stat (linkname ); ! os .IsNotExist (err ) {
142
+ // If it exists, create the hard link
143
+ if err := resolveHardlink (linkname , target ); err != nil {
144
+ return errors .Wrap (err , fmt .Sprintf ("Unable to create hard link from %s to %s" , linkname , target ))
145
+ }
122
146
}
123
147
}
124
148
return nil
125
149
}
126
150
151
+ func resolveHardlink (linkname , target string ) error {
152
+ if err := os .Link (linkname , target ); err != nil {
153
+ return err
154
+ }
155
+ logrus .Debugf ("Created hard link from %s to %s" , linkname , target )
156
+ return nil
157
+ }
158
+
127
159
func checkWhitelist (target string , whitelist []string ) bool {
128
160
for _ , w := range whitelist {
129
161
if HasFilepathPrefix (target , w ) {
0 commit comments