Skip to content

Commit

Permalink
feat!: combine deploy and update commands (#152)
Browse files Browse the repository at this point in the history
Signed-off-by: Zbynek Roubalik <[email protected]>
  • Loading branch information
zroubalik authored Oct 7, 2020
1 parent 3c0b2bb commit d5839ea
Show file tree
Hide file tree
Showing 12 changed files with 294 additions and 457 deletions.
78 changes: 10 additions & 68 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package faas

import (
"errors"
"fmt"
"io"
"io/ioutil"
Expand All @@ -22,8 +21,7 @@ type Client struct {
verbose bool // print verbose logs
builder Builder // Builds a runnable image from Function source
pusher Pusher // Pushes the image assocaited with a Function.
deployer Deployer // Deploys a Function
updater Updater // Updates a deployed Function
deployer Deployer // Deploys or Updates a Function
runner Runner // Runs the Function locally
remover Remover // Removes remote services
lister Lister // Lists remote services
Expand Down Expand Up @@ -53,12 +51,6 @@ type Deployer interface {
Deploy(Function) error
}

// Updater of a deployed Function with new image.
type Updater interface {
// Update a Function
Update(Function) error
}

// Runner runs the Function locally.
type Runner interface {
// Run the Function locally.
Expand Down Expand Up @@ -124,7 +116,6 @@ func New(options ...Option) *Client {
builder: &noopBuilder{output: os.Stdout},
pusher: &noopPusher{output: os.Stdout},
deployer: &noopDeployer{output: os.Stdout},
updater: &noopUpdater{output: os.Stdout},
runner: &noopRunner{output: os.Stdout},
remover: &noopRemover{output: os.Stdout},
lister: &noopLister{output: os.Stdout},
Expand Down Expand Up @@ -171,13 +162,6 @@ func WithDeployer(d Deployer) Option {
}
}

// WithUpdater provides the concrete implementation of an updater.
func WithUpdater(u Updater) Option {
return func(c *Client) {
c.updater = u
}
}

// WithRunner provides the concrete implementation of a deployer.
func WithRunner(r Runner) Option {
return func(c *Client) {
Expand Down Expand Up @@ -418,26 +402,24 @@ func (c *Client) Build(path string) (err error) {
// Deploy the Function at path. Errors if the Function has not been
// initialized with an image tag.
func (c *Client) Deploy(path string) (err error) {

f, err := NewFunction(path)
if err != nil {
return
}
if f.Image == "" {
return errors.New("Function needs to have Image tag calculated prior to building.")
}

err = c.pusher.Push(f) // First push the image to an image registry
if err != nil {
// Build the Function
if err = c.Build(f.Root); err != nil {
return
}
if err = c.deployer.Deploy(f); err != nil {

// Push the image for the named service to the configured registry
if err = c.pusher.Push(f); err != nil {
return
}
if c.verbose {
// TODO: aspirational. Should be an actual route echo.
fmt.Printf("OK https://%v/\n", f.Image)
}
return

// Deploy a new or Update the previously-deployed Function
return c.deployer.Deploy(f)
}

func (c *Client) Route(path string) (err error) {
Expand All @@ -455,42 +437,6 @@ func (c *Client) Route(path string) (err error) {
return c.dnsProvider.Provide(f)
}

// Update a previously created Function.
func (c *Client) Update(root string) (err error) {

// Create an instance of a Function representation at the given root.
f, err := NewFunction(root)
if err != nil {
return
}

if !f.Initialized() {
// TODO: this needs a test.
return fmt.Errorf("the given path '%v' does not contain an initialized Function. Please create one at this path before updating.", root)
}

// Build an image from the current state of the Function's implementation.
err = c.Build(f.Root)
if err != nil {
return
}

// reload the Function as it will now have the Image populated if it had not yet been set.
f, err = NewFunction(f.Root)
if err != nil {
return
}

// Push the image for the named service to the configured registry
if err = c.pusher.Push(f); err != nil {
return
}

// Update the previously-deployed Function, returning its publicly
// addressible name for possible registration.
return c.updater.Update(f)
}

// Run the Function whose code resides at root.
func (c *Client) Run(root string) error {

Expand Down Expand Up @@ -573,10 +519,6 @@ type noopDeployer struct{ output io.Writer }

func (n *noopDeployer) Deploy(_ Function) error { return nil }

type noopUpdater struct{ output io.Writer }

func (n *noopUpdater) Update(_ Function) error { return nil }

type noopRunner struct{ output io.Writer }

func (n *noopRunner) Run(_ Function) error { return nil }
Expand Down
14 changes: 7 additions & 7 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ func TestRun(t *testing.T) {
}
}

// TestUpdate ensures that the updater properly invokes the build/push/deploy
// TestUpdate ensures that the deployer properly invokes the build/push/deploy
// process, erroring if run on a directory uncreated.
func TestUpdate(t *testing.T) {
var (
Expand All @@ -469,7 +469,7 @@ func TestUpdate(t *testing.T) {
expectedImage = "quay.io/alice/testUpdate:latest"
builder = mock.NewBuilder()
pusher = mock.NewPusher()
updater = mock.NewUpdater()
deployer = mock.NewDeployer()
)

// Create the root Function directory
Expand All @@ -483,7 +483,7 @@ func TestUpdate(t *testing.T) {
faas.WithRepository(TestRepository),
faas.WithBuilder(builder),
faas.WithPusher(pusher),
faas.WithUpdater(updater))
faas.WithDeployer(deployer))

// create the new Function which will be updated
if err := client.Create(faas.Function{Root: root}); err != nil {
Expand Down Expand Up @@ -512,7 +512,7 @@ func TestUpdate(t *testing.T) {
}

// Update whose implementaiton verifed the expected name and image
updater.UpdateFn = func(f faas.Function) error {
deployer.DeployFn = func(f faas.Function) error {
if f.Name != expectedName {
t.Fatalf("updater expected name '%v', got '%v'", expectedName, f.Name)
}
Expand All @@ -524,7 +524,7 @@ func TestUpdate(t *testing.T) {

// Invoke the creation, triggering the Function delegates, and
// perform follow-up assertions that the Functions were indeed invoked.
if err := client.Update(root); err != nil {
if err := client.Deploy(root); err != nil {
t.Fatal(err)
}

Expand All @@ -534,8 +534,8 @@ func TestUpdate(t *testing.T) {
if !pusher.PushInvoked {
t.Fatal("pusher was not invoked")
}
if !updater.UpdateInvoked {
t.Fatal("updater was not invoked")
if !deployer.DeployInvoked {
t.Fatal("deployer was not invoked")
}
}

Expand Down
13 changes: 7 additions & 6 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ func runCreate(cmd *cobra.Command, args []string) (err error) {
pusher := docker.NewPusher()
pusher.Verbose = verbose

deployer := knative.NewDeployer()
deployer, err := knative.NewDeployer(config.Namespace)
if err != nil {
return
}
deployer.Verbose = verbose

listener := progress.New()
Expand All @@ -107,15 +110,13 @@ func runCreate(cmd *cobra.Command, args []string) (err error) {

type createConfig struct {
initConfig
buildConfig
deployConfig
// Note that ambiguous references set to assume .initConfig
}

func newCreateConfig(args []string) createConfig {
return createConfig{
initConfig: newInitConfig(args),
buildConfig: newBuildConfig(),
deployConfig: newDeployConfig(),
}
}
Expand All @@ -142,10 +143,10 @@ func (c createConfig) Prompt() createConfig {
Trigger: prompt.ForString("Trigger", c.Trigger),
// Templates intentionally omitted from prompt for being an edge case.
},
buildConfig: buildConfig{
Repository: prompt.ForString("Repository for Function images", c.buildConfig.Repository),
},
deployConfig: deployConfig{
buildConfig: buildConfig{
Repository: prompt.ForString("Repository for Function images", c.buildConfig.Repository),
},
Namespace: prompt.ForString("Override default deploy namespace", c.Namespace),
},
}
Expand Down
Loading

0 comments on commit d5839ea

Please sign in to comment.