@@ -4,6 +4,7 @@ package packer
44
55import (
66 "archive/tar"
7+ "bufio"
78 "context"
89 "fmt"
910 "io"
@@ -18,6 +19,7 @@ import (
1819 "github.com/gokrazy/internal/deviceconfig"
1920 "github.com/gokrazy/tools/internal/log"
2021 "github.com/gokrazy/tools/packer"
22+ "github.com/klauspost/compress/zstd"
2123)
2224
2325type contextKey int
@@ -93,7 +95,22 @@ func (ae *archiveExtraction) extractArchive(path string) (time.Time, error) {
9395 return time.Time {}, err
9496 }
9597 defer f .Close ()
96- rd := tar .NewReader (f )
98+
99+ // Sniff zstd magic bytes (0x28 0xb5 0x2f 0xfd) to transparently handle both plain tar
100+ // and zstd-compressed tar archives.
101+ // Ref: https://datatracker.ietf.org/doc/html/rfc8878#section-3.1.1
102+ br := bufio .NewReader (f )
103+ var r io.Reader = br
104+ if magic , err := br .Peek (4 ); err == nil &&
105+ magic [0 ] == 0x28 && magic [1 ] == 0xb5 && magic [2 ] == 0x2f && magic [3 ] == 0xfd {
106+ zr , err := zstd .NewReader (br )
107+ if err != nil {
108+ return time.Time {}, fmt .Errorf ("zstd %s: %v" , path , err )
109+ }
110+ defer zr .Close ()
111+ r = zr
112+ }
113+ rd := tar .NewReader (r )
97114
98115 var latestTime time.Time
99116 for {
@@ -147,17 +164,23 @@ func (ae *archiveExtraction) extractArchive(path string) (time.Time, error) {
147164 return latestTime , nil
148165}
149166
167+ // extraFilesArchiveCandidates returns the list of archive paths to probe
168+ // for a given extrafiles directory, in priority order.
169+ func extraFilesArchiveCandidates (dir string ) []string {
170+ targetArch := packer .TargetArch ()
171+ return []string {
172+ dir + "_" + targetArch + ".tar.zst" ,
173+ dir + "_" + targetArch + ".tar" ,
174+ dir + ".tar.zst" ,
175+ dir + ".tar" ,
176+ }
177+ }
178+
150179// findExtraFilesInDir probes for extrafiles .tar files (possibly with an
151180// architecture suffix like _amd64), or whether dir itself exists.
152181func findExtraFilesInDir (dir string ) (string , error ) {
153- targetArch := packer .TargetArch ()
154-
155182 var err error
156- for _ , p := range []string {
157- dir + "_" + targetArch + ".tar" ,
158- dir + ".tar" ,
159- dir ,
160- } {
183+ for _ , p := range append (extraFilesArchiveCandidates (dir ), dir ) {
161184 _ , err = os .Stat (p )
162185 if err == nil {
163186 return p , nil
@@ -179,19 +202,19 @@ func addExtraFilesFromDir(pkg, dir string, fi *FileInfo) error {
179202 }
180203 ae .dirs ["." ] = fi // root
181204
182- targetArch := packer .TargetArch ()
183-
184- effectivePath := dir + "_" + targetArch + ".tar"
185- latestModTime , err := ae .extractArchive (effectivePath )
186- if err != nil {
187- return err
188- }
189- if len (fi .Dirents ) == 0 {
190- effectivePath = dir + ".tar"
205+ var (
206+ effectivePath string
207+ latestModTime time.Time
208+ err error
209+ )
210+ for _ , effectivePath = range extraFilesArchiveCandidates (dir ) {
191211 latestModTime , err = ae .extractArchive (effectivePath )
192212 if err != nil {
193213 return err
194214 }
215+ if len (fi .Dirents ) > 0 {
216+ break
217+ }
195218 }
196219 if len (fi .Dirents ) == 0 {
197220 effectivePath = dir
0 commit comments