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

Commit

Permalink
Allow selecting a backend for specific services.
Browse files Browse the repository at this point in the history
  • Loading branch information
theothertomelliott committed Mar 18, 2018
1 parent 07713cf commit 0482f1f
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 26 deletions.
2 changes: 1 addition & 1 deletion builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (b *builder) BuildWithTracker(dirConfig *home.EdwardConfiguration, task tra
return errors.WithStack(err)
}

builder, err := services.GetBuilder(service)
builder, err := services.GetBuilder(b.Cfg, service)
if err != nil {
return errors.WithStack(err)
}
Expand Down
22 changes: 22 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"path"
"path/filepath"
"strings"

lumberjack "gopkg.in/natefinch/lumberjack.v2"

Expand Down Expand Up @@ -115,6 +116,10 @@ Build, start and manage service instances with a single command.`,
}

edwardClient.DirConfig = dirConfig
edwardClient.Backends, err = buildBackendOverrides()
if err != nil {
return errors.WithStack(err)
}

// Set service checks to restart the client on sudo as needed
edwardClient.ServiceChecks = func(sgs []services.ServiceOrGroup) error {
Expand Down Expand Up @@ -158,6 +163,21 @@ Build, start and manage service instances with a single command.`,
},
}

func buildBackendOverrides() (map[string]string, error) {
var overrides = make(map[string]string)
for _, backend := range backends {
separated := strings.Split(backend, ":")
if len(separated) != 2 {
return nil, errors.New("backend definition should be of the form '<service>:<backend>'")
}
if _, exists := overrides[separated[0]]; exists {
return nil, fmt.Errorf("multiple backend selections specified for service or group: %s", separated[0])
}
overrides[separated[0]] = separated[1]
}
return overrides, nil
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
Expand Down Expand Up @@ -197,6 +217,7 @@ var configPath string
var redirectLogs bool
var logFile string
var edwardHome string
var backends []string

func init() {
cobra.OnInitialize(initConfig)
Expand All @@ -205,6 +226,7 @@ func init() {
RootCmd.PersistentFlags().StringVarP(&configPath, "config", "c", "", "Use service configuration file at `PATH`")
RootCmd.PersistentFlags().BoolVar(&redirectLogs, "redirect_logs", false, "Redirect edward logs to the console")
RootCmd.PersistentFlags().StringVar(&edwardHome, "edward_home", "", "")
RootCmd.PersistentFlags().StringSliceVarP(&backends, "backend", "b", nil, "Choose a specific backend for a service or group, of the form '<service>:<backend name>'")
err := RootCmd.PersistentFlags().MarkHidden("redirect_logs")
if err != nil {
panic(err)
Expand Down
9 changes: 9 additions & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/yext/edward/runner"
"github.com/yext/edward/services"
)

// runCmd represents the run command
Expand All @@ -17,7 +18,15 @@ var runCmd = &cobra.Command{
if service == nil {
return fmt.Errorf("service not found: %s", args[0])
}
c := edwardClient
r, err := runner.NewRunner(
services.OperationConfig{
WorkingDir: c.WorkingDir,
EdwardExecutable: c.EdwardExecutable,
Tags: c.Tags,
LogFile: c.LogFile,
Backends: c.Backends,
},
service,
edwardClient.DirConfig,
*runFlags.noWatch,
Expand Down
3 changes: 3 additions & 0 deletions edward/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ type Client struct {
Tags []string // Tags to distinguish runners started by this instance of edward

DirConfig *home.EdwardConfiguration

Backends map[string]string // Service overrides for backends
}

type TaskFollower interface {
Expand Down Expand Up @@ -122,6 +124,7 @@ func (c *Client) startAndTrack(sgs []services.ServiceOrGroup, skipBuild bool, no
NoWatch: noWatch,
Tags: c.Tags,
LogFile: c.LogFile,
Backends: c.Backends,
}

task := tracker.NewTask(c.Follower.Handle)
Expand Down
1 change: 1 addition & 0 deletions edward/restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func (c *Client) restartOneOrMoreServices(serviceNames []string, skipBuild bool,
NoWatch: noWatch,
Tags: c.Tags,
LogFile: c.LogFile,
Backends: c.Backends,
}

task := tracker.NewTask(c.Follower.Handle)
Expand Down
1 change: 1 addition & 0 deletions edward/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func (c *Client) Stop(names []string, force bool, exclude []string, all bool) er
Exclusions: exclude,
Tags: c.Tags,
LogFile: c.LogFile,
Backends: c.Backends,
}

task := tracker.NewTask(c.Follower.Handle)
Expand Down
3 changes: 2 additions & 1 deletion runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Runner struct {
}

func NewRunner(
cfg services.OperationConfig,
service *services.ServiceConfig,
dirConfig *home.EdwardConfiguration,
noWatch bool,
Expand All @@ -53,7 +54,7 @@ func NewRunner(
Logger: logger,
}
var err error
r.backendRunner, err = services.GetRunner(service)
r.backendRunner, err = services.GetRunner(cfg, service)
if err != nil {
return nil, errors.WithStack(err)
}
Expand Down
17 changes: 11 additions & 6 deletions services/backends.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ type BackendLoader interface {
New() Backend
Name() string
Handles(Backend) bool
Builder(*ServiceConfig) (Builder, error)
Runner(*ServiceConfig) (Runner, error)
Builder(*ServiceConfig, Backend) (Builder, error)
Runner(*ServiceConfig, Backend) (Runner, error)
}

type Runner interface {
Expand All @@ -43,19 +43,24 @@ func RegisterBackend(loader BackendLoader) {
loaders[loader.Name()] = loader
}

func GetBuilder(s *ServiceConfig) (Builder, error) {
func GetBuilder(cfg OperationConfig, s *ServiceConfig) (Builder, error) {
expectedBackend := cfg.Backends[s.Name]
for _, backend := range s.Backends {
if expectedBackend != "" && backend.Name != expectedBackend {
continue
}
if loader, ok := loaders[backend.Type]; ok {
return loader.Builder(s)
// TODO: we need to be able to pass in the backend config
return loader.Builder(s, backend.Config)
}
}
return nil, fmt.Errorf("builder not found for service '%s'", s.Name)
}

func GetRunner(s *ServiceConfig) (Runner, error) {
func GetRunner(cfg OperationConfig, s *ServiceConfig) (Runner, error) {
for _, backend := range s.Backends {
if loader, ok := loaders[backend.Type]; ok {
return loader.Runner(s)
return loader.Runner(s, backend.Config)
}
}
return nil, fmt.Errorf("runner not found for service '%s'", s.Name)
Expand Down
4 changes: 2 additions & 2 deletions services/backends/commandline/buildandrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func TestStartService(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
runner, err := services.GetRunner(test.service)
runner, err := services.GetRunner(services.OperationConfig{}, test.service)
if err != nil {
t.Error(err)
return
Expand Down Expand Up @@ -196,7 +196,7 @@ func TestStartServiceFailure(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
runner, err := services.GetRunner(test.service)
runner, err := services.GetRunner(services.OperationConfig{}, test.service)
if err != nil {
t.Error(err)
return
Expand Down
12 changes: 6 additions & 6 deletions services/backends/commandline/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ func (l *Loader) Handles(c services.Backend) bool {
return ok
}

func (l *Loader) Builder(s *services.ServiceConfig) (services.Builder, error) {
return l.buildandrun(s)
func (l *Loader) Builder(s *services.ServiceConfig, b services.Backend) (services.Builder, error) {
return l.buildandrun(s, b)
}

func (l *Loader) Runner(s *services.ServiceConfig) (services.Runner, error) {
return l.buildandrun(s)
func (l *Loader) Runner(s *services.ServiceConfig, b services.Backend) (services.Runner, error) {
return l.buildandrun(s, b)
}

func (l *Loader) buildandrun(s *services.ServiceConfig) (*buildandrun, error) {
if config, ok := s.Backend().(*Backend); ok {
func (l *Loader) buildandrun(s *services.ServiceConfig, b services.Backend) (*buildandrun, error) {
if config, ok := b.(*Backend); ok {
return &buildandrun{
Service: s,
Backend: config,
Expand Down
4 changes: 2 additions & 2 deletions services/backends/docker/buildandrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestBuild(t *testing.T) {
},
},
}
b, err := services.GetBuilder(service)
b, err := services.GetBuilder(services.OperationConfig{}, service)
if err != nil {
t.Error(err)
return
Expand Down Expand Up @@ -102,7 +102,7 @@ func TestStart(t *testing.T) {
}

func doStartTest(t *testing.T, service *services.ServiceConfig) {
b, err := services.GetRunner(service)
b, err := services.GetRunner(services.OperationConfig{}, service)
if err != nil {
t.Error(err)
return
Expand Down
12 changes: 6 additions & 6 deletions services/backends/docker/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ func (l *Loader) Handles(c services.Backend) bool {
return ok
}

func (l *Loader) Builder(s *services.ServiceConfig) (services.Builder, error) {
return l.buildandrun(s)
func (l *Loader) Builder(s *services.ServiceConfig, backend services.Backend) (services.Builder, error) {
return l.buildandrun(s, backend)
}

func (l *Loader) Runner(s *services.ServiceConfig) (services.Runner, error) {
return l.buildandrun(s)
func (l *Loader) Runner(s *services.ServiceConfig, backend services.Backend) (services.Runner, error) {
return l.buildandrun(s, backend)
}

func (l *Loader) buildandrun(s *services.ServiceConfig) (*buildandrun, error) {
func (l *Loader) buildandrun(s *services.ServiceConfig, backend services.Backend) (*buildandrun, error) {
client, err := client.NewEnvClient()
if err != nil {
return nil, errors.WithMessage(err, "initializing client")
}
if config, ok := s.Backend().(*Backend); ok {
if config, ok := backend.(*Backend); ok {
return &buildandrun{
Service: s,
Backend: config,
Expand Down
6 changes: 4 additions & 2 deletions services/backends_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ type loaderProto struct {
func (l *loaderProto) New() services.Backend { return l.new() }
func (l *loaderProto) Name() string { return l.name }
func (l *loaderProto) Handles(c services.Backend) bool { return l.handles(c) }
func (l *loaderProto) Builder(s *services.ServiceConfig) (services.Builder, error) {
func (l *loaderProto) Builder(s *services.ServiceConfig, b services.Backend) (services.Builder, error) {
return l.builder(s)
}
func (l *loaderProto) Runner(s *services.ServiceConfig) (services.Runner, error) { return l.runner(s) }
func (l *loaderProto) Runner(s *services.ServiceConfig, b services.Backend) (services.Runner, error) {
return l.runner(s)
}

type configTest struct {
Field string `json:"field"`
Expand Down
1 change: 1 addition & 0 deletions services/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type OperationConfig struct {
SkipBuild bool
Tags []string // Tags to pass to `edward run`
LogFile string
Backends map[string]string // Service overrides for backends
}

// IsExcluded returns true if the given service/group is excluded by this OperationConfig.
Expand Down

0 comments on commit 0482f1f

Please sign in to comment.