Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
Merge pull request #30 from grammarly/dev
Browse files Browse the repository at this point in the history
0.1.2
  • Loading branch information
Yuriy Bogdanov committed Nov 23, 2015
2 parents 7d9dac2 + a791cfb commit 16ccae3
Show file tree
Hide file tree
Showing 50 changed files with 4,165 additions and 283 deletions.
16 changes: 10 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ PKGS := $(foreach pkg, $(sort $(dir $(SRCS))), $(pkg))

TESTARGS ?=

binary:
GOPATH=$(shell pwd):$(shell pwd)/vendor go build \
-ldflags "-X main.Version=$(VERSION) -X main.GitCommit=$(GITCOMMIT) -X main.GitBranch=$(GITBRANCH) -X main.BuildTime=$(BUILDTIME)" \
-v -o bin/rocker-compose src/cmd/rocker-compose/main.go

install:
cp bin/rocker-compose /usr/local/bin/rocker-compose
chmod +x /usr/local/bin/rocker-compose

all: $(ALL_BINARIES)
$(foreach BIN, $(BINARIES), $(shell cp dist/$(VERSION)/$(shell go env GOOS)/amd64/$(BIN) dist/$(BIN)))

Expand All @@ -64,17 +73,12 @@ $(ALL_BINARIES): build_image
docker run --rm -ti -v $(shell pwd)/dist:/src/dist \
-e GOOS=$(call os,$@) -e GOARCH=$(call arch,$@) -e GOPATH=/src:/src/vendor \
rocker-compose-build:latest go build \
-ldflags "-X main.Version '$(VERSION)' -X main.GitCommit '$(GITCOMMIT)' -X main.GitBranch '$(GITBRANCH)' -X main.BuildTime '$(BUILDTIME)'" \
-ldflags "-X main.Version=$(VERSION) -X main.GitCommit=$(GITCOMMIT) -X main.GitBranch=$(GITBRANCH) -X main.BuildTime=$(BUILDTIME)" \
-v -o $@ src/cmd/$(call bin,$@)/main.go

build_image:
rocker build -f Rockerfile.build-cross

local-binary:
GOPATH=$(shell pwd):$(shell pwd)/vendor go build \
-ldflags "-X main.Version=$(VERSION) -X main.GitCommit=$(GITCOMMIT) -X main.GitBranch=$(GITBRANCH) -X main.BuildTime=$(BUILDTIME)" \
-v -o bin/rocker-compose src/cmd/rocker-compose/main.go

clean:
rm -Rf dist

Expand Down
8 changes: 2 additions & 6 deletions Rockerfile.build-cross
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# Yeah, we have a tool called 'rocker' that is not open sourced yet.
# rocker is an extensible Dockerfile builder tool
FROM dockerhub.grammarly.io/golang-1.4.2-cross:v2
FROM dockerhub.grammarly.io/golang-1.5.1-cross:v1

ADD . /src
WORKDIR /src

TAG --no-alias rocker-compose-build:latest

# ATTACH ["bash"]
TAG rocker-compose-build:latest
21 changes: 21 additions & 0 deletions src/cmd/rocker-compose/debugtrap_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// +build !windows

package main

import (
"os"
"os/signal"
"syscall"

psignal "github.com/docker/docker/pkg/signal"
)

func setupDumpStackTrap() {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGUSR1)
go func() {
for range c {
psignal.DumpStacks()
}
}()
}
7 changes: 7 additions & 0 deletions src/cmd/rocker-compose/debugtrap_unsupported.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !linux,!darwin,!freebsd

package main

func setupDumpStackTrap() {
return
}
176 changes: 156 additions & 20 deletions src/cmd/rocker-compose/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,27 @@
package main

import (
"bytes"
"compose"
"compose/ansible"
"compose/config"
"encoding/json"
"fmt"
"io"
"os"
"path"
"path/filepath"
"strings"
"time"

log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
"github.com/fsouza/go-dockerclient"
"github.com/go-yaml/yaml"
"github.com/grammarly/rocker/src/rocker/debugtrap"
"github.com/grammarly/rocker/src/rocker/dockerclient"
"github.com/grammarly/rocker/src/rocker/template"
"github.com/grammarly/rocker/src/rocker/textformatter"
)

var (
Expand All @@ -52,6 +59,7 @@ var (
func init() {
log.SetOutput(os.Stdout)
log.SetLevel(log.InfoLevel)
debugtrap.SetupDumpStackTrap()
}

func main() {
Expand All @@ -76,6 +84,11 @@ func main() {
Value: &cli.StringSlice{},
Usage: "Set variables to pass to build tasks, value is like \"key=value\"",
},
cli.StringSliceFlag{
Name: "vars",
Value: &cli.StringSlice{},
Usage: "Load variables form a file, either JSON or YAML. Can pass multiple of this.",
},
cli.BoolFlag{
Name: "dry, d",
Usage: "Don't execute any run/stop operations on target docker",
Expand All @@ -84,11 +97,15 @@ func main() {
Name: "print",
Usage: "just print the rendered compose config and exit",
},
cli.BoolFlag{
Name: "demand-artifacts",
Usage: "fail if artifacts not found for {{ image }} helpers",
},
}

app.Flags = append([]cli.Flag{
cli.BoolFlag{
Name: "verbose, vv",
Name: "verbose, vv, D",
},
cli.StringFlag{
Name: "log, l",
Expand All @@ -101,6 +118,9 @@ func main() {
Value: "",
Usage: "Docker auth, username and password in user:password format",
},
cli.BoolTFlag{
Name: "colors",
},
}, dockerclient.GlobalCliParams()...)

app.Commands = []cli.Command{
Expand Down Expand Up @@ -165,6 +185,31 @@ func main() {
},
}, composeFlags...),
},
{
Name: "pin",
Usage: "pin versions",
Action: pinCommand,
Flags: append([]cli.Flag{
cli.BoolTFlag{
Name: "local, l",
Usage: "search across images available locally",
},
cli.BoolTFlag{
Name: "hub",
Usage: "search across images in the registry",
},
cli.StringFlag{
Name: "type, t",
Value: "yaml",
Usage: "output in specified format: json|yaml",
},
cli.StringFlag{
Name: "output, O",
Value: "-",
Usage: "write result in a file or stdout if the value is `-`",
},
}, composeFlags...),
},
{
Name: "recover",
Usage: "recover containers from machine reboot or docker daemon restart",
Expand Down Expand Up @@ -331,6 +376,69 @@ func cleanCommand(ctx *cli.Context) {
}
}

func pinCommand(ctx *cli.Context) {
initLogs(ctx)

var (
vars template.Vars
data []byte
output = ctx.String("output")
format = ctx.String("type")
local = ctx.BoolT("local")
hub = ctx.BoolT("hub")
fd = os.Stdout
)

if output == "-" && !ctx.GlobalIsSet("verbose") {
log.SetLevel(log.WarnLevel)
}

dockerCli := initDockerClient(ctx)
config := initComposeConfig(ctx, dockerCli)
auth := initAuthConfig(ctx)

compose, err := compose.New(&compose.Config{
Manifest: config,
Docker: dockerCli,
Auth: auth,
})
if err != nil {
log.Fatal(err)
}

if vars, err = compose.PinAction(local, hub); err != nil {
log.Fatal(err)
}

if output != "-" {
if fd, err = os.Create(output); err != nil {
log.Fatal(err)
}
defer fd.Close()

if ext := filepath.Ext(output); !ctx.IsSet("type") && ext == ".json" {
format = "json"
}
}

switch format {
case "yaml":
if data, err = yaml.Marshal(vars); err != nil {
log.Fatal(err)
}
case "json":
if data, err = json.Marshal(vars); err != nil {
log.Fatal(err)
}
default:
log.Fatalf("Possible tyoes are `yaml` and `json`, unknown type `%s`", format)
}

if _, err := io.Copy(fd, bytes.NewReader(data)); err != nil {
log.Fatal(err)
}
}

func recoverCommand(ctx *cli.Context) {
initLogs(ctx)

Expand All @@ -355,33 +463,44 @@ func recoverCommand(ctx *cli.Context) {
}

func initLogs(ctx *cli.Context) {
logger := log.StandardLogger()

if ctx.GlobalBool("verbose") {
log.SetLevel(log.DebugLevel)
logger.Level = log.DebugLevel
} else if ctx.Bool("print") && ctx.GlobalString("log") == "" {
logger.Level = log.ErrorLevel
}

if ctx.GlobalBool("json") {
log.SetFormatter(&log.JSONFormatter{})
}
var (
err error
isTerm = log.IsTerminal()
logFile = ctx.GlobalString("log")
logExt = path.Ext(logFile)
json = ctx.GlobalBool("json") || logExt == ".json"
useColors = isTerm && !json && logFile == ""
)

logFilename, err := toAbsolutePath(ctx.GlobalString("log"), false)
if err != nil {
log.Debugf("Initializing log: Skipped, because Log %s", err)
return
if ctx.GlobalIsSet("colors") {
useColors = ctx.GlobalBool("colors")
}

logFile, err := os.OpenFile(logFilename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
if err != nil {
log.Warnf("Initializing log: Cannot initialize log file %s due to error %s", logFilename, err)
return
if logFile != "" {
if logFile, err = toAbsolutePath(logFile, false); err != nil {
log.Fatal(err)
}
if logger.Out, err = os.OpenFile(logFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644); err != nil {
log.Fatalf("Initializing log: Cannot initialize log file %s due to error %s", logFile, err)
}
log.Debugf("Initializing log: Successfuly started loggin to '%s'", logFile)
}

log.SetOutput(logFile)

if path.Ext(logFilename) == ".json" {
log.SetFormatter(&log.JSONFormatter{})
if json {
logger.Formatter = &log.JSONFormatter{}
} else {
formatter := &textformatter.TextFormatter{}
formatter.DisableColors = !useColors
logger.Formatter = formatter
}

log.Debugf("Initializing log: Successfuly started loggin to '%s'", logFilename)
}

func initComposeConfig(ctx *cli.Context, dockerCli *docker.Client) *config.Config {
Expand All @@ -399,12 +518,24 @@ func initComposeConfig(ctx *cli.Context, dockerCli *docker.Client) *config.Confi
print = ctx.Bool("print")
)

vars, err := template.VarsFromStrings(ctx.StringSlice("var"))
vars, err := template.VarsFromFileMulti(ctx.StringSlice("vars"))
if err != nil {
log.Fatal(err)
os.Exit(1)
}

cliVars, err := template.VarsFromStrings(ctx.StringSlice("var"))
if err != nil {
log.Fatal(err)
os.Exit(1)
}

vars = vars.Merge(cliVars)

if ctx.Bool("demand-artifacts") {
vars["DemandArtifacts"] = true
}

// TODO: find better place for providing this helper
funcs := map[string]interface{}{
// lazy get bridge ip
Expand Down Expand Up @@ -436,6 +567,11 @@ func initComposeConfig(ctx *cli.Context, dockerCli *docker.Client) *config.Confi
log.Fatal(err)
}

// Check the docker connection before we actually run
if err := dockerclient.Ping(dockerCli, 5000); err != nil {
log.Fatal(err)
}

return manifest
}

Expand Down
Loading

0 comments on commit 16ccae3

Please sign in to comment.