You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by ho...@apache.org on 2017/06/23 04:04:30 UTC
[incubator-openwhisk-cli] 01/04: Allow docker actions with zip
files. (#2112)
This is an automated email from the ASF dual-hosted git repository.
houshengbo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git
commit 6c534d1c71166a03def3fff39f690d3731858b39
Author: rodric rabbah <ro...@gmail.com>
AuthorDate: Sat Jun 17 11:54:29 2017 -0400
Allow docker actions with zip files. (#2112)
* Allow docker actions with zip files.
Add native action for binary injection.
Add note about breaking change for --docker option.
* Separate dep fetching from rest of build to avoid repeated fetches when none changed.
---
commands/action.go | 89 +++++++++++++++++++++++++---------------
commands/flags.go | 41 ++++++++++--------
wski18n/resources/en_US.all.json | 20 ++++-----
3 files changed, 88 insertions(+), 62 deletions(-)
diff --git a/commands/action.go b/commands/action.go
index 2d8103f..8ba3633 100644
--- a/commands/action.go
+++ b/commands/action.go
@@ -58,10 +58,10 @@ var actionCreateCmd = &cobra.Command{
if whiskErr := checkArgs(
args,
- 2,
+ 1,
2,
"Action create",
- wski18n.T("An action name and action are required.")); whiskErr != nil {
+ wski18n.T("An action name and code artifact are required.")); whiskErr != nil {
return whiskErr
}
@@ -94,11 +94,11 @@ var actionUpdateCmd = &cobra.Command{
1,
2,
"Action update",
- wski18n.T("An action name is required. An action is optional.")); whiskErr != nil {
+ wski18n.T("An action name is required. A code artifact is optional.")); whiskErr != nil {
return whiskErr
}
- if action, err = parseAction(cmd, args, false); err != nil {
+ if action, err = parseAction(cmd, args, true); err != nil {
return actionParseError(cmd, args, err)
}
@@ -321,7 +321,6 @@ var actionListCmd = &cobra.Command{
func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action, error) {
var err error
- var artifact string
var existingAction *whisk.Action
var paramArgs []string
var annotArgs []string
@@ -334,10 +333,6 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action,
return nil, parseQualifiedNameError(args[0], err)
}
- if len(args) == 2 {
- artifact = args[1]
- }
-
client.Namespace = qualifiedName.namespace
action := new(whisk.Action)
action.Name = qualifiedName.entityName
@@ -387,11 +382,20 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action,
action.Parameters = append(action.Parameters, existingAction.Parameters...)
action.Annotations = append(action.Annotations, existingAction.Annotations...)
} else if Flags.action.sequence {
- action.Exec = new(whisk.Exec)
- action.Exec.Kind = "sequence"
- action.Exec.Components = csvToQualifiedActions(artifact)
- } else if len(artifact) > 0 {
- action.Exec, err = getExec(args[1], Flags.action.kind, Flags.action.docker, Flags.action.main)
+ if len(args) == 2 {
+ action.Exec = new(whisk.Exec)
+ action.Exec.Kind = "sequence"
+ action.Exec.Components = csvToQualifiedActions(args[1])
+ } else {
+ return nil, noArtifactError()
+ }
+ } else if len(args) > 1 || len(Flags.action.docker) > 0 {
+ action.Exec, err = getExec(args, Flags.action)
+ if err != nil {
+ return nil, err
+ }
+ } else if !update {
+ return nil, noArtifactError()
}
if cmd.LocalFlags().Changed(WEB_FLAG) {
@@ -403,39 +407,48 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action,
return action, err
}
-func getExec(artifact string, kind string, isDocker bool, mainEntry string) (*whisk.Exec, error) {
+func getExec(args []string, params ActionFlags) (*whisk.Exec, error) {
var err error
var code string
var exec *whisk.Exec
- ext := filepath.Ext(artifact)
exec = new(whisk.Exec)
+ kind := params.kind
+ isNative := params.native
+ docker := params.docker
+ mainEntry := params.main
+ ext := ""
- if !isDocker || ext == ".zip" {
+ if len(args) == 2 {
+ artifact := args[1]
+ ext = filepath.Ext(artifact)
code, err = ReadFile(artifact)
+ if err != nil {
+ whisk.Debug(whisk.DbgError, "ReadFile(%s) error: %s\n", artifact, err)
+ return nil, err
+ }
+
if ext == ".zip" || ext == ".jar" {
// Base64 encode the file
code = base64.StdEncoding.EncodeToString([]byte(code))
- exec.Code = &code
- } else {
- exec.Code = &code
}
- if err != nil {
- whisk.Debug(whisk.DbgError, "readFile(%s) error: %s\n", artifact, err)
- return nil, err
- }
+ exec.Code = &code
+ } else if len(args) == 1 && len(docker) == 0 {
+ return nil, noArtifactError()
+ } else if len(args) > 1 {
+ return nil, noArtifactError()
}
if len(kind) > 0 {
exec.Kind = kind
- } else if isDocker {
+ } else if len(docker) > 0 || isNative {
exec.Kind = "blackbox"
- if ext != ".zip" {
- exec.Image = artifact
- } else {
+ if isNative {
exec.Image = "openwhisk/dockerskeleton"
+ } else {
+ exec.Image = docker
}
} else if ext == ".swift" {
exec.Kind = "swift:default"
@@ -574,7 +587,7 @@ func nestedError(errorMessage string, err error) (error) {
func nonNestedError(errorMessage string) (error) {
return whisk.MakeWskError(
errors.New(errorMessage),
- whisk.EXITCODE_ERR_GENERAL,
+ whisk.EXITCODE_ERR_USAGE,
whisk.DISPLAY_MSG,
whisk.DISPLAY_USAGE)
}
@@ -583,9 +596,9 @@ func actionParseError(cmd *cobra.Command, args []string, err error) (error) {
whisk.Debug(whisk.DbgError, "parseAction(%s, %s) error: %s\n", cmd, args, err)
errMsg := wski18n.T(
- "Unable to parse action command arguments: {{.err}}",
+ "Invalid argument(s). {{.required}}",
map[string]interface{}{
- "err": err,
+ "required": err,
})
return nestedError(errMsg, err)
@@ -726,6 +739,12 @@ func zipKindError() (error) {
return nonNestedError(errMsg)
}
+func noArtifactError() (error) {
+ errMsg := wski18n.T("An action name and code artifact are required.")
+
+ return nonNestedError(errMsg)
+}
+
func extensionError(extension string) (error) {
errMsg := wski18n.T(
"'{{.name}}' is not a supported action runtime",
@@ -875,21 +894,23 @@ func isWebAction(client *whisk.Client, qname QualifiedName) error {
}
func init() {
- actionCreateCmd.Flags().BoolVar(&Flags.action.docker, "docker", false, wski18n.T("treat ACTION as docker image path on dockerhub"))
+ actionCreateCmd.Flags().BoolVar(&Flags.action.native, "native", false, wski18n.T("treat ACTION as native action (zip file provides a compatible executable to run)"))
+ actionCreateCmd.Flags().StringVar(&Flags.action.docker, "docker", "", wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
actionCreateCmd.Flags().BoolVar(&Flags.action.copy, "copy", false, wski18n.T("treat ACTION as the name of an existing action"))
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.logsize, "logsize", "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"))
- actionUpdateCmd.Flags().BoolVar(&Flags.action.docker, "docker", false, wski18n.T("treat ACTION as docker image path on dockerhub"))
+ 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"))
actionUpdateCmd.Flags().BoolVar(&Flags.action.copy, "copy", false, wski18n.T("treat ACTION as the name of an existing action"))
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)"))
diff --git a/commands/flags.go b/commands/flags.go
index d40e2aa..5695be8 100644
--- a/commands/flags.go
+++ b/commands/flags.go
@@ -32,7 +32,9 @@ const WEB_FLAG = "web"
var cliDebug = os.Getenv("WSK_CLI_DEBUG") // Useful for tracing init() code
-var Flags struct {
+var Flags FlagsStruct
+
+type FlagsStruct struct {
Global struct {
Verbose bool
@@ -49,10 +51,10 @@ var Flags struct {
annotFile string
param []string
paramFile string
- shared string // AKA "public" or "publish"
- skip int // skip first N records
- limit int // return max N records
- full bool // return full records (docs=true for client request)
+ shared string // AKA "public" or "publish"
+ skip int // skip first N records
+ limit int // return max N records
+ full bool // return full records (docs=true for client request)
summary bool
feed string // name of feed
detail bool
@@ -74,19 +76,7 @@ var Flags struct {
namespaceSet string
}
- action struct {
- docker bool
- copy bool
- pipe bool
- web string
- sequence bool
- timeout int
- memory int
- logsize int
- result bool
- kind string
- main string
- }
+ action ActionFlags
activation struct {
action string // retrieve results for this action
@@ -123,6 +113,21 @@ var Flags struct {
}
}
+
+type ActionFlags struct {
+ docker string
+ native bool
+ copy bool
+ web string
+ sequence bool
+ timeout int
+ memory int
+ logsize int
+ result bool
+ kind string
+ main string
+}
+
func IsVerbose() bool {
return Flags.Global.Verbose || IsDebug()
}
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index e173b42..7a9b778 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -688,10 +688,6 @@
"translation": "Arguments must be comma separated, and must be quoted if they contain spaces."
},
{
- "id": "Invalid arguments: {{.err}}",
- "translation": "Invalid arguments: {{.err}}"
- },
- {
"id": "The argument `{{.arg}}` is invalid: {{.err}}",
"translation": "The argument `{{.arg}}` is invalid: {{.err}}"
},
@@ -872,8 +868,12 @@
"translation": "Java actions require --main to specify the fully-qualified name of the main class"
},
{
- "id": "treat ACTION as docker image path on dockerhub",
- "translation": "treat ACTION as docker image path on dockerhub"
+ "id": "treat ACTION as native action (zip file provides a compatible executable to run)",
+ "translation": "treat ACTION as native action (zip file provides a compatible executable to run)"
+ },
+ {
+ "id": "use provided docker image (a path on DockerHub) to run the action",
+ "translation": "use provided docker image (a path on DockerHub) to run the action"
},
{
"id": "treat ACTION as the name of an existing action",
@@ -1048,16 +1048,16 @@
"translation": "The annotation arguments are invalid: {{.err}}"
},
{
- "id": "An action name and action are required.",
- "translation": "An action name and action are required."
+ "id": "An action name and code artifact are required.",
+ "translation": "An action name and code artifact are required."
},
{
"id": "An action name is required.",
"translation": "An action name is required."
},
{
- "id": "An action name is required. An action is optional.",
- "translation": "An action name is required. An action is optional."
+ "id": "An action name is required. A code artifact is optional.",
+ "translation": "An action name is required. A code artifact is optional."
},
{
"id": "An activation ID is required.",
--
To stop receiving notification emails like this one, please contact
"commits@openwhisk.apache.org" <co...@openwhisk.apache.org>.