Skip to content

Commit 994b1cc

Browse files
authored
Merge pull request #1130 from oasisprotocol/ptrus/feature/embed-migrations
Embed migrations in the Nexus binary
2 parents 6f51a3f + 7479ecf commit 994b1cc

File tree

10 files changed

+33
-39
lines changed

10 files changed

+33
-39
lines changed

.changelog/799.feature.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Embed migrations in the Nexus binary
2+
3+
Migrations are now embedded directly in the Nexus binary, simplifying
4+
deployment by eliminating the need to distribute migration files separately.

analyzer/block/block_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ import (
2323
pgTestUtil "github.com/oasisprotocol/nexus/storage/postgres/testutil"
2424
)
2525

26-
// Relative path to the migrations directory when running tests in this file.
27-
// When running go tests, the working directory is always set to the package directory of the test being run.
28-
const migrationsPath = "file://../../storage/migrations"
29-
3026
const testsTimeout = 10 * time.Second
3127

3228
// Default block based config used in slow-sync tests.
@@ -102,7 +98,7 @@ func setupDB(t *testing.T) *postgres.Client {
10298
// Ensure the test database is empty.
10399
require.NoError(t, testDB.Wipe(ctx), "testDb.Wipe")
104100
// Run DB migrations.
105-
require.NoError(t, analyzerCmd.RunMigrations(migrationsPath, os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
101+
require.NoError(t, analyzerCmd.RunMigrations(os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
106102

107103
return testDB
108104
}

analyzer/item/item_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@ import (
2121
pgTestUtil "github.com/oasisprotocol/nexus/storage/postgres/testutil"
2222
)
2323

24-
// Relative path to the migrations directory when running tests in this file.
25-
// When running go tests, the working directory is always set to the package directory of the test being run.
26-
const migrationsPath = "file://../../storage/migrations"
27-
2824
const testsTimeout = 10 * time.Second
2925

3026
const (
@@ -113,7 +109,7 @@ func setupDB(t *testing.T) *postgres.Client {
113109
// Ensure the test database is empty.
114110
require.NoError(t, testDB.Wipe(ctx), "testDb.Wipe")
115111
// Run DB migrations.
116-
require.NoError(t, analyzerCmd.RunMigrations(migrationsPath, os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
112+
require.NoError(t, analyzerCmd.RunMigrations(os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
117113
// Initialize test table.
118114
batch := &storage.QueryBatch{}
119115
batch.Queue(testTableCreate)

analyzer/runtime/runtime_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ import (
3636
pgTestUtil "github.com/oasisprotocol/nexus/storage/postgres/testutil"
3737
)
3838

39-
// Relative path to the migrations directory when running tests in this file.
40-
// When running go tests, the working directory is always set to the package directory of the test being run.
41-
const migrationsPath = "file://../../storage/migrations"
42-
4339
const testsTimeout = 10 * time.Second
4440

4541
func setupDB(t *testing.T) *postgres.Client {
@@ -50,7 +46,7 @@ func setupDB(t *testing.T) *postgres.Client {
5046
// Ensure the test database is empty.
5147
require.NoError(t, testDB.Wipe(ctx), "testDb.Wipe")
5248
// Run DB migrations.
53-
require.NoError(t, analyzerCmd.RunMigrations(migrationsPath, os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
49+
require.NoError(t, analyzerCmd.RunMigrations(os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
5450
// Initialize test table.
5551
// batch := &storage.QueryBatch{}
5652
// batch.Queue(testTableCreate)

cmd/analyzer/analyzer.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
migratePgx "github.com/golang-migrate/migrate/v4/database/pgx/v5" // postgres pgx driver for golang_migrate
1414
_ "github.com/golang-migrate/migrate/v4/source/file" // support file scheme for golang_migrate
1515
_ "github.com/golang-migrate/migrate/v4/source/github" // support github scheme for golang_migrate
16+
"github.com/golang-migrate/migrate/v4/source/iofs"
1617
"github.com/jackc/pgx/v5/pgxpool"
1718
pgxstd "github.com/jackc/pgx/v5/stdlib"
1819

@@ -42,6 +43,7 @@ import (
4243
"github.com/oasisprotocol/nexus/config"
4344
"github.com/oasisprotocol/nexus/log"
4445
"github.com/oasisprotocol/nexus/storage"
46+
"github.com/oasisprotocol/nexus/storage/migrations"
4547
source "github.com/oasisprotocol/nexus/storage/oasis"
4648
"github.com/oasisprotocol/nexus/storage/oasis/nodeapi"
4749
)
@@ -50,8 +52,8 @@ const (
5052
moduleName = "analysis_service"
5153
)
5254

53-
// RunMigrations runs migrations defined in sourceURL against databaseURL.
54-
func RunMigrations(sourceURL string, databaseURL string) error {
55+
// RunMigrations runs embedded migrations against databaseURL.
56+
func RunMigrations(databaseURL string) error {
5557
// Go-migrate supports only basic database URL parameters.
5658
// We use pgx to parse the database URL the same way as we do in the indexer
5759
// client. That way the config options for migrations and clients are compatible.
@@ -73,10 +75,16 @@ func RunMigrations(sourceURL string, databaseURL string) error {
7375
}
7476
defer driver.Close()
7577

76-
m, err := migrate.NewWithDatabaseInstance(sourceURL, config.ConnConfig.Database, driver)
78+
sourceDriver, err := iofs.New(migrations.FS, ".")
7779
if err != nil {
78-
return err
80+
return fmt.Errorf("failed to create embedded migration source: %w", err)
7981
}
82+
83+
m, err := migrate.NewWithInstance("iofs", sourceDriver, config.ConnConfig.Database, driver)
84+
if err != nil {
85+
return fmt.Errorf("failed to create migration instance: %w", err)
86+
}
87+
8088
return m.Up()
8189
}
8290

@@ -94,7 +102,7 @@ func Init(ctx context.Context, cfg *config.AnalysisConfig, logger *log.Logger) (
94102
}
95103

96104
logger.Info("checking if migrations need to be applied...")
97-
switch err := RunMigrations(cfg.Storage.Migrations, cfg.Storage.Endpoint); {
105+
switch err := RunMigrations(cfg.Storage.Endpoint); {
98106
case err == migrate.ErrNoChange:
99107
logger.Info("no migrations needed to be applied")
100108
case err != nil:

cmd/analyzer/analyzer_migrations_test.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ import (
1212
"github.com/oasisprotocol/nexus/tests"
1313
)
1414

15-
// Relative path to the migrations directory when running tests in this file.
16-
// When running go tests, the working directory is always set to the package directory of the test being run.
17-
const migrationsPath = "file://../../storage/migrations"
18-
1915
func TestMigrations(t *testing.T) {
2016
tests.SkipIfShort(t)
2117
client := testutil.NewTestClient(t)
@@ -27,5 +23,5 @@ func TestMigrations(t *testing.T) {
2723
require.NoError(t, client.Wipe(ctx), "failed to wipe database")
2824

2925
// Run migrations.
30-
require.NoError(t, cmdAnalyzer.RunMigrations(migrationsPath, os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
26+
require.NoError(t, cmdAnalyzer.RunMigrations(os.Getenv("CI_TEST_CONN_STRING")), "failed to run migrations")
3127
}

config/config.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func (cfg *AnalysisConfig) Validate() error {
133133
}
134134
}
135135

136-
return cfg.Storage.Validate(true /* requireMigrations */)
136+
return cfg.Storage.Validate()
137137
}
138138

139139
type AnalyzersList struct {
@@ -679,7 +679,7 @@ func (cfg *ServerConfig) Validate() error {
679679
}
680680
}
681681

682-
return cfg.Storage.Validate(false /* requireMigrations */)
682+
return cfg.Storage.Validate()
683683
}
684684

685685
// StorageBackend is a storage backend.
@@ -737,22 +737,16 @@ type StorageConfig struct {
737737
// Backend is the storage backend to select.
738738
Backend string `koanf:"backend"`
739739

740-
// Migrations is the directory containing schema migrations.
741-
Migrations string `koanf:"migrations"`
742-
743740
// If true, we'll first delete all tables in the DB to
744741
// force a full re-index of the blockchain.
745742
WipeStorage bool `koanf:"DANGER__WIPE_STORAGE_ON_STARTUP"`
746743
}
747744

748745
// Validate validates the storage configuration.
749-
func (cfg *StorageConfig) Validate(requireMigrations bool) error {
746+
func (cfg *StorageConfig) Validate() error {
750747
if cfg.Endpoint == "" {
751748
return fmt.Errorf("malformed storage endpoint '%s'", cfg.Endpoint)
752749
}
753-
if cfg.Migrations == "" && requireMigrations {
754-
return fmt.Errorf("invalid path to migrations '%s'", cfg.Migrations)
755-
}
756750
var sb StorageBackend
757751
return sb.Set(cfg.Backend)
758752
}

config/config_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ func TestServerConfigJSON(t *testing.T) {
1616
cfg := ServerConfig{
1717
Endpoint: "localhost:8080",
1818
Storage: &StorageConfig{
19-
Endpoint: "postgresql://user:pass@localhost:5432/db",
20-
Backend: "postgres",
21-
Migrations: "/path/to/migrations",
19+
Endpoint: "postgresql://user:pass@localhost:5432/db",
20+
Backend: "postgres",
2221
},
2322
Source: &SourceConfig{
2423
ChainName: "mainnet",
@@ -46,7 +45,6 @@ server:
4645
storage:
4746
endpoint: postgresql://user:pass@localhost:5432/db
4847
backend: postgres
49-
migrations: /path/to/migrations
5048
DANGER__WIPE_STORAGE_ON_STARTUP: false
5149
source:
5250
chain_name: mainnet

docker/nexus/Dockerfile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ RUN apt-get update -q -q && \
2828
apt-get install --yes apt-transport-https ca-certificates
2929

3030
COPY --from=nexus-builder /code/go/nexus /usr/local/bin/nexus
31-
COPY --from=nexus-builder /code/go/storage/migrations /storage/migrations/
3231
COPY --from=nexus-builder /code/go/ /nexus
3332
COPY --from=openapi-builder /api/spec/v1.html api/spec/v1.html
3433

storage/migrations/migrations.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Package migrations contains embedded database migration files.
2+
package migrations
3+
4+
import "embed"
5+
6+
//go:embed *.sql
7+
var FS embed.FS

0 commit comments

Comments
 (0)