Skip to content

Commit

Permalink
Merge pull request #52 from ethernetdan/spread-deploy
Browse files Browse the repository at this point in the history
implemented spread deploy
  • Loading branch information
ethernetdan committed Feb 20, 2016
2 parents f9dc328 + d961eb0 commit a9fecb3
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 34 deletions.
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
* Work well for a single developer or an entire team (no more broken bash scripts!)


Spread is under open, active development. New features will be added regularly over the next few months - explore our [roadmap](./roadmap) to see what will be built next and send us pull requests for any features you’d like to see added.
Spread is under open, active development. New features will be added regularly over the next few months - explore our [roadmap](./roadmap.md) to see what will be built next and send us pull requests for any features you’d like to see added.

See our [philosophy](./philosophy.md) for more on our mission and values.

##What's been done so far

* `spread deploy`: Deploys a Docker project to a Kubernetes cluster. It completes the following order of operations:
* `spread deploy [-s] PATH [kubectl context]`: Deploys a Docker project to a Kubernetes cluster. It completes the following order of operations:
* Reads context of directory and builds Kubernetes deployment hierarchy.
* Updates all Kubernetes objects on a Kubernetes cluster.
* Returns a public IP address, if type Load Balancer is specified.
Expand All @@ -26,15 +28,15 @@ Spread is under open, active development. New features will be added regularly o

##What's being worked on now

* Building functionality for `spread deploy` so it also builds any images indicated to be built and pushes those images to the indicated Docker registry.
* Build functionality for `spread deploy` so it also builds any images indicated to be built and pushes those images to the indicated Docker registry.
* `spread deploy -p`: Pushes all images to registry, even those not built by `spread deploy`.
* Support for Linux and Windows
* Inner-app linking
* `spread logs`: Returns logs for any deployment, automatic trying until logs are accessible.
* `spread build`: Builds Docker context and pushes to a local Kubernetes cluster.
* `spread rewind`: Quickly rollback to a previous deployment.

See more of our <a href="https://github.com/redspread/spread/blob/master/roadmap">roadmap</a> here!
See more of our <a href="https://github.com/redspread/spread/blob/master/roadmap.md">roadmap</a> here!

##Future Goals
* Develop workflow for container versioning (containers = image + config)
Expand All @@ -48,7 +50,7 @@ See more of our <a href="https://github.com/redspread/spread/blob/master/roadmap

##Installation

`$ brew tap redspread/homebrew-spread`
`$ brew tap redspread/spread`
`$ brew install spread`

##FAQ
Expand All @@ -71,7 +73,7 @@ See more of our <a href="https://github.com/redspread/spread/blob/master/roadmap

This assumes you have a <a href="https://blog.redspread.com/2016/02/04/google-container-engine-quickstart/">running Kubernetes cluster</a> and <a href="https://docs.docker.com/machine/get-started/">docker-machine</a> installed.

1. Install Spread with `$ brew tap redspread/homebrew-spread` then `$ brew install spread`
1. Install Spread with `$ brew tap redspread/spread` then `$ brew install spread`
2. Clone example project `$ git clone http://github.com/redspread/mvp-ex`
3. Start a docker machine `$ docker machine start <name>` or <a href="https://docs.docker.com/machine/get-started/">create a new machine</a>
4. Enter in your Docker registry configuration in the correct fields in .k2e/secret.yaml:
Expand Down
16 changes: 16 additions & 0 deletions cli/cli.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package cli

import (
"fmt"
"io"
"os"
"strings"
)

// SpreadCli is the spread command line client.
Expand All @@ -28,3 +31,16 @@ func NewSpreadCli(in io.ReadCloser, out, err io.Writer, version string) *SpreadC
version: version,
}
}

func (c SpreadCli) printf(message string, data ...interface{}) {
// add newline if doesn't have one
if !strings.HasSuffix(message, "\n") {
message = message + "\n"
}
fmt.Fprintf(c.out, message, data...)
}

func (c SpreadCli) fatalf(message string, data ...interface{}) {
c.printf(message, data...)
os.Exit(1)
}
93 changes: 93 additions & 0 deletions cli/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package cli

import (
"fmt"

"rsprd.com/spread/pkg/deploy"
"rsprd.com/spread/pkg/entity"
"rsprd.com/spread/pkg/input/dir"

"github.com/codegangsta/cli"
)

// Deploy allows the creation of deploy.Deployments remotely
func (s SpreadCli) Deploy() *cli.Command {
return &cli.Command{
Name: "deploy",
Usage: "spread deploy [-s] PATH [kubectl context]",
Description: "Deploys a Dockerfile to a remote Kubernetes cluster.",
ArgsUsage: "-s will deploy only if no other deployment found (otherwise fails)",
Action: func(c *cli.Context) {
srcDir := c.Args().First()
if len(srcDir) == 0 {
s.fatalf("A directory to deploy from must be specified")
}

input, err := dir.NewFileInput(srcDir)
if err != nil {
s.fatalf(inputError(srcDir, err))
}

e, err := input.Build()
if err != nil {
println("build")
s.fatalf(inputError(srcDir, err))
}

dep, err := e.Deployment()
if err == entity.ErrMissingContainer {
// check if has pod; if not deploy objects
pods, _ := input.Entities(entity.EntityPod)
if len(pods) != 0 {
s.fatalf("Failed to deploy: %v", err)
}

objects, err := input.Objects()
if err != nil {
s.fatalf(inputError(srcDir, err))
} else if len(objects) == 0 {
s.fatalf("Couldn't find objects to deploy in '%s'", srcDir)
}

dep = new(deploy.Deployment)
for _, obj := range objects {
err = dep.Add(obj)
if err != nil {
s.fatalf(inputError(srcDir, err))
}
}
} else if err != nil {
println("deploy")
s.fatalf(inputError(srcDir, err))
}

context := c.Args().Get(1)
cluster, err := deploy.NewKubeClusterFromContext(context)
if err != nil {
s.fatalf("Failed to deploy: %v", err)
}

s.printf("Deploying %d objects using the %s.", dep.Len(), displayContext(context))

update := !c.Bool("s")
err = cluster.Deploy(dep, update)
if err != nil {
//TODO: make better error messages (one to indicate a deployment already existed; another one if a deployment did not exist but some other error was thrown
s.fatalf("Did not deploy.: %v", err)
}

s.printf("Deployment successful!")
},
}
}

func inputError(srcDir string, err error) string {
return fmt.Sprintf("Error using `%s`: %v", srcDir, err)
}

func displayContext(name string) string {
if name == deploy.DefaultContext {
return "default context"
}
return fmt.Sprintf("context '%s'", name)
}
19 changes: 0 additions & 19 deletions cli/version.go

This file was deleted.

2 changes: 1 addition & 1 deletion cmd/spread/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ const (
Usage = "Quickly iterate with Kubernetes"

// Version is the current version number
Version = "0.0.1"
Version = "0.0.3"
)
13 changes: 13 additions & 0 deletions philosophy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#Our philosophy

Redspread's mission is to empower people to own their own deployment process and infrastructure. We're building the tools and workflows to fulfill that mission.

We value collaboration, transparency, and fairness in everything we do.

We also think the following are true:

* Container versioning (i.e. versioning both images and configuration) will become increasingly important over the next year as more people use containers in production, just as versioning services has become common practice.
* Software development is a multi-player game played with single player tools. Better collaborative tooling needs to be built for software organizations.
* Introducing proprietary software into your infrastructure introduces external market risk into your product, and this risk should be very carefully considered whenever evaluating options. [See more of our thoughts on this](https://medium.com/@ciaomack/parsegate-the-case-against-proprietary-infrastructure-d397a89cbb2b).

We love to talk philosophy - shoot us a note at [[email protected]](mailto:[email protected]) if you want to chat more.
25 changes: 17 additions & 8 deletions roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@ This is a high level roadmap for spread development. The dates below should not

####Feb. 2016

* Support deploying multiple containers to Kubernetes
* `spread deploy`: One command to deploy to a remote cluster
* Entity linking
* Logging and debugging
* `spread debug`: Returns the current spread version, Kubernetes version, Docker version, Go version, computer operating system, the Kubernetes config, spread config, and the content and timestamp of last command ran
* `spread logs`: Prints logs from deployment of current project
* `spread deploy`: One command deploy to a remote Kubernetes cluster
* Including building Docker context with deployment
* `spread deploy -p`: Pushes all images to registry, even those not built by `spread deploy`.
* Handle updates for all Kubernetes objects

####Mar. 2016

* Logging and debugging
* `spread debug`: Returns the current spread version, Kubernetes version, Docker version, Go version, computer operating system, the Kubernetes config, spread config, and the content and timestamp of last command ran
* `spread logs`: Returns logs for any deployment, automatic trying until logs are accessible.
* Support for local development with Kubernetes
* Easy setup of local cluster
* Cluster-to-cluster syncing
* `spread build`: One command to build to a local cluster
* `spread status`: Prints information about the state of the project
* `spread build`: Builds Docker context and pushes to a local Kubernetes cluster.
* `spread status`: Prints information about the state of the project
* Inner-app linking
* Support for Linux and Windows

####Apr. 2016

* Container versioning
* Version the image + configuration of containers
* `spread rewind`: Quickly rollback to a previous deployment.

0 comments on commit a9fecb3

Please sign in to comment.