This is an automated email from the ASF dual-hosted git repository.
dgrove pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-runtime-go.git
The following commit(s) were added to refs/heads/master by this push:
new 5780644 add golang1.17 as a runtime (#157)
5780644 is described below
commit 57806447fd0a7365b06530d819d8a1494ca76038
Author: David Grove <[email protected]>
AuthorDate: Mon Dec 13 12:19:28 2021 -0500
add golang1.17 as a runtime (#157)
---
.travis.yml | 2 +-
golang1.17/Dockerfile | 51 ++++++++
golang1.17/Makefile | 44 +++++++
golang1.17/bin/compile | 138 +++++++++++++++++++++
settings.gradle => golang1.17/build.gradle | 39 +++---
golang1.17/lib/launcher.go | 122 ++++++++++++++++++
settings.gradle | 1 +
.../ActionLoopBasicGo17Tests.scala | 36 ++----
.../ActionLoopGo17ContainerTests.scala | 34 ++---
9 files changed, 397 insertions(+), 70 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 22ae419..c09cd0b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -51,7 +51,7 @@ deploy:
repo: apache/openwhisk-runtime-go
- provider: script
skip_cleanup: true
- script: "./tools/travis/publish.sh openwhisk 1.13 nightly &&
./tools/travis/publish.sh openwhisk 1.15 nightly && ./tools/travis/publish.sh
openwhisk 1.16 nightly"
+ script: "./tools/travis/publish.sh openwhisk 1.13 nightly &&
./tools/travis/publish.sh openwhisk 1.15 nightly && ./tools/travis/publish.sh
openwhisk 1.16 nightly && ./tools/travis/publish.sh openwhisk 1.17 nightly"
on:
branch: master
repo: apache/openwhisk-runtime-go
diff --git a/golang1.17/Dockerfile b/golang1.17/Dockerfile
new file mode 100644
index 0000000..2f557e4
--- /dev/null
+++ b/golang1.17/Dockerfile
@@ -0,0 +1,51 @@
+#
+# 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.
+#
+
+# Do not fix the patch level for golang:1.17 to automatically get security
fixes.
+FROM golang:1.17-buster
+
+RUN echo "deb http://deb.debian.org/debian buster-backports main contrib
non-free" \
+ >>/etc/apt/sources.list &&\
+ echo 'debconf debconf/frontend select Noninteractive' |
debconf-set-selections &&\
+ apt-get update &&\
+ # Upgrade installed packages to get latest security fixes if the base
image does not contain them already.
+ apt-get upgrade -y --no-install-recommends &&\
+ apt-get install -y apt-utils &&\
+ apt-get install -y \
+ curl \
+ jq \
+ git \
+ vim &&\
+ apt-get -y install \
+ librdkafka1=0.11.6-1.1 \
+ librdkafka++1=0.11.6-1.1 &&\
+ apt-get -y install \
+ librdkafka-dev=0.11.6-1.1 &&\
+ # Cleanup apt data, we do not need them later on.
+ apt-get clean && rm -rf /var/lib/apt/lists/* &&\
+ go get -u github.com/go-delve/delve/cmd/dlv &&\
+ mkdir /action
+
+WORKDIR /action
+ADD proxy /bin/proxy
+ADD bin/compile /bin/compile
+ADD lib/launcher.go /lib/launcher.go
+ENV OW_COMPILER=/bin/compile
+ENV OW_LOG_INIT_ERROR=1
+ENV OW_WAIT_FOR_ACK=1
+ENV OW_EXECUTION_ENV=openwhisk/action-golang-v1.17
+ENTRYPOINT [ "/bin/proxy" ]
diff --git a/golang1.17/Makefile b/golang1.17/Makefile
new file mode 100644
index 0000000..bc87b7a
--- /dev/null
+++ b/golang1.17/Makefile
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+IMG=action-golang-v1.17
+
+build:
+ ../gradlew distDocker
+
+localbuild:
+ GOOS=linux GOARCH=amd64 go build -o proxy -a -ldflags '-extldflags
"-static"' ../main/proxy.go
+ docker build -t $(IMG) .
+ docker tag $(IMG) whisk/$(IMG)
+
+push: build
+ docker tag $(IMG) actionloop/$(IMG)
+ docker push actionloop/$(IMG):nightly
+
+clean:
+ docker rmi -f whisk/$(IMG) actionloop/$(IMG)
+
+debug: build
+ docker run -p 8080:8080 \
+ --name go-action --rm -ti --entrypoint=/bin/bash \
+ -e OW_COMPILER=/mnt/bin/compile \
+ -v $(PWD):/mnt whisk/$(IMG)
+
+enter:
+ docker exec -ti go-action bash
+
+
+.PHONY: build push clean debug enter
diff --git a/golang1.17/bin/compile b/golang1.17/bin/compile
new file mode 100755
index 0000000..9b1217f
--- /dev/null
+++ b/golang1.17/bin/compile
@@ -0,0 +1,138 @@
+#!/usr/bin/python -u
+"""Golang Action Compiler
+#
+# 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.
+#
+"""
+from __future__ import print_function
+import os, os.path, sys, re, shutil, subprocess, traceback, codecs
+from os.path import dirname, exists
+from time import sleep
+
+# write a file creating intermediate directories
+def write_file(file, body, executable=False):
+ try: os.makedirs(dirname(file), mode=0o755)
+ except: pass
+ with open(file, mode="wb") as f:
+ f.write(body)
+ if executable:
+ os.chmod(file, 0o755)
+
+# copy a file eventually replacing a substring
+def copy_replace(src, dst, match=None, replacement=""):
+ with open(src, 'rb') as s:
+ body = s.read()
+ if match:
+ body = body.replace(match, replacement)
+ write_file(dst, body)
+
+
+def sources(launcher, source_dir, main):
+ func = main.capitalize()
+ has_main = None
+
+ # copy the exec to exec.go
+ # also check if it has a main in it
+ src = "%s/exec" % source_dir
+ dst = "%s/exec__.go" % source_dir
+ if os.path.isfile(src):
+ with codecs.open(src, 'r', 'utf-8') as s:
+ with codecs.open(dst, 'w', 'utf-8') as d:
+ body = s.read()
+ has_main =
re.match(r".*package\s+main\W.*func\s+main\s*\(\s*\)", body, flags=re.DOTALL)
+ d.write(body)
+
+ # copy the launcher fixing the main
+ if not has_main:
+ dst = "%s/main__.go" % source_dir
+ if os.path.isdir("%s/main" % source_dir):
+ dst = "%s/main/main__.go" % source_dir
+ with codecs.open(dst, 'w', 'utf-8') as d:
+ with codecs.open(launcher, 'r', 'utf-8') as e:
+ code = e.read()
+ code = code.replace("Main", func)
+ d.write(code)
+
+def build(source_dir, target_dir):
+ # compile...
+ source_dir = os.path.abspath(source_dir)
+ parent = dirname(source_dir)
+ target = os.path.abspath("%s/exec" % target_dir)
+ if os.environ.get("__OW_EXECUTION_ENV"):
+ write_file("%s.env" % target, os.environ["__OW_EXECUTION_ENV"])
+
+ env = {
+ "GOROOT": "/usr/local/go",
+ "GOPATH": "/home/go",
+ "PATH": os.environ["PATH"],
+ "GOCACHE": "/tmp",
+ "GO111MODULE": "on"
+ }
+
+ gomod = "%s/go.mod" % source_dir
+ with open(os.devnull, "w") as dn:
+ if exists(gomod):
+ ret = subprocess.call(["go", "mod", "download"], cwd=source_dir,
env=env, stderr=dn, stdout=dn)
+ if ret != 0:
+ print("cannot download modules")
+ return
+ else:
+ ret = subprocess.call(["go", "mod", "init", "exec"],
cwd=source_dir, env=env, stdout=dn, stderr=dn)
+ if ret != 0:
+ print("cannot init modules")
+ return
+
+ ldflags = "-s -w"
+ gobuild = ["go", "build", "-o", target, "-ldflags", ldflags]
+ if os.environ.get("__OW_EXECUTION_ENV"):
+ ldflags += " -X main.OwExecutionEnv=%s" %
os.environ["__OW_EXECUTION_ENV"]
+ ret = subprocess.call(gobuild, cwd=source_dir, env=env)
+ if ret != 0:
+ print("failed", " ".join(gobuild), "\nin", source_dir, "\nenv", env)
+
+def debug(source_dir, target_dir, port):
+ source_dir = os.path.abspath(source_dir)
+ target = os.path.abspath("%s/exec" % target_dir)
+ if os.environ.get("__OW_EXECUTION_ENV"):
+ write_file("%s/exec.env" % source_dir, os.environ["__OW_EXECUTION_ENV"])
+ shutil.rmtree(target_dir)
+ shutil.move(source_dir, target_dir)
+ write_file(target, """#!/bin/bash
+cd "$(dirname $0)"
+export GOCACHE=/tmp
+export PATH=%s
+exec script -q -c '/go/bin/dlv debug --headless --listen=127.0.0.1:%s
--continue --accept-multiclient --log-dest /tmp/delve.log'
+""" % (os.environ["PATH"], port) , True)
+
+def main(argv):
+ if len(argv) < 4:
+ print("usage: <main-file> <source-dir> <target-dir>")
+ sys.exit(1)
+
+ main = argv[1]
+ source_dir = argv[2]
+ target_dir = argv[3]
+ launcher = dirname(dirname(argv[0]))+"/lib/launcher.go"
+ sources(launcher, source_dir, main)
+
+ # if the debug port is present and not empty build with debug
+ if os.environ.get("__OW_DEBUG_PORT"):
+ debug(source_dir, target_dir, os.environ["__OW_DEBUG_PORT"])
+ else:
+ build(source_dir, target_dir)
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/settings.gradle b/golang1.17/build.gradle
similarity index 58%
copy from settings.gradle
copy to golang1.17/build.gradle
index 8d52e78..429b380 100644
--- a/settings.gradle
+++ b/golang1.17/build.gradle
@@ -15,29 +15,24 @@
* limitations under the License.
*/
-include 'tests'
+ext.dockerImageName = 'action-golang-v1.17'
+apply from: '../gradle/docker.gradle'
-include 'actionloop'
-include 'golang1.13'
-include 'golang1.15'
-include 'golang1.16'
+distDocker.dependsOn 'staticBuildProxy'
+distDocker.finalizedBy('cleanup')
-rootProject.name = 'runtime-golang'
+task staticBuildProxy(type: Exec) {
+ environment CGO_ENABLED: "0"
+ environment GOOS: "linux"
+ environment GOARCH: "amd64"
+ environment GO111MODULE: "on"
-gradle.ext.openwhisk = [
- version: '1.0.0-SNAPSHOT'
-]
+ commandLine 'go', 'build',
+ '-o', 'proxy', '-a',
+ '-ldflags', '-extldflags "-static"',
+ '../main/proxy.go'
+}
-gradle.ext.scala = [
- version: '2.12.7',
- depVersion : '2.12',
- compileFlags: ['-feature', '-unchecked', '-deprecation',
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
- version: '1.5.0',
- config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
+task cleanup(type: Delete) {
+ delete 'proxy'
+}
diff --git a/golang1.17/lib/launcher.go b/golang1.17/lib/launcher.go
new file mode 100644
index 0000000..3f95c15
--- /dev/null
+++ b/golang1.17/lib/launcher.go
@@ -0,0 +1,122 @@
+/*
+ * 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 main
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strings"
+)
+
+// OwExecutionEnv is the execution environment set at compile time
+var OwExecutionEnv = ""
+
+func main() {
+ // check if the execution environment is correct
+ if OwExecutionEnv != "" && OwExecutionEnv !=
os.Getenv("__OW_EXECUTION_ENV") {
+ fmt.Println("Execution Environment Mismatch")
+ fmt.Println("Expected: ", OwExecutionEnv)
+ fmt.Println("Actual: ", os.Getenv("__OW_EXECUTION_ENV"))
+ os.Exit(1)
+ }
+
+ // debugging
+ var debug = os.Getenv("OW_DEBUG") != ""
+ if debug {
+ f, err := os.OpenFile("/tmp/action.log",
os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+ if err == nil {
+ log.SetOutput(f)
+ }
+ log.Printf("Environment: %v", os.Environ())
+ }
+
+ // assign the main function
+ type Action func(event map[string]interface{}) map[string]interface{}
+ var action Action
+ action = Main
+
+ // input
+ out := os.NewFile(3, "pipe")
+ defer out.Close()
+ reader := bufio.NewReader(os.Stdin)
+
+ // acknowledgement of started action
+ fmt.Fprintf(out, `{ "ok": true}%s`, "\n")
+ if debug {
+ log.Println("action started")
+ }
+
+ // read-eval-print loop
+ for {
+ // read one line
+ inbuf, err := reader.ReadBytes('\n')
+ if err != nil {
+ if err != io.EOF {
+ log.Println(err)
+ }
+ break
+ }
+ if debug {
+ log.Printf(">>>'%s'>>>", inbuf)
+ }
+ // parse one line
+ var input map[string]interface{}
+ err = json.Unmarshal(inbuf, &input)
+ if err != nil {
+ log.Println(err.Error())
+ fmt.Fprintf(out, "{ error: %q}\n", err.Error())
+ continue
+ }
+ if debug {
+ log.Printf("%v\n", input)
+ }
+ // set environment variables
+ for k, v := range input {
+ if k == "value" {
+ continue
+ }
+ if s, ok := v.(string); ok {
+ os.Setenv("__OW_"+strings.ToUpper(k), s)
+ }
+ }
+ // get payload if not empty
+ var payload map[string]interface{}
+ if value, ok := input["value"].(map[string]interface{}); ok {
+ payload = value
+ }
+ // process the request
+ result := action(payload)
+ // encode the answer
+ output, err := json.Marshal(&result)
+ if err != nil {
+ log.Println(err.Error())
+ fmt.Fprintf(out, "{ error: %q}\n", err.Error())
+ continue
+ }
+ output = bytes.Replace(output, []byte("\n"), []byte(""), -1)
+ if debug {
+ log.Printf("<<<'%s'<<<", output)
+ }
+ fmt.Fprintf(out, "%s\n", output)
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index 8d52e78..3a5c5ba 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -21,6 +21,7 @@ include 'actionloop'
include 'golang1.13'
include 'golang1.15'
include 'golang1.16'
+include 'golang1.17'
rootProject.name = 'runtime-golang'
diff --git a/settings.gradle
b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo17Tests.scala
similarity index 58%
copy from settings.gradle
copy to
tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo17Tests.scala
index 8d52e78..aa8269a 100644
--- a/settings.gradle
+++
b/tests/src/test/scala/runtime/actionContainers/ActionLoopBasicGo17Tests.scala
@@ -14,30 +14,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package runtime.actionContainers
-include 'tests'
+import common.WskActorSystem
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
-include 'actionloop'
-include 'golang1.13'
-include 'golang1.15'
-include 'golang1.16'
+@RunWith(classOf[JUnitRunner])
+class ActionLoopBasicGo17Tests
+ extends ActionLoopBasicGoTests
+ with WskActorSystem {
-rootProject.name = 'runtime-golang'
-
-gradle.ext.openwhisk = [
- version: '1.0.0-SNAPSHOT'
-]
-
-gradle.ext.scala = [
- version: '2.12.7',
- depVersion : '2.12',
- compileFlags: ['-feature', '-unchecked', '-deprecation',
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
- version: '1.5.0',
- config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
+ override lazy val goCompiler = "action-golang-v1.17"
+ override lazy val image = goCompiler
+ override lazy val requireAck = true
+}
diff --git a/settings.gradle
b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo17ContainerTests.scala
similarity index 58%
copy from settings.gradle
copy to
tests/src/test/scala/runtime/actionContainers/ActionLoopGo17ContainerTests.scala
index 8d52e78..bfb7b15 100644
--- a/settings.gradle
+++
b/tests/src/test/scala/runtime/actionContainers/ActionLoopGo17ContainerTests.scala
@@ -15,29 +15,17 @@
* limitations under the License.
*/
-include 'tests'
+package runtime.actionContainers
-include 'actionloop'
-include 'golang1.13'
-include 'golang1.15'
-include 'golang1.16'
+import common.WskActorSystem
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+@RunWith(classOf[JUnitRunner])
+class ActionLoopGo17ContainerTests
+ extends ActionLoopGoContainerTests
+ with WskActorSystem {
-rootProject.name = 'runtime-golang'
+ override lazy val goCompiler = "action-golang-v1.17"
+ override lazy val image = goCompiler
-gradle.ext.openwhisk = [
- version: '1.0.0-SNAPSHOT'
-]
-
-gradle.ext.scala = [
- version: '2.12.7',
- depVersion : '2.12',
- compileFlags: ['-feature', '-unchecked', '-deprecation',
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
- version: '1.5.0',
- config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
+}