From 8ee12cdf808a7e4908de44d5aa7ed0b1192a560e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Misbach?= Date: Tue, 24 Sep 2024 12:40:25 +0200 Subject: [PATCH] [cmd] Enable db-manager CLI to support subcommands (#1122) --- Makefile | 2 +- build/deploy/schema-manager.libsonnet | 4 +- build/dev/haproxy_local_setup.sh | 4 +- build/dev/startup/rid_bootstrapper.sh | 2 +- build/dev/startup/scd_bootstrapper.sh | 2 +- cmds/core-service/README.md | 4 +- cmds/db-manager/main.go | 247 +---------------- cmds/db-manager/migration/migrate.go | 260 ++++++++++++++++++ .../dss/templates/schema-manager.yaml | 1 + go.mod | 5 +- go.sum | 8 + 11 files changed, 295 insertions(+), 244 deletions(-) create mode 100644 cmds/db-manager/migration/migrate.go diff --git a/Makefile b/Makefile index a26c8a6d2..178c6eafc 100644 --- a/Makefile +++ b/Makefile @@ -113,7 +113,7 @@ test-go-units: test-go-units-crdb: cleanup-test-go-units-crdb @docker run -d --name dss-crdb-for-testing -p 26257:26257 -p 8080:8080 cockroachdb/cockroach:v24.1.3 start-single-node --insecure > /dev/null @until [ -n "`docker logs dss-crdb-for-testing | grep 'nodeID'`" ]; do echo "Waiting for CRDB to be ready"; sleep 3; done; - go run ./cmds/db-manager/main.go --schemas_dir ./build/db_schemas/rid --db_version latest --cockroach_host localhost + go run ./cmds/db-manager/main.go migrate --schemas_dir ./build/db_schemas/rid --db_version latest --cockroach_host localhost go test -count=1 -v ./pkg/rid/store/cockroach --cockroach_host localhost --cockroach_port 26257 --cockroach_ssl_mode disable --cockroach_user root --cockroach_db_name rid go test -count=1 -v ./pkg/rid/application --cockroach_host localhost --cockroach_port 26257 --cockroach_ssl_mode disable --cockroach_user root --cockroach_db_name rid @docker stop dss-crdb-for-testing > /dev/null diff --git a/build/deploy/schema-manager.libsonnet b/build/deploy/schema-manager.libsonnet index c23ea6dbb..65c88e0bc 100644 --- a/build/deploy/schema-manager.libsonnet +++ b/build/deploy/schema-manager.libsonnet @@ -16,7 +16,7 @@ local schema_dir = '/db-schemas'; }, soloContainer:: base.Container('rid-schema-manager') { image: metadata.schema_manager.image, - command: ['db-manager'], + command: ['db-manager', 'migrate'], args_:: { cockroach_host: 'cockroachdb-balanced.' + metadata.namespace, cockroach_port: metadata.cockroach.grpc_port, @@ -42,7 +42,7 @@ local schema_dir = '/db-schemas'; }, soloContainer:: base.Container('scd-schema-manager') { image: metadata.schema_manager.image, - command: ['db-manager'], + command: ['db-manager', 'migrate'], args_:: { cockroach_host: 'cockroachdb-balanced.' + metadata.namespace, cockroach_port: metadata.cockroach.grpc_port, diff --git a/build/dev/haproxy_local_setup.sh b/build/dev/haproxy_local_setup.sh index 1620b62c6..85c1a4c70 100644 --- a/build/dev/haproxy_local_setup.sh +++ b/build/dev/haproxy_local_setup.sh @@ -128,7 +128,7 @@ docker run --rm --name rid-db-manager \ --link dss-crdb-cluster-for-testing:crdb \ --network dss_sandbox-default \ local-interuss-dss-image \ - /usr/bin/db-manager \ + /usr/bin/db-manager migrate \ --schemas_dir db-schemas/rid \ --db_version "latest" \ --cockroach_host crdb @@ -139,7 +139,7 @@ docker run --rm --name scd-db-manager \ --link dss-crdb-cluster-for-testing:crdb \ --network dss_sandbox-default \ local-interuss-dss-image \ - /usr/bin/db-manager \ + /usr/bin/db-manager migrate \ --schemas_dir db-schemas/scd \ --db_version "latest" \ --cockroach_host crdb diff --git a/build/dev/startup/rid_bootstrapper.sh b/build/dev/startup/rid_bootstrapper.sh index 500b1e940..f57dda68f 100755 --- a/build/dev/startup/rid_bootstrapper.sh +++ b/build/dev/startup/rid_bootstrapper.sh @@ -11,7 +11,7 @@ else sleep 3 echo "Bootstrapping RID DB..." - /usr/bin/db-manager \ + /usr/bin/db-manager migrate \ --schemas_dir /db-schemas/rid \ --db_version "latest" \ --cockroach_host local-dss-crdb diff --git a/build/dev/startup/scd_bootstrapper.sh b/build/dev/startup/scd_bootstrapper.sh index 8dc494499..187198dbf 100755 --- a/build/dev/startup/scd_bootstrapper.sh +++ b/build/dev/startup/scd_bootstrapper.sh @@ -11,7 +11,7 @@ else sleep 3 echo "Bootstrapping SCD DB..." - /usr/bin/db-manager \ + /usr/bin/db-manager migrate \ --schemas_dir /db-schemas/scd \ --db_version "latest" \ --cockroach_host local-dss-crdb diff --git a/cmds/core-service/README.md b/cmds/core-service/README.md index bf58c629e..c5203050f 100644 --- a/cmds/core-service/README.md +++ b/cmds/core-service/README.md @@ -40,11 +40,11 @@ docker container run -p 26257:26257 -p 8080:8080 --rm cockroachdb/cockroach:v24. Once an initialized CockroachDB cluster is available, the necessary databases within the CRDB cluster must be created/configured properly. This can be accomplished with [migrate_local_db.sh](../../build/dev/migrate_local_db.sh), as documented in the [standalone instance documentation](../../build/dev/standalone_instance.md), when using the standard standalone development DSS instance, or it can be accomplished manually with commands similar to those below starting from the repo root folder: ```bash -go run ./cmds/db-manager \ +go run ./cmds/db-manager migrate \ --schemas_dir ./build/db_schemas/rid \ --db_version latest \ --cockroach_host localhost -go run ./cmds/db-manager \ +go run ./cmds/db-manager migrate \ --schemas_dir ./build/db_schemas/scd \ --db_version latest \ --cockroach_host localhost diff --git a/cmds/db-manager/main.go b/cmds/db-manager/main.go index d74806d8e..37052232f 100644 --- a/cmds/db-manager/main.go +++ b/cmds/db-manager/main.go @@ -1,250 +1,29 @@ -// Script for Database bootstrap deployment and migration - package main import ( - "context" "flag" - "fmt" "log" "os" - "path/filepath" - "regexp" - "strings" - - "github.com/coreos/go-semver/semver" - "github.com/interuss/dss/pkg/cockroach" - "github.com/interuss/dss/pkg/cockroach/flags" - "github.com/interuss/stacktrace" -) -type MigrationStep struct { - version semver.Version - upToFile string - downFromFile string -} - -var ( - // Pattern to match files describing migration steps - migrationStepRegexp = "(upto|downfrom)-v(\\d+\\.\\d+\\.\\d+)-(.*)\\.sql" + "github.com/interuss/dss/cmds/db-manager/migration" + "github.com/spf13/cobra" ) var ( - path = flag.String("schemas_dir", "", "path to db migration files directory. the migrations found there will be applied to the database whose name matches the folder name.") - dbVersion = flag.String("db_version", "", "the db version to migrate to (ex: 1.0.0) or use \"latest\" to automatically upgrade to the latest version or leave blank to print the current version") -) - -func main() { - // Read and validate schemas_dir input - flag.Parse() - if *path == "" { - log.Panic("Must specify schemas_dir path") - } - dbName := filepath.Base(*path) - - // Enumerate schema versions - steps, err := enumerateMigrationSteps(path) - if err != nil { - log.Panicf("Failed to read schema version migration definitions: %v", err) - } - if len(steps) == 0 { - log.Panicf("No migration definitions found in schemas_dir=%s", *path) - } - - // Determine target version - var targetVersion *semver.Version - if strings.ToLower(*dbVersion) == "latest" { - targetVersion = &steps[len(steps)-1].version - } else if strings.TrimSpace(*dbVersion) == "" { - // User just wants to print the current version - targetVersion = nil - } else { - targetVersion, err = semver.NewVersion(*dbVersion) - if err != nil { - log.Panicf("Failed to parse desired db_version: %v", err) - } - } - - // Connect to database server - connectParameters := flags.ConnectParameters() - connectParameters.ApplicationName = "db-manager" - connectParameters.DBName = "postgres" // Use an initial database that is known to always be present - crdb, err := cockroach.Dial(context.Background(), connectParameters) - if err != nil { - log.Panicf("Failed to connect to database with %+v: %v", connectParameters, err) - } - defer func() { - crdb.Pool.Close() - }() - - crdbVersion, err := crdb.GetServerVersion() - if err != nil { - log.Panicf("Unable to retrieve the version of the server %s:%d: %v", connectParameters.Host, connectParameters.Port, err) - } - log.Printf("CRDB server version: %s", crdbVersion) - - // Make sure specified database exists - exists, err := doesDatabaseExist(crdb, dbName) - if err != nil { - log.Panicf("Failed to check whether database %s exists: %v", dbName, err) - } - if !exists && dbName == "rid" { - // In the special case of rid, the database was previously named defaultdb - log.Printf("Database %s does not exist; checking for older \"defaultdb\" database", dbName) - dbName = "defaultdb" - exists, err = doesDatabaseExist(crdb, dbName) - if err != nil { - log.Panicf("Failed to check whether old defaultdb database exists: %v", err) - } - } - if !exists { - log.Printf("Database %s does not exist; creating now", dbName) - createDB := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName) - if _, err := crdb.Pool.Exec(context.Background(), createDB); err != nil { - log.Panicf("Failed to create new database %s: %v", dbName, err) - } - } else { - log.Printf("Database %s already exists; reading current state", dbName) - } - - // Read current schema version of database - currentVersion, err := crdb.GetVersion(context.Background(), dbName) - if err != nil { - log.Panicf("Failed to get current database version for %s: %v", dbName, err) - } - log.Printf("Initial %s database schema version is %v, target is %v", dbName, currentVersion, targetVersion) - if targetVersion == nil { - return - } - - // Compute index of current version - var currentStepIndex int = -1 - for i, version := range steps { - if version.version == *currentVersion { - currentStepIndex = i - } - } - - // Perform migration steps until current version matches target version - for !currentVersion.Equal(*targetVersion) { - // Compute which migration step to run next and how it will change the schema version - var newCurrentStepIndex int - var sqlFile string - var newVersion *semver.Version - if currentVersion.LessThan(*targetVersion) { - // Migrate up to next version - sqlFile = steps[currentStepIndex+1].upToFile - newVersion = &steps[currentStepIndex+1].version - newCurrentStepIndex = currentStepIndex + 1 - } else { - // Migrate down from current version - sqlFile = steps[currentStepIndex].downFromFile - newCurrentStepIndex = currentStepIndex - 1 - newVersion = &steps[newCurrentStepIndex].version - } - log.Printf("Running %s to migrate %v to %v", sqlFile, currentVersion, newVersion) - - // Read migration SQL into string - fullFilePath := filepath.Join(*path, sqlFile) - rawMigrationSQL, err := os.ReadFile(fullFilePath) - if err != nil { - log.Panicf("Failed to load SQL content from %s: %v", fullFilePath, err) - } - - // Ensure SQL session has implicit transactions disabled for CRDB versions 22.2+ - sessionConfigurationSQL := "" - if crdbVersion.Compare(*semver.New("22.2.0")) >= 0 { - sessionConfigurationSQL = "SET enable_implicit_transaction_for_batch_statements = false;\n" - } - - migrationSQL := sessionConfigurationSQL + fmt.Sprintf("USE %s;\n", dbName) + string(rawMigrationSQL) - - // Execute migration step - if _, err := crdb.Pool.Exec(context.Background(), migrationSQL); err != nil { - log.Panicf("Failed to execute %s migration step %s: %v", dbName, fullFilePath, err) - } - - // Update current state - if dbName == "defaultdb" && newVersion.String() == "4.0.0" && newCurrentStepIndex > currentStepIndex { - // RID database changes from `defaultdb` to `rid` when moving up to 4.0.0 - dbName = "rid" - } - if dbName == "rid" && currentVersion.String() == "4.0.0" && newCurrentStepIndex < currentStepIndex { - // RID database changes from `rid` to `defaultdb` when moving down from 4.0.0 - dbName = "defaultdb" - } - actualVersion, err := crdb.GetVersion(context.Background(), dbName) - if err != nil { - log.Panicf("Failed to get current database version for %s: %v", dbName, err) - } - if !actualVersion.Equal(*newVersion) { - log.Panicf("Migration %s should have migrated %s schema version %v to %v, but instead resulted in %v", fullFilePath, dbName, currentVersion, newVersion, currentVersion) - } - currentVersion = actualVersion - currentStepIndex = newCurrentStepIndex - } - - log.Printf("Final %s version: %v", dbName, currentVersion) -} - -func enumerateMigrationSteps(path *string) ([]MigrationStep, error) { - steps := make(map[semver.Version]MigrationStep) - - // Identify files defining version migration steps - files, err := os.ReadDir(*path) - if err != nil { - return make([]MigrationStep, 0), stacktrace.Propagate(err, "Failed to read schema files directory") - } - r := regexp.MustCompile(migrationStepRegexp) - for _, file := range files { - if !file.IsDir() { - match := r.FindStringSubmatch(file.Name()) - if len(match) > 0 { - v := *semver.New(match[2]) - step := steps[v] - step.version = v - if match[1] == "upto" { - step.upToFile = file.Name() - } else if match[1] == "downfrom" { - step.downFromFile = file.Name() - } else { - return make([]MigrationStep, 0), fmt.Errorf("Unexpected migration step prefix: %s", match[1]) - } - steps[v] = step - } - } - } - - // Sort versions in ascending order - versions := make([]*semver.Version, len(steps)) - i := 0 - for k := range steps { - v := steps[k].version - versions[i] = &v - i++ - } - semver.Sort(versions) - - // Render sorted step list - result := make([]MigrationStep, len(versions)+1) - result[0].version = *semver.New("0.0.0") - for i := 0; i < len(versions); i++ { - result[i+1] = steps[*versions[i]] + DBManagerCmd = &cobra.Command{ + Use: "db-manager", + Short: "DSS database management utility", } +) - return result, nil +func init() { + DBManagerCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) // enable support for flags not yet migrated to using pflag (e.g. crdb flags) + DBManagerCmd.AddCommand(migration.MigrationCmd) } -func doesDatabaseExist(crdb *cockroach.DB, database string) (bool, error) { - const checkDbQuery = ` - SELECT EXISTS ( - SELECT * FROM pg_database WHERE datname = $1 - )` - - var exists bool - if err := crdb.Pool.QueryRow(context.Background(), checkDbQuery, database).Scan(&exists); err != nil { - return false, err +func main() { + if err := DBManagerCmd.Execute(); err != nil { + log.Printf("failed to execute db-manager: %v", err) + os.Exit(1) } - - return exists, nil } diff --git a/cmds/db-manager/migration/migrate.go b/cmds/db-manager/migration/migrate.go new file mode 100644 index 000000000..56a86cf50 --- /dev/null +++ b/cmds/db-manager/migration/migrate.go @@ -0,0 +1,260 @@ +package migration + +import ( + "fmt" + "log" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/coreos/go-semver/semver" + "github.com/interuss/dss/pkg/cockroach" + crdbflags "github.com/interuss/dss/pkg/cockroach/flags" + + "github.com/interuss/stacktrace" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "golang.org/x/net/context" +) + +type MigrationStep struct { + version semver.Version + upToFile string + downFromFile string +} + +var ( + // Pattern to match files describing migration steps + migrationStepRegexp = "(upto|downfrom)-v(\\d+\\.\\d+\\.\\d+)-(.*)\\.sql" +) + +var ( + MigrationCmd = &cobra.Command{ + Use: "migrate", + Short: "Database bootstrap deployment and migration", + RunE: migrate, + } + flags = pflag.NewFlagSet("migrate", pflag.ExitOnError) + path = flags.String("schemas_dir", "", "path to db migration files directory. the migrations found there will be applied to the database whose name matches the folder name.") + dbVersion = flags.String("db_version", "", "the db version to migrate to (ex: 1.0.0) or use \"latest\" to automatically upgrade to the latest version or leave blank to print the current version") +) + +func init() { + MigrationCmd.Flags().AddFlagSet(flags) + _ = MigrationCmd.MarkFlagRequired("schemas_dir") +} + +func migrate(cmd *cobra.Command, _ []string) error { + var ( + ctx = cmd.Context() + dbName = filepath.Base(*path) + ) + + // Enumerate schema versions + steps, err := enumerateMigrationSteps(path) + if err != nil { + return fmt.Errorf("failed to read schema version migration definitions: %w", err) + } + if len(steps) == 0 { + return fmt.Errorf("no migration definitions found in schemas_dir=%s", *path) + } + + // Determine target version + var targetVersion *semver.Version + if strings.ToLower(*dbVersion) == "latest" { + targetVersion = &steps[len(steps)-1].version + } else if strings.TrimSpace(*dbVersion) == "" { + // User just wants to print the current version + targetVersion = nil + } else { + targetVersion, err = semver.NewVersion(*dbVersion) + if err != nil { + return fmt.Errorf("failed to parse desired db_version: %w", err) + } + } + + // Connect to database server + connectParameters := crdbflags.ConnectParameters() + connectParameters.ApplicationName = "db-manager" + connectParameters.DBName = "postgres" // Use an initial database that is known to always be present + crdb, err := cockroach.Dial(ctx, connectParameters) + if err != nil { + return fmt.Errorf("failed to connect to database with %+v: %w", connectParameters, err) + } + defer func() { + crdb.Pool.Close() + }() + + crdbVersion, err := crdb.GetServerVersion() + if err != nil { + return fmt.Errorf("unable to retrieve the version of the server %s:%d: %w", connectParameters.Host, connectParameters.Port, err) + } + log.Printf("CRDB server version: %s", crdbVersion) + + // Make sure specified database exists + exists, err := doesDatabaseExist(ctx, crdb, dbName) + if err != nil { + return fmt.Errorf("failed to check whether database %s exists: %w", dbName, err) + } + if !exists && dbName == "rid" { + // In the special case of rid, the database was previously named defaultdb + log.Printf("Database %s does not exist; checking for older \"defaultdb\" database", dbName) + dbName = "defaultdb" + exists, err = doesDatabaseExist(ctx, crdb, dbName) + if err != nil { + return fmt.Errorf("failed to check whether old defaultdb database exists: %w", err) + } + } + if !exists { + log.Printf("Database %s does not exist; creating now", dbName) + createDB := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName) + if _, err := crdb.Pool.Exec(ctx, createDB); err != nil { + return fmt.Errorf("failed to create new database %s: %v", dbName, err) + } + } else { + log.Printf("Database %s already exists; reading current state", dbName) + } + + // Read current schema version of database + currentVersion, err := crdb.GetVersion(ctx, dbName) + if err != nil { + return fmt.Errorf("failed to get current database version for %s: %w", dbName, err) + } + log.Printf("Initial %s database schema version is %v, target is %v", dbName, currentVersion, targetVersion) + if targetVersion == nil { + return nil + } + + // Compute index of current version + var currentStepIndex int = -1 + for i, version := range steps { + if version.version == *currentVersion { + currentStepIndex = i + } + } + + // Perform migration steps until current version matches target version + for !currentVersion.Equal(*targetVersion) { + // Compute which migration step to run next and how it will change the schema version + var newCurrentStepIndex int + var sqlFile string + var newVersion *semver.Version + if currentVersion.LessThan(*targetVersion) { + // Migrate up to next version + sqlFile = steps[currentStepIndex+1].upToFile + newVersion = &steps[currentStepIndex+1].version + newCurrentStepIndex = currentStepIndex + 1 + } else { + // Migrate down from current version + sqlFile = steps[currentStepIndex].downFromFile + newCurrentStepIndex = currentStepIndex - 1 + newVersion = &steps[newCurrentStepIndex].version + } + log.Printf("Running %s to migrate %v to %v", sqlFile, currentVersion, newVersion) + + // Read migration SQL into string + fullFilePath := filepath.Join(*path, sqlFile) + rawMigrationSQL, err := os.ReadFile(fullFilePath) + if err != nil { + return fmt.Errorf("failed to load SQL content from %s: %e", fullFilePath, err) + } + + // Ensure SQL session has implicit transactions disabled for CRDB versions 22.2+ + sessionConfigurationSQL := "" + if crdbVersion.Compare(*semver.New("22.2.0")) >= 0 { + sessionConfigurationSQL = "SET enable_implicit_transaction_for_batch_statements = false;\n" + } + + migrationSQL := sessionConfigurationSQL + fmt.Sprintf("USE %s;\n", dbName) + string(rawMigrationSQL) + + // Execute migration step + if _, err := crdb.Pool.Exec(ctx, migrationSQL); err != nil { + return fmt.Errorf("failed to execute %s migration step %s: %w", dbName, fullFilePath, err) + } + + // Update current state + if dbName == "defaultdb" && newVersion.String() == "4.0.0" && newCurrentStepIndex > currentStepIndex { + // RID database changes from `defaultdb` to `rid` when moving up to 4.0.0 + dbName = "rid" + } + if dbName == "rid" && currentVersion.String() == "4.0.0" && newCurrentStepIndex < currentStepIndex { + // RID database changes from `rid` to `defaultdb` when moving down from 4.0.0 + dbName = "defaultdb" + } + actualVersion, err := crdb.GetVersion(ctx, dbName) + if err != nil { + return fmt.Errorf("failed to get current database version for %s: %w", dbName, err) + } + if !actualVersion.Equal(*newVersion) { + return fmt.Errorf("migration %s should have migrated %s schema version %v to %v, but instead resulted in %v", fullFilePath, dbName, currentVersion, newVersion, currentVersion) + } + currentVersion = actualVersion + currentStepIndex = newCurrentStepIndex + } + + log.Printf("Final %s version: %v", dbName, currentVersion) + return nil +} + +func enumerateMigrationSteps(path *string) ([]MigrationStep, error) { + steps := make(map[semver.Version]MigrationStep) + + // Identify files defining version migration steps + files, err := os.ReadDir(*path) + if err != nil { + return make([]MigrationStep, 0), stacktrace.Propagate(err, "Failed to read schema files directory") + } + r := regexp.MustCompile(migrationStepRegexp) + for _, file := range files { + if !file.IsDir() { + match := r.FindStringSubmatch(file.Name()) + if len(match) > 0 { + v := *semver.New(match[2]) + step := steps[v] + step.version = v + if match[1] == "upto" { + step.upToFile = file.Name() + } else if match[1] == "downfrom" { + step.downFromFile = file.Name() + } else { + return make([]MigrationStep, 0), fmt.Errorf("Unexpected migration step prefix: %s", match[1]) + } + steps[v] = step + } + } + } + + // Sort versions in ascending order + versions := make([]*semver.Version, len(steps)) + i := 0 + for k := range steps { + v := steps[k].version + versions[i] = &v + i++ + } + semver.Sort(versions) + + // Render sorted step list + result := make([]MigrationStep, len(versions)+1) + result[0].version = *semver.New("0.0.0") + for i := 0; i < len(versions); i++ { + result[i+1] = steps[*versions[i]] + } + + return result, nil +} + +func doesDatabaseExist(ctx context.Context, crdb *cockroach.DB, database string) (bool, error) { + const checkDbQuery = ` + SELECT EXISTS ( + SELECT * FROM pg_database WHERE datname = $1 + )` + + var exists bool + if err := crdb.Pool.QueryRow(ctx, checkDbQuery, database).Scan(&exists); err != nil { + return false, err + } + + return exists, nil +} diff --git a/deploy/services/helm-charts/dss/templates/schema-manager.yaml b/deploy/services/helm-charts/dss/templates/schema-manager.yaml index 2edd5d880..e857c6185 100644 --- a/deploy/services/helm-charts/dss/templates/schema-manager.yaml +++ b/deploy/services/helm-charts/dss/templates/schema-manager.yaml @@ -36,6 +36,7 @@ spec: - --schemas_dir=/db-schemas/{{$service}} command: - db-manager + - migrate image: {{$image}} imagePullPolicy: IfNotPresent name: {{$service}}-schema-manager-{{$jobVersion}} diff --git a/go.mod b/go.mod index 6de06f97e..c20559ef9 100644 --- a/go.mod +++ b/go.mod @@ -15,8 +15,11 @@ require ( github.com/jonboulle/clockwork v0.3.0 github.com/pkg/errors v0.9.1 github.com/robfig/cron/v3 v3.0.1 + github.com/spf13/cobra v1.8.1 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 + golang.org/x/net v0.23.0 ) require ( @@ -31,6 +34,7 @@ require ( github.com/google/s2a-go v0.1.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.4 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect @@ -40,7 +44,6 @@ require ( go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/crypto v0.22.0 // indirect - golang.org/x/net v0.23.0 // indirect golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index 8c0dadb2b..cb034b8b5 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,7 @@ github.com/cockroachdb/cockroach-go/v2 v2.3.8 h1:53yoUo4+EtrC1NrAEgnnad4AS3ntNvG github.com/cockroachdb/cockroach-go/v2 v2.3.8/go.mod h1:9uH5jK4yQ3ZQUT9IXe4I2fHzMIF5+JC/oOdzTRgJYJk= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -89,6 +90,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5 github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/interuss/stacktrace v1.0.0 h1:AzxZ27CK6YRbxyDE3j23O27i2VEPStrMJRBafoznP7U= github.com/interuss/stacktrace v1.0.0/go.mod h1:WwNxCSINli7iw/AvwTCnlvC664Db+oItGERbj3XNFTg= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= @@ -117,6 +120,11 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=