Skip to content

Commit dc97104

Browse files
authored
Merge pull request #2102 from dolthub/zachmu/default-db
Set the default DB from the `DOLTGRES_DB` user var
2 parents 3902eda + ef8c746 commit dc97104

5 files changed

Lines changed: 90 additions & 55 deletions

File tree

docker-entrypoint.sh

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -272,19 +272,6 @@ docker_process_init_files() {
272272
done
273273
}
274274

275-
# create_database_from_env creates a database if the DATABASE environment variable is set.
276-
# It retrieves the database name from environment the env var DATABASE
277-
# and attempts to create the database using exec_sql.
278-
create_database_from_env() {
279-
local database
280-
database=$(get_env_var "DB")
281-
282-
if [ -n "$database" ]; then
283-
note "Creating database '${database}'"
284-
exec_sql "Failed to create database '$database': " "CREATE DATABASE IF NOT EXISTS \"$database\";"
285-
fi
286-
}
287-
288275
# is_port_open checks if a TCP port is open on a given host.
289276
# Arguments:
290277
# $1 - Host (IP or hostname)
@@ -310,12 +297,14 @@ start_server() {
310297
local start_time
311298
start_time=$(date +%s)
312299

313-
# If either of the doltgres or postgres specific user and password env vars are set, export them
300+
# If any of the doltgres or postgres specific user, password, and DB env vars are set, export them
314301
# to the ones that doltgres understands so they can be used during initialization.
315302
user=$(get_env_var "USER")
316303
password=$(get_env_var "PASSWORD")
304+
db=$(get_env_var "DB")
317305
export DOLTGRES_USER=$user
318306
export DOLTGRES_PASSWORD=$password
307+
export DOLTGRES_DB=$db
319308

320309
SERVER_PID=-1
321310

@@ -419,8 +408,6 @@ _main() {
419408

420409
start_server "$@"
421410

422-
create_database_from_env
423-
424411
if [[ ! -f $INIT_COMPLETED ]]; then
425412
if ls /docker-entrypoint-initdb.d/* >/dev/null 2>&1; then
426413
docker_process_init_files /docker-entrypoint-initdb.d/*

server/auth/init.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ func Init(dEnv *env.DoltEnv) {
3737

3838
// GetSuperUserAndPassword returns the superuser and password for the server to use, as defined in the environment
3939
func GetSuperUserAndPassword() (string, string) {
40-
password := "password"
41-
if envPassword := os.Getenv(doltgresPasswordEnvVar); envPassword != "" {
42-
password = envPassword
43-
}
44-
4540
user := "postgres"
4641
if envUser := os.Getenv(doltgresUserEnvVar); envUser != "" {
4742
user = envUser
4843
}
4944

45+
password := "password"
46+
if envPassword := os.Getenv(doltgresPasswordEnvVar); envPassword != "" {
47+
password = envPassword
48+
}
49+
5050
return user, password
5151
}

server/server.go

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"context"
1919
"fmt"
2020
_ "net/http/pprof"
21+
"os"
2122
"path/filepath"
2223

2324
"github.com/cockroachdb/errors"
@@ -49,9 +50,10 @@ import (
4950
const (
5051
Version = "0.54.4"
5152

52-
DefUserName = "postres"
53-
DefUserEmail = "postgres@somewhere.com"
54-
DoltgresDir = "postgres"
53+
DefUserName = "postres"
54+
DefUserEmail = "postgres@somewhere.com"
55+
DefUserEmailFmt = "%s@somewhere.com"
56+
DefaultDbNameEnvVar = "DOLTGRES_DB"
5557
)
5658

5759
func init() {
@@ -121,9 +123,10 @@ func runServer(ctx context.Context, cfg *servercfg.DoltgresConfig, dEnv *env.Dol
121123
}
122124

123125
// We need a username and password for many SQL commands, so set defaults if they don't exist
126+
user, _ := auth.GetSuperUserAndPassword()
124127
dEnv.Config.SetFailsafes(map[string]string{
125-
config.UserNameKey: DefUserName,
126-
config.UserEmailKey: DefUserEmail,
128+
config.UserNameKey: user,
129+
config.UserEmailKey: fmt.Sprintf(DefUserEmailFmt, user),
127130
})
128131

129132
// Reload the dolt environment with the correct data dir that was specified in the configuration.
@@ -134,19 +137,16 @@ func runServer(ctx context.Context, cfg *servercfg.DoltgresConfig, dEnv *env.Dol
134137
}
135138
dEnv = env.Load(ctx, dEnv.GetUserHomeDir, dataDirFs, doltdb.LocalDirDoltDB, dEnv.Version)
136139

137-
// Automatically initialize a doltgres database if necessary
138-
// TODO: probably should only do this if there are no databases in the data dir already
139-
createDoltgresDatabase := false
140-
if exists, isDirectory := dataDirFs.Exists(DoltgresDir); !exists {
141-
createDoltgresDatabase = true
142-
} else if !isDirectory {
143-
workingDir, _ := dataDirFs.Abs(".")
144-
// The else branch means that there's a Doltgres item, so we need to error if it's a file since we
145-
// enforce the creation of a Doltgres database/directory, which would create a name conflict with the file
146-
return nil, errors.Errorf("Attempted to create the default `postgres` database at `%s`, but a file with "+
147-
"the same name was found. Either remove the file, change the directory using the `--data-dir` argument, "+
148-
"or change the environment variable `%s` so that it points to a different directory.", workingDir, servercfg.DOLTGRES_DATA_DIR)
140+
// Determine whether we need to initialize the default database
141+
initializeDefaultDatabase := true
142+
mrEnv, err := env.MultiEnvForDirectory(ctx, dEnv.Config.WriteableConfig(), dataDirFs, Version, dEnv)
143+
if err != nil {
144+
return nil, err
149145
}
146+
mrEnv.Iter(func(_ string, _ *env.DoltEnv) (stop bool, err error) {
147+
initializeDefaultDatabase = false
148+
return true, nil
149+
})
150150

151151
controller := svcs.NewController()
152152
newCtx, cancelF := context.WithCancel(ctx)
@@ -178,8 +178,8 @@ func runServer(ctx context.Context, cfg *servercfg.DoltgresConfig, dEnv *env.Dol
178178
return nil, err
179179
}
180180

181-
if createDoltgresDatabase {
182-
err = createDatabase(ssCfg, "postgres")
181+
if initializeDefaultDatabase {
182+
err = createDefaultDatabase(ssCfg)
183183
if err != nil {
184184
return nil, err
185185
}
@@ -194,10 +194,11 @@ func runServer(ctx context.Context, cfg *servercfg.DoltgresConfig, dEnv *env.Dol
194194
return controller, nil
195195
}
196196

197-
// createDatabase creates the database named on the local server using the configuration values to connect, returning
197+
// createDefaultDatabase creates the database named on the local server using the configuration values to connect, returning
198198
// any error
199-
func createDatabase(cfg doltservercfg.ServerConfig, dbName string) error {
199+
func createDefaultDatabase(cfg doltservercfg.ServerConfig) error {
200200
user, password := auth.GetSuperUserAndPassword()
201+
dbName := getDefaultDatabaseName(user)
201202

202203
dsn := fmt.Sprintf("postgres://%s:%s@localhost:%d", user, password, cfg.Port())
203204

@@ -213,6 +214,17 @@ func createDatabase(cfg doltservercfg.ServerConfig, dbName string) error {
213214
return err
214215
}
215216

217+
// getDefaultDatabaseName returns the name of the default database to create on first server start.
218+
// If the environment variable DOLTGRES_DB is set, that value is used. Otherwise, the username is used.
219+
// The username is in turn configured with the environment variable DOLTGRES_USER, defaulting to "postgres".
220+
func getDefaultDatabaseName(userName string) string {
221+
defaultDbName := os.Getenv(DefaultDbNameEnvVar)
222+
if defaultDbName != "" {
223+
return defaultDbName
224+
}
225+
return userName
226+
}
227+
216228
// startReplication begins the background thread that replicates from Postgres, if one is configured.
217229
func startReplication(cfg *servercfg.DoltgresConfig, ssCfg doltservercfg.ServerConfig) (*logrepl.LogicalReplicator, error) {
218230
if cfg.PostgresReplicationConfig == nil {

testing/bats/doltgres.bats

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -354,25 +354,44 @@ EOF
354354

355355
[ ! -d "auth.db" ]
356356

357-
start_sql_server postgres log.txt myuser mypass
357+
start_sql_server "" log.txt myuser mypass
358358
cat log.txt
359359

360-
query_server_for_user_and_pass myuser mypass -c "create table myTable (a int);"
360+
# db matches user name since DOLTGRES_DB was not set
361+
query_server_for_user_and_pass myuser mypass myuser -c "create table myTable (a int);"
361362

362-
run query_server_for_user_and_pass myuser mypass -c "insert into mytable values (1), (2)"
363+
run query_server_for_user_and_pass myuser mypass myuser -c "insert into mytable values (1), (2)"
363364
[ "$status" -eq 0 ]
364365
[[ "$output" =~ "INSERT" ]] || false
365366

366-
run query_server_for_user_and_pass postgres password -c "insert into mytable values (1), (2)"
367+
run query_server_for_user_and_pass postgres password myuser -c "insert into mytable values (1), (2)"
368+
[ "$status" -ne 0 ]
369+
}
370+
371+
@test 'doltgres: default db via env' {
372+
[ ! -d "auth.db" ]
373+
374+
start_sql_server mydb log.txt myuser
375+
cat log.txt
376+
377+
query_server_for_user_and_pass myuser password mydb -c "create table myTable (a int);"
378+
379+
run query_server_for_user_and_pass myuser password mydb -c "insert into mytable values (1), (2)"
380+
[ "$status" -eq 0 ]
381+
[[ "$output" =~ "INSERT" ]] || false
382+
383+
run query_server_for_user_and_pass postgres password mydb -c "insert into mytable values (1), (2)"
367384
[ "$status" -ne 0 ]
368385
}
369386

370387
query_server_for_user_and_pass() {
371388
user=$1
372389
pass=$2
390+
db=$3
391+
shift
373392
shift
374393
shift
375394

376395
nativevar PGPASSWORD "$pass" /w
377-
psql -U "$user" -h localhost -p $PORT "$@" postgres
396+
psql -U "$user" -h localhost -p $PORT "$@" $db
378397
}

testing/bats/setup/query-server-common.bash

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ wait_for_connection() {
1919
nativevar PGPASSWORD "$PASSWORD" /w
2020

2121
while [ $SECONDS -lt $end_time ]; do
22-
run psql -U $USERNAME -h localhost -p $port -c "SELECT 1;" postgres
22+
run psql -U $USERNAME -h localhost -p $port -c "SELECT 1;" $DEFAULT_DB
2323
if [ $status -eq 0 ]; then
2424
echo "Connected successfully!"
2525
return 0
26+
else
27+
echo "$output"
2628
fi
2729
sleep 1
2830
done
@@ -33,17 +35,32 @@ wait_for_connection() {
3335

3436
start_sql_server() {
3537
DEFAULT_DB="$1"
36-
DEFAULT_DB="${DEFAULT_DB:=postgres}"
3738
logFile=$2
3839
USERNAME=$3
39-
USERNAME="${USERNAME:=postgres}"
4040
PASSWORD=$4
41-
PASSWORD="${PASSWORD:=password}"
4241

43-
nativevar DEFAULT_DB "$DEFAULT_DB" /w
44-
nativevar PGPASSWORD "$PASSWORD" /w
45-
nativevar DOLTGRES_PASSWORD "$PASSWORD" /w
46-
nativevar DOLTGRES_USER "$USERNAME" /w
42+
if [ -n "$DEFAULT_DB" ]; then
43+
nativevar DOLTGRES_DB "$DEFAULT_DB" /w
44+
fi
45+
46+
if [ -n "$PASSWORD" ]; then
47+
nativevar PGPASSWORD "password" /w
48+
nativevar DOLTGRES_PASSWORD "$PASSWORD" /w
49+
else
50+
nativevar PGPASSWORD "$PASSWORD" /w
51+
PASSWORD="password"
52+
fi
53+
54+
if [ -n "$USERNAME" ]; then
55+
nativevar DOLTGRES_USER "$USERNAME" /w
56+
if [ -z "$DEFAULT_DB" ]; then
57+
DEFAULT_DB="$USERNAME"
58+
fi
59+
else
60+
USERNAME="postgres"
61+
fi
62+
63+
DEFAULT_DB="${DEFAULT_DB:=postgres}"
4764

4865
PORT=$( definePORT )
4966
CONFIG=$( defineCONFIG $PORT )

0 commit comments

Comments
 (0)