You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by mr...@apache.org on 2017/09/05 20:44:59 UTC

[incubator-openwhisk-wskdeploy] branch master updated: Handle the case when openwhisk service is unavailable (#444)

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

mrutkowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-wskdeploy.git


The following commit(s) were added to refs/heads/master by this push:
     new 2693478  Handle the case when openwhisk service is unavailable (#444)
2693478 is described below

commit 2693478c90dcffb586d47a737292a8ca95ee0578
Author: Vincent <sh...@us.ibm.com>
AuthorDate: Tue Sep 5 16:44:56 2017 -0400

    Handle the case when openwhisk service is unavailable (#444)
---
 parsers/manifest_parser_test.go                  |   2 +-
 tests/src/integration/runtimetests/manifest.yaml |   3 +-
 utils/misc.go                                    |  42 +-
 wski18n/detection.go                             |  24 +-
 wski18n/i18n.go                                  | 152 +++----
 wski18n/i18n_resources.go                        | 508 +++++++++++------------
 wski18n/resources/en_US.all.json                 |  12 +
 7 files changed, 390 insertions(+), 353 deletions(-)

diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index 586a8e0..b8cb664 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -1,4 +1,4 @@
-//// +build unit
+// +build unit
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
diff --git a/tests/src/integration/runtimetests/manifest.yaml b/tests/src/integration/runtimetests/manifest.yaml
index 9e9482f..18473e1 100644
--- a/tests/src/integration/runtimetests/manifest.yaml
+++ b/tests/src/integration/runtimetests/manifest.yaml
@@ -121,4 +121,5 @@ package:
   rules:
     myRuleRuntime:
       trigger: locationUpdateRuntime
-      action: greeting
+      action:  greetingnodejs-with-explicit-runtime
+
diff --git a/utils/misc.go b/utils/misc.go
index 99396bd..56ae3bd 100644
--- a/utils/misc.go
+++ b/utils/misc.go
@@ -39,8 +39,12 @@ import (
 	"io/ioutil"
 	"net/http"
 	"path"
+    "time"
 )
 
+const (
+    HTTP_TIMEOUT = 30
+)
 // ActionRecord is a container to keep track of
 // a whisk action struct and a location filepath we use to
 // map files and manifest declared actions
@@ -448,22 +452,42 @@ func ParseOpenWhisk(apiHost string) (op OpenWhiskInfo, err error) {
 	http.DefaultClient.Transport = &http.Transport{
 		TLSClientConfig: tlsConfig,
 	}
-	res, err := http.DefaultClient.Do(req)
-	defer res.Body.Close()
+
+    var netTransport = &http.Transport{
+        TLSClientConfig: tlsConfig,
+    }
+
+    var netClient = &http.Client{
+        Timeout: time.Second * HTTP_TIMEOUT,
+        Transport: netTransport,
+    }
+
+	res, err := netClient.Do(req)
+    if err != nil {
+        errString := wski18n.T("Failed to get the supported runtimes from OpenWhisk service: {{.err}}.\n",
+            map[string]interface{}{"err": err.Error()})
+        whisk.Debug(whisk.DbgWarn, errString)
+    }
+
+    if res != nil {
+        defer res.Body.Close()
+    }
 
 	// Local openwhisk deployment sometimes only returns "application/json" as the content type
+    openWhiskInfo := OpenWhiskInfo{}
 	if err != nil || !strings.Contains(ct, res.Header.Get("Content-Type")) {
-		fmt.Println("failed get openwhisk info from internet")
-		fmt.Println("Start unmarshal Openwhisk info from local values")
-		err = json.Unmarshal(runtimeInfo, &op)
+        stdout := wski18n.T("Start to unmarshal Openwhisk info from local values.\n")
+        whisk.Debug(whisk.DbgInfo, stdout)
+		err = json.Unmarshal(runtimeInfo, &openWhiskInfo)
 	} else {
 		b, _ := ioutil.ReadAll(res.Body)
 		if b != nil && len(b) > 0 {
-			fmt.Println("Unmarshal Openwhisk info from internet")
-			err = json.Unmarshal(b, &op)
+            stdout := wski18n.T("Unmarshal Openwhisk info from internet.\n")
+            whisk.Debug(whisk.DbgInfo, stdout)
+			err = json.Unmarshal(b, &openWhiskInfo)
 		}
 	}
-	return
+	return openWhiskInfo, err
 }
 
 func ConvertToMap(op OpenWhiskInfo) (rt map[string][]string) {
@@ -476,7 +500,7 @@ func ConvertToMap(op OpenWhiskInfo) (rt map[string][]string) {
 			}
 		}
 	}
-	return
+	return rt
 }
 
 var runtimeInfo = []byte(`{
diff --git a/wski18n/detection.go b/wski18n/detection.go
index c3866dd..b442cc4 100644
--- a/wski18n/detection.go
+++ b/wski18n/detection.go
@@ -20,24 +20,24 @@ package wski18n
 import "github.com/cloudfoundry/jibber_jabber"
 
 type Detector interface {
-	DetectLocale() string
-	DetectLanguage() string
+    DetectLocale() string
+    DetectLanguage() string
 }
 
 type JibberJabberDetector struct{}
 
 func (d *JibberJabberDetector) DetectLocale() string {
-	userLocale, err := jibber_jabber.DetectIETF()
-	if err != nil {
-		userLocale = ""
-	}
-	return userLocale
+    userLocale, err := jibber_jabber.DetectIETF()
+    if err != nil {
+        userLocale = ""
+    }
+    return userLocale
 }
 
 func (d *JibberJabberDetector) DetectLanguage() string {
-	lang, err := jibber_jabber.DetectLanguage()
-	if err != nil {
-		lang = ""
-	}
-	return lang
+    lang, err := jibber_jabber.DetectLanguage()
+    if err != nil {
+        lang = ""
+    }
+    return lang
 }
diff --git a/wski18n/i18n.go b/wski18n/i18n.go
index 02a25d3..245dc3b 100644
--- a/wski18n/i18n.go
+++ b/wski18n/i18n.go
@@ -18,131 +18,131 @@
 package wski18n
 
 import (
-	"path/filepath"
-	"strings"
+    "path/filepath"
+    "strings"
 
-	goi18n "github.com/nicksnyder/go-i18n/i18n"
+    goi18n "github.com/nicksnyder/go-i18n/i18n"
 )
 
 const (
-	DEFAULT_LOCALE = "en_US"
+    DEFAULT_LOCALE = "en_US"
 )
 
 var SUPPORTED_LOCALES = []string{
-	"de_DE",
-	"en_US",
-	"es_ES",
-	"fr_FR",
-	"it_IT",
-	"ja_JA",
-	"ko_KR",
-	"pt_BR",
-	"zh_Hans",
-	"zh_Hant",
+    "de_DE",
+    "en_US",
+    "es_ES",
+    "fr_FR",
+    "it_IT",
+    "ja_JA",
+    "ko_KR",
+    "pt_BR",
+    "zh_Hans",
+    "zh_Hant",
 }
 
 var resourcePath = filepath.Join("wski18n", "resources")
 
 func GetResourcePath() string {
-	return resourcePath
+    return resourcePath
 }
 
 func SetResourcePath(path string) {
-	resourcePath = path
+    resourcePath = path
 }
 
 var T goi18n.TranslateFunc
 var curLocale string
 
 func init() {
-	curLocale = Init(new(JibberJabberDetector))
+    curLocale = Init(new(JibberJabberDetector))
 }
 
 func CurLocale() string {
-	return curLocale
+    return curLocale
 }
 
 func Locale(detector Detector) string {
 
-	// Use default locale until strings are translated
-	/*sysLocale := normalize(detector.DetectLocale())
-	  if isSupported(sysLocale) {
-	      return sysLocale
-	  }
+    // Use default locale until strings are translated
+    /*sysLocale := normalize(detector.DetectLocale())
+      if isSupported(sysLocale) {
+          return sysLocale
+      }
 
-	  locale := defaultLocaleForLang(detector.DetectLanguage())
-	  if locale != "" {
-	      return locale
-	  }*/
+      locale := defaultLocaleForLang(detector.DetectLanguage())
+      if locale != "" {
+          return locale
+      }*/
 
-	return DEFAULT_LOCALE
+    return DEFAULT_LOCALE
 }
 
 func Init(detector Detector) string {
-	l := Locale(detector)
-	InitWithLocale(l)
-	return l
+    l := Locale(detector)
+    InitWithLocale(l)
+    return l
 }
 
 func InitWithLocale(locale string) {
-	err := loadFromAsset(locale)
-	if err != nil {
-		panic(err)
-	}
-	T = goi18n.MustTfunc(locale)
+    err := loadFromAsset(locale)
+    if err != nil {
+        panic(err)
+    }
+    T = goi18n.MustTfunc(locale)
 }
 
 func loadFromAsset(locale string) (err error) {
-	assetName := locale + ".all.json"
-	assetKey := filepath.Join(resourcePath, assetName)
-	bytes, err := Asset(assetKey)
-	if err != nil {
-		return
-	}
-	err = goi18n.ParseTranslationFileBytes(assetName, bytes)
-	return
+    assetName := locale + ".all.json"
+    assetKey := filepath.Join(resourcePath, assetName)
+    bytes, err := Asset(assetKey)
+    if err != nil {
+        return
+    }
+    err = goi18n.ParseTranslationFileBytes(assetName, bytes)
+    return
 }
 
 func normalize(locale string) string {
-	locale = strings.ToLower(strings.Replace(locale, "-", "_", 1))
-	for _, l := range SUPPORTED_LOCALES {
-		if strings.EqualFold(locale, l) {
-			return l
-		}
-	}
-	switch locale {
-	case "zh_cn", "zh_sg":
-		return "zh_Hans"
-	case "zh_hk", "zh_tw":
-		return "zh_Hant"
-	}
-	return locale
+    locale = strings.ToLower(strings.Replace(locale, "-", "_", 1))
+    for _, l := range SUPPORTED_LOCALES {
+        if strings.EqualFold(locale, l) {
+            return l
+        }
+    }
+    switch locale {
+    case "zh_cn", "zh_sg":
+        return "zh_Hans"
+    case "zh_hk", "zh_tw":
+        return "zh_Hant"
+    }
+    return locale
 }
 
 func isSupported(locale string) bool {
-	for _, l := range SUPPORTED_LOCALES {
-		if strings.EqualFold(locale, l) {
-			return true
-		}
-	}
-	return false
+    for _, l := range SUPPORTED_LOCALES {
+        if strings.EqualFold(locale, l) {
+            return true
+        }
+    }
+    return false
 }
 
 func defaultLocaleForLang(lang string) string {
-	if lang != "" {
-		lang = strings.ToLower(lang)
-		for _, l := range SUPPORTED_LOCALES {
-			if lang == LangOfLocale(l) {
-				return l
-			}
-		}
-	}
-	return ""
+    if lang != "" {
+        lang = strings.ToLower(lang)
+        for _, l := range SUPPORTED_LOCALES {
+            if lang == LangOfLocale(l) {
+                return l
+            }
+        }
+    }
+    return ""
 }
 
 func LangOfLocale(locale string) string {
-	if len(locale) < 2 {
-		return ""
-	}
-	return locale[0:2]
+    if len(locale) < 2 {
+        return ""
+    }
+    return locale[0:2]
 }
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 81bd161..ec202e8 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -32,104 +32,104 @@
 package wski18n
 
 import (
-	"bytes"
-	"compress/gzip"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
+    "bytes"
+    "compress/gzip"
+    "fmt"
+    "io"
+    "io/ioutil"
+    "os"
+    "path/filepath"
+    "strings"
+    "time"
 )
 
 func bindataRead(data []byte, name string) ([]byte, error) {
-	gz, err := gzip.NewReader(bytes.NewBuffer(data))
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
+    gz, err := gzip.NewReader(bytes.NewBuffer(data))
+    if err != nil {
+        return nil, fmt.Errorf("Read %q: %v", name, err)
+    }
 
-	var buf bytes.Buffer
-	_, err = io.Copy(&buf, gz)
-	clErr := gz.Close()
+    var buf bytes.Buffer
+    _, err = io.Copy(&buf, gz)
+    clErr := gz.Close()
 
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
-	if clErr != nil {
-		return nil, err
-	}
+    if err != nil {
+        return nil, fmt.Errorf("Read %q: %v", name, err)
+    }
+    if clErr != nil {
+        return nil, err
+    }
 
-	return buf.Bytes(), nil
+    return buf.Bytes(), nil
 }
 
 type asset struct {
-	bytes []byte
-	info  os.FileInfo
+    bytes []byte
+    info  os.FileInfo
 }
 
 type bindataFileInfo struct {
-	name    string
-	size    int64
-	mode    os.FileMode
-	modTime time.Time
+    name    string
+    size    int64
+    mode    os.FileMode
+    modTime time.Time
 }
 
 func (fi bindataFileInfo) Name() string {
-	return fi.name
+    return fi.name
 }
 func (fi bindataFileInfo) Size() int64 {
-	return fi.size
+    return fi.size
 }
 func (fi bindataFileInfo) Mode() os.FileMode {
-	return fi.mode
+    return fi.mode
 }
 func (fi bindataFileInfo) ModTime() time.Time {
-	return fi.modTime
+    return fi.modTime
 }
 func (fi bindataFileInfo) IsDir() bool {
-	return false
+    return false
 }
 func (fi bindataFileInfo) Sys() interface{} {
-	return nil
+    return nil
 }
 
 var _wski18nResourcesDe_deAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesDe_deAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesDe_deAllJson,
-		"wski18n/resources/de_DE.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesDe_deAllJson,
+        "wski18n/resources/de_DE.all.json",
+    )
 }
 
 func wski18nResourcesDe_deAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesDe_deAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesDe_deAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xa4\x94\xc1\x8e\xd3\x30\x10\x86\xef\x7e\x8a\x51\x2e\x7b\xa9\xc2\x9d\xdb\x1e\x56\xda\x15\x82\x5d\xb1\x0b\x12\x02\xa4\x9a\x78\xd2\x98\xc6\x76\x64\x8f\x41\xc5\xca\xbb\x23\xbb\x6d\xa8\x8a\xdd\xa6\xdd\x5b\x6c\xcf\x7c\xf3\x7b\x7e\x4f\xbe\x32\x80\xc0\x00\x00\x2a\x29\xaa\xb7\x50\xdd\x63\xdf\x9b\x6a\xb1\xdd\x22\xcb\xb5\xeb\x39\x49\xa3\xe3\xd9\xad\x86\xdb\xa7\x07\xe8\x8c\x23\x50\xde\x11\xfc\x40\x18\xac\xf9\x25\x05 [...]
+var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x95\xc1\x8e\xd3\x30\x10\x40\xef\xf9\x8a\x51\x2f\x7b\x59\x85\xfb\xde\xf6\xb0\x68\x57\x08\xba\xa2\x0b\x08\x01\x52\x4d\x32\x69\x4c\xed\x71\x64\x8f\x8b\x4a\x94\x7f\x47\x76\xda\x52\x15\x27\x4d\x0b\xb7\xc4\x99\x79\xf3\xec\xb1\x9d\x2f\x19\x40\x9b\x01\x00\xcc\x64\x39\xbb\x83\xd9\x23\x2a\x65\x66\xb7\xfd\x10\x5b\x41\x4e\x09\x96\x86\xc2\xb7\x7b\x82\xfb\xe7\x27\xa8\x8d\x63\xd0\xde\x31\x7c\x47\x68\xac\xd9\xc8\x12 [...]
 
 func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesEn_usAllJson,
-		"wski18n/resources/en_US.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesEn_usAllJson,
+        "wski18n/resources/en_US.all.json",
+    )
 }
 
 func wski18nResourcesEn_usAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesEn_usAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesEn_usAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-    info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 1890, mode: os.FileMode(420), modTime: time.Unix(1504289235, 0)}
+    info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 2359, mode: os.FileMode(420), modTime: time.Unix(1504640900, 0)}
     a := &asset{bytes: bytes, info: info}
     return a, nil
 }
@@ -137,225 +137,225 @@ func wski18nResourcesEn_usAllJson() (*asset, error) {
 var _wski18nResourcesEs_esAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesEs_esAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesEs_esAllJson,
-		"wski18n/resources/es_ES.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesEs_esAllJson,
+        "wski18n/resources/es_ES.all.json",
+    )
 }
 
 func wski18nResourcesEs_esAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesEs_esAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesEs_esAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 var _wski18nResourcesFr_frAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\xe6\x52\x50\xa8\xe6\x52\x50\x50\x50\x50\xca\x4c\x51\xb2\x52\x50\x4a\xaa\x2c\x48\x2c\x2e\x56\x48\x4e\x2d\x2a\xc9\x4c\xcb\x4c\x4e\x2c\x49\x55\x48\xce\x48\x4d\xce\xce\xcc\x4b\x57\xd2\x81\x28\x2c\x29\x4a\xcc\x2b\xce\x49\x2c\xc9\xcc\xcf\x03\xe9\x08\xce\xcf\x4d\x55\x40\x12\x53\xc8\xcc\x53\x70\x2b\x4a\xcd\x4b\xce\x50\xe2\x52\x50\xa8\xe5\x8a\xe5\x02\x04\x00\x00\xff\xff\x45\xa4\xe9\x62\x65\x00\x00\x00")
 
 func wski18nResourcesFr_frAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesFr_frAllJson,
-		"wski18n/resources/fr_FR.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesFr_frAllJson,
+        "wski18n/resources/fr_FR.all.json",
+    )
 }
 
 func wski18nResourcesFr_frAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesFr_frAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesFr_frAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 var _wski18nResourcesIt_itAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesIt_itAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesIt_itAllJson,
-		"wski18n/resources/it_IT.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesIt_itAllJson,
+        "wski18n/resources/it_IT.all.json",
+    )
 }
 
 func wski18nResourcesIt_itAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesIt_itAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesIt_itAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 var _wski18nResourcesJa_jaAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesJa_jaAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesJa_jaAllJson,
-		"wski18n/resources/ja_JA.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesJa_jaAllJson,
+        "wski18n/resources/ja_JA.all.json",
+    )
 }
 
 func wski18nResourcesJa_jaAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesJa_jaAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesJa_jaAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 var _wski18nResourcesKo_krAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesKo_krAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesKo_krAllJson,
-		"wski18n/resources/ko_KR.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesKo_krAllJson,
+        "wski18n/resources/ko_KR.all.json",
+    )
 }
 
 func wski18nResourcesKo_krAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesKo_krAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesKo_krAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 var _wski18nResourcesPt_brAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesPt_brAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesPt_brAllJson,
-		"wski18n/resources/pt_BR.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesPt_brAllJson,
+        "wski18n/resources/pt_BR.all.json",
+    )
 }
 
 func wski18nResourcesPt_brAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesPt_brAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesPt_brAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 var _wski18nResourcesZh_hansAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesZh_hansAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesZh_hansAllJson,
-		"wski18n/resources/zh_Hans.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesZh_hansAllJson,
+        "wski18n/resources/zh_Hans.all.json",
+    )
 }
 
 func wski18nResourcesZh_hansAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesZh_hansAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesZh_hansAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 var _wski18nResourcesZh_hantAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
 
 func wski18nResourcesZh_hantAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesZh_hantAllJson,
-		"wski18n/resources/zh_Hant.all.json",
-	)
+    return bindataRead(
+        _wski18nResourcesZh_hantAllJson,
+        "wski18n/resources/zh_Hant.all.json",
+    )
 }
 
 func wski18nResourcesZh_hantAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesZh_hantAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
+    bytes, err := wski18nResourcesZh_hantAllJsonBytes()
+    if err != nil {
+        return nil, err
+    }
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
+    info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1500653295, 0)}
+    a := &asset{bytes: bytes, info: info}
+    return a, nil
 }
 
 // Asset loads and returns the asset for the given name.
 // It returns an error if the asset could not be found or
 // could not be loaded.
 func Asset(name string) ([]byte, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
-		}
-		return a.bytes, nil
-	}
-	return nil, fmt.Errorf("Asset %s not found", name)
+    cannonicalName := strings.Replace(name, "\\", "/", -1)
+    if f, ok := _bindata[cannonicalName]; ok {
+        a, err := f()
+        if err != nil {
+            return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+        }
+        return a.bytes, nil
+    }
+    return nil, fmt.Errorf("Asset %s not found", name)
 }
 
 // MustAsset is like Asset but panics when Asset would return an error.
 // It simplifies safe initialization of global variables.
 func MustAsset(name string) []byte {
-	a, err := Asset(name)
-	if err != nil {
-		panic("asset: Asset(" + name + "): " + err.Error())
-	}
+    a, err := Asset(name)
+    if err != nil {
+        panic("asset: Asset(" + name + "): " + err.Error())
+    }
 
-	return a
+    return a
 }
 
 // AssetInfo loads and returns the asset info for the given name.
 // It returns an error if the asset could not be found or
 // could not be loaded.
 func AssetInfo(name string) (os.FileInfo, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
-		}
-		return a.info, nil
-	}
-	return nil, fmt.Errorf("AssetInfo %s not found", name)
+    cannonicalName := strings.Replace(name, "\\", "/", -1)
+    if f, ok := _bindata[cannonicalName]; ok {
+        a, err := f()
+        if err != nil {
+            return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+        }
+        return a.info, nil
+    }
+    return nil, fmt.Errorf("AssetInfo %s not found", name)
 }
 
 // AssetNames returns the names of the assets.
 func AssetNames() []string {
-	names := make([]string, 0, len(_bindata))
-	for name := range _bindata {
-		names = append(names, name)
-	}
-	return names
+    names := make([]string, 0, len(_bindata))
+    for name := range _bindata {
+        names = append(names, name)
+    }
+    return names
 }
 
 // _bindata is a table, holding each asset generator, mapped to its name.
 var _bindata = map[string]func() (*asset, error){
-	"wski18n/resources/de_DE.all.json":   wski18nResourcesDe_deAllJson,
-	"wski18n/resources/en_US.all.json":   wski18nResourcesEn_usAllJson,
-	"wski18n/resources/es_ES.all.json":   wski18nResourcesEs_esAllJson,
-	"wski18n/resources/fr_FR.all.json":   wski18nResourcesFr_frAllJson,
-	"wski18n/resources/it_IT.all.json":   wski18nResourcesIt_itAllJson,
-	"wski18n/resources/ja_JA.all.json":   wski18nResourcesJa_jaAllJson,
-	"wski18n/resources/ko_KR.all.json":   wski18nResourcesKo_krAllJson,
-	"wski18n/resources/pt_BR.all.json":   wski18nResourcesPt_brAllJson,
-	"wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
-	"wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
+    "wski18n/resources/de_DE.all.json": wski18nResourcesDe_deAllJson,
+    "wski18n/resources/en_US.all.json": wski18nResourcesEn_usAllJson,
+    "wski18n/resources/es_ES.all.json": wski18nResourcesEs_esAllJson,
+    "wski18n/resources/fr_FR.all.json": wski18nResourcesFr_frAllJson,
+    "wski18n/resources/it_IT.all.json": wski18nResourcesIt_itAllJson,
+    "wski18n/resources/ja_JA.all.json": wski18nResourcesJa_jaAllJson,
+    "wski18n/resources/ko_KR.all.json": wski18nResourcesKo_krAllJson,
+    "wski18n/resources/pt_BR.all.json": wski18nResourcesPt_brAllJson,
+    "wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
+    "wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
 }
 
 // AssetDir returns the file names below a certain
@@ -372,92 +372,92 @@ var _bindata = map[string]func() (*asset, error){
 // AssetDir("foo.txt") and AssetDir("notexist") would return an error
 // AssetDir("") will return []string{"data"}.
 func AssetDir(name string) ([]string, error) {
-	node := _bintree
-	if len(name) != 0 {
-		cannonicalName := strings.Replace(name, "\\", "/", -1)
-		pathList := strings.Split(cannonicalName, "/")
-		for _, p := range pathList {
-			node = node.Children[p]
-			if node == nil {
-				return nil, fmt.Errorf("Asset %s not found", name)
-			}
-		}
-	}
-	if node.Func != nil {
-		return nil, fmt.Errorf("Asset %s not found", name)
-	}
-	rv := make([]string, 0, len(node.Children))
-	for childName := range node.Children {
-		rv = append(rv, childName)
-	}
-	return rv, nil
+    node := _bintree
+    if len(name) != 0 {
+        cannonicalName := strings.Replace(name, "\\", "/", -1)
+        pathList := strings.Split(cannonicalName, "/")
+        for _, p := range pathList {
+            node = node.Children[p]
+            if node == nil {
+                return nil, fmt.Errorf("Asset %s not found", name)
+            }
+        }
+    }
+    if node.Func != nil {
+        return nil, fmt.Errorf("Asset %s not found", name)
+    }
+    rv := make([]string, 0, len(node.Children))
+    for childName := range node.Children {
+        rv = append(rv, childName)
+    }
+    return rv, nil
 }
 
 type bintree struct {
-	Func     func() (*asset, error)
-	Children map[string]*bintree
+    Func     func() (*asset, error)
+    Children map[string]*bintree
 }
-
 var _bintree = &bintree{nil, map[string]*bintree{
-	"wski18n": &bintree{nil, map[string]*bintree{
-		"resources": &bintree{nil, map[string]*bintree{
-			"de_DE.all.json":   &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}},
-			"en_US.all.json":   &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}},
-			"es_ES.all.json":   &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}},
-			"fr_FR.all.json":   &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}},
-			"it_IT.all.json":   &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}},
-			"ja_JA.all.json":   &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
-			"ko_KR.all.json":   &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}},
-			"pt_BR.all.json":   &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}},
-			"zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
-			"zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
-		}},
-	}},
+    "wski18n": &bintree{nil, map[string]*bintree{
+        "resources": &bintree{nil, map[string]*bintree{
+            "de_DE.all.json": &bintree{wski18nResourcesDe_deAllJson, map[string]*bintree{}},
+            "en_US.all.json": &bintree{wski18nResourcesEn_usAllJson, map[string]*bintree{}},
+            "es_ES.all.json": &bintree{wski18nResourcesEs_esAllJson, map[string]*bintree{}},
+            "fr_FR.all.json": &bintree{wski18nResourcesFr_frAllJson, map[string]*bintree{}},
+            "it_IT.all.json": &bintree{wski18nResourcesIt_itAllJson, map[string]*bintree{}},
+            "ja_JA.all.json": &bintree{wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
+            "ko_KR.all.json": &bintree{wski18nResourcesKo_krAllJson, map[string]*bintree{}},
+            "pt_BR.all.json": &bintree{wski18nResourcesPt_brAllJson, map[string]*bintree{}},
+            "zh_Hans.all.json": &bintree{wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
+            "zh_Hant.all.json": &bintree{wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
+        }},
+    }},
 }}
 
 // RestoreAsset restores an asset under the given directory
 func RestoreAsset(dir, name string) error {
-	data, err := Asset(name)
-	if err != nil {
-		return err
-	}
-	info, err := AssetInfo(name)
-	if err != nil {
-		return err
-	}
-	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
-	if err != nil {
-		return err
-	}
-	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
-	if err != nil {
-		return err
-	}
-	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
-	if err != nil {
-		return err
-	}
-	return nil
+    data, err := Asset(name)
+    if err != nil {
+        return err
+    }
+    info, err := AssetInfo(name)
+    if err != nil {
+        return err
+    }
+    err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+    if err != nil {
+        return err
+    }
+    err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+    if err != nil {
+        return err
+    }
+    err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+    if err != nil {
+        return err
+    }
+    return nil
 }
 
 // RestoreAssets restores an asset under the given directory recursively
 func RestoreAssets(dir, name string) error {
-	children, err := AssetDir(name)
-	// File
-	if err != nil {
-		return RestoreAsset(dir, name)
-	}
-	// Dir
-	for _, child := range children {
-		err = RestoreAssets(dir, filepath.Join(name, child))
-		if err != nil {
-			return err
-		}
-	}
-	return nil
+    children, err := AssetDir(name)
+    // File
+    if err != nil {
+        return RestoreAsset(dir, name)
+    }
+    // Dir
+    for _, child := range children {
+        err = RestoreAssets(dir, filepath.Join(name, child))
+        if err != nil {
+            return err
+        }
+    }
+    return nil
 }
 
 func _filePath(dir, name string) string {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+    cannonicalName := strings.Replace(name, "\\", "/", -1)
+    return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
 }
+
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 45c3bdb..c218af0 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -69,6 +69,18 @@
   {
     "id": "The namespace is {{.namespace}}, from {{.namespacesource}}.\n",
     "translation": "The namespace is {{.namespace}}, from {{.namespacesource}}.\n"
+  },
+  {
+    "id": "Failed to get the supported runtimes from OpenWhisk service: {{.err}}.\n",
+    "translation": "Failed to get the supported runtimes from OpenWhisk service: {{.err}}.\n"
+  },
+  {
+    "id": "Start to unmarshal Openwhisk info from local values.\n",
+    "translation": "Start to unmarshal Openwhisk info from local values.\n"
+  },
+  {
+    "id": "Unmarshal Openwhisk info from internet.\n",
+    "translation": "Unmarshal Openwhisk info from internet.\n"
   }
 
 ]

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