mirror of https://github.com/knative/func.git
gather create parameters into a structure
This commit is contained in:
parent
fd27affb4b
commit
c12c5c17d2
109
cmd/create.go
109
cmd/create.go
|
@ -12,6 +12,16 @@ import (
|
|||
"github.com/boson-project/faas/kubectl"
|
||||
)
|
||||
|
||||
// The create command invokes the Service Funciton Client to create a new,
|
||||
// functional, deployed service function with a noop implementation. It
|
||||
// can be optionally created only locally (no deploy) using --local.
|
||||
var createCmd = &cobra.Command{
|
||||
Use: "create <language>",
|
||||
Short: "Create a Service Function",
|
||||
SuggestFor: []string{"init", "new"},
|
||||
RunE: create,
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Add the `create` command as a subcommand to root.
|
||||
root.AddCommand(createCmd)
|
||||
|
@ -34,71 +44,105 @@ func init() {
|
|||
|
||||
}
|
||||
|
||||
// The create command invokes the Service Funciton Client to create a new,
|
||||
// functional, deployed service function with a noop implementation. It
|
||||
// can be optionally created only locally (no deploy) using --local.
|
||||
var createCmd = &cobra.Command{
|
||||
Use: "create <language>",
|
||||
Short: "Create a Service Function",
|
||||
SuggestFor: []string{"init", "new"},
|
||||
RunE: create,
|
||||
// The create command expects several parameters, most of which can be
|
||||
// defaulted. When an interactive terminal is detected, these parameters,
|
||||
// which are gathered into this config object, are passed through the shell
|
||||
// allowing the user to interactively confirm and optionally modify values.
|
||||
type createConfig struct {
|
||||
// Verbose mode instructs the system to output detailed logs as the command
|
||||
// progresses.
|
||||
Verbose bool
|
||||
|
||||
// Local mode flag only builds a function locally, with no deployed
|
||||
// counterpart.
|
||||
Local bool
|
||||
|
||||
// Internal only flag. A public route will not be allocated and the domain
|
||||
// suffix will be a .local (depending on underlying cluster configuration)
|
||||
Internal bool
|
||||
|
||||
// Name of the service in DNS-compatible format (ex myfunc.example.com)
|
||||
Name string
|
||||
|
||||
// Registry of containers (ex. quay.io or hub.docker.com)
|
||||
Registry string
|
||||
|
||||
// Namespace within the container registry within which interstitial built
|
||||
// images will be stored by their canonical name.
|
||||
Namespace string
|
||||
|
||||
// Language is the first argument, and specifies the resultant Function
|
||||
// implementation language.
|
||||
Language string
|
||||
|
||||
// Path of the Function implementation on local disk. Defaults to current
|
||||
// working directory of the process.
|
||||
Path string
|
||||
}
|
||||
|
||||
// create a new service function using the client about config.
|
||||
func create(cmd *cobra.Command, args []string) (err error) {
|
||||
// Assert a language parameter was provided
|
||||
if len(args) == 0 {
|
||||
return errors.New("'faas create' requires a language argument.")
|
||||
}
|
||||
|
||||
// Assemble parameters for use in client's 'create' invocation.
|
||||
var (
|
||||
language = args[0] // language is the first argument
|
||||
path = "" // path is defaulted to current working directory.
|
||||
local = viper.GetBool("local") // Only perform local creation steps
|
||||
internal = viper.GetBool("internal") // Do not expose publicly (internal route only)
|
||||
name = viper.GetString("name") // Explicit name override (by default path-derives)
|
||||
verbose = viper.GetBool("verbose") // Verbose logging
|
||||
registry = viper.GetString("registry") // Registry (ex: docker.io)
|
||||
namespace = viper.GetString("namespace") // namespace at registry (user or org name)
|
||||
)
|
||||
// Create a deafult configuration populated first with environment variables,
|
||||
// followed by overrides by flags.
|
||||
var config = createConfig{
|
||||
Verbose: viper.GetBool("verbose"),
|
||||
Local: viper.GetBool("local"),
|
||||
Internal: viper.GetBool("internal"),
|
||||
Name: viper.GetString("name"),
|
||||
Registry: viper.GetString("registry"),
|
||||
Namespace: viper.GetString("namespace"),
|
||||
Language: args[0],
|
||||
Path: ".", // will be expanded to process current working dir.
|
||||
}
|
||||
|
||||
// If path is provided
|
||||
if len(args) == 2 {
|
||||
path = args[1]
|
||||
config.Path = args[1]
|
||||
}
|
||||
|
||||
// Namespace can not be defaulted.
|
||||
if namespace == "" {
|
||||
if config.Namespace == "" {
|
||||
return errors.New("image registry namespace (--namespace or FAAS_NAMESPACE is required)")
|
||||
}
|
||||
|
||||
// If we are running as an interactive terminal, allow the user
|
||||
// to mutate default config prior to execution.
|
||||
if isInteractive() {
|
||||
config = gatherFromUser(config)
|
||||
}
|
||||
|
||||
// Initializer creates a deployable noop function implementation in the
|
||||
// configured path.
|
||||
initializer := appsody.NewInitializer()
|
||||
initializer.Verbose = verbose
|
||||
initializer.Verbose = config.Verbose
|
||||
|
||||
// Builder creates images from function source.
|
||||
builder := appsody.NewBuilder(registry, namespace)
|
||||
builder.Verbose = verbose
|
||||
builder := appsody.NewBuilder(config.Registry, config.Namespace)
|
||||
builder.Verbose = config.Verbose
|
||||
|
||||
// Pusher of images
|
||||
pusher := docker.NewPusher()
|
||||
pusher.Verbose = verbose
|
||||
pusher.Verbose = config.Verbose
|
||||
|
||||
// Deployer of built images.
|
||||
deployer := kubectl.NewDeployer()
|
||||
deployer.Verbose = verbose
|
||||
deployer.Verbose = config.Verbose
|
||||
|
||||
// Instantiate a client, specifying concrete implementations for
|
||||
// Initializer and Deployer, as well as setting the optional verbosity param.
|
||||
client, err := faas.New(
|
||||
faas.WithVerbose(verbose),
|
||||
faas.WithVerbose(config.Verbose),
|
||||
faas.WithInitializer(initializer),
|
||||
faas.WithBuilder(builder),
|
||||
faas.WithPusher(pusher),
|
||||
faas.WithDeployer(deployer),
|
||||
faas.WithLocal(local), // local template only (no cluster deployment)
|
||||
faas.WithInternal(internal), // if deployed, no publicly accessible route.
|
||||
faas.WithLocal(config.Local), // local template only (no cluster deployment)
|
||||
faas.WithInternal(config.Internal), // if deployed, no publicly accessible route.
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -108,5 +152,10 @@ func create(cmd *cobra.Command, args []string) (err error) {
|
|||
// Returns the final address.
|
||||
// Name can be empty string (path-dervation will be attempted)
|
||||
// Path can be empty, defaulting to current working directory.
|
||||
return client.Create(language, name, path)
|
||||
return client.Create(config.Language, config.Name, config.Path)
|
||||
}
|
||||
|
||||
func gatherFromUser(config createConfig) createConfig {
|
||||
// TODO
|
||||
return config
|
||||
}
|
||||
|
|
|
@ -62,3 +62,11 @@ func Execute() {
|
|||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// isInteractive returns whether or not the currently attached process terminal
|
||||
// is interactive. Used for determining whether or not to interactively prompt
|
||||
// the user to confirm default choices, etc.
|
||||
func isInteractive() bool {
|
||||
fi, err := os.Stdin.Stat()
|
||||
return err == nil && ((fi.Mode() & os.ModeCharDevice) != 0)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue