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 2018/03/21 18:18:12 UTC
[incubator-openwhisk-cli] branch master updated: Remove notes.md
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
The following commit(s) were added to refs/heads/master by this push:
new 377940b Remove notes.md
377940b is described below
commit 377940b3e3b15c47359de0bd3b3ca380be256667
Author: dubeejw <jw...@us.ibm.com>
AuthorDate: Wed Mar 21 13:23:12 2018 -0400
Remove notes.md
---
notes.md | 753 ---------------------------------------------------------------
1 file changed, 753 deletions(-)
diff --git a/notes.md b/notes.md
deleted file mode 100644
index ac0e0e7..0000000
--- a/notes.md
+++ /dev/null
@@ -1,753 +0,0 @@
-<!--
-#
-# 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.
-#
--->
-
-## Tasks
-- [X] Environment variables
- + what are they?
- + unclear ...
-- [x] sdk
-- [x] apibuild + cliversion
-- [x] props variable, revisited
-- [x] Edge ?
--
-
----
-
-+ parse toml file into properties and constants
-+
-
-## Notes
-
-Now testing... first, read through the tests and make sure that they look like they should pass...
-- [ ] make a list of potentially failing tests -->
- + [x] activation poll
- + add method
- + in python app, `poll` wraps `console`
- + console
- + if no `since-`flags have been passed, then return fetch most recent (activation.list({limit:1,}))
- + else, once a second do:
- +
-
- + add flags
- + sinceSeconds [int ?]
- + sinceMinutes
- + sinceHours
- + sinceDays
- + exit int
-
- + [ ] namespace list --> type ?
- + [ ] add package refresh command / client action
- + `refresh` command
- + just takes an optional namespace argument
- + service
- +
- + [x] action create --> add flags [ and maybe add to client as well ]
- + [ ] memory
- + [ ] sequence
- + [ ] param
- + [ ] annotation
- + [ ] timeout
-
-- [ ] fix or approve tests in list
-
----
-- [x] fails gracelessly when given invalid url as apiHOST
-
-- [x] edge broken
- - needs protocol / https
-
-
-- [x] set property broken
-
-- [x] (unable to assign apihost with flag)
-
-
-- [x] apibuild does not print out
---> client.Info.Get()
- --> info is blank --> print out response body
-
----
-
-
-
-[x] Props -> namespace --> need to make a request to "/namespaces" first to get a list of legal namespaces, then confirm that requested is legal.
-
-
----
-
-Need to consider how props is being stored ... --> need to have a single global props, with defaults
-
-
-top-level properties struct
-
-on init, load properties from .wskprops, environment, flags.
-
-initialize client config from properties.
-
-
-
-getProperties --> print out Properties --> according to flags set.
-
-setProperties -->
-
- readProps
-
- according to flags, update props
- write props
-
-
-unsetProperties -->
-
- readProps
- delete relevant ones.
- writeProps
-
-
-readProps -> map[string]string, ok
-writeProps(map[string]string) -> ok
-
-
----
-
-
-Check that it is up to date...
-Anything known to be missing?
-
-SDK --> simple enough... just do it.
-
-What's the deal with apibuild, and cliversion ?
-
-Do a side-by-side comparision of wsk versions. should be the same, except formatting
-
-Anything else I'm missing?
-
-Environment variables.
-WHISK_APIVERSION
-WHISK_AUTH
-WHISK_etc..
-WHISK_
-
-
-
-
----
-
-Updates to the client / command line api
-
-
-client changes:
-[X] add namespace get / list --> modify to be current (list is list triggers etc for current, get is list of namespaces)
-
-Get namespace contents:
-
-wsk namespace get --> GET /v1/namespaces/_
-wsk namespace get namespace --> GET /v1/namespaces/_/user--
-
-Get list of namespaces available
-
-wsk namespace list -> GET /v1/namespaces
-
-So ... --> update namespace client.
-
-
-new top-level flags:
-- `--apihost`: whisk api host
-- `--apiversion`: whisk api version
-
-[X] add `PropertyCmd`
-
-
-Need to remove persistent global flags and re-add. (auth etc.)
-
-- use: "work with whisk properties"
-- set
- + -u, --auth
- + --apihost
- + --apiversion
- + --namespace
-
-
-- get
- + -u, --auth
- + --apihost
- + --apiversion
- + --cliversion
- + --apibuild
- + --namespace
- + --all
-
-Namespace --> api is `:443/api/{apivesion}/namespaces/{namespace}`
-
-[x] remove top-level commands:
-- auth
-- list
-- whoami
-- health
-- clean
-- namespace
-- version
-
-remove top-level flags:
-
-- --auth (added to local level ?)
--
-
-
-
-Implemenmt sdk command
-- install
- - component {docker, swift, iOS}
-
----
-
-Parsing params, annotations, and action#invoke payload --> as json data
-
-params and annotations --> attempt to parse as json into map[string]interface{}. if it fails, then throw error
-
-payload is the same except for that if it is not valid json then obj is created "{payload: arg}".
-
-What about response object ?? Will also be a map[string]interface{} ??
-
-To start: --> change action invoke :payload to a map[string]interface{} and see if it breaks.
-
-Ok mostly working ...
-
---> need to add it back in to
-- [x] trigger
-- [x] package
-- [x] rule ?
-
-
-What does trigger#fire return? {id: "id"}
-
-
-
----
-Order of variables: flags -> env -> .wsk
-
-1. load flags, env, and .wsk (props)
-2. for each value, check and assign in order
-3. initialize client + other variables that depend on values
-
-config:
-- `auth`
-- `namespace`
-- `edge`
-
-- [X] load props and env. variables in main init. Write a top-level persistent pre-run function to read the command line variables.
-
-- [X] add setter functions
- + [X] `auth`
- + [X] `namespace`
-
----
-
-package.bind ...
-
-```python
-
-def bind(self, args, props):
- url = 'https://%(url)s/api/v1/%(namespace)s/packages/%(name)s' % {
- 'url': props['api'],
- 'namespace': urllib.quote(args.namespace),
- 'name': self.getSafeName(args.name)
- }
- split = args.package.split(':')
- binding = {}
- if (len(split) == 1):
- binding = { 'name': split[0], 'namespace': args.namespace}
- elif (len(split) == 2):
- binding = { 'name': split[1], 'namespace': split[0]}
- else:
- print 'package name malformed. name or namespace/name allowed'
- sys.exit(1)
-
- payload = {
- 'name': args.name,
- 'binding': binding,
- 'annotations': getAnnotations(args),
- 'parameters': getParams(args)
- }
- args.shared = False
- self.addPublish(payload, args)
- headers= {
- 'Content-Type': 'application/json'
- }
- res = request('PUT', url, json.dumps(payload), headers, auth=args.auth, verbose=args.verbose)
-
- resBody = res.read()
- result = json.loads(resBody)
-
- if res.status == httplib.OK:
- print 'ok: created binding %(name)s ' % {'name': args.name }
- return 0
- else:
- print 'error: ' + result['error']
- return res.status
-```
-
----
-
-
-```python
-
-def create(self, args, props, update):
- exe = self.getExec(args, props)
- if args.pipe:
- if args.param is None:
- args.param = []
- args.param.append([ '_actions', json.dumps(self.csvToList(args.artifact))])
-
- validExe = exe is not None and ('image' in exe or 'code' in exe)
- if update or validExe: # if create action, then exe must be valid
- payload = {
- 'name': args.name,
- 'annotations': getAnnotations(args),
- 'parameters': getParams(args),
- 'limits' : self.getLimits(args)
- }
- if validExe:
- payload['exec'] = exe
- self.addPublish(payload, args)
- return self.put(args, props, update, json.dumps(payload))
- else:
- print 'the artifact "%s" is not a valid file. If this is a docker image, use --docker.' % args.artifact
- return 2
-
-
-# creates { code: "js code", image: "docker image", initializer: "base64 encoded string" }
-# where code and image are mutually exclusive and initializer is optional
-def getExec(self, args, props):
- exe = {}
- if args.docker:
- exe['image'] = args.artifact
- elif args.copy:
- existingAction = args.artifact
- exe = self.getActionExec(args, props, existingAction)
- elif args.pipe:
- args2 = copy.copy(args) # shallow copy of args object
- args2.namespace = 'client.system'
- pipeAction = 'common/pipe'
- exe = self.getActionExec(args2, props, pipeAction)
- elif args.artifact is not None and os.path.isfile(args.artifact):
- exe['code'] = open(args.artifact, 'rb').read()
- if args.lib:
- exe['initializer'] = base64.b64encode(args.lib.read())
- return exe
-
-def getActionExec(self, args, props, name):
- res = self.Get(args, props, name)
- resBody = res.read()
- if res.status == httplib.OK:
- execField = json.loads(resBody)['exec']
- else:
- execField = None
- return execField
-
-```
-
-
-Action Create:
-
-```golang
-
- if flags.docker
- exec.image = artifact // what artifact ?
-
- else if flags.copy
- -> actions.Get(actionName), copy exec
-
- else if flags.pipe
- -> (copy args)
- -> client.Config.Namespace = "client.system"
- -> actionName = "common/pipe"
- -> actions.Get(actionName), copy exec
-
- else if artifact != "" && os.FileExists(artifact)
- -> exec.code = os.ReadFile(artifact)
-
- if flags.lib
- -> exec.init = base64.Encode(flag.lib.read()) // lib is gzipped or tar file.
-
-
-
-
-```
-
-
----
-
-Thinking about how to persist data in between wsk calls. The way that the python version does it is to write to a file on disk. What other ways are there to do this?
-- How does github cli do this ?
-
-- Start working on command ...
- + fill out methods.
- + first need to create a reference to the whisk... Top-level variable. --> parse flags, then assign
-
-## To do's
-
-- [X] actionInvokeCmd --> parse payload properly.
-
-- [ ] better error responses
- + read resp.Body for message.
-
-- [ ] Add support for environment variables
- - EDGE_HOST
- - CLI_API_HOST
- - WHISK_VERSION_DATE
-
-- [x] create action
- + see above
-- [ ] verbose
-- [ ] Verbose (with a writer or something fancy)
- + how to avoid putting this on the client ?
-- [X] params / annotations
-- [X] positional arguments
-- [ ] SDK
-
-
-- [X] finish all simple methods
- + [x] package
- + [X] rule
- + [X] trigger
-
-- [ ] Figure out how to properly define positional arguments with cobra / pflags.
-
-- [ ] Implement verbose mode to help with debugging.
-
-- [X] finish complex methods
- + [X] Action.Create with exec and all flags
- + [X] Action.Invoke with params
-
-- Local install
- - vagrant.
- - test everything locally, include how in docs.
- - Debug locally.
-
-- review how other cli packages store props (to disk)
- + hugo
- + github
-
-- Cmd
- + implement loadConfig + updateConfig
- + add basic Client methods
- + auth
- + clean
- + version
- + add verbose
- + add arguments
- + add flags
- + top-level
- + sub-cmd-level
-
- + add messages
- + add functions (link up with stubbed out client + props)
-- Client
- + [X] stub out methods for all services (with arguments)
- + [X] complete services
- + [X] complete request method for Client ()
- + [X] figure out what namespaces is about
- + [X] add auth to Client
-
-
-
-## Solutions
-
-
-
-
-<!--
-
-NONE OF THIS MATTERS! stuff is reloaded every time the
- - watching props
- + have a loadPropsFromFile function
- + if file missing, use default
- + have an update prop(s) function
- + updates the file.
- + have a watch propsFile function -> updates client when it detects a change. -->
-
-- auth
- + include token in Client struct (base64 encoded?)
- + Add Auth header in *whisk.Request
-- verbose
- + include bool in Client struct
- + print out in *whisk.Do
-- BUT ALSO!!!
- + need to store on disk so that it is the same in between invocations. This is done in cmd --> initialized the client based on contents of .wskprops
-
-## Code Samples From whisk *python
-
----
-
-`wskitem.py`
-
-```python
-def put(self, args, props, update, payload):
- url = 'https://%(url)s/%(service)s/v1/%(namespace)s/%(collection)s/%(name)s%(update)s' % {
- 'url': props[self.service],
- 'service': self.service,
- 'namespace': urllib.quote(args.namespace),
- 'collection': self.collection,
- 'name': self.getSafeName(args.name),
- 'update': '?overwrite=true' if update else ''
- }
-
- headers= {
- 'Content-Type': 'application/json'
- }
-
- res = request('PUT', url, payload, headers, auth=args.auth, verbose=args.verbose)
- resBody = res.read()
-
- if res.status == httplib.OK:
- print 'ok: %(mode)s %(item)s %(name)s' % { 'mode': 'updated' if update else 'created', 'item': self.name, 'name': args.name }
- return 0
- else:
- result = json.loads(resBody)
- print 'error: ' + result['error']
- return res.status
-```
-
-- This gives the url structure for resource requests
-- `request` is defined in `wskutil.py`
-
----
-
-`wskutil.py`
-
-```python
-def request(method, urlString, body = "", headers = {}, auth = None, verbose = False):
- url = urlparse(urlString)
- if url.scheme == 'http':
- conn = httplib.HTTPConnection(url.netloc)
- else:
- if hasattr(ssl, '_create_unverified_context'):
- conn = httplib.HTTPSConnection(url.netloc, context=ssl._create_unverified_context())
- else:
- conn = httplib.HTTPSConnection(url.netloc)
-
- if auth != None:
- auth = base64.encodestring(auth).replace('\n', '')
- headers['Authorization'] = 'Basic %s' % auth
-
- if verbose:
- print "========"
- print "REQUEST:"
- print "%s %s" % (method, urlString)
- print "Headers sent:"
- print json.dumps(headers, indent=4)
- if body != "":
- print "Body sent:"
- print body
-
- conn.request(method, urlString, body, headers)
- res = conn.getresponse()
- body = res.read()
-
- # patch the read to return just the body since the normal read
- # can only be done once
- res.read = lambda: body
-
- if verbose:
- print "--------"
- print "RESPONSE:"
- print "Got response with code %s" % res.status
- print "Body received:"
- print res.read()
- print "========"
-
- return res
-```
-
-- Shows auth scheme --> just base64 encode and use basic authorization for requests
-
-
-## Code samples from hugo
-
----
-
-from `commands/hugo.go`
-
-```go
-
-// Execute adds all child commands to the root command HugoCmd and sets flags appropriately.
-func Execute() {
- HugoCmd.SetGlobalNormalizationFunc(helpers.NormalizeHugoFlags)
-
- HugoCmd.SilenceUsage = true
-
- AddCommands()
-
- if c, err := HugoCmd.ExecuteC(); err != nil {
- if isUserError(err) {
- c.Println("")
- c.Println(c.UsageString())
- }
-
- return
- }
-}
-
-// AddCommands adds child commands to the root command HugoCmd.
-func AddCommands() {
- HugoCmd.AddCommand(serverCmd)
- HugoCmd.AddCommand(versionCmd)
- HugoCmd.AddCommand(configCmd)
- HugoCmd.AddCommand(checkCmd)
- HugoCmd.AddCommand(benchmarkCmd)
- HugoCmd.AddCommand(convertCmd)
- HugoCmd.AddCommand(newCmd)
- HugoCmd.AddCommand(listCmd)
- HugoCmd.AddCommand(undraftCmd)
- HugoCmd.AddCommand(importCmd)
-
- HugoCmd.AddCommand(genCmd)
- genCmd.AddCommand(genautocompleteCmd)
- genCmd.AddCommand(gendocCmd)
- genCmd.AddCommand(genmanCmd)
-}
-
-```
-
-- use a top-level execute function like this to wrap Cmd.Execute().
-- Add all the commands in one place in the main function --> makes it much easier to see what's going on vs. in lots of different init files --> also easier to update / edit etc.
-
-```go
-
-
-
-
-// Flags that are to be added to commands.
-var BuildWatch, IgnoreCache, Draft, Future, UglyURLs, CanonifyURLs, Verbose, Logging, VerboseLog, DisableRSS, DisableSitemap, DisableRobotsTXT, PluralizeListTitles, PreserveTaxonomyNames, NoTimes, ForceSync bool
-var Source, CacheDir, Destination, Theme, BaseURL, CfgFile, LogFile, Editor string
-
-func initCoreCommonFlags(cmd *cobra.Command) {
- cmd.Flags().BoolVarP(&Draft, "buildDrafts", "D", false, "include content marked as draft")
- cmd.Flags().BoolVarP(&Future, "buildFuture", "F", false, "include content with publishdate in the future")
- cmd.Flags().BoolVar(&DisableRSS, "disableRSS", false, "Do not build RSS files")
- cmd.Flags().BoolVar(&DisableSitemap, "disableSitemap", false, "Do not build Sitemap file")
- cmd.Flags().BoolVar(&DisableRobotsTXT, "disableRobotsTXT", false, "Do not build Robots TXT file")
- cmd.Flags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from")
- cmd.Flags().StringVarP(&CacheDir, "cacheDir", "", "", "filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/")
- cmd.Flags().BoolVarP(&IgnoreCache, "ignoreCache", "", false, "Ignores the cache directory for reading but still writes to it")
- cmd.Flags().StringVarP(&Destination, "destination", "d", "", "filesystem path to write files to")
- cmd.Flags().StringVarP(&Theme, "theme", "t", "", "theme to use (located in /themes/THEMENAME/)")
- cmd.Flags().BoolVar(&UglyURLs, "uglyURLs", false, "if true, use /filename.html instead of /filename/")
- cmd.Flags().BoolVar(&CanonifyURLs, "canonifyURLs", false, "if true, all relative URLs will be canonicalized using baseURL")
- cmd.Flags().StringVarP(&BaseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/")
- cmd.Flags().StringVar(&CfgFile, "config", "", "config file (default is path/config.yaml|json|toml)")
- cmd.Flags().StringVar(&Editor, "editor", "", "edit new content with this editor, if provided")
- cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program")
- cmd.Flags().BoolVar(&PluralizeListTitles, "pluralizeListTitles", true, "Pluralize titles in lists using inflect")
- cmd.Flags().BoolVar(&PreserveTaxonomyNames, "preserveTaxonomyNames", false, `Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")`)
- cmd.Flags().BoolVarP(&ForceSync, "forceSyncStatic", "", false, "Copy all files when static is changed.")
- // For bash-completion
- validConfigFilenames := []string{"json", "js", "yaml", "yml", "toml", "tml"}
- cmd.Flags().SetAnnotation("config", cobra.BashCompFilenameExt, validConfigFilenames)
- cmd.Flags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
- cmd.Flags().SetAnnotation("cacheDir", cobra.BashCompSubdirsInDir, []string{})
- cmd.Flags().SetAnnotation("destination", cobra.BashCompSubdirsInDir, []string{})
- cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})
-}
-```
-
-- Parse variables like this.
-
----
-
-
-## Thoughts
-
----
-
-Now... -> fill out command functions.
-
-Perhaps start with a different function... with fewer flags ??
-
-
-Need to figure out how flags will be done...
-
-Can put in cmd.init() functions ?? yeah ...
-
-would be really nice if i could test this ...
-
-
----
-
-How to set namespace properly... ?
-
-stored in .wskprops, initialized in whisk.
-client offers namespaceService.List() only.
-
----
-
-Review other python cli commands that are not listed in swagger doc (e.g. namespaces, sdk )
-
----
-What does "clean" do ??
-
----
-
-What am I doing with Config / props ??
-
-What is the requirement?
-> read .wsk config into map[string]string
-> write map[string]string to file (configurable)
-
-
----
-
-
-current issue:
-Optional parameters... should not be listed in url params. If not there, then don't print.
-e.g. How to deal with activationsListOptions .since and .upto
-
-possible solution: use pointers. if pointer is nil, then ignore.
-
-
-```go
-func addRouteOptions(route string, options interface{}) (string, error) {
- v := reflect.ValueOf(options)
- if v.Kind() == reflect.Ptr && v.IsNil() {
- return route, nil
- }
-
- u, err := url.Parse(route)
- if err != nil {
- return route, err
- }
-
- qs, err := query.Values(options)
- if err != nil {
- return route, err
- }
-
- u.RawQuery = qs.Encode()
- return u.String(), nil
-}
-```
-- How does go-querystring/query.Values() work ?? has options ??
- + want to take all non-nil values from options and write key=value in url. Should ignore nil values (like for pointers and empty structs.)
-
-
-Already does this! using the tags... --> omit empty. Anything to worry about then ... ?
-
-
-- consider using pointers to structs.
--
-- for now, just flag and skip anything difficult.
--
To stop receiving notification emails like this one, please contact
houshengbo@apache.org.