Skip to content

Commit

Permalink
Merge pull request #27 from gondor/master
Browse files Browse the repository at this point in the history
Add app log support, Support new Marathon schema
  • Loading branch information
gondor committed May 6, 2016
2 parents fafa980 + 7f9e7f6 commit d3206e1
Show file tree
Hide file tree
Showing 13 changed files with 853 additions and 69 deletions.
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION = 0.8.3
VERSION = 0.8.5

GO_FMT = gofmt -s -w -l .
GO_XC = goxc -os="linux darwin windows" -tasks-="rmbin"
Expand All @@ -17,10 +17,12 @@ goxc:
$(shell echo ' "publish-github": {' >> $(GOXC_FILE))
$(shell echo ' "apikey": "$(GITHUB_APIKEY)",' >> $(GOXC_FILE))
$(shell echo ' "body": "",' >> $(GOXC_FILE))
$(shell echo ' "include": "*.zip,*.tar.gz,*.deb,depcon_$(VERSION)_linux_amd64-bin"' >> $(GOXC_FILE))
$(shell echo ' "include": "*.tar.gz,*.deb,depcon-linux64,depcon-osx64,depcon-win64.exe"' >> $(GOXC_FILE))
$(shell echo ' }\n } \n}' >> $(GOXC_FILE))
$(GO_XC)
cp build/$(VERSION)/linux_amd64/depcon build/$(VERSION)/depcon_$(VERSION)_linux_amd64-bin
cp build/$(VERSION)/linux_amd64/depcon build/$(VERSION)/depcon-linux64
cp build/$(VERSION)/darwin_amd64/depcon build/$(VERSION)/depcon-osx64
cp build/$(VERSION)/windows_amd64/depcon.exe build/$(VERSION)/depcon-win64.exe

deps:
go get
Expand Down
4 changes: 2 additions & 2 deletions cliconfig/create_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package cliconfig

import (
"fmt"
"github.com/bgentry/speakeasy"
"github.com/ContainX/depcon/utils"
"github.com/bgentry/speakeasy"
"net/url"
"os"
"regexp"
)

const (
AlphaNumDash string = `^[a-zA-Z0-9_]*$`
AlphaNumDash string = `^[a-zA-Z0-9_-]*$`
)

var (
Expand Down
6 changes: 4 additions & 2 deletions commands/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const (
TypeColumn string = "column"
)

var log = logger.GetLogger("depcon")

func init() {
cli.Register(&cli.CLIWriter{FormatWriter: PrintFormat, ErrorWriter: PrintError})
rootCmd.PersistentFlags().StringP(FLAG_FORMAT, "o", "column", "Specifies the output format [column | json | yaml]")
Expand All @@ -34,7 +36,7 @@ func getFormatType() string {
}

func PrintError(err error) {
logger.Logger().Error("%v", err.Error())
log.Error("%v", err.Error())
os.Exit(1)
}

Expand All @@ -58,6 +60,6 @@ func printEncodedType(formatter cli.Formatter, encoder encoding.EncoderType) {
func printColumn(formatter cli.Formatter) {
err := formatter.ToColumns(os.Stdout)
if err != nil {
logger.Logger().Error("Error: %s", err.Error())
log.Error("Error: %s", err.Error())
}
}
2 changes: 1 addition & 1 deletion commands/marathon/app_cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ var appConvertFileCmd = &cobra.Command{

func init() {
appUpdateCmd.AddCommand(appUpdateCPUCmd, appUpdateMemoryCmd)
appCmd.AddCommand(appListCmd, appGetCmd, appCreateCmd, appUpdateCmd, appDestroyCmd, appRollbackCmd, bgCmd, appRestartCmd, appScaleCmd, appVersionsCmd, appConvertFileCmd)
appCmd.AddCommand(appListCmd, appGetCmd, logCmd, appCreateCmd, appUpdateCmd, appDestroyCmd, appRollbackCmd, bgCmd, appRestartCmd, appScaleCmd, appVersionsCmd, appConvertFileCmd)

// Create Flags
appCreateCmd.Flags().BoolP(FORCE_FLAG, "f", false, "Force deployment (updates application if it already exists)")
Expand Down
10 changes: 5 additions & 5 deletions commands/marathon/app_cmds_test.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package marathon

import (
"log"
l "log"
"testing"
)

func TestParseParamFile(t *testing.T) {
envParams, _ := parseParamsFile("resources/test.env")
el, ok := envParams["APP1_VERSION"]
if !ok && el != "3" {
log.Printf("Actual envParams %v", envParams)
log.Panic("Expected envFile parsed correctly")
l.Printf("Actual envParams %v", envParams)
l.Panic("Expected envFile parsed correctly")
}
el, ok = envParams["APP2_VERSION"]
if !ok && el != "345" {
log.Printf("Actual envParams %v", envParams)
log.Panic("Expected envFile parsed correctly")
l.Printf("Actual envParams %v", envParams)
l.Panic("Expected envFile parsed correctly")
}
}
110 changes: 110 additions & 0 deletions commands/marathon/app_log_cmds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package marathon

import (
"fmt"
"github.com/ContainX/depcon/pkg/cli"
"github.com/ContainX/depcon/pkg/logger"
ml "github.com/ContainX/go-mesoslog/mesoslog"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"net/url"
"strings"
)

const (
STDERR_FLAG = "stderr"
FOLLOW_FLAG = "follow"
POLL_FLAG = "poll"

)

var logCmd = &cobra.Command{
Use: "log [appId]",
Short: "Log or Tail Mesos application logs",
Long: "Log or Tail Mesos application logs",
Run: showLogCmd,
}

var log = logger.GetLogger("depcon")

func init() {
logCmd.Flags().BoolP(STDERR_FLAG, "s", false, "Show StdErr vs default StdOut log")
logCmd.Flags().BoolP(FOLLOW_FLAG, "f", false, "Tail/Follow log")
logCmd.Flags().IntP(POLL_FLAG, "p", 5, "Log poll time (duration) in seconds")
}

func showLogCmd(cmd *cobra.Command, args []string) {
if cli.EvalPrintUsage(cmd.Usage, args, 1) {
return
}

host := getMesosHost()
logType := ml.STDOUT

if stderr, _ := cmd.Flags().GetBool(STDERR_FLAG); stderr {
logType = ml.STDERR
}

c, _ := ml.NewMesosClient(host, 5050)
appId := getMesosAppIdentifier(cmd, c, args[0])

if follow, _ := cmd.Flags().GetBool(FOLLOW_FLAG); follow {
duration, _ := cmd.Flags().GetInt(POLL_FLAG)
if duration < 1 {
duration = 5

}
if err := c.TailLog(appId, logType, duration); err != nil {
log.Fatal(err)
}
return
}

logs, err := c.GetLog(appId, logType, "")
if err != nil {
log.Fatal(err)
}

showBreaks := len(logs) > 1
for _, log := range logs {
if showBreaks {
fmt.Printf("\n::: [ %s - Logs For: %s ] ::: \n", args[0], log.TaskID)
}
fmt.Printf("%s\n", log.Log)
if showBreaks {
fmt.Printf("\n!!! [ %s - End Logs For: %s ] !!! \n", args[0], log.TaskID)
}
}
}

func getMesosAppIdentifier(cmd *cobra.Command, c *ml.MesosClient, appId string) string {
tasks, err := client(cmd).GetTasks(appId)
if err != nil {
log.Fatal(err)
}

if len(tasks) > 0 {
name, err := c.GetAppNameForTaskID(tasks[0].ID)
if err != nil {
log.Fatal(err)
}
return name
}

log.Fatal("Currently no tasks found for application: %s\n", appId)
return ""
}

func getMesosHost() string {
envName := viper.GetString("env_name")
mc := *configFile.Environments[envName].Marathon

u, err := url.Parse(mc.HostUrl)
if err != nil {
log.Fatal(err)
}
if strings.Index(u.Host, ":") > 0 {
return strings.Split(u.Host, ":")[0]
}
return u.Host
}
61 changes: 21 additions & 40 deletions compose/compose_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ package compose
import (
"errors"
"fmt"
"github.com/ContainX/depcon/pkg/envsubst"
"github.com/docker/libcompose/docker"
"github.com/docker/libcompose/project"
"github.com/ContainX/depcon/pkg/envsubst"
"io/ioutil"
"os"
"strings"
"github.com/docker/libcompose/project/options"
)

const (
Expand All @@ -21,7 +22,7 @@ var (

type ComposeWrapper struct {
context *Context
project *project.Project
project project.APIProject
}

func NewCompose(context *Context) Compose {
Expand All @@ -36,31 +37,36 @@ func NewCompose(context *Context) Compose {
}

func (c *ComposeWrapper) Up(services ...string) error {
return c.project.Up(services...)
options := options.Up{ Create: options.Create{} }
return c.project.Up(options, services...)
}

func (c *ComposeWrapper) Kill(services ...string) error {
return c.project.Kill(services...)
return c.project.Kill("SIGKILL", services...)
}

func (c *ComposeWrapper) Build(services ...string) error {
return c.project.Build(services...)
options := options.Build{}
return c.project.Build(options, services...)
}

func (c *ComposeWrapper) Restart(services ...string) error {
return c.project.Restart(services...)
timeout := 10
return c.project.Restart(timeout, services...)
}

func (c *ComposeWrapper) Pull(services ...string) error {
return c.project.Pull(services...)
}

func (c *ComposeWrapper) Delete(services ...string) error {
return c.project.Delete(services...)
options := options.Delete{
}
return c.project.Delete(options, services...)
}

func (c *ComposeWrapper) Logs(services ...string) error {
return c.project.Log(services...)
return c.project.Log(true, services...)
}

func (c *ComposeWrapper) Start(services ...string) error {
Expand All @@ -75,26 +81,14 @@ func (c *ComposeWrapper) execStartStop(start bool, services ...string) error {
if start {
return c.project.Start(services...)
}
return c.project.Down(services...)
options := options.Down{
}
return c.project.Down(options, services...)
}

func (c *ComposeWrapper) Port(index int, proto, service, port string) error {

s, err := c.project.CreateService(service)
if err != nil {
return err
}

containers, err := s.Containers()
if err != nil {
return err
}

if index < 1 || index > len(containers) {
fmt.Errorf("Invalid index %d", index)
}

output, err := containers[index-1].Port(fmt.Sprintf("%s/%s", port, proto))
output, err := c.project.Port(index, proto, service, port)
if err != nil {
return err
}
Expand All @@ -103,26 +97,13 @@ func (c *ComposeWrapper) Port(index int, proto, service, port string) error {
}

func (c *ComposeWrapper) PS(quiet bool) error {
allInfo := project.InfoSet{}

for _, name := range c.project.Configs.Keys() {
service, err := c.project.CreateService(name)
if err != nil {
return err
}

info, err := service.Info(quiet)
if err != nil {
return err
}

allInfo = append(allInfo, info...)
if allInfo, err := c.project.Ps(quiet); err == nil {
os.Stdout.WriteString(allInfo.String(!quiet))
}
os.Stdout.WriteString(allInfo.String(!quiet))
return nil
}

func (c *ComposeWrapper) createDockerContext() (*project.Project, error) {
func (c *ComposeWrapper) createDockerContext() (project.APIProject, error) {

clientFactory, err := docker.NewDefaultClientFactory(docker.ClientOpts{})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion compose/logfactory.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package compose

import (
"github.com/docker/libcompose/logger"
depconLog "github.com/ContainX/depcon/pkg/logger"
"github.com/docker/libcompose/logger"
)

var log = depconLog.GetLogger("depcon.compose")
Expand Down
2 changes: 1 addition & 1 deletion marathon/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (c *MarathonClient) CreateApplication(app *Application, wait, force bool) (
return nil, ErrorAppExists
}
if resp.Status == 422 {
return nil, ErrorInvalidAppId
return nil, fmt.Errorf("Error occurred: %s", resp.Content)
}
return nil, fmt.Errorf("Error occurred (Status %v) Body -> %s", resp.Status, resp.Content)
}
Expand Down
1 change: 0 additions & 1 deletion marathon/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ func TestCreateApplicationInvalidAppId(t *testing.T) {
_, err := c.CreateApplication(NewApplication("/someapp"), false, false)

assert.NotNil(t, err, "Expecting Error")
assert.Equal(t, ErrorInvalidAppId, err)
}

func TestNewApplication(t *testing.T) {
Expand Down
4 changes: 0 additions & 4 deletions marathon/marathon.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const (

/* --- api related constants --- */
API_VERSION = "v2"
API_SUBSCRIPTION = API_VERSION + "/eventSubscriptions"
API_APPS = API_VERSION + "/apps"
API_TASKS = API_VERSION + "/tasks"
API_TASKS_DELETE = API_VERSION + "/tasks/delete"
Expand All @@ -23,9 +22,6 @@ const (
API_INFO = API_VERSION + "/info"
API_LEADER = API_VERSION + "/leader"
API_PING = "ping"
API_LOGGING = "logging"
API_HELP = "help"
API_METRICS = "metrics"

DefaultTimeout = time.Duration(90) * time.Second
)
Expand Down
Loading

0 comments on commit d3206e1

Please sign in to comment.