Skip to content

Commit

Permalink
[rdbms] Schema migration tool
Browse files Browse the repository at this point in the history
Schema migration tool which supports both pure SQL migration
files and go migrations (for more complex operations which
require back-filling and manipulating previous entries).
Based on github.com/pressly/goose.

Every migration is executed within a transaction. SQL migrations
offer the possibility to turn off transactions, while golang migrations
by default receive a *sql.Tx object. At the moment, this cannot be
changed.
  • Loading branch information
marcoguerri committed Nov 3, 2020
1 parent 5efe844 commit c6ac0fb
Show file tree
Hide file tree
Showing 21 changed files with 967 additions and 519 deletions.
3 changes: 3 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
coverage:
status:
patch:
default:
target: 30%
project:
default:
target: auto
Expand Down
98 changes: 7 additions & 91 deletions cmds/contest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,120 +6,41 @@
package main

import (
"errors"
"flag"
"os"
"os/signal"
"syscall"

"github.com/facebookincubator/contest/cmds/plugins"

"github.com/facebookincubator/contest/pkg/api"
"github.com/facebookincubator/contest/pkg/config"
"github.com/facebookincubator/contest/pkg/job"
"github.com/facebookincubator/contest/pkg/jobmanager"
"github.com/facebookincubator/contest/pkg/logging"
"github.com/facebookincubator/contest/pkg/pluginregistry"
"github.com/facebookincubator/contest/pkg/storage"
"github.com/facebookincubator/contest/pkg/target"
"github.com/facebookincubator/contest/pkg/test"

"github.com/facebookincubator/contest/plugins/listeners/httplistener"
"github.com/facebookincubator/contest/plugins/reporters/noop"
"github.com/facebookincubator/contest/plugins/reporters/targetsuccess"
"github.com/facebookincubator/contest/plugins/storage/rdbms"

"github.com/facebookincubator/contest/plugins/targetlocker/inmemory"
"github.com/facebookincubator/contest/plugins/targetmanagers/csvtargetmanager"
"github.com/facebookincubator/contest/plugins/targetmanagers/targetlist"
"github.com/facebookincubator/contest/plugins/testfetchers/literal"
"github.com/facebookincubator/contest/plugins/testfetchers/uri"
"github.com/facebookincubator/contest/plugins/teststeps/cmd"
"github.com/facebookincubator/contest/plugins/teststeps/echo"
"github.com/facebookincubator/contest/plugins/teststeps/example"
"github.com/facebookincubator/contest/plugins/teststeps/randecho"
"github.com/facebookincubator/contest/plugins/teststeps/slowecho"
"github.com/facebookincubator/contest/plugins/teststeps/sshcmd"
"github.com/facebookincubator/contest/plugins/teststeps/terminalexpect"

"github.com/sirupsen/logrus"
)

const defaultDBURI = "contest:contest@tcp(localhost:3306)/contest?parseTime=true"

var (
flagDBURI = flag.String("dbURI", defaultDBURI, "Database URI")
flagDBURI = flag.String("dbURI", config.DefaultDBURI, "Database URI")
flagServerID = flag.String("serverID", "", "Set a static server ID, e.g. the host name or another unique identifier. If unset, will use the listener's default")
)

var targetManagers = []target.TargetManagerLoader{
csvtargetmanager.Load,
targetlist.Load,
}

var testFetchers = []test.TestFetcherLoader{
uri.Load,
literal.Load,
}

var testSteps = []test.TestStepLoader{
echo.Load,
slowecho.Load,
example.Load,
cmd.Load,
sshcmd.Load,
randecho.Load,
terminalexpect.Load,
}

var reporters = []job.ReporterLoader{
targetsuccess.Load,
noop.Load,
}

// user-defined functions that will be made available to plugins for advanced
// expressions in config parameters.
var userFunctions = map[string]interface{}{
// dummy function to prove that function registration works.
"do_nothing": func(a ...string) (string, error) {
if len(a) == 0 {
return "", errors.New("do_nothing: no arg specified")
}
return a[0], nil
},
}

func main() {
flag.Parse()
log := logging.GetLogger("contest")
log.Level = logrus.DebugLevel

pluginRegistry := pluginregistry.NewPluginRegistry()

// Register TargetManager plugins
for _, tmloader := range targetManagers {
if err := pluginRegistry.RegisterTargetManager(tmloader()); err != nil {
log.Fatal(err)
}
}

// Register TestFetcher plugins
for _, tfloader := range testFetchers {
if err := pluginRegistry.RegisterTestFetcher(tfloader()); err != nil {
log.Fatal(err)
}
}

// Register TestStep plugins
for _, tsloader := range testSteps {
if err := pluginRegistry.RegisterTestStep(tsloader()); err != nil {
log.Fatal(err)

}
}

// Register Reporter plugins
for _, rfloader := range reporters {
if err := pluginRegistry.RegisterReporter(rfloader()); err != nil {
log.Fatal(err)
}
}

// storage initialization
log.Infof("Using database URI: %s", *flagDBURI)
s, err := rdbms.New(*flagDBURI)
Expand All @@ -131,12 +52,7 @@ func main() {
// set Locker engine
target.SetLocker(inmemory.New(config.LockInitialTimeout, config.LockRefreshTimeout))

// user-defined function registration
for name, fn := range userFunctions {
if err := test.RegisterFunction(name, fn); err != nil {
log.Fatal(err)
}
}
plugins.Init(pluginRegistry, log)

// spawn JobManager
listener := httplistener.HTTPListener{}
Expand Down
107 changes: 107 additions & 0 deletions cmds/plugins/plugins.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.

package plugins

import (
"errors"

"github.com/facebookincubator/contest/pkg/pluginregistry"

"github.com/facebookincubator/contest/pkg/job"
"github.com/facebookincubator/contest/pkg/target"
"github.com/facebookincubator/contest/pkg/test"

"github.com/facebookincubator/contest/plugins/reporters/noop"
"github.com/facebookincubator/contest/plugins/reporters/targetsuccess"
"github.com/facebookincubator/contest/plugins/targetmanagers/csvtargetmanager"
"github.com/facebookincubator/contest/plugins/targetmanagers/targetlist"
"github.com/facebookincubator/contest/plugins/testfetchers/literal"
"github.com/facebookincubator/contest/plugins/testfetchers/uri"
"github.com/facebookincubator/contest/plugins/teststeps/cmd"
"github.com/facebookincubator/contest/plugins/teststeps/echo"
"github.com/facebookincubator/contest/plugins/teststeps/example"
"github.com/facebookincubator/contest/plugins/teststeps/randecho"
"github.com/facebookincubator/contest/plugins/teststeps/slowecho"
"github.com/facebookincubator/contest/plugins/teststeps/sshcmd"
"github.com/sirupsen/logrus"
)

var targetManagers = []target.TargetManagerLoader{
csvtargetmanager.Load,
targetlist.Load,
}

var testFetchers = []test.TestFetcherLoader{
uri.Load,
literal.Load,
}

var testSteps = []test.TestStepLoader{
echo.Load,
slowecho.Load,
example.Load,
cmd.Load,
sshcmd.Load,
randecho.Load,
}

var reporters = []job.ReporterLoader{
targetsuccess.Load,
noop.Load,
}

// user-defined functions that will be made available to plugins for advanced
// expressions in config parameters.
var userFunctions = map[string]interface{}{
// sample function to prove that function registration works.
"do_nothing": func(a ...string) (string, error) {
if len(a) == 0 {
return "", errors.New("do_nothing: no arg specified")
}
return a[0], nil
},
}

// Init initializes the plugin registry
func Init(pluginRegistry *pluginregistry.PluginRegistry, log *logrus.Entry) {

// Register TargetManager plugins
for _, tmloader := range targetManagers {
if err := pluginRegistry.RegisterTargetManager(tmloader()); err != nil {
log.Fatal(err)
}
}

// Register TestFetcher plugins
for _, tfloader := range testFetchers {
if err := pluginRegistry.RegisterTestFetcher(tfloader()); err != nil {
log.Fatal(err)
}
}

// Register TestStep plugins
for _, tsloader := range testSteps {
if err := pluginRegistry.RegisterTestStep(tsloader()); err != nil {
log.Fatal(err)

}
}

// Register Reporter plugins
for _, rfloader := range reporters {
if err := pluginRegistry.RegisterReporter(rfloader()); err != nil {
log.Fatal(err)
}
}

// user-defined function registration
for name, fn := range userFunctions {
if err := test.RegisterFunction(name, fn); err != nil {
log.Fatal(err)
}
}

}
5 changes: 5 additions & 0 deletions db/rdbms/migration/0001_add_extended_descriptor.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- +goose Up
ALTER TABLE jobs ADD COLUMN extended_descriptor text;

-- +goose Down
ALTER TABLE jobs DROP COLUMN extended_descriptor;
Loading

0 comments on commit c6ac0fb

Please sign in to comment.