Skip to content

Commit

Permalink
Fix concurrency issue when granting privileges on databases (cyrilgdn…
Browse files Browse the repository at this point in the history
…#224)

Co-authored-by: Timothe Genzmer <[email protected]>
  • Loading branch information
timothegenzmer and Timothe Genzmer authored Nov 17, 2022
1 parent d03ab42 commit fa723cf
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Building The Provider
Clone repository to: `$GOPATH/src/github.com/cyrilgdn/terraform-provider-postgresql`

```sh
$ mkdir -p $GOPATH/src/github.com/terraform-providers; cd $GOPATH/src/github.com/terraform-providers
$ mkdir -p $GOPATH/src/github.com/cyrilgdn; cd $GOPATH/src/github.com/cyrilgdn
$ git clone [email protected]:cyrilgdn/terraform-provider-postgresql
```

Expand Down
13 changes: 13 additions & 0 deletions postgresql/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,19 @@ func pgLockRole(txn *sql.Tx, role string) error {
return nil
}

// Lock a database and all his members to avoid concurrent updates on some resources
func pgLockDatabase(txn *sql.Tx, database string) error {
// Disable statement timeout for this connection otherwise the lock could fail
if _, err := txn.Exec("SET statement_timeout = 0"); err != nil {
return fmt.Errorf("could not disable statement_timeout: %w", err)
}
if _, err := txn.Exec("SELECT pg_advisory_xact_lock(oid::bigint) FROM pg_database WHERE datname = $1", database); err != nil {
return fmt.Errorf("could not get advisory lock for database %s: %w", database, err)
}

return nil
}

func arrayDifference(a, b []interface{}) (diff []interface{}) {
m := make(map[interface{}]bool)

Expand Down
16 changes: 15 additions & 1 deletion postgresql/resource_postgresql_grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ func resourcePostgreSQLGrantCreate(db *DBConnection, d *schema.ResourceData) err
return err
}

if objectType == "database" {
if err := pgLockDatabase(txn, database); err != nil {
return err
}
}

owners, err := getRolesToGrant(txn, d)
if err != nil {
return err
Expand Down Expand Up @@ -189,7 +195,8 @@ func resourcePostgreSQLGrantDelete(db *DBConnection, d *schema.ResourceData) err
return fmt.Errorf("feature is not supported: %v", err)
}

txn, err := startTransaction(db.client, d.Get("database").(string))
database := d.Get("database").(string)
txn, err := startTransaction(db.client, database)
if err != nil {
return err
}
Expand All @@ -200,6 +207,13 @@ func resourcePostgreSQLGrantDelete(db *DBConnection, d *schema.ResourceData) err
return err
}

objectType := d.Get("object_type").(string)
if objectType == "database" {
if err := pgLockDatabase(txn, database); err != nil {
return err
}
}

owners, err := getRolesToGrant(txn, d)
if err != nil {
return err
Expand Down

0 comments on commit fa723cf

Please sign in to comment.