in internal/apiclient/bundles.go [121:226]
func ExtractTgz(gcsURL string) (folder string, err error) {
ctx := context.Background()
folder, err = os.MkdirTemp("", "integration")
if err != nil {
return "", err
}
// Parse the GCS URL
parsedURL, err := url.Parse(gcsURL)
if err != nil {
return "", fmt.Errorf("Error parsing GCS URL:", err)
}
if parsedURL.Scheme != "gs" {
return "", fmt.Errorf("Invalid GCS URL scheme. Should be 'gs://'")
}
bucketName := parsedURL.Host
objectName := strings.TrimPrefix(parsedURL.Path, "/")
fileName := filepath.Base(gcsURL)
// Create a Google Cloud Storage client
client, err := storage.NewClient(ctx)
if err != nil {
return "", fmt.Errorf("Error creating GCS client:", err)
}
defer client.Close()
// Get a handle to the bucket and the object
bucket := client.Bucket(bucketName)
object := bucket.Object(objectName)
// Create a reader to stream the object's content
reader, err := object.NewReader(ctx)
if err != nil {
return "", fmt.Errorf("Error creating object reader:", err)
}
defer reader.Close()
// Create the local file to save the download
localFile, err := os.Create(path.Join(folder, fileName))
if err != nil {
return "", fmt.Errorf("Error creating local file:", err)
}
defer localFile.Close()
// Download the object and save it to the local file
if _, err := io.Copy(localFile, reader); err != nil {
return "", fmt.Errorf("Error downloading object:", err)
}
// Open the .tgz file
file, err := os.Open(path.Join(folder, fileName))
if err != nil {
return "", fmt.Errorf("Error opening file:", err)
}
defer file.Close() // Ensure file closure
// Create a gzip reader
gzipReader, err := gzip.NewReader(file)
if err != nil {
return "", fmt.Errorf("Error creating gzip reader:", err)
}
defer gzipReader.Close() // Ensure closure
// Create a tar reader
tarReader := tar.NewReader(gzipReader)
// Extract each file from the tar archive
for {
header, err := tarReader.Next()
if err == io.EOF {
break // End of archive
}
if err != nil {
return "", fmt.Errorf("Error reading tar entry:", err)
}
if strings.Contains(header.Name, "..") {
continue
}
// Process the file header
switch header.Typeflag {
case tar.TypeDir:
// Create directory
if err := os.Mkdir(path.Join(folder, header.Name), 0o755); err != nil {
return "", fmt.Errorf("Error creating directory:", err)
}
case tar.TypeReg:
// Create output file
outFile, err := os.Create(path.Join(folder, header.Name))
if err != nil {
return "", fmt.Errorf("Error creating file:", err)
}
defer outFile.Close()
// Copy contents from the tar to the output file
if _, err := io.Copy(outFile, tarReader); err != nil {
return "", fmt.Errorf("Error writing file:", err)
}
default:
return "", fmt.Errorf("Unsupported type: %b in %s\n", header.Typeflag, header.Name)
}
}
return folder, nil
}