You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2017/10/19 14:01:56 UTC

[incubator-openwhisk-cli] branch master updated (63e6635 -> 24f3a2b)

This is an automated email from the ASF dual-hosted git repository.

csantanapr pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git.


    from 63e6635  Update the client go verion to 4a63a306d52f5dd54454e0ba38e0c7eb9cb2852b
     new eeedc6c  Move docker runtime into its own repo  (#2850)
     new c692c98  Allow CLI to Save Code from Action (#2544)
     new 3ac6a03  Update the version of client go to ad5aa3402b033edd8b30aec7f33434a253aa35ed
     new 62c6d66  Delete test assets. (#2826)
     new baf3348  Make console tests more robust (#2831)
     new 771d533  Move docker runtime into its own repo  (#2850)
     new 24f3a2b  Allow CLI to Save Code from Action (#2544)

The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Godeps/Godeps.json                                 |   2 +-
 commands/action.go                                 | 187 +++++++++++++++++----
 commands/flags.go                                  |  15 +-
 commands/sdk.go                                    |   2 +-
 commands/util.go                                   | 135 ++++++++++++---
 .../test/scala/system/basic/WskConsoleTests.scala  |  56 ++++--
 .../src/test/scala/system/basic/WskSdkTests.scala  |   9 -
 .../whisk/core/cli/test/WskBasicUsageTests.scala   |  81 ++++++++-
 .../whisk/core/cli/test/WskEntitlementTests.scala  |  16 +-
 wski18n/i18n_resources.go                          |  22 +--
 wski18n/resources/en_US.all.json                   |  47 +++++-
 11 files changed, 456 insertions(+), 116 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
['"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>'].

[incubator-openwhisk-cli] 06/07: Move docker runtime into its own repo (#2850)

Posted by cs...@apache.org.
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-cli.git

commit 771d533c0c1a8ed4b69a300f804c58aa5497c000
Author: Carlos Santana <cs...@gmail.com>
AuthorDate: Tue Oct 17 17:56:37 2017 -0400

    Move docker runtime into its own repo  (#2850)
---
 tests/src/test/scala/system/basic/WskSdkTests.scala | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/tests/src/test/scala/system/basic/WskSdkTests.scala b/tests/src/test/scala/system/basic/WskSdkTests.scala
index 3e7e3b2..021e8ca 100644
--- a/tests/src/test/scala/system/basic/WskSdkTests.scala
+++ b/tests/src/test/scala/system/basic/WskSdkTests.scala
@@ -19,15 +19,12 @@ package system.basic
 
 import java.io.File
 
-import scala.collection.JavaConversions.asScalaBuffer
-
 import org.apache.commons.io.FileUtils
 import org.junit.runner.RunWith
 import org.scalatest.junit.JUnitRunner
 import common.TestHelpers
 import common.TestUtils.ERROR_EXIT
 import common.TestUtils.SUCCESS_EXIT
-import common.WhiskProperties
 import common.Wsk
 import common.WskProps
 import common.WskTestHelpers
@@ -78,12 +75,6 @@ class WskSdkTests extends TestHelpers with WskTestHelpers {
 
       val buildAndPushFile = new File(sdk, "buildAndPush.sh")
       buildAndPushFile.canExecute() should be(true)
-
-      // confirm there is no other divergence from the base dockerfile
-      val originalDockerfile = WhiskProperties.getFileRelativeToWhiskHome("sdk/docker/Dockerfile")
-      val originalLines = FileUtils.readLines(originalDockerfile)
-      lines.get(0) shouldBe originalLines.get(0)
-      lines.drop(2).mkString("\n") shouldBe originalLines.drop(2).mkString("\n")
     } finally {
       FileUtils.deleteDirectory(dir)
     }

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.

[incubator-openwhisk-cli] 07/07: Allow CLI to Save Code from Action (#2544)

Posted by cs...@apache.org.
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-cli.git

commit 24f3a2b9ef98d4f554922943c38cb5b270650e68
Author: James Dubee <jw...@us.ibm.com>
AuthorDate: Wed Oct 18 13:54:01 2017 -0400

    Allow CLI to Save Code from Action (#2544)
    
    * Allow CLI to Save Code from Action
    
    * Formatting changes
    
    * Test refactor
    
    * Update test
    
    * Refactor
    
    * Review updates
    
    * Review updates
---
 commands/action.go                                 |  2 +-
 .../whisk/core/cli/test/WskBasicUsageTests.scala   | 81 +++++++++++++++++++++-
 2 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/commands/action.go b/commands/action.go
index efbf842..75aa7c5 100644
--- a/commands/action.go
+++ b/commands/action.go
@@ -261,7 +261,7 @@ var actionGetCmd = &cobra.Command{
         } else if Flags.common.summary {
             printSummary(action)
         } else if cmd.LocalFlags().Changed(SAVE_AS_FLAG) || cmd.LocalFlags().Changed(SAVE_FLAG) {
-            return saveCode(*action, flags.action.saveAs)
+            return saveCode(*action, Flags.action.saveAs)
         } else {
             if len(field) > 0 {
                 printActionGetWithField(qualifiedName.GetEntityName(), field, action)
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
index ea23ce3..abac6c2 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala
@@ -21,6 +21,7 @@ import java.time.Instant
 import java.net.URLEncoder
 import java.nio.charset.StandardCharsets
 import java.time.Clock
+import java.io.File
 
 import scala.language.postfixOps
 import scala.concurrent.duration.Duration
@@ -143,8 +144,9 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
   }
 
   it should "reject create with missing file" in {
-    wsk.action.create("missingFile", Some("notfound"), expectedExitCode = MISUSE_EXIT).stderr should include(
-      "not a valid file")
+    val name = "notfound"
+    wsk.action.create("missingFile", Some(name), expectedExitCode = MISUSE_EXIT).stderr should include(
+      s"File '$name' is not a valid file or it does not exist")
   }
 
   it should "reject action update when specified file is missing" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
@@ -812,6 +814,81 @@ class WskBasicUsageTests extends TestHelpers with WskTestHelpers {
     stdoutNoDescOrParams should include regex (s"(?i)action /${namespace}/${actNameNoDescOrParams}\\s*\\(parameters: none defined\\)")
   }
 
+  it should "save action code to file" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
+    val name = "saveAction"
+    val seqName = "seqName"
+    val dockerName = "dockerName"
+    val containerName = s"bogus${Random.alphanumeric.take(16).mkString.toLowerCase}"
+    val saveName = s"save-as-$name.js"
+    val badSaveName = s"bad-directory${File.separator}$saveName"
+
+    // Test for successful --save
+    assetHelper.withCleaner(wsk.action, name) { (action, _) =>
+      action.create(name, defaultAction)
+    }
+
+    val saveMsg = wsk.action.get(name, save = Some(true)).stdout
+
+    saveMsg should include(s"saved action code to ")
+
+    val savePath = saveMsg.split("ok: saved action code to ")(1).trim()
+    val saveFile = new File(savePath);
+
+    try {
+      saveFile.exists shouldBe true
+
+      // Test for failure saving file when it already exist
+      wsk.action.get(name, save = Some(true), expectedExitCode = MISUSE_EXIT).stderr should include(
+        s"The file '$name.js' already exists")
+    } finally {
+      saveFile.delete()
+    }
+
+    // Test for successful --save-as
+    val saveAsMsg = wsk.action.get(name, saveAs = Some(saveName)).stdout
+
+    saveAsMsg should include(s"saved action code to ")
+
+    val saveAsPath = saveAsMsg.split("ok: saved action code to ")(1).trim()
+    val saveAsFile = new File(saveAsPath);
+
+    try {
+      saveAsFile.exists shouldBe true
+
+      // Test for failure saving file when it already exist
+      wsk.action.get(name, saveAs = Some(saveName), expectedExitCode = MISUSE_EXIT).stderr should include(
+        s"The file '$saveName' already exists")
+    } finally {
+      saveAsFile.delete()
+    }
+
+    // Test for failure when using an invalid filename
+    wsk.action.get(name, saveAs = Some(badSaveName), expectedExitCode = MISUSE_EXIT).stderr should include(
+      s"Cannot create file '$badSaveName'")
+
+    // Test for failure saving Docker images
+    assetHelper.withCleaner(wsk.action, dockerName) { (action, _) =>
+      action.create(dockerName, None, docker = Some(containerName))
+    }
+
+    wsk.action.get(dockerName, save = Some(true), expectedExitCode = MISUSE_EXIT).stderr should include(
+      "Cannot save Docker images")
+
+    wsk.action.get(dockerName, saveAs = Some(dockerName), expectedExitCode = MISUSE_EXIT).stderr should include(
+      "Cannot save Docker images")
+
+    // Tes for failure saving sequences
+    assetHelper.withCleaner(wsk.action, seqName) { (action, _) =>
+      action.create(seqName, Some(name), kind = Some("sequence"))
+    }
+
+    wsk.action.get(seqName, save = Some(true), expectedExitCode = MISUSE_EXIT).stderr should include(
+      "Cannot save action sequences")
+
+    wsk.action.get(seqName, saveAs = Some(seqName), expectedExitCode = MISUSE_EXIT).stderr should include(
+      "Cannot save action sequences")
+  }
+
   behavior of "Wsk packages"
 
   it should "create, and delete a package" in {

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.

[incubator-openwhisk-cli] 05/07: Make console tests more robust (#2831)

Posted by cs...@apache.org.
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-cli.git

commit baf3348bde84b7d78432296c38738614cb6f1535
Author: Sven Lange-Last <sv...@de.ibm.com>
AuthorDate: Fri Oct 6 04:13:23 2017 +0200

    Make console tests more robust (#2831)
    
    Use activation start times as time base when polling for activations since a point in time -
    before, local system time was used. If there is a clock mismatch between the local system
    and the system which records activations (controller, invokers), poll results can be empty.
    
    Other queries use relative times, i.e. return activations since the specified number
    of seconds. For these relative times, a start and end time is taken based on the local
    system time and the time difference in seconds is computed. It is important to use start
    and end time from the same time source.
    
    In addition, use some time contingency to make tests more robust.
    Provide more debug output in case an assertion fails.
---
 .../test/scala/system/basic/WskConsoleTests.scala  | 56 +++++++++++++++-------
 1 file changed, 40 insertions(+), 16 deletions(-)

diff --git a/tests/src/test/scala/system/basic/WskConsoleTests.scala b/tests/src/test/scala/system/basic/WskConsoleTests.scala
index 5252d0a..83526d7 100644
--- a/tests/src/test/scala/system/basic/WskConsoleTests.scala
+++ b/tests/src/test/scala/system/basic/WskConsoleTests.scala
@@ -17,7 +17,6 @@
 
 package system.basic;
 
-import java.time.Clock
 import java.time.Instant
 
 import scala.concurrent.duration.Duration
@@ -47,11 +46,16 @@ class WskConsoleTests extends TestHelpers with WskTestHelpers {
   val wsk = new Wsk
   val guestNamespace = wskprops.namespace
 
+  /**
+   * Append the current timestamp in ms
+   */
+  def withTimestamp(text: String) = s"${text}-${System.currentTimeMillis}"
+
   behavior of "Wsk Activation Console"
 
   it should "show an activation log message for hello world" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val packageName = "samples"
-    val actionName = "helloWorld"
+    val packageName = withTimestamp("samples")
+    val actionName = withTimestamp("helloWorld")
     val fullActionName = s"/$guestNamespace/$packageName/$actionName"
     assetHelper.withCleaner(wsk.pkg, packageName) { (pkg, _) =>
       pkg.create(packageName, shared = Some(true))
@@ -61,31 +65,51 @@ class WskConsoleTests extends TestHelpers with WskTestHelpers {
       action.create(fullActionName, Some(TestCLIUtils.getTestActionFilename("hello.js")))
     }
 
-    val duration = Some(30 seconds)
+    // Some contingency to make query more robust
+    // Account for time differences between controller and invoker
+    val start = Instant.now.minusSeconds(5)
     val payload = new String("from the console!".getBytes, "UTF-8")
     val run = wsk.action.invoke(fullActionName, Map("payload" -> payload.toJson))
-    withActivation(wsk.activation, run, totalWait = duration.get) { activation =>
-      val console = wsk.activation.console(10 seconds, since = duration)
-      console.stdout should include(payload)
+    withActivation(wsk.activation, run, totalWait = 30 seconds) { activation =>
+      val duration = Duration(Instant.now.minusMillis(start.toEpochMilli).toEpochMilli, MILLISECONDS)
+      val pollTime = 10 seconds
+      // since: poll for activations since specified number of seconds ago (relative)
+      val console = wsk.activation.console(pollTime, since = Some(duration))
+      withClue(
+        s"Poll for ${pollTime.toSeconds} seconds since ${duration.toSeconds} seconds did not return expected result:") {
+        console.stdout should include(payload)
+      }
     }
   }
 
   it should "show repeated activations" in withAssetCleaner(wskprops) { (wp, assetHelper) =>
-    val name = "countdown"
+    val name = withTimestamp("countdown")
     assetHelper.withCleaner(wsk.action, name) { (action, _) =>
       action.create(name, Some(TestCLIUtils.getTestActionFilename("countdown.js")))
     }
 
-    val start = Instant.now(Clock.systemUTC())
-    val run = wsk.action.invoke(name, Map("n" -> 3.toJson))
+    val count = 3
+    // Some contingency to make query more robust
+    // Account for time differences between controller and invoker
+    val start = Instant.now.minusSeconds(5)
+    val run = wsk.action.invoke(name, Map("n" -> count.toJson))
     withActivation(wsk.activation, run) { activation =>
-      val activations = wsk.activation.pollFor(N = 4, Some(name), since = Some(start), retries = 80).length
-      withClue(s"expected activations:") {
-        activations should be(4)
+      // Time recorded by invoker, some contingency to make query more robust
+      val queryTime = activation.start.minusMillis(500)
+      // since: poll for activations since specified point in time (absolute)
+      val activations = wsk.activation.pollFor(N = 4, Some(name), since = Some(queryTime), retries = 80).length
+      withClue(
+        s"expected activations of action '${name}' since ${queryTime.toString} / initial activation ${activation.activationId}:") {
+        activations should be(count + 1)
+      }
+      val duration = Duration(Instant.now.minusMillis(start.toEpochMilli).toEpochMilli, MILLISECONDS)
+      val pollTime = 10 seconds
+      // since: poll for activations since specified number of seconds ago (relative)
+      val console = wsk.activation.console(pollTime, since = Some(duration))
+      withClue(
+        s"Poll for ${pollTime.toSeconds} seconds since ${duration.toSeconds} seconds did not return expected result:") {
+        console.stdout should include("Happy New Year")
       }
-      val duration = Duration(Instant.now(Clock.systemUTC()).toEpochMilli - start.toEpochMilli, MILLISECONDS)
-      val console = wsk.activation.console(10 seconds, since = Some(duration))
-      console.stdout should include("Happy New Year")
     }
   }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.

[incubator-openwhisk-cli] 04/07: Delete test assets. (#2826)

Posted by cs...@apache.org.
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-cli.git

commit 62c6d662139075f17a685629ef2cff99b41a033e
Author: rodric rabbah <ro...@gmail.com>
AuthorDate: Tue Oct 3 21:17:33 2017 -0400

    Delete test assets. (#2826)
---
 .../scala/whisk/core/cli/test/WskEntitlementTests.scala  | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
index 27310aa..9a96e4d 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskEntitlementTests.scala
@@ -70,6 +70,7 @@ class WskEntitlementTests extends TestHelpers with WskTestHelpers with BeforeAnd
           rr.stderr should include("not authorized")
           rr
         }
+
         assetHelper.withCleaner(wsk.action, "unauthorized sequence", confirmDelete = false) { (action, name) =>
           val rr = action.create(
             name,
@@ -271,16 +272,17 @@ class WskEntitlementTests extends TestHelpers with WskTestHelpers with BeforeAnd
   it should "not allow invoke an action sequence with more than one component from package after entitlement change" in withAssetCleaner(
     guestWskProps) { (guestwp, assetHelper) =>
     val privateSamplePackage = samplePackage + "prv"
-    assetHelper.withCleaner(wsk.pkg, samplePackage) { (pkg, _) =>
-      pkg.create(samplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
-      pkg.create(privateSamplePackage, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
+    Seq(samplePackage, privateSamplePackage).foreach { n =>
+      assetHelper.withCleaner(wsk.pkg, n) { (pkg, _) =>
+        pkg.create(n, parameters = Map("a" -> "A".toJson), shared = Some(true))(guestwp)
+      }
     }
 
-    assetHelper.withCleaner(wsk.action, fullSampleActionName) {
+    Seq(fullSampleActionName, s"$privateSamplePackage/$sampleAction").foreach { a =>
       val file = Some(TestCLIUtils.getTestActionFilename("hello.js"))
-      (action, _) =>
-        action.create(fullSampleActionName, file)(guestwp)
-        action.create(s"$privateSamplePackage/$sampleAction", file)(guestwp)
+      assetHelper.withCleaner(wsk.action, a) { (action, _) =>
+        action.create(a, file)(guestwp)
+      }
     }
 
     withAssetCleaner(defaultWskProps) { (dwp, assetHelper) =>

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.

[incubator-openwhisk-cli] 02/07: Allow CLI to Save Code from Action (#2544)

Posted by cs...@apache.org.
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-cli.git

commit c692c980d2ef4efa4b730383c2d478031b4700aa
Author: James Dubee <jw...@us.ibm.com>
AuthorDate: Wed Oct 18 13:54:01 2017 -0400

    Allow CLI to Save Code from Action (#2544)
    
    * Allow CLI to Save Code from Action
    
    * Formatting changes
    
    * Test refactor
    
    * Update test
    
    * Refactor
    
    * Review updates
    
    * Review updates
---
 commands/action.go               | 187 ++++++++++++++++++++++++++++++++-------
 commands/flags.go                |  15 +++-
 commands/util.go                 | 135 ++++++++++++++++++++++------
 wski18n/resources/en_US.all.json |  47 ++++++++--
 4 files changed, 315 insertions(+), 69 deletions(-)

diff --git a/commands/action.go b/commands/action.go
index b80bfb0..efbf842 100644
--- a/commands/action.go
+++ b/commands/action.go
@@ -24,6 +24,7 @@ import (
     "path/filepath"
     "io"
     "strings"
+    "os"
 
     "github.com/apache/incubator-openwhisk-client-go/whisk"
     "github.com/apache/incubator-openwhisk-cli/wski18n"
@@ -33,13 +34,29 @@ import (
     "github.com/mattn/go-colorable"
 )
 
-const MEMORY_LIMIT      = 256
-const TIMEOUT_LIMIT     = 60000
-const LOGSIZE_LIMIT     = 10
-const ACTIVATION_ID     = "activationId"
-const WEB_EXPORT_ANNOT  = "web-export"
-const RAW_HTTP_ANNOT    = "raw-http"
-const FINAL_ANNOT       = "final"
+const (
+    MEMORY_LIMIT      = 256
+    TIMEOUT_LIMIT     = 60000
+    LOGSIZE_LIMIT     = 10
+    ACTIVATION_ID     = "activationId"
+    WEB_EXPORT_ANNOT  = "web-export"
+    RAW_HTTP_ANNOT    = "raw-http"
+    FINAL_ANNOT       = "final"
+    NODE_JS_EXT       = ".js"
+    PYTHON_EXT        = ".py"
+    JAVA_EXT          = ".jar"
+    SWIFT_EXT         = ".swift"
+    ZIP_EXT           = ".zip"
+    PHP_EXT           = ".php"
+    NODE_JS           = "nodejs"
+    PYTHON            = "python"
+    JAVA              = "java"
+    SWIFT             = "swift"
+    PHP               = "php"
+    DEFAULT           = "default"
+    BLACKBOX          = "blackbox"
+    SEQUENCE          = "sequence"
+)
 
 var actionCmd = &cobra.Command{
     Use:   "action",
@@ -243,6 +260,8 @@ var actionGetCmd = &cobra.Command{
             printActionGetWithURL(qualifiedName.GetEntity(), actionURL)
         } else if Flags.common.summary {
             printSummary(action)
+        } else if cmd.LocalFlags().Changed(SAVE_AS_FLAG) || cmd.LocalFlags().Changed(SAVE_FLAG) {
+            return saveCode(*action, flags.action.saveAs)
         } else {
             if len(field) > 0 {
                 printActionGetWithField(qualifiedName.GetEntityName(), field, action)
@@ -399,7 +418,7 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action,
     } else if Flags.action.sequence {
         if len(args) == 2 {
             action.Exec = new(whisk.Exec)
-            action.Exec.Kind = "sequence"
+            action.Exec.Kind = SEQUENCE
             action.Exec.Components = csvToQualifiedActions(args[1])
         } else {
             return nil, noArtifactError()
@@ -445,8 +464,7 @@ func getExec(args []string, params ActionFlags) (*whisk.Exec, error) {
             return nil, err
         }
 
-        if ext == ".zip" || ext == ".jar" {
-            // Base64 encode the file
+        if ext == ZIP_EXT || ext == JAVA_EXT {
             code = base64.StdEncoding.EncodeToString([]byte(code))
         }
 
@@ -460,24 +478,24 @@ func getExec(args []string, params ActionFlags) (*whisk.Exec, error) {
     if len(kind) > 0 {
         exec.Kind = kind
     } else if len(docker) > 0 || isNative {
-        exec.Kind = "blackbox"
+        exec.Kind = BLACKBOX
         if isNative {
             exec.Image = "openwhisk/dockerskeleton"
         } else {
             exec.Image = docker
         }
-    } else if ext == ".swift" {
-        exec.Kind = "swift:default"
-    } else if ext == ".js" {
-        exec.Kind = "nodejs:default"
-    } else if ext == ".py" {
-        exec.Kind = "python:default"
-    } else if ext == ".jar" {
-        exec.Kind = "java:default"
-    } else if ext == ".php" {
-        exec.Kind = "php:default"
+    } else if ext == SWIFT_EXT {
+        exec.Kind = fmt.Sprintf("%s:%s", SWIFT, DEFAULT)
+    } else if ext == NODE_JS_EXT {
+        exec.Kind = fmt.Sprintf("%s:%s", NODE_JS, DEFAULT)
+    } else if ext == PYTHON_EXT {
+        exec.Kind = fmt.Sprintf("%s:%s", PYTHON, DEFAULT)
+    } else if ext == JAVA_EXT {
+        exec.Kind = fmt.Sprintf("%s:%s", JAVA, DEFAULT)
+    } else if ext == PHP_EXT {
+        exec.Kind = fmt.Sprintf("%s:%s", PHP, DEFAULT)
     } else {
-        if ext == ".zip" {
+        if ext == ZIP_EXT {
             return nil, zipKindError()
         } else {
             return nil, extensionError(ext)
@@ -496,6 +514,86 @@ func getExec(args []string, params ActionFlags) (*whisk.Exec, error) {
     return exec, nil
 }
 
+func getBinaryKindExtension(runtime string) (extension string) {
+    switch strings.ToLower(runtime) {
+    case JAVA:
+        extension = JAVA_EXT
+    default:
+        extension = ZIP_EXT
+    }
+
+    return extension
+}
+
+func getKindExtension(runtime string) (extension string) {
+    switch strings.ToLower(runtime) {
+    case NODE_JS:
+        extension = NODE_JS_EXT
+    case PYTHON:
+        extension = PYTHON_EXT
+    case SWIFT:
+        fallthrough
+    case PHP:
+        extension = fmt.Sprintf(".%s", runtime)
+    }
+
+    return extension
+}
+
+func saveCode(action whisk.Action, filename string) (err error) {
+    var code string
+    var runtime string
+    var exec whisk.Exec
+
+    exec = *action.Exec
+    runtime = strings.Split(exec.Kind, ":")[0]
+
+    if strings.ToLower(runtime) == BLACKBOX {
+        return cannotSaveImageError()
+    } else if strings.ToLower(runtime) == SEQUENCE {
+        return cannotSaveSequenceError()
+    }
+
+    if exec.Code != nil {
+        code = *exec.Code
+    }
+
+    if *exec.Binary {
+        decoded, _ := base64.StdEncoding.DecodeString(code)
+        code = string(decoded)
+
+        if len(filename) == 0 {
+            filename = action.Name + getBinaryKindExtension(runtime)
+        }
+    } else {
+        if len(filename) == 0 {
+            filename = action.Name + getKindExtension(runtime)
+        }
+    }
+
+    if exists, err := FileExists(filename); err != nil {
+        return err
+    } else if exists {
+        return fileExistsError(filename)
+    }
+
+    if err := writeFile(filename, code); err != nil {
+        return err
+    }
+
+    pwd, err := os.Getwd()
+    if err != nil {
+        whisk.Debug(whisk.DbgError, "os.Getwd() error: %s\n", err)
+        return err
+    }
+
+    savedPath := fmt.Sprintf("%s%s%s", pwd, string(os.PathSeparator), filename)
+
+    printSavedActionCodeSuccess(savedPath)
+
+    return nil
+}
+
 func webAction(webMode string, annotations whisk.KeyValueArr, entityName string, preserveAnnotations bool) (whisk.KeyValueArr, error){
     switch strings.ToLower(webMode) {
     case "yes":
@@ -770,6 +868,22 @@ func javaEntryError() (error) {
     return nonNestedError(errMsg)
 }
 
+func cannotSaveImageError() (error) {
+    return nonNestedError(wski18n.T("Cannot save Docker images"))
+}
+
+func cannotSaveSequenceError() (error) {
+    return nonNestedError(wski18n.T("Cannot save action sequences"))
+}
+
+func fileExistsError(file string) (error) {
+    errMsg := wski18n.T("The file '{{.file}}' already exists", map[string]interface{} {
+        "file": file,
+    })
+
+    return nonNestedError(errMsg)
+}
+
 func printActionCreated(entityName string) {
     fmt.Fprintf(
         color.Output,
@@ -877,6 +991,17 @@ func printActionDeleted(entityName string) {
             }))
 }
 
+func printSavedActionCodeSuccess(name string) {
+    fmt.Fprintf(
+        color.Output,
+        wski18n.T(
+            "{{.ok}} saved action code to {{.name}}\n",
+            map[string]interface{}{
+                "ok": color.GreenString("ok:"),
+                "name": boldString(name),
+            }))
+}
+
 // Check if the specified action is a web-action
 func isWebAction(client *whisk.Client, qname QualifiedName) (error) {
     var err error = nil
@@ -915,14 +1040,14 @@ func init() {
     actionCreateCmd.Flags().BoolVar(&Flags.action.sequence, "sequence", false, wski18n.T("treat ACTION as comma separated sequence of actions to invoke"))
     actionCreateCmd.Flags().StringVar(&Flags.action.kind, "kind", "", wski18n.T("the `KIND` of the action runtime (example: swift:default, nodejs:default)"))
     actionCreateCmd.Flags().StringVar(&Flags.action.main, "main", "", wski18n.T("the name of the action entry point (function or fully-qualified method name when applicable)"))
-    actionCreateCmd.Flags().IntVarP(&Flags.action.timeout, "timeout", "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
-    actionCreateCmd.Flags().IntVarP(&Flags.action.memory, "memory", "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
-    actionCreateCmd.Flags().IntVarP(&Flags.action.logsize, "logsize", "l", LOGSIZE_LIMIT, wski18n.T("the maximum log size `LIMIT` in MB for the action"))
+    actionCreateCmd.Flags().IntVarP(&Flags.action.timeout, TIMEOUT_FLAG, "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
+    actionCreateCmd.Flags().IntVarP(&Flags.action.memory, MEMORY_FLAG, "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
+    actionCreateCmd.Flags().IntVarP(&Flags.action.logsize, LOG_SIZE_FLAG, "l", LOGSIZE_LIMIT, wski18n.T("the maximum log size `LIMIT` in MB for the action"))
     actionCreateCmd.Flags().StringSliceVarP(&Flags.common.annotation, "annotation", "a", nil, wski18n.T("annotation values in `KEY VALUE` format"))
     actionCreateCmd.Flags().StringVarP(&Flags.common.annotFile, "annotation-file", "A", "", wski18n.T("`FILE` containing annotation values in JSON format"))
     actionCreateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", nil, wski18n.T("parameter values in `KEY VALUE` format"))
     actionCreateCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
-    actionCreateCmd.Flags().StringVar(&Flags.action.web, "web", "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
+    actionCreateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
 
     actionUpdateCmd.Flags().BoolVar(&Flags.action.native, "native", false, wski18n.T("treat ACTION as native action (zip file provides a compatible executable to run)"))
     actionUpdateCmd.Flags().StringVar(&Flags.action.docker, "docker", "", wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
@@ -930,14 +1055,14 @@ func init() {
     actionUpdateCmd.Flags().BoolVar(&Flags.action.sequence, "sequence", false, wski18n.T("treat ACTION as comma separated sequence of actions to invoke"))
     actionUpdateCmd.Flags().StringVar(&Flags.action.kind, "kind", "", wski18n.T("the `KIND` of the action runtime (example: swift:default, nodejs:default)"))
     actionUpdateCmd.Flags().StringVar(&Flags.action.main, "main", "", wski18n.T("the name of the action entry point (function or fully-qualified method name when applicable)"))
-    actionUpdateCmd.Flags().IntVarP(&Flags.action.timeout, "timeout", "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
-    actionUpdateCmd.Flags().IntVarP(&Flags.action.memory, "memory", "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
-    actionUpdateCmd.Flags().IntVarP(&Flags.action.logsize, "logsize", "l", LOGSIZE_LIMIT, wski18n.T("the maximum log size `LIMIT` in MB for the action"))
+    actionUpdateCmd.Flags().IntVarP(&Flags.action.timeout, TIMEOUT_FLAG, "t", TIMEOUT_LIMIT, wski18n.T("the timeout `LIMIT` in milliseconds after which the action is terminated"))
+    actionUpdateCmd.Flags().IntVarP(&Flags.action.memory, MEMORY_FLAG, "m", MEMORY_LIMIT, wski18n.T("the maximum memory `LIMIT` in MB for the action"))
+    actionUpdateCmd.Flags().IntVarP(&Flags.action.logsize, LOG_SIZE_FLAG, "l", LOGSIZE_LIMIT, wski18n.T("the maximum log size `LIMIT` in MB for the action"))
     actionUpdateCmd.Flags().StringSliceVarP(&Flags.common.annotation, "annotation", "a", []string{}, wski18n.T("annotation values in `KEY VALUE` format"))
     actionUpdateCmd.Flags().StringVarP(&Flags.common.annotFile, "annotation-file", "A", "", wski18n.T("`FILE` containing annotation values in JSON format"))
     actionUpdateCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
     actionUpdateCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
-    actionUpdateCmd.Flags().StringVar(&Flags.action.web, "web", "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
+    actionUpdateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
 
     actionInvokeCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
     actionInvokeCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
@@ -946,6 +1071,8 @@ func init() {
 
     actionGetCmd.Flags().BoolVarP(&Flags.common.summary, "summary", "s", false, wski18n.T("summarize action details; parameters with prefix \"*\" are bound, \"**\" are bound and finalized"))
     actionGetCmd.Flags().BoolVarP(&Flags.action.url, "url", "r", false, wski18n.T("get action url"))
+    actionGetCmd.Flags().StringVar(&Flags.action.saveAs, SAVE_AS_FLAG, "", wski18n.T("file to save action code to"))
+    actionGetCmd.Flags().BoolVarP(&Flags.action.save, SAVE_FLAG, "", false, wski18n.T("save action code to file corresponding with action name"))
 
     actionListCmd.Flags().IntVarP(&Flags.common.skip, "skip", "s", 0, wski18n.T("exclude the first `SKIP` number of actions from the result"))
     actionListCmd.Flags().IntVarP(&Flags.common.limit, "limit", "l", 30, wski18n.T("only return `LIMIT` number of actions from the collection"))
diff --git a/commands/flags.go b/commands/flags.go
index b30d04f..8a06d05 100644
--- a/commands/flags.go
+++ b/commands/flags.go
@@ -25,10 +25,15 @@ import (
 // Flags //
 ///////////
 
-const MEMORY_FLAG   = "memory"
-const LOG_SIZE_FLAG = "logsize"
-const TIMEOUT_FLAG  = "timeout"
-const WEB_FLAG      = "web"
+const (
+    MEMORY_FLAG     = "memory"
+    LOG_SIZE_FLAG   = "logsize"
+    TIMEOUT_FLAG    = "timeout"
+    WEB_FLAG        = "web"
+    SAVE_FLAG       = "save"
+    SAVE_AS_FLAG    = "save-as"
+)
+
 
 var cliDebug = os.Getenv("WSK_CLI_DEBUG")  // Useful for tracing init() code
 
@@ -139,6 +144,8 @@ type ActionFlags struct {
     kind        string
     main        string
     url         bool
+    save        bool
+    saveAs     string
 }
 
 func IsVerbose() bool {
diff --git a/commands/util.go b/commands/util.go
index a4056ad..e5ec6ee 100644
--- a/commands/util.go
+++ b/commands/util.go
@@ -586,21 +586,37 @@ func printJsonNoColor(decoded interface{}, stream ...io.Writer) {
 }
 
 func unpackGzip(inpath string, outpath string) error {
-    // Make sure the target file does not exist
-    if _, err := os.Stat(outpath); err == nil {
-        whisk.Debug(whisk.DbgError, "os.Stat reports file '%s' exists\n", outpath)
+    var exists bool
+    var err error
+
+    exists, err = FileExists(outpath)
+
+    if err != nil {
+        return err
+    }
+
+    if exists {
         errStr := wski18n.T("The file '{{.name}}' already exists.  Delete it and retry.",
             map[string]interface{}{"name": outpath})
         werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
         return werr
     }
 
-    // Make sure the input file exists
-    if _, err := os.Stat(inpath); err != nil {
-        whisk.Debug(whisk.DbgError, "os.Stat reports file '%s' does not exist\n", inpath)
-        errStr := wski18n.T("The file '{{.name}}' does not exist.", map[string]interface{}{"name": inpath})
-        werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
-        return werr
+    exists, err = FileExists(inpath)
+
+    if err != nil {
+        return err
+    }
+
+    if !exists {
+        errMsg := wski18n.T("File '{{.name}}' is not a valid file or it does not exist",
+            map[string]interface{}{
+                "name": inpath,
+            })
+        whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_USAGE,
+            whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+
+        return whiskErr
     }
 
     unGzFile, err := os.Create(outpath)
@@ -645,14 +661,22 @@ func unpackGzip(inpath string, outpath string) error {
 }
 
 func unpackZip(inpath string) error {
-    // Make sure the input file exists
-    if _, err := os.Stat(inpath); err != nil {
-        whisk.Debug(whisk.DbgError, "os.Stat reports file '%s' does not exist\n", inpath)
-        errStr := wski18n.T("The file '{{.name}}' does not exist.", map[string]interface{}{"name": inpath})
-        werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
-        return werr
+    exists, err := FileExists(inpath)
+
+    if err != nil {
+        return err
     }
 
+    if !exists {
+        errMsg := wski18n.T("File '{{.name}}' is not a valid file or it does not exist",
+            map[string]interface{}{
+                "name": inpath,
+            })
+        whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_USAGE,
+            whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+
+        return whiskErr
+    }
     zipFileReader, err := zip.OpenReader(inpath)
     if err != nil {
         whisk.Debug(whisk.DbgError, "zip.OpenReader(%s) failed: %s\n", inpath, err)
@@ -712,13 +736,21 @@ func unpackZip(inpath string) error {
 }
 
 func unpackTar(inpath string) error {
+    exists, err := FileExists(inpath)
 
-    // Make sure the input file exists
-    if _, err := os.Stat(inpath); err != nil {
-        whisk.Debug(whisk.DbgError, "os.Stat reports file '%s' does not exist\n", inpath)
-        errStr := wski18n.T("The file '{{.name}}' does not exist.", map[string]interface{}{"name": inpath})
-        werr := whisk.MakeWskError(errors.New(errStr), whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE)
-        return werr
+    if err != nil {
+        return err
+    }
+
+    if !exists {
+        errMsg := wski18n.T("File '{{.name}}' is not a valid file or it does not exist",
+            map[string]interface{}{
+                "name": inpath,
+            })
+        whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_USAGE,
+            whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+
+        return whiskErr
     }
 
     tarFileReader, err := os.Open(inpath)
@@ -828,11 +860,17 @@ func getClientNamespace() (string) {
 }
 
 func ReadFile(filename string) (string, error) {
-    _, err := os.Stat(filename)
+    exists, err := FileExists(filename)
+
     if err != nil {
-        whisk.Debug(whisk.DbgError, "os.Stat(%s) error: %s\n", filename, err)
-        errMsg := wski18n.T("File '{{.name}}' is not a valid file or it does not exist: {{.err}}",
-                map[string]interface{}{"name": filename, "err": err})
+        return "", err
+    }
+
+    if !exists {
+        errMsg := wski18n.T("File '{{.name}}' is not a valid file or it does not exist",
+            map[string]interface{}{
+                "name": filename,
+            })
         whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_USAGE,
             whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
 
@@ -842,7 +880,7 @@ func ReadFile(filename string) (string, error) {
     file, err := ioutil.ReadFile(filename)
     if err != nil {
         whisk.Debug(whisk.DbgError, "os.ioutil.ReadFile(%s) error: %s\n", filename, err)
-        errMsg := wski18n.T("Unable to read '{{.name}}': {{.err}}",
+        errMsg := wski18n.T("Unable to read the file '{{.name}}': {{.err}}",
                 map[string]interface{}{"name": filename, "err": err})
         whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
             whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
@@ -852,6 +890,51 @@ func ReadFile(filename string) (string, error) {
     return string(file), nil
 }
 
+func writeFile(filename string, content string) (error) {
+    file, err := os.Create(filename)
+
+    if err != nil {
+        whisk.Debug(whisk.DbgError, "os.Create(%s) error: %#v\n", filename, err)
+        errMsg := wski18n.T("Cannot create file '{{.name}}': {{.err}}",
+            map[string]interface{}{"name": filename, "err": err})
+        whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_USAGE, whisk.DISPLAY_MSG,
+            whisk.DISPLAY_USAGE)
+        return whiskErr
+    }
+
+    defer file.Close()
+
+    if _, err = file.WriteString(content); err != nil {
+        whisk.Debug(whisk.DbgError, "File.WriteString(%s) error: %#v\n", content, err)
+        errMsg := wski18n.T("Cannot create file '{{.name}}': {{.err}}",
+            map[string]interface{}{"name": filename, "err": err})
+        whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_USAGE, whisk.DISPLAY_MSG,
+            whisk.DISPLAY_USAGE)
+        return whiskErr
+    }
+
+    return nil
+}
+
+func FileExists(file string) (bool, error) {
+    _, err := os.Stat(file)
+
+    if err != nil {
+        if os.IsNotExist(err) == true {
+            return false, nil
+        } else {
+            whisk.Debug(whisk.DbgError, "os.Stat(%s) error: %#v\n", file, err)
+            errMsg := wski18n.T("Cannot access file '{{.name}}': {{.err}}",
+                map[string]interface{}{"name": file, "err": err})
+            whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_USAGE,
+                whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+            return true, whiskErr
+        }
+    }
+
+    return true, nil
+}
+
 func fieldExists(value interface{}, field string) (bool) {
     element := reflect.ValueOf(value).Elem()
 
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 3236830..acc6e2c 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -732,8 +732,8 @@
     "translation": "shared"
   },
   {
-    "id": "The file '{{.name}}' does not exist.",
-    "translation": "The file '{{.name}}' does not exist."
+    "id": "File '{{.name}}' is not a valid file or it does not exist",
+    "translation": "File '{{.name}}' is not a valid file or it does not exist"
   },
   {
     "id": "Error creating unGzip file '{{.name}}': {{.err}}",
@@ -876,12 +876,8 @@
     "translation": "Unable to get action '{{.name}}': {{.err}}"
   },
   {
-    "id": "File '{{.name}}' is not a valid file or it does not exist: {{.err}}",
-    "translation": "File '{{.name}}' is not a valid file or it does not exist: {{.err}}"
-  },
-  {
-    "id": "Unable to read '{{.name}}': {{.err}}",
-    "translation": "Unable to read '{{.name}}': {{.err}}"
+    "id": "Unable to read the file '{{.name}}': {{.err}}",
+    "translation": "Unable to read the file '{{.name}}': {{.err}}"
   },
   {
     "id": "'{{.name}}' is not a supported action runtime",
@@ -1526,4 +1522,37 @@
   {
     "id": "sorts a list alphabetically by order of [BASE_PATH | API_NAME], API_PATH, then API_VERB; only applicable within the limit/skip returned entity block",
     "translation": "sorts a list alphabetically by order of [BASE_PATH | API_NAME], API_PATH, then API_VERB; only applicable within the limit/skip returned entity block"
-  }]
+  },
+  {
+    "id": "prints bash command completion script to stdout",
+    "translation": "prints bash command completion script to stdout"
+  },
+  {
+    "id": "save action code to file corresponding with action name",
+    "translation": "save action code to file corresponding with action name"
+  },
+  {
+    "id": "file to save action code to",
+    "translation": "file to save action code to"
+  },
+  {
+    "id": "The file '{{.file}}' already exists",
+    "translation": "The file '{{.file}}' already exists"
+  },
+  {
+    "id": "{{.ok}} saved action code to {{.name}}\n",
+    "translation": "{{.ok}} saved action code to {{.name}}\n"
+  },
+  {
+    "id": "Cannot save Docker images",
+    "translation": "Cannot save Docker images"
+  },
+  {
+    "id": "Cannot save action sequences",
+    "translation": "Cannot save action sequences"
+  },
+  {
+    "id": "Cannot create file '{{.name}}': {{.err}}",
+    "translation": "Cannot create file '{{.name}}': {{.err}}"
+  }
+]

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.

[incubator-openwhisk-cli] 01/07: Move docker runtime into its own repo (#2850)

Posted by cs...@apache.org.
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-cli.git

commit eeedc6cea5fdd50d5c3aacf54886e8bdaff19fdd
Author: Carlos Santana <cs...@gmail.com>
AuthorDate: Tue Oct 17 17:56:37 2017 -0400

    Move docker runtime into its own repo  (#2850)
---
 commands/sdk.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/commands/sdk.go b/commands/sdk.go
index 3dbb1fe..4f4eaaf 100644
--- a/commands/sdk.go
+++ b/commands/sdk.go
@@ -253,6 +253,6 @@ func init() {
     sdkCmd.AddCommand(sdkInstallCmd)
 
     sdkMap = make(map[string]*sdkInfo)
-    sdkMap["docker"] = &sdkInfo{ UrlPath: "blackbox-0.1.0.tar.gz", FileName: "blackbox-0.1.0.tar.gz", isGzTar: true, Unpack: true, UnpackDir: "dockerSkeleton"}
+    sdkMap["docker"] = &sdkInfo{ UrlPath: "blackbox.tar.gz", FileName: "blackbox.tar.gz", isGzTar: true, Unpack: true, UnpackDir: "dockerSkeleton"}
     sdkMap["ios"] = &sdkInfo{ UrlPath: "OpenWhiskIOSStarterApp.zip", FileName: "OpenWhiskIOSStarterApp.zip", IsZip: true, Unpack: false}
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.

[incubator-openwhisk-cli] 03/07: Update the version of client go to ad5aa3402b033edd8b30aec7f33434a253aa35ed

Posted by cs...@apache.org.
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-cli.git

commit 3ac6a0386c3f3f1d926bfe5a63de57bfe66e099a
Author: Vincent Hou <sh...@us.ibm.com>
AuthorDate: Wed Oct 18 19:32:21 2017 -0400

    Update the version of client go to ad5aa3402b033edd8b30aec7f33434a253aa35ed
---
 Godeps/Godeps.json        |  2 +-
 wski18n/i18n_resources.go | 22 +++++++++++-----------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index 8348838..ca7adae 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -65,7 +65,7 @@
 		},
         {
             "ImportPath": "github.com/apache/incubator-openwhisk-client-go/whisk",
-            "Rev": "4a63a306d52f5dd54454e0ba38e0c7eb9cb2852b"
+            "Rev": "ad5aa3402b033edd8b30aec7f33434a253aa35ed"
         }
 	]
 }
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 26f85a3..1bccb9f 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -109,12 +109,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x7d\x4f\x73\xdb\x38\xd2\xf7\x7d\x3e\x45\x57\x2e\x76\xde\x92\x9d\xdd\xd3\x5b\x4f\x52\x73\xd0\x24\x9e\x8d\x37\x89\xed\x8a\x9d\xd9\x9d\xda\x6c\x8d\x20\x12\x92\xb0\xa6\x00\x0e\x00\x5a\x51\xb2\xfe\xee\x4f\x01\x20\x29\x52\xc2\x5f\x52\x4e\x9e\x53\x1c\xb1\xfb\xd7\x0d\xa0\x01\x34\x1a\x0d\xe0\x5f\x3f\x01\x7c\xfb\x09\x00\xe0\x19\xc9\x9f\xbd\x84\x67\xd3\xb2\x2c\x48\x86\x24\x61\x14\xf0\x17\x22\x71\x0e\x15\xc5\x5f [...]
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5d\x4f\x73\xdb\x38\xb2\xbf\xcf\xa7\xe8\xca\xc5\xce\x2b\xd9\xd9\x3d\xbd\x7a\x49\xcd\x41\x13\x7b\x36\xde\x49\x6c\x57\xec\xcc\xee\xd4\x66\x6b\x04\x91\x90\x85\x35\x05\x70\x00\xd0\xb2\x92\xf1\x77\x7f\x05\x80\xa4\x48\x09\x7f\x49\x39\xd9\x53\x1c\xb1\xfb\xd7\x0d\xa0\x01\x34\x1a\x0d\xe0\x5f\x3f\x00\x7c\xfd\x01\x00\xe0\x05\xc9\x5f\xbc\x86\x17\xd3\xb2\x2c\x48\x86\x24\x61\x14\xf0\x23\x91\x38\x87\x8a\xe2\xc7\x12 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
     return bindataRead(
@@ -129,7 +129,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 50999, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 51835, mode: os.FileMode(420), modTime: time.Unix(1508369296, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -149,7 +149,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -169,7 +169,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -189,7 +189,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -209,7 +209,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -229,7 +229,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -249,7 +249,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -269,7 +269,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -289,7 +289,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) {
         return nil, err
     }
 
-    info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1506363546, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1508369189, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.