Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deployment support #222

Merged
merged 3 commits into from
Jun 8, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions cmd/autocomplete/deployments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package autocomplete

import (
"fmt"

"github.com/Scalingo/codegangsta-cli"
"gopkg.in/errgo.v1"
"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/appdetect"
)

func DeploymentsAutoComplete(c *cli.Context) error {
client := config.ScalingoClient()
currentApp := appdetect.CurrentApp(c)

deployments, err := client.DeploymentList(currentApp)
if err != nil {
return errgo.Mask(err, errgo.Any)
}

for _, deployment := range(deployments) {
fmt.Println(deployment.ID)
}

return nil
}
5 changes: 5 additions & 0 deletions cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ var (
DomainsRemoveCommand,
DomainsSSLCommand,

// Deploiments
DeploymentsListCommand,
DeploymentLogCommand,
DeploymentFollowCommand,

// Collaborators
CollaboratorsListCommand,
CollaboratorsAddCommand,
Expand Down
66 changes: 66 additions & 0 deletions cmd/deployments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package cmd

import (
"github.com/Scalingo/cli/deployments"
"github.com/Scalingo/cli/appdetect"
"github.com/Scalingo/cli/cmd/autocomplete"
"github.com/Scalingo/codegangsta-cli"
)

var (
DeploymentsListCommand = cli.Command{
Name: "deployments",
Category: "Deployment",
Usage: "List app deployments",
Flags: []cli.Flag{appFlag},
Description: ` List all of your previous app deployments
$ scalingo -a myapp deployments
`,
Action: func(c *cli.Context) {
currentApp := appdetect.CurrentApp(c)
err := deployments.List(currentApp)
if err != nil {
errorQuit(err)
}
},
}
DeploymentLogCommand = cli.Command{
Name: "deployment-logs",
Category: "Deployment",
Usage: "View deployment logs",
Flags: []cli.Flag{appFlag},
Description: ` Get the logs of an app deployment
$ scalingo -a myapp deployment-logs my-deployment
`,
Action: func(c *cli.Context) {
currentApp := appdetect.CurrentApp(c)
if len(c.Args()) == 1 {
err := deployments.Logs(currentApp, c.Args()[0])
if err != nil {
errorQuit(err)
}
} else {
cli.ShowCommandHelp(c, "deployment-logs")
}
},
BashComplete: func(c *cli.Context){
autocomplete.DeploymentsAutoComplete(c)
},
}
DeploymentFollowCommand = cli.Command{
Name: "deployment-follow",
Category: "Deployment",
Usage: "Follow deployement event stream",
Flags: []cli.Flag{appFlag},
Description: ` Get real-time deployment informations
$ scalingo -a myapp deployment-follow
`,
Action: func(c *cli.Context) {
currentApp := appdetect.CurrentApp(c)
err := deployments.Stream(currentApp)
if err != nil {
errorQuit(err)
}
},
}
)
2 changes: 2 additions & 0 deletions cmd/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/stvp/rollbar"
"gopkg.in/errgo.v1"
"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/debug"
"github.com/Scalingo/cli/io"
"github.com/Scalingo/cli/session"
)
Expand Down Expand Up @@ -64,6 +65,7 @@ func errorQuit(err error) {
newReportError(err).Report()
rollbar.Wait()
io.Error("An error occured:")
debug.Println(errgo.Details(err))
fmt.Println(io.Indent(err.Error(), 7))
os.Exit(1)
}
Expand Down
97 changes: 97 additions & 0 deletions deployments/follow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package deployments

import (
"encoding/json"
"fmt"
stdio "io"
"strings"
"time"

"github.com/Scalingo/go-scalingo"
"golang.org/x/net/websocket"
"gopkg.in/errgo.v1"
"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/debug"
)

type deployEvent struct {
ID string `json:"id"`
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}

type logData struct {
Content string `json:"content"`
}

type statusData struct {
Content string `json:"Status"`
}

func Stream(appName string) error {
c := config.ScalingoClient()
app, err := c.AppsShow(appName)
if err != nil {
return errgo.Mask(err, errgo.Any)
}

debug.Println("Opening socket to : " + app.Links.DeploymentsStream)

conn, err := c.DeploymentStream(app.Links.DeploymentsStream)
if err != nil {
return errgo.Mask(err, errgo.Any)
}

var event deployEvent
oldStatus := ""
for {
err := websocket.JSON.Receive(conn, &event)
if err != nil {
conn.Close()
if err == stdio.EOF {
debug.Println("Remote server broke the connection, reconnecting")
for err != nil {
conn, err = c.DeploymentStream(app.Links.DeploymentsStream)
time.Sleep(time.Second * 1)
}
continue
} else {
return errgo.Mask(err, errgo.Any)
}
} else {
switch event.Type {
case "ping":
case "log":
var logData logData
err := json.Unmarshal(event.Data, &logData)
if err != nil {
config.C.Logger.Println(err)
} else {
fmt.Println("[LOG] " + strings.TrimSpace(logData.Content))
}
case "status":
var statusData statusData
err := json.Unmarshal(event.Data, &statusData)
if err != nil {
config.C.Logger.Println(err)
} else {
if oldStatus == "" {
fmt.Println("[STATUS] New status : " + statusData.Content)
} else {
fmt.Println("[STATUS] New status : " + oldStatus + " → " + statusData.Content)
}
oldStatus = statusData.Content
}
case "new":
var newData map[string]*scalingo.Deployment
err := json.Unmarshal(event.Data, &newData)
if err != nil {
config.C.Logger.Println(err)
} else {
fmt.Println("[NEW] New deploy : " + newData["deployment"].ID + " from " + newData["deployment"].User.Username)
oldStatus = ""
}
}
}
}
}
36 changes: 36 additions & 0 deletions deployments/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package deployments

import (
"os"

"github.com/olekukonko/tablewriter"
"gopkg.in/errgo.v1"
"github.com/Scalingo/cli/config"
)

func List(app string) error {
c := config.ScalingoClient()
deployments, err := c.DeploymentList(app)
if err != nil {
return errgo.Mask(err)
}

if len(deployments) == 0 {

} else {
t := tablewriter.NewWriter(os.Stdout)
t.SetHeader([]string{"ID", "Date", "User", "Status"})

for _, deployment := range deployments {
t.Append([]string{deployment.ID,
deployment.CreatedAt.Format("2006/01/02 15:04:05"),
deployment.User.Username,
deployment.Status,
})
}
t.Render()

}

return nil
}
34 changes: 34 additions & 0 deletions deployments/logs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package deployments

import (
stdio "io"
"os"

"gopkg.in/errgo.v1"
"github.com/Scalingo/cli/config"
"github.com/Scalingo/cli/io"
)

func Logs(app string, deployment string) error {
client := config.ScalingoClient()
deploy, err := client.Deployment(app, deployment)

if err != nil {
return errgo.Mask(err, errgo.Any)
}

res, err := client.DeploymentLogs(deploy.Links.Output)

if err != nil {
return errgo.Mask(err, errgo.Any)
}

defer res.Body.Close()

if res.StatusCode == 404 {
io.Error("There is no log for this deployment.")
} else {
stdio.Copy(os.Stdout, res.Body)
}
return nil
}
39 changes: 33 additions & 6 deletions vendor/github.com/Scalingo/go-scalingo/apps.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading