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-docker.git


The following commit(s) were added to refs/heads/master by this push:
     new a200df6  support large arguments (#3)
a200df6 is described below

commit a200df6c0f9765fe09ba8a80c11fb7df13fac72a
Author: RSulzmann <r...@de.ibm.com>
AuthorDate: Sun Feb 4 09:58:37 2018 +0100

    support large arguments (#3)
---
 core/actionProxy/actionproxy.py                    | 34 +++++++++++++++-------
 core/actionProxy/stub.sh                           | 14 +++++++--
 .../ActionProxyContainerTests.scala                | 19 ++++++++++++
 3 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/core/actionProxy/actionproxy.py b/core/actionProxy/actionproxy.py
index 8e43576..bbe9902 100644
--- a/core/actionProxy/actionproxy.py
+++ b/core/actionProxy/actionproxy.py
@@ -47,10 +47,11 @@ class ActionRunner:
     # @param source the path where the source code will be located (if any)
     # @param binary the path where the binary will be located (may be the
     # same as source code path)
-    def __init__(self, source=None, binary=None):
+    def __init__(self, source=None, binary=None, zipdest=None):
         defaultBinary = '/action/exec'
         self.source = source if source else defaultBinary
         self.binary = binary if binary else defaultBinary
+        self.zipdest = zipdest if zipdest else os.path.dirname(self.source)
 
     def preinit(self):
         return
@@ -127,18 +128,29 @@ class ActionRunner:
 
         try:
             input = json.dumps(args)
-            p = subprocess.Popen(
-                [self.binary, input],
-                stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE,
-                env=env)
+            if len(input) > 131071:             # MAX_ARG_STRLEN (131071) 
linux/binfmts.h
+                # pass argument via stdin
+                p = subprocess.Popen(
+                    [self.binary],
+                    stdin=subprocess.PIPE,
+                    stdout=subprocess.PIPE,
+                    stderr=subprocess.PIPE,
+                    env=env)
+            else:
+                # pass argument via stdin and command parameter
+                p = subprocess.Popen(
+                    [self.binary, input],
+                    stdin=subprocess.PIPE,
+                    stdout=subprocess.PIPE,
+                    stderr=subprocess.PIPE,
+                    env=env)
+            # run the process and wait until it completes.
+            # stdout/stderr will always be set because we passed PIPEs to Popen
+            (o, e) = p.communicate(input=input.encode())
+
         except Exception as e:
             return error(e)
 
-        # run the process and wait until it completes.
-        # stdout/stderr will always be set because we passed PIPEs to Popen
-        (o, e) = p.communicate()
-
         # stdout/stderr may be either text or bytes, depending on Python
         # version, so if bytes, decode to text. Note that in Python 2
         # a string will match both types; so also skip decoding in that case
@@ -182,7 +194,7 @@ class ActionRunner:
             bytes = base64.b64decode(message['code'])
             bytes = io.BytesIO(bytes)
             archive = zipfile.ZipFile(bytes)
-            archive.extractall(os.path.dirname(self.source))
+            archive.extractall(self.zipdest)
             archive.close()
             return True
         except Exception as e:
diff --git a/core/actionProxy/stub.sh b/core/actionProxy/stub.sh
index 842d00a..420b7fd 100644
--- a/core/actionProxy/stub.sh
+++ b/core/actionProxy/stub.sh
@@ -2,8 +2,18 @@
 
 echo \
 'This is a stub action that should be replaced with user code (e.g., script or 
compatible binary).
-The input to the action is received as an argument from the command line.
+The input to the action is received from stdin, and up to a size of 
MAX_ARG_STRLEN (131071) also as an argument from the command line.
 Actions may log to stdout or stderr. By convention, the last line of output 
must
 be a stringified JSON object which represents the result of the action.'
 
-echo '{ "error": "This is a stub action. Replace it with custom logic." }'
\ No newline at end of file
+# getting arguments from command line
+# only arguments up to a size of MAX_ARG_STRLEN (else empty) supported
+echo 'command line argument: '$1
+echo 'command line argument length: '${#1}
+
+# getting arguments from stdin
+read inputstring
+echo 'stdin input length: '${#inputstring}
+
+# last line of output = ation result
+echo '{ "error": "This is a stub action. Replace it with custom logic." }'
diff --git 
a/tests/src/test/scala/actionContainers/ActionProxyContainerTests.scala 
b/tests/src/test/scala/actionContainers/ActionProxyContainerTests.scala
index bcf5602..80109bc 100644
--- a/tests/src/test/scala/actionContainers/ActionProxyContainerTests.scala
+++ b/tests/src/test/scala/actionContainers/ActionProxyContainerTests.scala
@@ -343,4 +343,23 @@ trait BasicActionRunnerTests extends 
ActionProxyContainerTestUtils {
       }
     }
   }
+
+  it should "receive a large (1MB) argument" in {
+    withActionContainer() { c =>
+      val code = """
+                   |#!/bin/bash
+                   |  read inputstring
+                   |  echo $inputstring
+                   |
+                 """.stripMargin.trim
+
+      val (initCode, initRes) = c.init(initPayload(code))
+      initCode should be(200)
+
+      val arg = JsObject("arg" -> JsString(("a" * 1048561)))
+      val (_, runRes) = c.run(runPayload(arg))
+      runRes.get shouldBe arg
+    }
+  }
+
 }

-- 
To stop receiving notification emails like this one, please contact
csantan...@apache.org.

Reply via email to