blob: 7e4e06f9bff754001dd6b604994137c284f083d8 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package botanist
import (
"archive/tar"
"fmt"
"io"
"io/ioutil"
"net"
"os"
"path/filepath"
"fuchsia.googlesource.com/tools/tftp"
)
// ArchiveDirectory archives the given directory.
func ArchiveDirectory(tw *tar.Writer, dir string) error {
return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
hdr, err := tar.FileInfoHeader(info, path)
if err != nil {
return err
}
hdr.Name = path[len(dir)+1:]
if err := tw.WriteHeader(hdr); err != nil {
return err
}
fi, err := os.Open(path)
if err != nil {
return err
}
_, err = io.Copy(tw, fi)
return err
})
}
// ArchiveBuffer writes the given bytes to a given path within an archive.
func ArchiveBuffer(tw *tar.Writer, buf []byte, path string) error {
hdr := &tar.Header{
Name: path,
Size: int64(len(buf)),
Mode: 0666,
}
if err := tw.WriteHeader(hdr); err != nil {
return err
}
_, err := tw.Write(buf)
return err
}
// ArchiveReader writes data from the given Reader to the given tar.Writer.
func ArchiveReader(tw *tar.Writer, r io.Reader, path string) error {
bytes, err := ioutil.ReadAll(r)
if err != nil {
return err
}
return ArchiveBuffer(tw, bytes, path)
}
// FetchAndArchiveFile fetches a remote file via TFTP from a given node, and
// writes it an archive.
func FetchAndArchiveFile(t *tftp.Client, addr *net.UDPAddr, tw *tar.Writer, path, name string) error {
receiver, err := t.Receive(addr, path)
if err != nil {
return fmt.Errorf("failed to receive file %s: %v\n", path, err)
}
hdr := &tar.Header{
Name: name,
Size: receiver.(tftp.Session).Size(),
Mode: 0666,
}
if err := tw.WriteHeader(hdr); err != nil {
return err
}
_, err = receiver.WriteTo(tw)
return err
}