Skip to content

Commit

Permalink
feat: implement local TigrisDB server starting and stopping
Browse files Browse the repository at this point in the history
  • Loading branch information
efirs committed Apr 5, 2022
1 parent 771d802 commit 0203ca3
Show file tree
Hide file tree
Showing 7 changed files with 287 additions and 24 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/go-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: '1.17.6'
go-version: '1.18'
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.44.2
version: v1.45.2
skip-pkg-cache: true
skip-build-cache: true
21 changes: 21 additions & 0 deletions .github/workflows/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: release-binaries
on:
release:
types: [created]

jobs:
releases-matrix:
name: Release Go Binaries
runs-on: ubuntu-latest
strategy:
matrix:
goos: [linux, windows, darwin]
goarch: [amd64, arm64]
steps:
- uses: actions/checkout@v2
- uses: wangyoucao577/go-release-action@v1.25
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
sha256sum: true
189 changes: 189 additions & 0 deletions cmd/local.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package cmd

import (
"context"
"fmt"
"io"
"os"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/mount"
volumetypes "github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client"
"github.com/docker/docker/errdefs"
"github.com/docker/go-connections/nat"
"github.com/rs/zerolog/log"
"github.com/spf13/cobra"
)

const (
ImagePath = "tigrisdata/tigrisdb"
FDBImagePath = "foundationdb/foundationdb:6.3.23"
volumeName = "fdbdata"
FDBContainerName = "tigrisdb-cli-fdb"
ContainerName = "tigrisdb-cli-server"
)

var ImageTag = "1.0.0-alpha.4"

func ensureVolume(cli *client.Client) {
ctx := context.Background()

volumes, err := cli.VolumeList(ctx, filters.NewArgs())
if err != nil {
log.Fatal().Err(err).Msg("error listing volumes")
}

found := false
for _, v := range volumes.Volumes {
if v.Name == volumeName {
found = true
}
}

if !found {
_, err := cli.VolumeCreate(ctx, volumetypes.VolumeCreateBody{
Driver: "local",
Name: volumeName,
})
if err != nil {
log.Fatal().Err(err).Msg("error creating docker volume")
}
}
}

func stopContainer(client *client.Client, cname string) {
ctx := context.Background()

if err := client.ContainerStop(ctx, cname, nil); err != nil {
if !errdefs.IsNotFound(err) {
log.Fatal().Err(err).Str("name", cname).Msg("error stopping container")
}
}

opts := types.ContainerRemoveOptions{
RemoveVolumes: true,
Force: true,
}

if err := client.ContainerRemove(ctx, cname, opts); err != nil {
if !errdefs.IsNotFound(err) {
log.Fatal().Err(err).Str("name", cname).Msg("error stopping container")
}
}
}

func startContainer(cli *client.Client, cname string, image string, volumeMount string, port string) string {
ctx := context.Background()

reader, err := cli.ImagePull(ctx, image, types.ImagePullOptions{})
if err != nil {
log.Fatal().Err(err).Str("image", image).Msg("error pulling docker image")
}
defer func() { _ = reader.Close() }()

_, _ = io.Copy(os.Stdout, reader)

m := mount.Mount{
Type: mount.TypeVolume,
Source: volumeName,
Target: volumeMount,
}

p, err := nat.ParsePortSpec(port)
if err != nil {
log.Fatal().Err(err).Str("image", image).Msg("error parsing port")
}

pm := nat.PortMap{}

for _, v := range p {
pm[v.Port] = []nat.PortBinding{v.Binding}
}

resp, err := cli.ContainerCreate(ctx,
&container.Config{
Image: image,
Tty: false,
},
&container.HostConfig{
Mounts: []mount.Mount{m},
PortBindings: pm,
}, nil, nil, cname)
if err != nil {
log.Fatal().Err(err).Str("image", image).Msg("error creating container docker image")
}

if err = cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
log.Fatal().Err(err).Str("image", image).Msg("error starting docker image")
}

return resp.ID
}

var serverUpCmd = &cobra.Command{
Use: "up [port] [version]",
Short: "Start an instance of TigrisDB for local development",
Run: func(cmd *cobra.Command, args []string) {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
log.Fatal().Err(err).Msg("error creating docker client")
}

ensureVolume(cli)

port := "8081"
if len(args) > 0 {
port = args[0]
}
rport := port + ":8081"

if len(args) > 1 {
t := args[1]
if t[0] == 'v' {
t = t[1:]
}
ImageTag = t
}

stopContainer(cli, FDBContainerName)
stopContainer(cli, ContainerName)

_ = startContainer(cli, FDBContainerName, FDBImagePath, "/var/fdb", "4500")
_ = startContainer(cli, ContainerName, ImagePath+":"+ImageTag, "/etc/foundationdb", rport)

fmt.Printf("TigrisDB is running at localhost:%s\n", port)
if port != "8081" {
fmt.Printf("run 'export TIGRISDB_URL=localhost:%s' for tigrisdb-cli to automatically connect\n", port)
}
},
}

var serverDownCmd = &cobra.Command{
Use: "down",
Short: "Stop local TigrisDB instance",
Run: func(cmd *cobra.Command, args []string) {
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
log.Fatal().Err(err).Msg("error creating docker client")
}

stopContainer(cli, FDBContainerName)
stopContainer(cli, ContainerName)

fmt.Printf("TigrisDB stopped\n")
},
}

var localCmd = &cobra.Command{
Use: "local",
Short: "Starting and stopping local TigrisDB server",
}

func init() {
rootCmd.AddCommand(localCmd)
localCmd.AddCommand(serverUpCmd)
localCmd.AddCommand(serverDownCmd)
}
3 changes: 1 addition & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import (
)

var DefaultConfig = Config{
Token: "e30K",
URL: "api.apps.tigrisinternal.com",
URL: "localhost:8081",
}

type Config struct {
Expand Down
24 changes: 18 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module github.com/tigrisdata/tigrisdb-cli
go 1.18

require (
github.com/docker/docker v20.10.14+incompatible
github.com/docker/go-connections v0.4.0
github.com/rs/zerolog v1.26.1
github.com/spf13/cobra v1.4.0
github.com/spf13/pflag v1.0.5
Expand All @@ -13,38 +15,48 @@ require (

require (
cloud.google.com/go v0.99.0 // indirect
github.com/Microsoft/go-winio v0.5.1 // indirect
github.com/containerd/containerd v1.6.2 // indirect
github.com/deepmap/oapi-codegen v1.9.1 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/getkin/kin-openapi v0.92.0 // indirect
github.com/getkin/kin-openapi v0.90.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/swag v0.21.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.9.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.8.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/stretchr/testify v1.7.1 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220317150908-0efb43f6373e // indirect
google.golang.org/grpc v1.45.0 // indirect
google.golang.org/genproto v0.0.0-20220303160752-862486edd9cc // indirect
google.golang.org/grpc v1.44.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gotest.tools/v3 v3.1.0 // indirect
)
Loading

0 comments on commit 0203ca3

Please sign in to comment.