Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

services/horizon/cmd: Check ingest flag before executing horizon db migrate commands #4664

Merged
merged 2 commits into from
Oct 18, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 30 additions & 11 deletions services/horizon/cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"log"
"os"
"strconv"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/viper"
Expand All @@ -32,23 +33,36 @@ var dbMigrateCmd = &cobra.Command{
Short: "commands to run schema migrations on horizon's postgres db",
}

func requireAndSetFlag(name string) error {
func requireAndSetFlags(names ...string) error {
set := map[string]bool{}
for _, name := range names {
set[name] = true
}
for _, flag := range flags {
if flag.Name == name {
if set[flag.Name] {
flag.Require()
flag.SetValue()
return nil
if err := flag.SetValue(); err != nil {
return err
}
delete(set, flag.Name)
}
}
return fmt.Errorf("could not find %s flag", name)
if len(set) == 0 {
return nil
}
var missing []string
for name := range set {
missing = append(missing, name)
}
return fmt.Errorf("could not find %s flags", strings.Join(missing, ","))
}

var dbInitCmd = &cobra.Command{
Use: "init",
Short: "install schema",
Long: "init initializes the postgres database used by horizon.",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAndSetFlag(horizon.DatabaseURLFlagName); err != nil {
if err := requireAndSetFlags(horizon.DatabaseURLFlagName, horizon.IngestFlagName); err != nil {
return err
}

Expand All @@ -72,6 +86,11 @@ var dbInitCmd = &cobra.Command{
}

func migrate(dir schema.MigrateDir, count int) error {
if !config.Ingest {
log.Println("Skipping migrations because ingest flag is not enabled")
return nil
}

dbConn, err := db.Open("postgres", config.DatabaseURL)
if err != nil {
return err
Expand All @@ -95,7 +114,7 @@ var dbMigrateDownCmd = &cobra.Command{
Short: "run downwards db schema migrations",
Long: "performs a downards schema migration command",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAndSetFlag(horizon.DatabaseURLFlagName); err != nil {
if err := requireAndSetFlags(horizon.DatabaseURLFlagName, horizon.IngestFlagName); err != nil {
return err
}

Expand All @@ -119,7 +138,7 @@ var dbMigrateRedoCmd = &cobra.Command{
Short: "redo db schema migrations",
Long: "performs a redo schema migration command",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAndSetFlag(horizon.DatabaseURLFlagName); err != nil {
if err := requireAndSetFlags(horizon.DatabaseURLFlagName, horizon.IngestFlagName); err != nil {
return err
}

Expand All @@ -143,7 +162,7 @@ var dbMigrateStatusCmd = &cobra.Command{
Short: "print current database migration status",
Long: "print current database migration status",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAndSetFlag(horizon.DatabaseURLFlagName); err != nil {
if err := requireAndSetFlags(horizon.DatabaseURLFlagName); err != nil {
return err
}

Expand Down Expand Up @@ -173,7 +192,7 @@ var dbMigrateUpCmd = &cobra.Command{
Short: "run upwards db schema migrations",
Long: "performs an upwards schema migration command",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAndSetFlag(horizon.DatabaseURLFlagName); err != nil {
if err := requireAndSetFlags(horizon.DatabaseURLFlagName, horizon.IngestFlagName); err != nil {
return err
}

Expand Down Expand Up @@ -453,7 +472,7 @@ var dbDetectGapsCmd = &cobra.Command{
Short: "detects ingestion gaps in Horizon's database",
Long: "detects ingestion gaps in Horizon's database and prints a list of reingest commands needed to fill the gaps",
RunE: func(cmd *cobra.Command, args []string) error {
if err := requireAndSetFlag(horizon.DatabaseURLFlagName); err != nil {
if err := requireAndSetFlags(horizon.DatabaseURLFlagName); err != nil {
return err
}

Expand Down
4 changes: 3 additions & 1 deletion services/horizon/internal/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
const (
// DatabaseURLFlagName is the command line flag for configuring the Horizon postgres URL
DatabaseURLFlagName = "db-url"
// IngestFlagName is the command line flag for enabling ingestion on the Horizon instance
IngestFlagName = "ingest"
// StellarCoreDBURLFlagName is the command line flag for configuring the postgres Stellar Core URL
StellarCoreDBURLFlagName = "stellar-core-db-url"
// StellarCoreURLFlagName is the command line flag for configuring the URL fore Stellar Core HTTP endpoint
Expand Down Expand Up @@ -456,7 +458,7 @@ func Flags() (*Config, support.ConfigOptions) {
Usage: "TLS private key file to use for securing connections to horizon",
},
&support.ConfigOption{
Name: "ingest",
Name: IngestFlagName,
ConfigKey: &config.Ingest,
OptType: types.Bool,
FlagDefault: true,
Expand Down
42 changes: 42 additions & 0 deletions services/horizon/internal/integration/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,48 @@ func command(horizonConfig horizon.Config, args ...string) []string {
}, args...)
}

func TestMigrateIngestIsTrueByDefault(t *testing.T) {
tt := assert.New(t)
// Create a fresh Horizon database
newDB := dbtest.Postgres(t)
freshHorizonPostgresURL := newDB.DSN

horizoncmd.RootCmd.SetArgs([]string{
// ingest is set to true by default
"--db-url", freshHorizonPostgresURL,
"db", "migrate", "up",
})
tt.NoError(horizoncmd.RootCmd.Execute())

dbConn, err := db.Open("postgres", freshHorizonPostgresURL)
tt.NoError(err)

status, err := schema.Status(dbConn.DB.DB)
tt.NoError(err)
tt.NotContains(status, "1_initial_schema.sql\t\t\t\t\t\tno")
}

func TestMigrateChecksIngestFlag(t *testing.T) {
tt := assert.New(t)
// Create a fresh Horizon database
newDB := dbtest.Postgres(t)
freshHorizonPostgresURL := newDB.DSN

horizoncmd.RootCmd.SetArgs([]string{
"--ingest=false",
"--db-url", freshHorizonPostgresURL,
"db", "migrate", "up",
})
tt.NoError(horizoncmd.RootCmd.Execute())

dbConn, err := db.Open("postgres", freshHorizonPostgresURL)
tt.NoError(err)

status, err := schema.Status(dbConn.DB.DB)
tt.NoError(err)
tt.Contains(status, "1_initial_schema.sql\t\t\t\t\t\tno")
}

func TestFillGaps(t *testing.T) {
itest, reachedLedger := initializeDBIntegrationTest(t)
tt := assert.New(t)
Expand Down