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

Add spanner emulator env var detection #574

Merged
merged 2 commits into from
May 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 6 additions & 2 deletions internal/datastore/spanner/migrations/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
const (
tableSchemaVersion = "schema_version"
colVersionNum = "version_num"
emulatorSettingKey = "SPANNER_EMULATOR_HOST"
)

// SpannerMigrationDriver can migrate a Cloud Spanner instance
Expand All @@ -26,10 +27,13 @@ type SpannerMigrationDriver struct {
}

// NewSpannerDriver returns a migration driver for the given Cloud Spanner instance
func NewSpannerDriver(database, credentialsFilePath string) (SpannerMigrationDriver, error) {
func NewSpannerDriver(database, credentialsFilePath, emulatorHost string) (SpannerMigrationDriver, error) {
ctx := context.Background()

log.Info().Str("spanner-emulator-host", os.Getenv("SPANNER_EMULATOR_HOST")).Msg("spanner emulator")
if len(emulatorHost) > 0 {
os.Setenv(emulatorSettingKey, emulatorHost)
}
log.Info().Str("spanner-emulator-host", os.Getenv(emulatorSettingKey)).Msg("spanner emulator")
log.Info().Str("credentials", credentialsFilePath).Str("db", database).Msg("connecting")
client, err := spanner.NewClient(ctx, database, option.WithCredentialsFile(credentialsFilePath))
if err != nil {
Expand Down
9 changes: 9 additions & 0 deletions internal/datastore/spanner/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type spannerOptions struct {
gcInterval time.Duration
maxRetries int
credentialsFilePath string
emulatorHost string
}

const (
Expand Down Expand Up @@ -135,3 +136,11 @@ func CredentialsFile(path string) Option {
so.credentialsFilePath = path
}
}

// EmulatorHost is the URI of a Spanner emulator to connect to for
// development and testing use
func EmulatorHost(uri string) Option {
return func(so *spannerOptions) {
so.emulatorHost = uri
}
}
6 changes: 5 additions & 1 deletion internal/datastore/spanner/spanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func NewSpannerDatastore(database string, opts ...Option) (datastore.Datastore,
return nil, fmt.Errorf(errUnableToInstantiate, err)
}

if len(config.emulatorHost) > 0 {
os.Setenv("SPANNER_EMULATOR_HOST", config.emulatorHost)
}

config.gcInterval = common.WithJitter(0.2, config.gcInterval)
log.Info().Float64("factor", 0.2).Msg("gc configured with jitter")
log.Info().Str("spanner-emulator-host", os.Getenv("SPANNER_EMULATOR_HOST")).Msg("spanner emulator")
Expand Down Expand Up @@ -104,7 +108,7 @@ func (sd spannerDatastore) IsReady(ctx context.Context) (bool, error) {
return false, fmt.Errorf("invalid head migration found for postgres: %w", err)
}

currentRevision, err := migrations.NewSpannerDriver(sd.client.DatabaseName(), sd.config.credentialsFilePath)
currentRevision, err := migrations.NewSpannerDriver(sd.client.DatabaseName(), sd.config.credentialsFilePath, sd.config.emulatorHost)
if err != nil {
return false, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/testserver/datastore/spanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (b *spannerTest) NewDatabase(t testing.TB) string {
func (b *spannerTest) NewDatastore(t testing.TB, initFunc InitFunc) datastore.Datastore {
db := b.NewDatabase(t)

migrationDriver, err := migrations.NewSpannerDriver(db, "")
migrationDriver, err := migrations.NewSpannerDriver(db, "", os.Getenv("SPANNER_EMULATOR_HOST"))
require.NoError(t, err)

err = migrations.SpannerMigrations.Run(migrationDriver, migrate.Head, migrate.LiveRun)
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ type Config struct {

// Spanner
SpannerCredentialsFile string
SpannerEmulatorHost string

// MySQL
TablePrefix string
Expand Down Expand Up @@ -113,6 +114,7 @@ func RegisterDatastoreFlags(cmd *cobra.Command, opts *Config) {
cmd.Flags().StringVar(&opts.OverlapStrategy, "datastore-tx-overlap-strategy", "static", `strategy to generate transaction overlap keys ("prefix", "static", "insecure") (cockroach driver only)`)
cmd.Flags().StringVar(&opts.OverlapKey, "datastore-tx-overlap-key", "key", "static key to touch when writing to ensure transactions overlap (only used if --datastore-tx-overlap-strategy=static is set; cockroach driver only)")
cmd.Flags().StringVar(&opts.SpannerCredentialsFile, "datastore-spanner-credentials", "", "path to service account key credentials file with access to the cloud spanner instance")
cmd.Flags().StringVar(&opts.SpannerEmulatorHost, "datastore-spanner-emulator-host", "", "URI of spanner emulator instance used for development and testing (e.g. localhost:9010)")
cmd.Flags().StringVar(&opts.TablePrefix, "datastore-mysql-table-prefix", "", "prefix to add to the name of all SpiceDB database tables")

cmd.Flags().DurationVar(&opts.LegacyFuzzing, "datastore-revision-fuzzing-duration", -1, "amount of time to advertize stale revisions")
Expand Down Expand Up @@ -251,6 +253,7 @@ func newSpannerDatastore(opts Config) (datastore.Datastore, error) {
spanner.GCWindow(opts.GCWindow),
spanner.CredentialsFile(opts.SpannerCredentialsFile),
spanner.WatchBufferLength(opts.WatchBufferLength),
spanner.EmulatorHost(opts.SpannerEmulatorHost),
)
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/cmd/datastore/zz_generated.options.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion pkg/cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func RegisterMigrateFlags(cmd *cobra.Command) {
cmd.Flags().String("datastore-engine", "memory", fmt.Sprintf(`type of datastore to initialize (%s)`, datastore.EngineOptions()))
cmd.Flags().String("datastore-conn-uri", "", `connection string used by remote datastores (e.g. "postgres://postgres:password@localhost:5432/spicedb")`)
cmd.Flags().String("datastore-spanner-credentials", "", "path to service account key credentials file with access to the cloud spanner instance")
cmd.Flags().String("datastore-spanner-emulator-host", "", "URI of spanner emulator instance used for development and testing (e.g. localhost:9010)")
cmd.Flags().String("datastore-mysql-table-prefix", "", "prefix to add to the name of all mysql database tables")
}

Expand Down Expand Up @@ -65,7 +66,11 @@ func migrateRun(cmd *cobra.Command, args []string) error {

credFile := cobrautil.MustGetStringExpanded(cmd, "datastore-spanner-credentials")
var err error
migrationDriver, err = spannermigrations.NewSpannerDriver(dbURL, credFile)
emulatorHost, err := cmd.Flags().GetString("datastore-spanner-emulator-host")
if err != nil {
log.Fatal().Err(err).Msg("unable to get spanner emulator host")
}
migrationDriver, err = spannermigrations.NewSpannerDriver(dbURL, credFile, emulatorHost)
if err != nil {
log.Fatal().Err(err).Msg("unable to create migration driver")
}
Expand Down