Skip to content

Commit

Permalink
Refactor and add registry flag
Browse files Browse the repository at this point in the history
  • Loading branch information
krzko committed May 19, 2023
1 parent 18518de commit fbda7bd
Show file tree
Hide file tree
Showing 18 changed files with 493 additions and 172 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
### Custom ###

bin/
run-o11y-run
run_o11y_run_files
/run-o11y-run
/run_o11y_run_files
/run-o11y-run-legacy

# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,linux,visualstudiocode,go,intellij+all
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,linux,visualstudiocode,go,intellij+all
Expand Down
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,22 @@ Download the latest version from the [Releases](https://github.com/krzko/run-o11

## Commands

`run-o11y-run` is a command-line tool with three simple commands: `start`, `stop`, and `clean`.

- `start`: Starts run-o11y-run containers. You can use the `--registry` flag to specify a Docker Registry. By default, it uses Docker Hub.
Example: `run-o11y-run start --registry <registry-url>`

- `stop`: Stops run-o11y-run containers.
Example: `run-o11y-run stop`

- `clean`: Stops and removes run-o11y-run containers, files, and networks.
Example: `run-o11y-run clean`

### Examples

```sh
# start
$ run-o11y-run
$ run-o11y-run start

[+] Running 3/24
⠿ prometheus Pulled 78.5s
Expand All @@ -54,7 +67,7 @@ $ run-o11y-run
⠸ 8476389c268a Exists 75.2s

# clean
run-o11y-run -clean
run-o11y-run clean

[+] Running 5/4
⠿ Container stack-prometheus-1 Removed 0.1s
Expand Down
22 changes: 22 additions & 0 deletions cmd/run-o11y-run/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"log"
"os"

"github.com/krzko/run-o11y-run/internal/cli"
)

var (
version string
commit string
date string
)

func main() {
app := cli.New(version, commit, date)

if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}
20 changes: 20 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
module github.com/krzko/run-o11y-run

go 1.20

require (
github.com/fatih/color v1.15.0
github.com/urfave/cli/v2 v2.25.3
go.uber.org/zap v1.24.0
gopkg.in/yaml.v2 v2.4.0
)

require (
github.com/BurntSushi/toml v1.2.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/sys v0.6.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
43 changes: 43 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/urfave/cli/v2 v2.25.3 h1:VJkt6wvEBOoSjPFQvOkv6iWIrsJyCrKGtCtxXWwmGeY=
github.com/urfave/cli/v2 v2.25.3/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
63 changes: 63 additions & 0 deletions internal/cli/clean.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package cli

import (
"fmt"
"os"
"path/filepath"

"github.com/krzko/run-o11y-run/internal/files"
"github.com/urfave/cli/v2"
)

func genCleanCommand() *cli.Command {
return &cli.Command{
Name: "clean",
Usage: "Stop and remove containers, files, networks",
Aliases: []string{"c"},
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "legacy",
Usage: "removes legacy \"stack\" docker resources",
Value: false,
},
},
Action: func(c *cli.Context) error {
fmt.Println("🧹 Cleaning...")

if !checkDockerAvailability() {
fmt.Println("Docker command not found. Please make sure Docker is installed and available in your PATH.")
os.Exit(1)
}

targetDir := "run_o11y_run_files"
err := files.ExtractFiles(targetDir)
if err != nil {
fmt.Println("Error extracting files:", err)
return err
}

if c.Bool("legacy") {
err = runDockerCompose(filepath.Join(targetDir, "files", "grafana", "stack"), "down", "")
if err != nil {
fmt.Println("Error running docker compose down:", err)
return err
}
} else {
err = runDockerCompose(filepath.Join(targetDir, "files", "grafana", "run-o11y-run"), "down", "")
if err != nil {
fmt.Println("Error running docker compose down:", err)
return err
}
}

err = removeDirectory(targetDir)
if err != nil {
fmt.Println("Error removing target directory:", err)
return err
}

fmt.Println("🧹 Cleaned")
return nil
},
}
}
123 changes: 123 additions & 0 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package cli

import (
"fmt"
"math/rand"
"os"
"os/exec"
"os/signal"
"syscall"
"time"

"github.com/fatih/color"
"github.com/urfave/cli/v2"
)

func initBanner(c *cli.Context) error {
banner := `
_____ _____ _____ _____ ___ ___ __ __ _____ _____ _____
| __ | | | | |___| |_ | |_ | | | |___| __ | | | | |
| -| | | | | |___| | |_| |_ _| |_|_ _|___| -| | | | | |
|__|__|_____|_|___| |_____|_____|_____| |_| |__|__|_____|_|___|
`
fmt.Println(banner)

return nil
}

func New(version, commit, date string) *cli.App {
c := []color.Attribute{color.FgRed, color.FgGreen, color.FgYellow, color.FgMagenta, color.FgCyan, color.FgWhite, color.FgHiRed, color.FgHiGreen, color.FgHiYellow, color.FgHiBlue, color.FgHiMagenta, color.FgHiCyan, color.FgHiWhite}
rand.Seed(time.Now().UnixNano())
rand.Shuffle(len(c), func(i, j int) { c[i], c[j] = c[j], c[i] })

colors := make(map[int]func(...interface{}) string)
for i, attr := range c {
colors[i] = color.New(attr).SprintFunc()
}

name := fmt.Sprintf("%s%s%s%s%s%s%s%s%s%s%s%s", colors[0]("r"), colors[1]("u"), colors[2]("n"), colors[3]("-"), colors[4]("o"), colors[5]("1"), colors[6]("1"), colors[7]("y"), colors[8]("-"), colors[9]("r"), colors[10]("u"), colors[11]("n"))

flags := getGlobalFlags()

var v string
if version == "" {
v = "develop"
} else {
v = fmt.Sprintf("v%v-%v (%v)", version, commit, date)
}

app := &cli.App{
Name: name,
Usage: "A single-binary 🌯 wrapper around `docker compose` with embedded configurations to effortlessly run your local observability stack ",
Version: v,
Flags: flags,
Commands: []*cli.Command{
genCleanCommand(),
genStartCommand(),
genStopCommand(),
},
Before: initBanner,
}

app.EnableBashCompletion = true

return app
}

func checkDockerAvailability() bool {
_, err := exec.LookPath("docker")
return err == nil
}

func removeDirectory(dir string) error {
return os.RemoveAll(dir)
}

func runDockerCompose(dir string, subcommand string, flag string) error {
args := []string{"compose", subcommand}
if flag != "" {
args = append(args, flag)
}

cmd := exec.Command("docker", args...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

err := cmd.Start()
if err != nil {
return fmt.Errorf("docker compose %s failed: %w", subcommand, err)
}

if subcommand == "down" {
err = cmd.Wait()
if err != nil {
return fmt.Errorf("docker compose %s failed: %w", subcommand, err)
}
} else {
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM)

done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()

select {
case <-signalChan:
fmt.Printf("Received interrupt signal, stopping Docker %s...\n", subcommand)
_ = cmd.Process.Signal(os.Interrupt)
case err := <-done:
if err != nil {
return fmt.Errorf("docker compose %s failed: %w", subcommand, err)
}
}

err = <-done
if err != nil {
return fmt.Errorf("docker compose %s failed: %w", subcommand, err)
}
}

return nil
}
17 changes: 17 additions & 0 deletions internal/cli/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cli

import (
"github.com/urfave/cli/v2"
"github.com/urfave/cli/v2/altsrc"
)

func getGlobalFlags() []cli.Flag {
return []cli.Flag{
altsrc.NewBoolFlag(&cli.BoolFlag{
Name: "squeaky-lobster",
Aliases: []string{"sl"},
Value: false,
Hidden: true,
}),
}
}
Loading

0 comments on commit fbda7bd

Please sign in to comment.