Created
November 28, 2023 02:12
-
-
Save jbweber/f31e3a49eb9546469a25c6d46a06aa18 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"archive/tar" | |
"archive/zip" | |
"bytes" | |
"compress/gzip" | |
"errors" | |
"fmt" | |
"io" | |
"log" | |
"os" | |
) | |
// grab a tar.gz file with a binary called "bootstrap" inside | |
// assume this is a lambda function handler | |
// extract the 'bootstrap' binary and write it to a zip file suitable for upload to lambda | |
func main() { | |
f, err := os.Open("c:\\users\\jweber\\gringotts-lambda.tar.gz") | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer func() { _ = f.Close() }() | |
b, err := extractBootstrapFromTGZ(f) | |
if err != nil { | |
if errors.Is(err, gzip.ErrHeader) { | |
log.Fatalf("file is not gzipped: %v", err) | |
} | |
log.Fatalf("unknown error: %v", err) | |
} | |
err = os.WriteFile("c:\\users\\jweber\\bootstrap", b, 0755) | |
if err != nil { | |
log.Fatal(err) | |
} | |
o, err := createLambdaZip(b) | |
if err != nil { | |
log.Fatal(err) | |
} | |
fmt.Println(len(o)) | |
err = os.WriteFile("c:\\users\\jweber\\bootstrap.zip", o, 0666) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} | |
func extractBootstrapFromTGZ(r io.Reader) ([]byte, error) { | |
gzr, err := gzip.NewReader(r) | |
if err != nil { | |
return nil, err | |
} | |
defer func() { _ = gzr.Close() }() | |
tr := tar.NewReader(gzr) | |
for { | |
header, err := tr.Next() | |
switch { | |
// no more files in tar | |
case err == io.EOF: | |
return nil, nil | |
// error | |
case err != nil: | |
return nil, err | |
// skip if header is nil | |
case header == nil: | |
continue | |
} | |
if header.Typeflag == tar.TypeReg { | |
fmt.Println(header.Name) | |
} | |
var bsBuf bytes.Buffer | |
if _, err := io.Copy(&bsBuf, tr); err != nil { | |
return nil, err | |
} | |
return bsBuf.Bytes(), nil | |
} | |
} | |
func createLambdaZip(in []byte) ([]byte, error) { | |
var buf bytes.Buffer | |
writer := zip.NewWriter(&buf) | |
// https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html | |
// version made by -> upper byte | |
// external attr | |
// https://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute | |
fw, err := writer.CreateHeader(&zip.FileHeader{ | |
Name: "bootstrap", | |
Method: zip.Deflate, | |
CreatorVersion: 3 << 8, | |
ExternalAttrs: 0777 << 16, | |
}) | |
if err != nil { | |
return nil, err | |
} | |
_, err = fw.Write(in) | |
if err != nil { | |
return nil, err | |
} | |
// not closed under a defer because it doesn't close the underlying writer only finishes the zip file | |
// if we return bytes before close the zip is bad, if we don't close it doesn't matter anyway since zip build failed | |
err = writer.Close() | |
if err != nil { | |
return nil, err | |
} | |
return buf.Bytes(), err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment