This is an automated email from the ASF dual-hosted git repository.
msciabarra pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk.git
The following commit(s) were added to refs/heads/master by this push:
new 165d957 A docker image for the standalone openwhisk (#4782)
165d957 is described below
commit 165d9579764697d33919ce850c9613de2719b4cf
Author: Michele Sciabarra <[email protected]>
AuthorDate: Tue Jan 14 08:33:43 2020 +0100
A docker image for the standalone openwhisk (#4782)
* use system properties to set standalone host ip and name
* show values
* plaground support and dockerfile
* fixes to the standalone docker image
* making scancode happy
making scalafmt happy
* using stop, disabling launcher, publishing image, updated docs
* licenses
* adding cors support
* fixed start.sh and docs
* scancode
* removing extra push
* support for CONTAINER_EXTRA_ENV and JVM_EXTRA_ARGS
* update readme
* fixes - wait for the server ready
* forgot file
* rebuild
* Update core/standalone/README.md
Co-Authored-By: rodric rabbah <[email protected]>
* Update core/standalone/README.md
Co-Authored-By: rodric rabbah <[email protected]>
* Update core/standalone/README.md
Co-Authored-By: rodric rabbah <[email protected]>
Co-authored-by: rodric rabbah <[email protected]>
---
core/standalone/Dockerfile | 33 ++++++++++++++++
core/standalone/README.md | 35 +++++++++++++++++
core/standalone/build.gradle | 6 +++
core/standalone/init | 27 +++++++++++++
core/standalone/src/main/resources/standalone.conf | 16 ++++++++
.../openwhisk/standalone/PlaygroundLauncher.scala | 45 ++++++++++++++--------
.../openwhisk/standalone/PreFlightChecks.scala | 6 ++-
.../standalone/StandaloneDockerSupport.scala | 33 ++++++++++++----
.../openwhisk/standalone/StandaloneOpenWhisk.scala | 12 +++++-
core/standalone/start.sh | 31 +++++++++++++++
core/standalone/stop | 18 +++++++++
core/standalone/stop.sh | 18 +++++++++
core/standalone/waitready | 22 +++++++++++
13 files changed, 275 insertions(+), 27 deletions(-)
diff --git a/core/standalone/Dockerfile b/core/standalone/Dockerfile
new file mode 100644
index 0000000..6b01383
--- /dev/null
+++ b/core/standalone/Dockerfile
@@ -0,0 +1,33 @@
+#
+# 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 scala
+ARG OPENWHISK_JAR
+ENV DOCKER_VERSION=18.06.3-ce
+ENV WSK_VERSION=1.0.0
+ADD init /
+ADD stop waitready /bin/
+RUN chmod +x /bin/stop /bin/waitready ;\
+ curl -sL \
+
https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz
\
+ | tar xzvf - -C /usr/bin --strip 1 docker/docker ;\
+ curl -sL \
+
https://github.com/apache/openwhisk-cli/releases/download/${WSK_VERSION}/OpenWhisk_CLI-${WSK_VERSION}-linux-amd64.tgz
\
+ | tar xzvf - -C /usr/bin wsk
+ADD ${OPENWHISK_JAR} /openwhisk-standalone.jar
+WORKDIR /
+EXPOSE 8080
+ENTRYPOINT ["/init"]
diff --git a/core/standalone/README.md b/core/standalone/README.md
index 4149508..ff19351 100644
--- a/core/standalone/README.md
+++ b/core/standalone/README.md
@@ -65,6 +65,12 @@ To pass argument to the run command use
$ ./gradlew :core:standalone:bootRun --args='-m runtimes.json'
```
+You can also build a standalone docker image with:
+
+```bash
+$ ./gradlew :core:standalone:distDocker
+```
+
### Usage
OpenWhisk standalone server support various launch options
@@ -380,6 +386,35 @@ This shows an output like below indicating that
KubernetesContainerFactory based
}
```
+## Launching OpenWhisk standalone with Docker
+
+If you have docker and bash installed, you can launch the standalone openwhisk
from the docker image with just:
+
+`bash <(curl -sL https://s.apache.org/openwhisk.sh)`
+
+If you do not want to execute arbitrary code straight from the net, you can
look at [this script](start.sh), check it and run it when you feel safe.
+
+The script will start the standalone controller with Docker, and will also try
to open the playground. It was tested on Linux, OSX and Windows with Git Bash.
If a browser does not open with playground, access it at
`http://localhost:3232`.
+
+You can then install the [wsk
CLI](https://github.com/apache/openwhisk-cli/releases) and retrieve the command
line to configure `wsk` with:
+
+`docker logs openwhisk | grep 'wsk property'`
+
+To properly shut down OpenWhisk and containers it creates, use [this
script](stop.sh) or run the command:
+
+`docker exec openwhisk stop`
+
+### Extra Args for the Standalone OpenWhisk Docker Image
+
+When running OpenWhisk Standalone using the docker image, you can set
environment variables to pass extra args with the `-e` flag.
+
+Extra args are useful to configure the JVM running OpenWhisk and to propagate
additional environment variables to containers running images. This feature is
useful for example to enable debugging for actions.
+
+You can pass additional parameters (for example set system properties) to the
JVM running OpenWhisk setting the environment variable `JVM_EXTRA_ARGS`. For
example `-e JVM_EXTRA_ARGS=-Dconfig.loads` allows to enable tracing of
configuration. You can set any OpenWhisk parameter with feature.
+
+You can also set additional environment variables for each container running
actions invoked by OpenWhisk by setting `CONTAINER_EXTRA_ENV`. For example,
setting `-e CONTAINER_EXTRA_ENV=__OW_DEBUG_PORT=8081` enables debugging for
those images supporting starting the action under a debugger, like the
typescript runtime.
+
+
[1]: https://github.com/apache/incubator-openwhisk/blob/master/docs/cli.md
[2]: https://github.com/apache/incubator-openwhisk/blob/master/docs/samples.md
[3]: https://github.com/apache/incubator-openwhisk-apigateway
diff --git a/core/standalone/build.gradle b/core/standalone/build.gradle
index 0027785..6e97466 100644
--- a/core/standalone/build.gradle
+++ b/core/standalone/build.gradle
@@ -25,6 +25,11 @@ plugins {
id 'com.gorylenko.gradle-git-properties' version '2.0.0'
}
+ext.dockerImageName = 'standalone'
+ext.dockerBuildArgs = [
"OPENWHISK_JAR=build/libs/openwhisk-standalone-${version}.jar"]
+apply from: '../../gradle/docker.gradle'
+distDocker.dependsOn 'bootJar'
+
project.archivesBaseName = "openwhisk-standalone"
task copySwagger(type: Copy) {
@@ -153,6 +158,7 @@ dependencies {
compile
"io.github.embeddedkafka:embedded-kafka_${gradle.scala.depVersion}:2.4.0"
compile "org.scala-lang:scala-reflect:${gradle.scala.version}"
+ compile "ch.megard:akka-http-cors_${gradle.scala.depVersion}:0.4.2"
testCompile "junit:junit:4.11"
testCompile "org.scalatest:scalatest_${gradle.scala.depVersion}:3.0.8"
diff --git a/core/standalone/init b/core/standalone/init
new file mode 100755
index 0000000..76f0ab1
--- /dev/null
+++ b/core/standalone/init
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# 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.
+#
+if ! test -e /var/run/docker.sock
+then echo "Please launch this image with the option -v
/var/run/docker.sock:/var/run/docker.sock"
+ exit 1
+fi
+JVM_ARGS="$JVM_EXTRA_ARGS\
+ -Dwhisk.standalone.host.name=$(hostname)\
+ -Dwhisk.standalone.host.internal=$(hostname -i)\
+ -Dwhisk.standalone.host.external=localhost"
+set -x
+java $JVM_ARGS -jar openwhisk-standalone.jar --no-browser "$@"
diff --git a/core/standalone/src/main/resources/standalone.conf
b/core/standalone/src/main/resources/standalone.conf
index dd2d203..5c8d7cf 100644
--- a/core/standalone/src/main/resources/standalone.conf
+++ b/core/standalone/src/main/resources/standalone.conf
@@ -124,5 +124,21 @@ whisk {
apache-client {
retry-no-http-response-exception = true
}
+ container-factory {
+ container-args {
+ extra-args {
+ env += ${?CONTAINER_EXTRA_ENV}
+ }
+ }
+ }
+}
+akka-http-cors {
+ allow-generic-http-requests = yes
+ allow-credentials = yes
+ allowed-origins = "*"
+ allowed-headers = "*"
+ allowed-methods = ["GET", "POST", "HEAD", "OPTIONS"]
+ exposed-headers = []
+ max-age = 1800 seconds
}
diff --git
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PlaygroundLauncher.scala
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PlaygroundLauncher.scala
index 146ccc7..bac8cc9 100644
---
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PlaygroundLauncher.scala
+++
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PlaygroundLauncher.scala
@@ -20,11 +20,12 @@ package org.apache.openwhisk.standalone
import java.nio.charset.StandardCharsets.UTF_8
import akka.actor.ActorSystem
-import akka.http.scaladsl.model.{ContentType, HttpCharsets, HttpEntity,
MediaTypes, StatusCodes}
+import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Route
import
akka.http.scaladsl.server.directives.FileAndResourceDirectives.ResourceFile
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Sink, Source}
+import ch.megard.akka.http.cors.scaladsl.CorsDirectives._
import org.apache.commons.io.IOUtils
import org.apache.commons.lang3.SystemUtils
import org.apache.openwhisk.common.{Logging, TransactionId}
@@ -34,15 +35,20 @@ import pureconfig._
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext}
-import scala.util.{Failure, Success, Try}
import scala.sys.process._
+import scala.util.{Failure, Success, Try}
-class PlaygroundLauncher(host: String, controllerPort: Int, pgPort: Int,
authKey: String, devMode: Boolean)(
- implicit logging: Logging,
- ec: ExecutionContext,
- actorSystem: ActorSystem,
- materializer: ActorMaterializer,
- tid: TransactionId) {
+class PlaygroundLauncher(host: String,
+ extHost: String,
+ controllerPort: Int,
+ pgPort: Int,
+ authKey: String,
+ devMode: Boolean,
+ noBrowser: Boolean)(implicit logging: Logging,
+ ec: ExecutionContext,
+ actorSystem: ActorSystem,
+ materializer: ActorMaterializer,
+ tid: TransactionId) {
private val interface =
loadConfigOrThrow[String]("whisk.controller.interface")
private val jsFileName = "playgroundFunctions.js"
private val jsContentType = ContentType(MediaTypes.`application/javascript`,
HttpCharsets.`UTF-8`)
@@ -58,7 +64,8 @@ class PlaygroundLauncher(host: String, controllerPort: Int,
pgPort: Int, authKey
private val jsFileContent = {
val js = resourceToString(jsFileName, "ui")
- val content = js.replace("window.APIHOST='http://localhost:3233'",
s"window.APIHOST='http://$host:$controllerPort'")
+ val content =
+ js.replace("window.APIHOST='http://localhost:3233'",
s"window.APIHOST='http://$extHost:$controllerPort'")
content.getBytes(UTF_8)
}
@@ -88,8 +95,10 @@ class PlaygroundLauncher(host: String, controllerPort: Int,
pgPort: Int, authKey
if (!devMode) {
prePullDefaultImages()
}
- launchBrowser(pgUrl)
- logging.info(this, s"Launched browser $pgUrl")
+ if (!noBrowser) {
+ launchBrowser(pgUrl)
+ logging.info(this, s"Launched browser $pgUrl")
+ }
}.failed.foreach(t => logging.warn(this, "Failed to launch browser " + t))
}
@@ -112,12 +121,14 @@ class PlaygroundLauncher(host: String, controllerPort:
Int, pgPort: Int, authKey
object PlaygroundService extends BasicHttpService {
override def routes(implicit transid: TransactionId): Route =
path(PathEnd | Slash | pg) { redirect(s"/$pg/ui/index.html",
StatusCodes.Found) } ~
- pathPrefix(pg / "ui" / Segment) { fileName =>
- get {
- if (fileName == jsFileName) {
- complete(HttpEntity(jsContentType, jsFileContent))
- } else {
- getFromResource(s"$uiPath/$fileName")
+ cors() {
+ pathPrefix(pg / "ui" / Segment) { fileName =>
+ get {
+ if (fileName == jsFileName) {
+ complete(HttpEntity(jsContentType, jsFileContent))
+ } else {
+ getFromResource(s"$uiPath/$fileName")
+ }
}
}
}
diff --git
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PreFlightChecks.scala
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PreFlightChecks.scala
index 3d430c5..454d04c 100644
---
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PreFlightChecks.scala
+++
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/PreFlightChecks.scala
@@ -45,6 +45,9 @@ case class PreFlightChecks(conf: Conf) extends AnsiColor {
println(separator)
println("Running pre flight checks ...")
println()
+ println(s"Local Host Name: ${StandaloneDockerSupport.getLocalHostName()}")
+ println(s"Local Internal Name:
${StandaloneDockerSupport.getLocalHostInternalName()}")
+ println()
checkForDocker()
checkForWsk()
checkForPorts()
@@ -113,6 +116,7 @@ case class PreFlightChecks(conf: Conf) extends AnsiColor {
val apihost = "wsk property get --apihost".!!.trim
val requiredHostValue =
s"http://${StandaloneDockerSupport.getLocalHostName()}:${conf.port()}"
+ val externalHostValue =
s"http://${StandaloneDockerSupport.getExternalHostName()}:${conf.port()}"
//We can use -o option to get raw value. However as its a recent addition
//using a lazy approach where we check if output ends with one of the
configured auth keys or
@@ -130,7 +134,7 @@ case class PreFlightChecks(conf: Conf) extends AnsiColor {
case Some((ns, guestAuth)) =>
println(s"$warn Configure wsk via below command to connect to this
server as [$ns]")
println()
- println(clr(s"wsk property set --apihost '$requiredHostValue' --auth
'$guestAuth'", MAGENTA, clrEnabled))
+ println(clr(s"wsk property set --apihost '$externalHostValue' --auth
'$guestAuth'", MAGENTA, clrEnabled))
case None =>
}
}
diff --git
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneDockerSupport.scala
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneDockerSupport.scala
index 1662b6a..8b6eb5b 100644
---
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneDockerSupport.scala
+++
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneDockerSupport.scala
@@ -106,28 +106,45 @@ object StandaloneDockerSupport {
}
/**
+ * Returns the hostname to access the playground.
+ * It defaults to localhost but it can be overriden
+ * and it is useful when the standalone is run in a container.
+ */
+ def getExternalHostName(): String = {
+
sys.props.get("whisk.standalone.host.external").getOrElse(getLocalHostName())
+ }
+
+ /**
* Returns the address to be used by code running outside of container to
connect to
* server. On non linux setups its 'localhost'. However for Linux setups its
the ip used
* by docker for docker0 network to refer to host system
*/
def getLocalHostName(): String = {
- if (SystemUtils.IS_OS_LINUX) hostIpLinux
- else "localhost"
+ sys.props
+ .get("whisk.standalone.host.name")
+ .getOrElse(if (SystemUtils.IS_OS_LINUX) hostIpLinux
+ else "localhost")
}
def getLocalHostIp(): String = {
- if (SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_WINDOWS)
- hostIpNonLinux
- else hostIpLinux
+ sys.props
+ .get("whisk.standalone.host.ip")
+ .getOrElse(
+ if (SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_WINDOWS)
+ hostIpNonLinux
+ else hostIpLinux)
}
/**
* Determines the name/ip which code running within container can use to
connect back to Controller
*/
def getLocalHostInternalName(): String = {
- if (SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_WINDOWS)
- "host.docker.internal"
- else hostIpLinux
+ sys.props
+ .get("whisk.standalone.host.internal")
+ .getOrElse(
+ if (SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_WINDOWS)
+ "host.docker.internal"
+ else hostIpLinux)
}
def prePullImage(imageName: String)(implicit logging: Logging): Unit = {
diff --git
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneOpenWhisk.scala
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneOpenWhisk.scala
index b77d759..3fb2abb 100644
---
a/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneOpenWhisk.scala
+++
b/core/standalone/src/main/scala/org/apache/openwhisk/standalone/StandaloneOpenWhisk.scala
@@ -104,11 +104,14 @@ class Conf(arguments: Seq[String]) extends
ScallopConf(Conf.expandAllMode(argume
val devKcf = opt[Boolean](descr = "Enables KubernetesContainerFactory for
local development")
val noUi = opt[Boolean](descr = "Disable Playground UI", noshort = true)
+
val uiPort = opt[Int](
descr = s"Playground UI server port. If not specified then
$preferredPgPort or some random free port " +
s"(if $StandaloneOpenWhisk is busy) would be used",
noshort = true)
+ val noBrowser = opt[Boolean](descr = "Disable Launching Browser", noshort =
true)
+
val devUserEventsPort = opt[Int](
descr = "Specify the port for the user-event service. This mode can be
used for local " +
"development of user-event service by configuring Prometheus to connect
to existing running service instance")
@@ -564,7 +567,14 @@ object StandaloneOpenWhisk extends SLF4JLogging {
conf: Conf)(implicit logging: Logging, as: ActorSystem, ec:
ExecutionContext, materializer: ActorMaterializer) = {
implicit val tid: TransactionId = TransactionId(systemPrefix +
"playground")
val pgPort = getPort(conf.uiPort.toOption, preferredPgPort)
- new PlaygroundLauncher(StandaloneDockerSupport.getLocalHostName(), owPort,
pgPort, systemAuthKey, conf.devMode())
+ new PlaygroundLauncher(
+ StandaloneDockerSupport.getLocalHostName(),
+ StandaloneDockerSupport.getExternalHostName(),
+ owPort,
+ pgPort,
+ systemAuthKey,
+ conf.devMode(),
+ conf.noBrowser())
}
private def systemAuthKey: String = {
diff --git a/core/standalone/start.sh b/core/standalone/start.sh
new file mode 100755
index 0000000..c81ec76
--- /dev/null
+++ b/core/standalone/start.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+#
+# 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.
+#
+USER="${1:-openwhisk}"
+shift
+docker run --rm -d \
+ -h openwhisk --name openwhisk \
+ -p 3233:3233 -p 3232:3232 \
+ -v //var/run/docker.sock:/var/run/docker.sock \
+ $USER/standalone "$@"
+docker exec openwhisk waitready
+case "$(uname)" in
+ (Linux) xdg-open http://localhost:3232 ;;
+ (Darwin) open http://localhost:3232 ;;
+ (MINGW*) start http://localhost:3232 ;;
+ (*) echo Please use http://localhost:3232 for playground ;;
+esac
diff --git a/core/standalone/stop b/core/standalone/stop
new file mode 100755
index 0000000..99edfcf
--- /dev/null
+++ b/core/standalone/stop
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# 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.
+#
+ps -o comm,pid ax | awk '/^java/ { print $2 }' | xargs kill
diff --git a/core/standalone/stop.sh b/core/standalone/stop.sh
new file mode 100755
index 0000000..2aa7e2a
--- /dev/null
+++ b/core/standalone/stop.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# 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.
+#
+docker exec openwhisk stop
diff --git a/core/standalone/waitready b/core/standalone/waitready
new file mode 100755
index 0000000..78c876f
--- /dev/null
+++ b/core/standalone/waitready
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# 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.
+#
+AUTH="23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP"
+wsk property set --apihost "http://$(hostname):3233" --auth "$AUTH"
+until wsk action list 2>/dev/null >/dev/null
+do sleep 1 ; echo server still not ready - retrying
+done