package dependencies import ( "archive/tar" "archive/zip" "bytes" "compress/gzip" "fmt" "io" "net/http" "os" "path/filepath" "strings" "github.com/juju/errors" log "github.com/sirupsen/logrus" ) // downloadFile will download file from a given url and store in memory the content // content will probably be untar, ungzip, .... func downloadFile(url string) (io.Reader, error) { // Get the data resp, err := http.Get(url) if err != nil { return nil, errors.Trace(err) } defer resp.Body.Close() buf := new(bytes.Buffer) _, err = buf.ReadFrom(resp.Body) if err != nil { return nil, errors.Trace(err) } return buf, nil } func unGzip(reader io.Reader) (io.Reader, error) { gzipReader, err := gzip.NewReader(reader) if err != nil { return nil, errors.Trace(err) } defer gzipReader.Close() return gzipReader, nil } func unTar(reader io.Reader, subdir string, dest string) error { tr := tar.NewReader(reader) if subdir != "" && !strings.HasSuffix(subdir, "/") { subdir = fmt.Sprintf("%s/", subdir) } for { header, err := tr.Next() switch { // no more files case err == io.EOF: return nil case err != nil: return errors.Trace(err) case header == nil: continue } filename := header.Name if subdir != "" && strings.HasPrefix(filename, subdir) { filename = strings.TrimPrefix(filename, subdir) if filename == "" { continue } } target := filepath.Join(dest, filename) log.Debugf("Extacting %s", target) switch header.Typeflag { // create directory if doesn't exit case tar.TypeDir: if _, err := os.Stat(target); err != nil { if err := os.MkdirAll(target, 0755); err != nil { return errors.Trace(err) } } // create file case tar.TypeReg: f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode)) if err != nil { return errors.Trace(err) } defer f.Close() // copy contents to file if _, err := io.Copy(f, tr); err != nil { return errors.Trace(err) } } } } func unZip(reader io.Reader, subdir string, dest string) error { if subdir != "" && !strings.HasSuffix(subdir, "/") { subdir = fmt.Sprintf("%s/", subdir) } // transform io.Reader buff := bytes.NewBuffer([]byte{}) size, err := io.Copy(buff, reader) if err != nil { return errors.Trace(err) } readerBytes := bytes.NewReader(buff.Bytes()) // Open a zip archive for reading. zipReader, err := zip.NewReader(readerBytes, size) if err != nil { return errors.Trace(err) } for _, file := range zipReader.File { filename := file.Name if subdir != "" && strings.HasPrefix(filename, subdir) { filename = strings.TrimPrefix(filename, subdir) if filename == "" { continue } } target := filepath.Join(dest, filename) log.Debugf("Extacting %s", target) if file.FileInfo().IsDir() { if _, err := os.Stat(target); err != nil { if err := os.MkdirAll(target, 0755); err != nil { return errors.Trace(err) } } } else { f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, file.Mode()) if err != nil { return errors.Trace(err) } defer f.Close() fileInArchive, err := file.Open() if err != nil { return errors.Trace(err) } defer fileInArchive.Close() // copy contents to file if _, err := io.Copy(f, fileInArchive); err != nil { return errors.Trace(err) } } } return nil }