I'm deploying a Rails app that uses PostgreSQL and HSTORE.
To deploy it, I'm ussing rubber.
Everything works, except for HSTORE not being properly enabled. When the migration that contains execute("CREATE EXTENSION hstore")
runs, I get the following errors:
** [out :: production.---]
** [out :: production.---] -- execute("CREATE EXTENSION hstore")
** [out :: production.---]
** [out :: production.---] rake aborted!
** [out :: production.---] An error has occurred, this and all later migrations canceled:
** [out :: production.---]
** [out :: production.---] PG::Error: ERROR: permission denied to create extension "hstore"
** [out :: production.---] HINT: Must be superuser to create this extension.
The script that creates the postgres instance has this code:
create_user_cmd = "CREATE USER #{env.db_user} WITH NOSUPERUSER CREATEDB NOCREATEROLE"
so I think the problem might be related to the NOSUPERUSER
attribute being set here.
Is there any way to enable hstore using rubber while keeping most of the generated files unchanged?
The problem is that rubber creates the DB user as NOSUPERUSER
. My workaround is to create tasks that run before and after capistrano's deploy:migrate
that will change the user to SUPERUSER
and back.
Here's the code:
namespace :rubber do
namespace :project do
before "deploy:migrate", "rubber:project:add_pg_superuser_and_enable_hstore"
after "deploy:migrate", "rubber:project:remove_pg_superuser"
task :add_pg_superuser_and_enable_hstore,
:roles => [:postgresql_master, :postgresql_slave] do
alter_user_cmd = "ALTER USER #{rubber_env.db_user} SUPERUSER"
create_hstore_cmd = "CREATE EXTENSION IF NOT EXISTS hstore;"
rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT
sudo -i -u postgres psql -c "#{alter_user_cmd}"
sudo -i -u postgres psql -c "#{create_hstore_cmd}"
ENDSCRIPT
end
task :remove_pg_superuser, :roles => [:postgresql_master,
:postgresql_slave] do
alter_user_cmd = "ALTER USER #{rubber_env.db_user} NOSUPERUSER"
rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT
sudo -i -u postgres psql -c "#{alter_user_cmd}"
ENDSCRIPT
end
end
end