This is an automated email from the ASF dual-hosted git repository.
csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-runtime-go.git
The following commit(s) were added to refs/heads/master by this push:
new c3e94d5 Static Build, Versioning and Support for More Languages (#72)
c3e94d5 is described below
commit c3e94d5f755b7b52b2a6e09e53154d06bde74505
Author: Michele Sciabarra <30654959+sciabarracom@users.noreply.github.com>
AuthorDate: Mon Mar 4 17:42:01 2019 +0100
Static Build, Versioning and Support for More Languages (#72)
---
.gitignore | 6 +-
openwhisk/_test/build.sh => CHANGES.md | 57 ++++-------
CREDITS.txt | 4 +-
LICENSE-filetype.txt | 25 -----
README.md | 4 +
{actionProxyLoop => actionloop}/Dockerfile | 0
{actionProxyLoop => actionloop}/build.gradle | 16 +++-
build.gradle | 7 +-
examples/Makefile | 3 +-
examples/bash-hello/Makefile | 2 +-
examples/golang-hello-single/Makefile | 4 +-
examples/golang-hello-vendor/Makefile | 8 +-
examples/golang-main-package/Makefile | 8 +-
examples/golang-main-single/Makefile | 4 +-
examples/golang-main-standalone/Makefile | 2 +-
examples/golang-main-vendor/Makefile | 4 +-
golang1.11/build.gradle | 3 +-
main/proxy.go | 33 +------
openwhisk/_test/build.sh | 6 +-
openwhisk/_test/compile.py | 11 +++
openwhisk/_test/{build.sh => find.sh} | 40 +-------
openwhisk/_test/pysample/exec | 6 ++
openwhisk/_test/pysample/lib/action/__init__.py | 2 +
openwhisk/_test/pysample/lib/action/main.py | 7 ++
openwhisk/_test/pysample/lib/exec.py | 20 ++++
openwhisk/actionProxy.go | 34 ++++++-
openwhisk/actionProxy_test.go | 44 +++++++++
openwhisk/compiler_test.go | 2 +-
openwhisk/extractor.go | 56 +----------
openwhisk/extractor_test.go | 2 +-
openwhisk/filetype.go | 10 +-
openwhisk/filetype_test.go | 6 ++
openwhisk/initHandler.go | 24 ++---
openwhisk/initHandler_test.go | 17 ++++
openwhisk/util_test.go | 19 ++--
openwhisk/version.go | 2 +-
openwhisk/zip.go | 104 +++++++++++++++++++++
openwhisk/{version.go => zip_test.go} | 26 +++++-
settings.gradle | 3 +-
.../actionContainers/ActionLoopBasicTests.scala | 2 +-
.../ActionLoopContainerTests.scala | 6 +-
41 files changed, 379 insertions(+), 260 deletions(-)
diff --git a/.gitignore b/.gitignore
index d490e01..7eacee2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,8 +11,9 @@ tests/build/
vendor/
# Go binary proxy
-actionProxyLoop/proxy
-golang1.10/proxy
+common/proxy
+actionloop/proxy
+golang1.11/proxy
# Go test transient files
openwhisk/_test/exec
@@ -26,6 +27,7 @@ openwhisk/_test/output/
openwhisk/action/
openwhisk/compile/
openwhisk/debug.test
+*.pyc
# Eclipse
tests/bin/
diff --git a/openwhisk/_test/build.sh b/CHANGES.md
old mode 100755
new mode 100644
similarity index 54%
copy from openwhisk/_test/build.sh
copy to CHANGES.md
index 58f80e8..c9a557b
--- a/openwhisk/_test/build.sh
+++ b/CHANGES.md
@@ -1,4 +1,4 @@
-#!/bin/bash
+<!--
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
@@ -15,42 +15,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-
-cd "$(dirname $0)"
-
-function build {
- test -e exec && rm exec
- cp $1.src $1.go
- GOPATH=$PWD go build -a -o exec $1.go
- rm $1.go
-}
-
-function build_main {
- test -e exec && rm exec
- cp ../../common/gobuild.py.launcher.go $1.go
- cat $1.src >>$1.go
- go build -a -o exec $1.go
- rm $1.go
-}
-
-
-build hi
-zip hi.zip exec
-cp exec hi
-
-build_main hello_message
-zip hello_message.zip exec
-cp exec hello_message
-
-build_main hello_greeting
-zip hello_greeting.zip exec
-cp exec hello_greeting
-
-test -e hello.zip && rm hello.zip
-cd src
-zip -q -r ../hello.zip main.go hello
-cd ..
-
-build exec
-test -e exec.zip && rm exec.zip
-zip -q -r exec.zip exec etc dir
+-->
+# ActionLoop v1.0.1
+- embedded file type detection
+- now showing the commend
+- librdkafka in golang image
+- showing version numbuer with -debug
+
+# Actionloop v2
+Versioning
+- renamed actionloop docker image to actionloop-v2
+Docker Images Support
+- static build of the executable docker image, so actionloop can be used also in alpine images
+ActionLoop for Scripting Languages
+- any script starting with '#!' is recognized as executable
+- now the -compile will zip the entire directory of the `bin` directory after compilation
+- if you upload a folder `src/exec` the entire directory is moved to `bin`, including other
uploaded files
diff --git a/CREDITS.txt b/CREDITS.txt
index f3d5e6a..c47fb41 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -1,6 +1,6 @@
-Michele Sciabarra <michele@sciabarra.com>
+Michele Sciabarra <msciabarra@apache.org>
-Carlos Santana
+Carlos Santana <csantana23@gmail.com>
Rodric Rabbah <rodric@gmail.com>
diff --git a/LICENSE-filetype.txt b/LICENSE-filetype.txt
deleted file mode 100644
index c03a05c..0000000
--- a/LICENSE-filetype.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-The MIT License
-
-Copyright (c) Tomas Aparicio
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/README.md b/README.md
index 186221c..88c634b 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,10 @@ This repository containst both the OpenWhisk runtime for Golang Actions,
as well
- Deployment for [Generic](docs/DEPLOY.md#generic) actions
- The [ActionLoop](docs/ACTION.md#actionloop) protocol for generic actions
+# Change Log
+
+[CHANGES.md](Here.)
+
# License
[Apache 2.0](LICENSE.txt)
diff --git a/actionProxyLoop/Dockerfile b/actionloop/Dockerfile
similarity index 100%
rename from actionProxyLoop/Dockerfile
rename to actionloop/Dockerfile
diff --git a/actionProxyLoop/build.gradle b/actionloop/build.gradle
similarity index 74%
rename from actionProxyLoop/build.gradle
rename to actionloop/build.gradle
index b0586ce..4daba91 100644
--- a/actionProxyLoop/build.gradle
+++ b/actionloop/build.gradle
@@ -15,5 +15,19 @@
* limitations under the License.
*/
-ext.dockerImageName = 'actionloop'
+ext.dockerImageName = 'actionloop-v2'
apply from: '../gradle/docker.gradle'
+
+distDocker.dependsOn 'copyProxy'
+distDocker.finalizedBy('cleanup')
+
+task copyProxy(type: Copy) {
+ from '../common/proxy'
+ into '.'
+}
+
+task cleanup(type: Delete) {
+ delete 'proxy'
+ delete 'gobuild.py'
+ delete 'gobuild.py.launcher.go'
+}
diff --git a/build.gradle b/build.gradle
index 18cebe0..149426f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -46,10 +46,13 @@ golang {
goVersion = '1.11.5'
}
-
build.dependsOn vendor
build {
targetPlatform = ['linux-amd64']
- go 'build -o actionProxyLoop/proxy main/proxy.go'
+ go """build -o common/proxy -ldflags '-extldflags "-static"' main/proxy.go"""
+}
+
+task cleanup(type: Delete) {
+ delete 'common/proxy'
}
diff --git a/examples/Makefile b/examples/Makefile
index 8774e4d..538ec75 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -3,6 +3,8 @@ IMAGES?=openwhisk
all: .PHONY
+.PHONY: bash-hello golang-hello-single golang-main-single golang-main-standalone golang-main-package
golang-main-vendor golang-hello-vendor
+
bash-hello:
cd $@ && OW_USER=$(IMAGES) make clean deploy test
@@ -30,5 +32,4 @@ golang-hello-vendor:
cd $@ && OW_USER=$(IMAGES) make clean devel test
cd $@ && OW_USER=$(IMAGES) make clean deploy test
-.PHONY: bash-hello golang-hello-single golang-main-single golang-main-standalone golang-main-package
golang-main-vendor golang-hello-vendor
diff --git a/examples/bash-hello/Makefile b/examples/bash-hello/Makefile
index f0e4914..29c12de 100644
--- a/examples/bash-hello/Makefile
+++ b/examples/bash-hello/Makefile
@@ -1,6 +1,6 @@
WSK?=wsk
OW_USER?=openwhisk
-OW_RUNTIME?=$(OW_USER)/actionloop
+OW_RUNTIME?=$(OW_USER)/actionloop-v2
NAME=bash-hello
PACKAGE=test
SRC=hello.sh
diff --git a/examples/golang-hello-single/Makefile b/examples/golang-hello-single/Makefile
index c88906a..c74fdba 100644
--- a/examples/golang-hello-single/Makefile
+++ b/examples/golang-hello-single/Makefile
@@ -1,5 +1,5 @@
OW_USER?=openwhisk
-OW_RUNTIME?=$(OW_USER)/actionloop
+OW_RUNTIME?=$(OW_USER)/actionloop-v2
OW_COMPILER?=$(OW_USER)/actionloop-golang-v1.11
WSK?=wsk
MAIN=hello
@@ -19,7 +19,7 @@ $(ZIP): $(SRC)
clean:
-$(WSK) action delete $(PACKAGE)/$(NAME)
- -rm $(ZIP) package.done test.json
+ -rm $(ZIP) package.done test.json 2>/dev/null
test: test.json
$(WSK) action invoke test/$(NAME) -r
diff --git a/examples/golang-hello-vendor/Makefile b/examples/golang-hello-vendor/Makefile
index 120dcd9..9d417fb 100644
--- a/examples/golang-hello-vendor/Makefile
+++ b/examples/golang-hello-vendor/Makefile
@@ -1,5 +1,5 @@
OW_USER?=openwhisk
-OW_RUNTIME?=$(OW_USER)/actionloop
+OW_RUNTIME?=$(OW_USER)/actionloop-v2
OW_COMPILER?=$(OW_USER)/actionloop-golang-v1.11
WSK?=wsk
MAIN=hello
@@ -23,14 +23,14 @@ $(BINZIP): $(SRCS) $(VENDORS) $(SRCZIP)
docker run -i $(OW_COMPILER) -compile $(MAIN) <$(SRCZIP) >$(BINZIP)
$(SRCZIP): $(SRCS) $(VENDORS)
- cd src ; zip ../$(SRCZIP) -r *
+ cd src ; zip ../$(SRCZIP) -qr *
clean:
-$(WSK) action delete $(PACKAGE)/$(NAME)
- -rm $(BINZIP) $(SRCZIP) package.done test.json
+ -rm $(BINZIP) $(SRCZIP) package.done test.json 2>/dev/null
clean_vendor:
- -rm -r $(VENDORS)
+ -rm -r $(VENDORS)
test: test.json
$(WSK) action invoke test/$(NAME) -r
diff --git a/examples/golang-main-package/Makefile b/examples/golang-main-package/Makefile
index c097852..d42a9df 100644
--- a/examples/golang-main-package/Makefile
+++ b/examples/golang-main-package/Makefile
@@ -1,5 +1,5 @@
OW_USER?=openwhisk
-OW_RUNTIME?=$(OW_USER)/actionloop
+OW_RUNTIME?=$(OW_USER)/actionloop-v2
OW_COMPILER?=$(OW_USER)/actionloop-golang-v1.11
WSK?=wsk
MAIN=main
@@ -16,14 +16,14 @@ devel: package.done $(SRCZIP)
$(WSK) action update $(PACKAGE)/$(NAME) $(SRCZIP) --main $(MAIN) --docker $(OW_COMPILER)
$(BINZIP): $(SRCS)
- cd src ; zip - -r * | docker run -i $(OW_COMPILER) -compile $(MAIN) >../$(BINZIP)
+ cd src ; zip - -qr * | docker run -i $(OW_COMPILER) -compile $(MAIN) >../$(BINZIP)
$(SRCZIP): $(SRCS)
- cd src ; zip ../$(SRCZIP) -r *
+ cd src ; zip ../$(SRCZIP) -qr *
clean:
-$(WSK) action delete $(PACKAGE)/$(NAME)
- -rm $(BINZIP) $(SRCZIP) package.done test.json
+ -rm $(BINZIP) $(SRCZIP) package.done test.json 2>/dev/null
test: test.json
$(WSK) action invoke test/$(NAME) -r
diff --git a/examples/golang-main-single/Makefile b/examples/golang-main-single/Makefile
index 64e2415..e861905 100644
--- a/examples/golang-main-single/Makefile
+++ b/examples/golang-main-single/Makefile
@@ -1,5 +1,5 @@
OW_USER?=openwhisk
-OW_RUNTIME?=$(OW_USER)/actionloop
+OW_RUNTIME?=$(OW_USER)/actionloop-v2
OW_COMPILER?=$(OW_USER)/actionloop-golang-v1.11
WSK?=wsk
MAIN=main
@@ -19,7 +19,7 @@ $(ZIP): $(SRC)
clean:
-$(WSK) action delete $(PACKAGE)/$(NAME)
- -rm $(ZIP) package.done test.json
+ -rm $(ZIP) package.done test.json 2>/dev/null
test: test.json
$(WSK) action invoke test/$(NAME) -r
diff --git a/examples/golang-main-standalone/Makefile b/examples/golang-main-standalone/Makefile
index f7a8ec4..4918436 100644
--- a/examples/golang-main-standalone/Makefile
+++ b/examples/golang-main-standalone/Makefile
@@ -1,5 +1,5 @@
OW_USER?=openwhisk
-OW_RUNTIME?=$(OW_USER)/actionloop
+OW_RUNTIME?=$(OW_USER)/actionloop-v2
OW_COMPILER?=$(OW_USER)/actionloop-golang-v1.11
WSK?=wsk
MAIN=main
diff --git a/examples/golang-main-vendor/Makefile b/examples/golang-main-vendor/Makefile
index 06ea478..bca6b37 100644
--- a/examples/golang-main-vendor/Makefile
+++ b/examples/golang-main-vendor/Makefile
@@ -1,5 +1,5 @@
OW_USER?=openwhisk
-OW_RUNTIME?=$(OW_USER)/actionloop
+OW_RUNTIME?=$(OW_USER)/actionloop-v2
OW_COMPILER?=$(OW_USER)/actionloop-golang-v1.11
WSK?=wsk
MAIN=main
@@ -23,7 +23,7 @@ $(BINZIP): $(SRCS) $(VENDORS) $(SRCZIP)
docker run -i $(OW_COMPILER) -compile $(MAIN) <$(SRCZIP) >$(BINZIP)
$(SRCZIP): $(SRCS) $(VENDORS)
- cd src ; zip ../$(SRCZIP) -r *
+ cd src ; zip ../$(SRCZIP) -qr *
clean:
-$(WSK) action delete $(PACKAGE)/$(NAME)
diff --git a/golang1.11/build.gradle b/golang1.11/build.gradle
index ea0731c..cfe8e61 100644
--- a/golang1.11/build.gradle
+++ b/golang1.11/build.gradle
@@ -23,9 +23,8 @@ distDocker.dependsOn 'copyCompiler'
distDocker.dependsOn 'copyEpilogue'
distDocker.finalizedBy('cleanup')
-
task copyProxy(type: Copy) {
- from '../actionProxyLoop/proxy'
+ from '../common/proxy'
into '.'
}
diff --git a/main/proxy.go b/main/proxy.go
index 1fb9cdf..7f35914 100644
--- a/main/proxy.go
+++ b/main/proxy.go
@@ -17,11 +17,8 @@
package main
import (
- "archive/zip"
- "bytes"
"flag"
"fmt"
- "io/ioutil"
"log"
"os"
@@ -44,38 +41,12 @@ func fatalIf(err error) {
}
}
-// use the runtime as a compiler "on-the-fly"
-func extractAndCompile(ap *openwhisk.ActionProxy) {
-
- // read the std input
- in, err := ioutil.ReadAll(os.Stdin)
- fatalIf(err)
-
- // extract and compile it
- file, err := ap.ExtractAndCompile(&in, *compile)
- fatalIf(err)
-
- // read the file, zip it and write it to stdout
- buf := new(bytes.Buffer)
- zwr := zip.NewWriter(buf)
- zf, err := zwr.Create("exec")
- fatalIf(err)
- filedata, err := ioutil.ReadFile(file)
- fatalIf(err)
- _, err = zf.Write(filedata)
- fatalIf(err)
- fatalIf(zwr.Flush())
- fatalIf(zwr.Close())
- _, err = os.Stdout.Write(buf.Bytes())
- fatalIf(err)
-}
-
func main() {
flag.Parse()
// show version number
if *version {
- fmt.Println("OpenWhisk ActionLoop Proxy", openwhisk.Version)
+ fmt.Printf("OpenWhisk ActionLoop Proxy v%s\n", openwhisk.Version)
return
}
@@ -91,7 +62,7 @@ func main() {
// compile on the fly upon request
if *compile != "" {
- extractAndCompile(ap)
+ ap.ExtractAndCompileIO(os.Stdin, os.Stdout, *compile)
return
}
diff --git a/openwhisk/_test/build.sh b/openwhisk/_test/build.sh
index 58f80e8..42707f8 100755
--- a/openwhisk/_test/build.sh
+++ b/openwhisk/_test/build.sh
@@ -35,15 +35,15 @@ function build_main {
build hi
-zip hi.zip exec
+zip -q hi.zip exec
cp exec hi
build_main hello_message
-zip hello_message.zip exec
+zip -q hello_message.zip exec
cp exec hello_message
build_main hello_greeting
-zip hello_greeting.zip exec
+zip -q hello_greeting.zip exec
cp exec hello_greeting
test -e hello.zip && rm hello.zip
diff --git a/openwhisk/_test/compile.py b/openwhisk/_test/compile.py
new file mode 100755
index 0000000..e52486a
--- /dev/null
+++ b/openwhisk/_test/compile.py
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements; and to You under the Apache License, Version 2.0.
+import os, sys
+os.rename(sys.argv[2], sys.argv[3]+"/action")
+with open(sys.argv[3]+"/exec", "w") as f:
+ f.write("""#!/bin/bash
+cd "$(dirname $0)"
+export PYTHONPATH=$PWD/action
+python action/exec.py
+""")
diff --git a/openwhisk/_test/build.sh b/openwhisk/_test/find.sh
similarity index 54%
copy from openwhisk/_test/build.sh
copy to openwhisk/_test/find.sh
index 58f80e8..20255ba 100755
--- a/openwhisk/_test/build.sh
+++ b/openwhisk/_test/find.sh
@@ -15,42 +15,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-
-cd "$(dirname $0)"
-
-function build {
- test -e exec && rm exec
- cp $1.src $1.go
- GOPATH=$PWD go build -a -o exec $1.go
- rm $1.go
-}
-
-function build_main {
- test -e exec && rm exec
- cp ../../common/gobuild.py.launcher.go $1.go
- cat $1.src >>$1.go
- go build -a -o exec $1.go
- rm $1.go
-}
-
-
-build hi
-zip hi.zip exec
-cp exec hi
-
-build_main hello_message
-zip hello_message.zip exec
-cp exec hello_message
-
-build_main hello_greeting
-zip hello_greeting.zip exec
-cp exec hello_greeting
-
-test -e hello.zip && rm hello.zip
-cd src
-zip -q -r ../hello.zip main.go hello
-cd ..
-
-build exec
-test -e exec.zip && rm exec.zip
-zip -q -r exec.zip exec etc dir
+find "$1" | sort
diff --git a/openwhisk/_test/pysample/exec b/openwhisk/_test/pysample/exec
new file mode 100755
index 0000000..eedf580
--- /dev/null
+++ b/openwhisk/_test/pysample/exec
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements; and to You under the Apache License, Version 2.0.
+cd "$(dirname $0)"
+export PYTHONPATH=$PWD/lib
+python lib/exec.py
diff --git a/openwhisk/_test/pysample/lib/action/__init__.py b/openwhisk/_test/pysample/lib/action/__init__.py
new file mode 100644
index 0000000..e4e2475
--- /dev/null
+++ b/openwhisk/_test/pysample/lib/action/__init__.py
@@ -0,0 +1,2 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements; and to You under the Apache License, Version 2.0.
diff --git a/openwhisk/_test/pysample/lib/action/main.py b/openwhisk/_test/pysample/lib/action/main.py
new file mode 100644
index 0000000..1796dbf
--- /dev/null
+++ b/openwhisk/_test/pysample/lib/action/main.py
@@ -0,0 +1,7 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements; and to You under the Apache License, Version 2.0.
+def main(args):
+ name = "world"
+ if "name" in args:
+ name = args["name"]
+ return {"python": "Hello, %s" % name }
diff --git a/openwhisk/_test/pysample/lib/exec.py b/openwhisk/_test/pysample/lib/exec.py
new file mode 100644
index 0000000..4bd6ac1
--- /dev/null
+++ b/openwhisk/_test/pysample/lib/exec.py
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements; and to You under the Apache License, Version 2.0.
+
+from __future__ import print_function
+import os, json
+from action.main import main
+inp = os.fdopen(0, "rb")
+out = os.fdopen(3, "wb")
+while True:
+ while True:
+ line = inp.readline()
+ args = json.loads(line)
+ payload = {}
+ if "value" in args:
+ payload = args["value"]
+ res = main(payload)
+ out.write(json.dumps(res, ensure_ascii=False).encode('utf-8'))
+ out.write("\n")
+ out.flush()
+
diff --git a/openwhisk/actionProxy.go b/openwhisk/actionProxy.go
index cb6e441..22bb31c 100644
--- a/openwhisk/actionProxy.go
+++ b/openwhisk/actionProxy.go
@@ -19,9 +19,12 @@ package openwhisk
import (
"fmt"
+ "io"
+ "io/ioutil"
"log"
"net/http"
"os"
+ "path/filepath"
)
// ActionProxy is the container of the data specific to a server
@@ -100,7 +103,6 @@ func (ap *ActionProxy) StartLatestAction() error {
Debug("removing the failed action in %s", exeDir)
os.RemoveAll(exeDir)
}
-
return err
}
@@ -115,9 +117,33 @@ func (ap *ActionProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
{
// Start creates a proxy to execute actions
func (ap *ActionProxy) Start(port int) {
-
// listen and start
- //http.HandleFunc("/init", func(w http.ResponseWriter, r *http.Request) { ap.initHandler(w,
r) })
- //http.HandleFunc("/run", func(w http.ResponseWriter, r *http.Request) { ap.runHandler(w,
r) })
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), ap))
}
+
+// ExtractAndCompileIO read in input and write in output to use the runtime as a compiler
"on-the-fly"
+func (ap *ActionProxy) ExtractAndCompileIO(r io.Reader, w io.Writer, main string) {
+
+ // read the std input
+ in, err := ioutil.ReadAll(r)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // extract and compile it
+ file, err := ap.ExtractAndCompile(&in, main)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // zip the directory containing the file and write output
+ zip, err := Zip(filepath.Dir(file))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ _, err = w.Write(zip)
+ if err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/openwhisk/actionProxy_test.go b/openwhisk/actionProxy_test.go
index 2d767af..31901c0 100644
--- a/openwhisk/actionProxy_test.go
+++ b/openwhisk/actionProxy_test.go
@@ -18,8 +18,10 @@
package openwhisk
import (
+ "bytes"
"fmt"
"io/ioutil"
+ "log"
"os"
"testing"
@@ -81,3 +83,45 @@ func TestStartLatestAction_emit2(t *testing.T) {
/**/
ap.theExecutor.Stop()
}
+
+func Example_compile_bin() {
+ os.RemoveAll("./action/c1")
+ logf, _ := ioutil.TempFile("/tmp", "log")
+ ap := NewActionProxy("./action/c1", "_test/compile.py", logf, logf)
+ dat, _ := Zip("_test/pysample")
+ inp := bytes.NewBuffer(dat)
+ out := new(bytes.Buffer)
+ ap.ExtractAndCompileIO(inp, out, "main")
+ Unzip(out.Bytes(), "./action/c1/out")
+ sys("_test/find.sh", "./action/c1/out")
+ // Output:
+ // ./action/c1/out
+ // ./action/c1/out/exec
+ // ./action/c1/out/lib
+ // ./action/c1/out/lib/action
+ // ./action/c1/out/lib/action/__init__.py
+ // ./action/c1/out/lib/action/main.py
+ // ./action/c1/out/lib/exec.py
+}
+
+func Example_compile_src() {
+ os.RemoveAll("./action/c2")
+ logf, _ := ioutil.TempFile("/tmp", "log")
+ ap := NewActionProxy("./action/c2", "_test/compile.py", logf, logf)
+ log.Println(ioutil.ReadAll(logf))
+ dat, _ := Zip("_test/pysample/lib")
+ inp := bytes.NewBuffer(dat)
+ out := new(bytes.Buffer)
+ ap.ExtractAndCompileIO(inp, out, "main")
+ Unzip(out.Bytes(), "./action/c2/out")
+ sys("_test/find.sh", "./action/c2/out")
+ // Output:
+ // ./action/c2/out
+ // ./action/c2/out/action
+ // ./action/c2/out/action/action
+ // ./action/c2/out/action/action/__init__.py
+ // ./action/c2/out/action/action/main.py
+ // ./action/c2/out/action/exec.py
+ // ./action/c2/out/exec
+
+}
diff --git a/openwhisk/compiler_test.go b/openwhisk/compiler_test.go
index ca43b2a..ed91ad4 100644
--- a/openwhisk/compiler_test.go
+++ b/openwhisk/compiler_test.go
@@ -50,7 +50,7 @@ const (
)
// compile a main
-func Example_compile() {
+func Example_cli_compiler() {
sys(PREP, "hello.src", "0", "exec")
ap := NewActionProxy(TMP, COMP, os.Stdout, os.Stderr)
fmt.Println(isCompiled(TMP + "0/src/exec"))
diff --git a/openwhisk/extractor.go b/openwhisk/extractor.go
index 8140151..f750fc6 100644
--- a/openwhisk/extractor.go
+++ b/openwhisk/extractor.go
@@ -18,66 +18,12 @@
package openwhisk
import (
- "archive/zip"
- "bytes"
"fmt"
- "io"
"io/ioutil"
"os"
- "path/filepath"
"strconv"
)
-func unzip(src []byte, dest string) error {
- reader := bytes.NewReader(src)
- r, err := zip.NewReader(reader, int64(len(src)))
- if err != nil {
- return err
- }
-
- os.MkdirAll(dest, 0755)
-
- // Closure to address file descriptors issue with all the deferred .Close() methods
- extractAndWriteFile := func(f *zip.File) error {
- rc, err := f.Open()
- if err != nil {
- return err
- }
- defer func() {
- rc.Close()
- }()
-
- path := filepath.Join(dest, f.Name)
-
- if f.FileInfo().IsDir() {
- os.MkdirAll(path, f.Mode())
- } else {
- os.MkdirAll(filepath.Dir(path), f.Mode())
- f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
- if err != nil {
- return err
- }
- defer func() {
- f.Close()
- }()
-
- _, err = io.Copy(f, rc)
- if err != nil {
- return err
- }
- }
- return nil
- }
-
- for _, f := range r.File {
- err := extractAndWriteFile(f)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
// higherDir will find the highest numeric name a sub directory has
// 0 if no numeric dir names found
func highestDir(dir string) int {
@@ -111,7 +57,7 @@ func (ap *ActionProxy) ExtractAction(buf *[]byte, suffix string) (string,
error)
file := newDir + "/exec"
if IsZip(*buf) {
Debug("Extract Action, assuming a zip")
- return file, unzip(*buf, newDir)
+ return file, Unzip(*buf, newDir)
}
return file, ioutil.WriteFile(file, *buf, 0755)
}
diff --git a/openwhisk/extractor_test.go b/openwhisk/extractor_test.go
index 891d7d2..c3009ad 100644
--- a/openwhisk/extractor_test.go
+++ b/openwhisk/extractor_test.go
@@ -74,7 +74,7 @@ func TestHighestDir(t *testing.T) {
}
// Issue #62 sample zip
-func ExampleBadZip() {
+func Example_badZip() {
buf := []byte{
0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xb0, 0x81, 0x4d, 0x2d,
0xf6,
0xa5, 0x66, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x09, 0x00, 0x1c, 0x00, 0x69,
0x6e,
diff --git a/openwhisk/filetype.go b/openwhisk/filetype.go
index f4d6c3d..4825837 100644
--- a/openwhisk/filetype.go
+++ b/openwhisk/filetype.go
@@ -37,13 +37,19 @@ func IsMach64(buf []byte) bool {
buf[2] == 0xed && buf[3] == 0xfe
}
+// IsBangPath checks for a shell executable
+func IsBangPath(buf []byte) bool {
+ return len(buf) > 2 &&
+ buf[0] == '#' && buf[1] == '!'
+}
+
// IsExecutable check if it is an executable, according the current runtime
func IsExecutable(buf []byte, runtime string) bool {
switch runtime {
case "darwin":
- return IsMach64(buf)
+ return IsMach64(buf) || IsBangPath(buf)
case "linux":
- return IsElf(buf)
+ return IsElf(buf) || IsBangPath(buf)
case "windows":
return IsExe(buf)
default:
diff --git a/openwhisk/filetype_test.go b/openwhisk/filetype_test.go
index 5f016c6..1ee6986 100644
--- a/openwhisk/filetype_test.go
+++ b/openwhisk/filetype_test.go
@@ -37,6 +37,8 @@ var windowsFile = []byte{
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00,
}
+var shellFile = []byte("#!/bin/sh\necho hello\n")
+
func Example_filetype() {
fmt.Printf("%t\n%t\n", IsElf(linuxFile), IsElf(zipFile))
fmt.Printf("%t\n%t\n", IsMach64(darwinFile), IsMach64(zipFile))
@@ -45,6 +47,7 @@ func Example_filetype() {
fmt.Printf("%t\n%t\n", IsExecutable(linuxFile, "linux"), IsExecutable(zipFile, "linux"))
fmt.Printf("%t\n%t\n", IsExecutable(windowsFile, "windows"), IsExecutable(zipFile, "windows"))
fmt.Printf("%t\n%t\n", IsExecutable(darwinFile, "darwin"), IsExecutable(zipFile, "darwin"))
+ fmt.Printf("%t\n%t\n%t\n", IsExecutable(shellFile, "darwin"), IsExecutable(shellFile, "linux"),
IsExecutable(shellFile, "windows"))
// Output:
// true
// false
@@ -60,5 +63,8 @@ func Example_filetype() {
// false
// true
// false
+ // true
+ // true
+ // false
}
diff --git a/openwhisk/initHandler.go b/openwhisk/initHandler.go
index 73b5ffd..474e85c 100644
--- a/openwhisk/initHandler.go
+++ b/openwhisk/initHandler.go
@@ -127,14 +127,9 @@ func (ap *ActionProxy) initHandler(w http.ResponseWriter, r *http.Request)
{
// ExtractAndCompile decode the buffer and if a compiler is defined, compile it also
func (ap *ActionProxy) ExtractAndCompile(buf *[]byte, main string) (string, error) {
- // extract in "bin" or in "src" if the runtime can compile
- suffix := "bin"
- if ap.compiler != "" {
- suffix = "src"
- }
- // extract action
- file, err := ap.ExtractAction(buf, suffix)
+ // extract action in src folder
+ file, err := ap.ExtractAction(buf, "src")
if err != nil {
return "", err
}
@@ -148,26 +143,21 @@ func (ap *ActionProxy) ExtractAndCompile(buf *[]byte, main string) (string,
erro
srcDir := filepath.Join(parent, "src")
binDir := filepath.Join(parent, "bin")
binFile := filepath.Join(binDir, "exec")
- os.Mkdir(binDir, 0755)
-
- // if the file is already compiled just move it from src to bin
- if isCompiled(file) {
- os.Rename(file, binFile)
- return binFile, nil
- }
- // no compiler, move it anyway
- if ap.compiler == "" {
- os.Rename(file, binFile)
+ // if the file is already compiled or there is no compiler just move it from src to bin
+ if ap.compiler == "" || isCompiled(file) {
+ os.Rename(srcDir, binDir)
return binFile, nil
}
// ok let's try to compile
Debug("compiling: %s main: %s", file, main)
+ os.Mkdir(binDir, 0755)
err = ap.CompileAction(main, srcDir, binDir)
if err != nil {
return "", err
}
+
// check only if the file exist
if _, err := os.Stat(binFile); os.IsNotExist(err) {
return "", fmt.Errorf("cannot compile")
diff --git a/openwhisk/initHandler_test.go b/openwhisk/initHandler_test.go
index de71f6d..c76a86c 100644
--- a/openwhisk/initHandler_test.go
+++ b/openwhisk/initHandler_test.go
@@ -226,3 +226,20 @@ func Example_badinit_nocompiler() {
// 500 {"error":"no action defined yet"}
// hi
}
+
+func Example_zip_init() {
+ ts, cur, log := startTestServer("")
+ buf, _ := Zip("_test/pysample")
+ doInit(ts, initBytes(buf, ""))
+ doRun(ts, ``)
+ doRun(ts, `{"name":"World"}`)
+ stopTestServer(ts, cur, log)
+ // Output:
+ // 200 {"ok":true}
+ // 200 {"python": "Hello, Mike"}
+ // 200 {"python": "Hello, World"}
+ // XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+ // XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+ // XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+ // XXX_THE_END_OF_A_WHISK_ACTIVATION_XXX
+}
diff --git a/openwhisk/util_test.go b/openwhisk/util_test.go
index 59fd5f3..19a0d4c 100644
--- a/openwhisk/util_test.go
+++ b/openwhisk/util_test.go
@@ -110,8 +110,7 @@ func initCode(file string, main string) string {
return string(j)
}
-func initBinary(file string, main string) string {
- dat, _ := ioutil.ReadFile(file)
+func initBytes(dat []byte, main string) string {
enc := base64.StdEncoding.EncodeToString(dat)
body := initBodyRequest{Binary: true, Code: enc}
if main != "" {
@@ -121,6 +120,11 @@ func initBinary(file string, main string) string {
return string(j)
}
+func initBinary(file string, main string) string {
+ dat, _ := ioutil.ReadFile(file)
+ return initBytes(dat, main)
+}
+
func abs(in string) string {
out, _ := filepath.Abs(in)
return out
@@ -166,17 +170,18 @@ func removeLineNr(out string) string {
return re.ReplaceAllString(out, "::")
}
func TestMain(m *testing.M) {
- // Debugging = true // enable debug
- // silence those annoying logs
- if !Debugging {
+ var Debug = false // enable debug of tests
+ if !Debug {
+ // silence those annoying tests
log.SetOutput(ioutil.Discard)
+ // build support files
+ sys("_test/build.sh")
+ sys("_test/zips.sh")
}
// increase timeouts for init
DefaultTimeoutStart = 1000 * time.Millisecond
// build some test stuff
- sys("_test/build.sh")
- sys("_test/zips.sh")
// go ahead
code := m.Run()
os.Exit(code)
diff --git a/openwhisk/version.go b/openwhisk/version.go
index 27af90b..3640360 100644
--- a/openwhisk/version.go
+++ b/openwhisk/version.go
@@ -17,4 +17,4 @@
package openwhisk
// Version number - internal
-var Version = "1.0.1"
+var Version = "2"
diff --git a/openwhisk/zip.go b/openwhisk/zip.go
new file mode 100644
index 0000000..36ae387
--- /dev/null
+++ b/openwhisk/zip.go
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package openwhisk
+
+import (
+ "archive/zip"
+ "bytes"
+ "io"
+ "log"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+// Unzip extracts file and directories in the given destination folder
+func Unzip(src []byte, dest string) error {
+ reader := bytes.NewReader(src)
+ r, err := zip.NewReader(reader, int64(len(src)))
+ if err != nil {
+ return err
+ }
+ os.MkdirAll(dest, 0755)
+ // Closure to address file descriptors issue with all the deferred .Close() methods
+ extractAndWriteFile := func(f *zip.File) error {
+ rc, err := f.Open()
+ defer rc.Close()
+ if err != nil {
+ return err
+ }
+ path := filepath.Join(dest, f.Name)
+ if f.FileInfo().IsDir() {
+ return os.MkdirAll(path, f.Mode())
+ }
+ err = os.MkdirAll(filepath.Dir(path), 0755)
+ if err != nil {
+ return err
+ }
+ file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
+ defer file.Close()
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(file, rc)
+ return err
+ }
+ for _, f := range r.File {
+ err := extractAndWriteFile(f)
+ if err != nil {
+ log.Println(err)
+ }
+ }
+ return nil
+}
+
+// Zip a directory
+func Zip(dir string) ([]byte, error) {
+ buf := new(bytes.Buffer)
+ zwr := zip.NewWriter(buf)
+ dir = filepath.Clean(dir)
+ err := filepath.Walk(dir, func(filePath string, info os.FileInfo, err error) error {
+ if info.IsDir() {
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+ relPath := strings.TrimPrefix(filePath, dir)[1:]
+ zipFile, err := zwr.Create(relPath)
+ if err != nil {
+ return err
+ }
+ fsFile, err := os.Open(filePath)
+ if err != nil {
+ return err
+ }
+ _, err = io.Copy(zipFile, fsFile)
+ if err != nil {
+ return err
+ }
+ return nil
+ })
+ if err != nil {
+ return nil, err
+ }
+ err = zwr.Close()
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
diff --git a/openwhisk/version.go b/openwhisk/zip_test.go
similarity index 62%
copy from openwhisk/version.go
copy to openwhisk/zip_test.go
index 27af90b..a2c8eef 100644
--- a/openwhisk/version.go
+++ b/openwhisk/zip_test.go
@@ -16,5 +16,27 @@
*/
package openwhisk
-// Version number - internal
-var Version = "1.0.1"
+import (
+ "fmt"
+ "os"
+)
+
+func Example() {
+ os.RemoveAll("./action/unzip")
+ os.Mkdir("./action/unzip", 0755)
+ buf, err := Zip("_test/pysample")
+ fmt.Println(err)
+ err = Unzip(buf, "./action/unzip")
+ sys("_test/find.sh", "./action/unzip")
+ fmt.Println(err)
+ // Output:
+ // <nil>
+ // ./action/unzip
+ // ./action/unzip/exec
+ // ./action/unzip/lib
+ // ./action/unzip/lib/action
+ // ./action/unzip/lib/action/__init__.py
+ // ./action/unzip/lib/action/main.py
+ // ./action/unzip/lib/exec.py
+ // <nil>
+}
diff --git a/settings.gradle b/settings.gradle
index 01343e2..15eaa52 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -17,7 +17,7 @@
include 'tests'
-include 'actionProxyLoop'
+include 'actionloop'
include 'golang1.11'
rootProject.name = 'runtime-golang'
@@ -35,4 +35,3 @@ gradle.ext.scalafmt = [
version: '1.5.0',
config: new File(rootProject.projectDir, '.scalafmt.conf')
]
-
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicTests.scala
index 7936af4..1a346ce 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicTests.scala
@@ -25,7 +25,7 @@ import org.scalatest.junit.JUnitRunner
@RunWith(classOf[JUnitRunner])
class ActionLoopBasicTests extends BasicActionRunnerTests with WskActorSystem {
- val image = "actionloop"
+ val image = "actionloop-v2"
override def withActionContainer(env: Map[String, String] = Map.empty)(
code: ActionContainer => Unit) = {
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionLoopContainerTests.scala
b/tests/src/test/scala/runtime/actionContainers/ActionLoopContainerTests.scala
index 0e35784..59ff555 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionLoopContainerTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionLoopContainerTests.scala
@@ -32,12 +32,12 @@ class ActionLoopContainerTests
import GoResourceHelpers._
- val image = "actionloop"
+ val image = "actionloop-v2"
def withActionLoopContainer(code: ActionContainer => Unit) =
- withContainer("actionloop")(code)
+ withContainer(image)(code)
- behavior of "actionloop"
+ behavior of image
def shCodeHello(main: String) = Seq(
Seq(main) ->
|