-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This implementation allows to start, stop and manipulate a swarm cluster from a go program or a CLI. Add a first integration test. And make sure all the join cmd are done before returning. Master => Manager cli is a basic example sind -> go-sind + README let the docker daemon decide which port to bind for exposing the remote docker daemon port manage host properly update readme wait for the remote daemon to be ready add an empty cobra entrypoint dumb implementation of create use ping instead of info got a working implementation for a store file use docker labels instead of storing ids. make --cluster a global flag implement delete implement the env command implement list-clusters add ls as an alias of list add a test suite for store first attempt to implement deploy still does not work broken implemntation of port bindings working-ish implementation of deploy deploy => push more agressive delete ports mapping works as expected add a note about how to use it as a CLI better UX go mod tidy wait for the image to be pulled add a basic makefile add test targets to the makefile setup goreleaster add a goreleaser target
- Loading branch information
0 parents
commit 0e24fde
Showing
22 changed files
with
1,875 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
project_name: sind | ||
before: | ||
hooks: | ||
- go mod download | ||
builds: | ||
- main: ./cmd/sind/main.go | ||
binary: sind | ||
ldflags: | ||
- "-s -w" | ||
env: | ||
- CGO_ENABLED=0 | ||
archive: | ||
replacements: | ||
darwin: Darwin | ||
linux: Linux | ||
windows: Windows | ||
386: i386 | ||
amd64: x86_64 | ||
checksum: | ||
name_template: 'checksums.txt' | ||
snapshot: | ||
name_template: "{{ .Tag }}-next" | ||
changelog: | ||
sort: asc | ||
filters: | ||
exclude: | ||
- '^docs:' | ||
- '^test:' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
DIST_DIR=dist | ||
|
||
all: build | ||
|
||
# | ||
# Release targets | ||
# | ||
|
||
.PHONY: release | ||
release: clean | ||
goreleaser | ||
|
||
.PHONY: dry_release | ||
dry_release: clean | ||
goreleaser --skip-publish | ||
|
||
# | ||
# Test targets | ||
# | ||
|
||
test: unit_test integration_test | ||
|
||
.PHONY: integration_test | ||
integration_test: | ||
go test ./integration | ||
|
||
.PHONY: unit_test | ||
unit_test: | ||
go test -race -v -cover -timeout=5s -run=$(T) $(shell go list ./... | grep -v integration) | ||
|
||
# | ||
# Build targets | ||
# | ||
|
||
install: build | ||
mv ${DIST_DIR}/sind $${GOPATH}/bin/sind | ||
|
||
build: clean dist binary | ||
|
||
.PHONY: binary | ||
binary: | ||
CGO_ENABLED=0 go build -ldflags="-s -w" -o ${DIST_DIR}/sind ./cmd/sind | ||
|
||
dist: | ||
mkdir -p ${DIST_DIR} | ||
|
||
clean: | ||
rm -rf ${DIST_DIR} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# go-sind | ||
|
||
go-SIND enables you to create swarm clusters on a docker host using SIND (swarm in docker). | ||
|
||
Not yet ready to use, this is a PoC at the moment. | ||
|
||
## Requirements | ||
|
||
- A reachable docker daemon. | ||
- go 1.11.x | ||
|
||
## Using it as a go package | ||
|
||
Head to the [base example](./example/base/main.go) or to the [integration test suite](./integration/sind_test.go) to get started. | ||
|
||
## Using it as a CLI | ||
|
||
``` | ||
go install github.com/jlevesy/go-sind/cmd/sind | ||
# Will create a new cluster with 3 managers, 3 workers and the port 8080 of the host bound | ||
# to the port 8080 of the ingress network of the cluster. | ||
sind create --managers=3 --workers=3 -p 8080:8080 | ||
# Setup the docker cli configuration to communicate with the new cluster. | ||
eval $(sind env) | ||
# Deploy an app | ||
docker stack deploy -c my-stack.yml app | ||
# Enjoy your app :) | ||
docker service ls | ||
# Once your're done, clear your docker CLI configuration then delete your cluster | ||
unset DOCKER_HOST | ||
sind delete | ||
``` | ||
|
||
## Why ? | ||
|
||
Mostly for automated testing. | ||
|
||
## TODO list | ||
|
||
- [ ] CI | ||
- [ ] Release process |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package cli | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"github.com/spf13/cobra" | ||
"os" | ||
|
||
"github.com/jlevesy/go-sind/sind" | ||
) | ||
|
||
var ( | ||
managers = 0 | ||
workers = 0 | ||
networkName = "" | ||
portsMapping = []string{} | ||
|
||
createCmd = &cobra.Command{ | ||
Use: "create", | ||
Short: "Create a new swarm cluster.", | ||
Run: runCreate, | ||
} | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(createCmd) | ||
|
||
createCmd.Flags().IntVarP(&managers, "managers", "m", 1, "Amount of managers in the created cluster.") | ||
createCmd.Flags().IntVarP(&workers, "workers", "w", 0, "Amount of workers in the created cluster.") | ||
createCmd.Flags().StringVarP(&networkName, "network_name", "n", "sind_default", "Name of the network to create.") | ||
createCmd.Flags().StringSliceVarP(&portsMapping, "ports", "p", []string{}, "Ingress network port binding.") | ||
} | ||
|
||
func runCreate(cmd *cobra.Command, args []string) { | ||
fmt.Printf("Creating a new cluster %q with %d managers and %d, workers...\n", clusterName, managers, workers) | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), timeout) | ||
defer cancel() | ||
|
||
store, err := NewStore() | ||
if err != nil { | ||
fmt.Printf("unable to create store: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
if err := store.ValidateName(clusterName); err != nil { | ||
fmt.Printf("invalid cluster name: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
clusterParams := sind.CreateClusterParams{ | ||
Managers: managers, | ||
Workers: workers, | ||
NetworkName: networkName, | ||
ClusterName: clusterName, | ||
PortBindings: portsMapping, | ||
} | ||
|
||
cluster, err := sind.CreateCluster(ctx, clusterParams) | ||
if err != nil { | ||
fmt.Printf("unable to setup a swarm cluster: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
if err = store.Save(*cluster); err != nil { | ||
fmt.Printf("unable to save cluster: %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
fmt.Printf("Cluster %s successfuly created !\n", clusterName) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package cli | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
deleteCmd = &cobra.Command{ | ||
Use: "delete", | ||
Short: "Delete a swarm cluster.", | ||
Run: runDelete, | ||
} | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(deleteCmd) | ||
} | ||
|
||
func runDelete(cmd *cobra.Command, args []string) { | ||
fmt.Printf("Deleting cluster %q...\n", clusterName) | ||
ctx, cancel := context.WithTimeout(context.Background(), timeout) | ||
defer cancel() | ||
|
||
store, err := NewStore() | ||
if err != nil { | ||
fail("unable to create store: %v\n", err) | ||
} | ||
|
||
cluster, err := store.Load(clusterName) | ||
if err != nil { | ||
fail("unable to load cluster: %v\n", err) | ||
} | ||
|
||
if err = cluster.Delete(ctx); err != nil { | ||
fail("unable to tear down cluster: %v", err) | ||
} | ||
|
||
if err = store.Delete(clusterName); err != nil { | ||
fail("unable to delete cluster from storage: %v", err) | ||
} | ||
|
||
fmt.Printf("Cluster %s successfuly deleted !\n", clusterName) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package cli | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
envCmd = &cobra.Command{ | ||
Use: "env", | ||
Short: "Sets up docker env variables.", | ||
Run: runEnv, | ||
} | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(envCmd) | ||
} | ||
|
||
func runEnv(cmd *cobra.Command, args []string) { | ||
store, err := NewStore() | ||
if err != nil { | ||
fail("unable to create store: %v\n", err) | ||
} | ||
|
||
cluster, err := store.Load(clusterName) | ||
if err != nil { | ||
fail("unable to load cluster: %v\n", err) | ||
} | ||
|
||
fmt.Printf("export DOCKER_HOST=%s", cluster.Cluster.DockerHost()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package cli | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"text/tabwriter" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
listCmd = &cobra.Command{ | ||
Use: "list", | ||
Short: "List existing clusters.", | ||
Aliases: []string{"ls"}, | ||
Run: runList, | ||
} | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(listCmd) | ||
} | ||
|
||
func runList(cmd *cobra.Command, args []string) { | ||
store, err := NewStore() | ||
if err != nil { | ||
fail("unable to create store: %v\n", err) | ||
} | ||
|
||
clusters, err := store.List() | ||
if err != nil { | ||
fail("unable to list existing clusters: %v\n", err) | ||
} | ||
|
||
wr := tabwriter.NewWriter(os.Stdout, 4, 8, 0, '\t', 0) | ||
fmt.Fprintf(wr, "NAME\tSWARM DOCKER HOST\tDOCKER HOST\t\n") | ||
for _, cluster := range clusters { | ||
fmt.Fprintf(wr, "%s\t%s\t%s\t\n", cluster.Name, cluster.Cluster.DockerHost(), cluster.Host.Host) | ||
} | ||
wr.Flush() | ||
fmt.Printf("\nTotal: %d\n", len(clusters)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package cli | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
pushCmd = &cobra.Command{ | ||
Use: "push", | ||
Short: "Push an image to the swarm cluster.", | ||
Run: runPush, | ||
} | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(pushCmd) | ||
} | ||
|
||
func runPush(cmd *cobra.Command, args []string) { | ||
fmt.Printf("Pushing images %v to the cluster %s...\n", args, clusterName) | ||
ctx, cancel := context.WithTimeout(context.Background(), timeout) | ||
defer cancel() | ||
|
||
store, err := NewStore() | ||
if err != nil { | ||
fail("unable to create store: %v\n", err) | ||
} | ||
|
||
cluster, err := store.Load(clusterName) | ||
if err != nil { | ||
fail("unable to load cluster: %v\n", err) | ||
} | ||
|
||
if err = cluster.PushImage(ctx, args); err != nil { | ||
fail("unable to push %v to the cluster: %v", args, err) | ||
} | ||
|
||
fmt.Printf("Images %v successfuly pushed to %s !\n", args, clusterName) | ||
} |
Oops, something went wrong.