diff --git a/cmd/localstack/awsutil.go b/cmd/localstack/awsutil.go index 8415cc7..3fd0c54 100644 --- a/cmd/localstack/awsutil.go +++ b/cmd/localstack/awsutil.go @@ -6,6 +6,7 @@ package main import ( + "archive/zip" "fmt" "github.com/jessevdk/go-flags" log "github.com/sirupsen/logrus" @@ -15,6 +16,8 @@ import ( "math" "net/http" "os" + "path" + "path/filepath" "strings" "time" ) @@ -22,6 +25,7 @@ import ( const ( optBootstrap = "/opt/bootstrap" runtimeBootstrap = "/var/runtime/bootstrap" + taskFolder = "/var/task" ) type options struct { @@ -128,6 +132,70 @@ func GetenvWithDefault(key string, defaultValue string) string { return envValue } +func DownloadCodeArchive(url string) { + // download and unzip code archive, if url is given + if url == "" { + return + } + log.Infoln("Downloading code archive") + // create tmp directory + tmpDir := os.TempDir() + // download code archive into tmp directory + res, err := http.Get(url) + if err != nil { + log.Fatal(err) + } + defer res.Body.Close() + tmp_file_path := path.Join(tmpDir, "code-archive.zip") + tmp_file, err := os.OpenFile(tmp_file_path, os.O_WRONLY|os.O_CREATE, os.ModePerm) + if err != nil { + log.Fatal(err) + } + _, err = io.Copy(tmp_file, res.Body) + if err != nil { + log.Fatal(err) + } + err = tmp_file.Close() + if err != nil { + log.Fatal(err) + } + // unzip into /var/task + log.Infoln("Unzipping code archive") + r, err := zip.OpenReader(tmp_file_path) + if err != nil { + log.Fatal(err) + } + defer r.Close() + for _, f := range r.File { + rc, err := f.Open() + if err != nil { + log.Fatal(err) + } + target_file_name := path.Join(taskFolder, f.Name) + if f.FileInfo().IsDir() { + err = os.MkdirAll(target_file_name, os.ModePerm) + if err != nil { + log.Fatal(err) + } + continue + } + if err := os.MkdirAll(filepath.Dir(target_file_name), os.ModePerm); err != nil { + panic(err) + } + target_file, err := os.OpenFile(target_file_name, os.O_WRONLY|os.O_CREATE, os.ModePerm) + if err != nil { + log.Fatal(err) + } + _, err = io.Copy(target_file, rc) + if err != nil { + log.Fatal(err) + } + target_file.Close() + rc.Close() + } + +} + func InitHandler(sandbox Sandbox, functionVersion string, timeout int64) (time.Time, time.Time) { additionalFunctionEnvironmentVariables := map[string]string{} diff --git a/cmd/localstack/main.go b/cmd/localstack/main.go index f5c55b9..77437ba 100644 --- a/cmd/localstack/main.go +++ b/cmd/localstack/main.go @@ -16,6 +16,7 @@ type LsOpts struct { RuntimeEndpoint string RuntimeId string InitTracingPort string + CodeDownloadUrl string } func GetEnvOrDie(env string) string { @@ -33,6 +34,8 @@ func InitLsOpts() *LsOpts { // optional with default InteropPort: GetenvWithDefault("LOCALSTACK_INTEROP_PORT", "9563"), InitTracingPort: GetenvWithDefault("LOCALSTACK_RUNTIME_TRACING_PORT", "9564"), + // optional or empty + CodeDownloadUrl: os.Getenv("LOCALSTACK_CODE_ARCHIVE_DOWNLOAD_URL"), } } @@ -47,7 +50,8 @@ func main() { //log.SetLevel(log.TraceLevel) log.SetLevel(log.DebugLevel) log.SetReportCaller(true) - + // download code archive if env variable is set + DownloadCodeArchive(lsOpts.CodeDownloadUrl) // parse CLI args opts, args := getCLIArgs() bootstrap, handler := getBootstrap(args, opts)