capistrano-postgresql 4.9.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80305e773c32e2e4eeaa17fc94f06554747d9e8b4e1d62475098873ee32888d6
4
- data.tar.gz: 59444fe5adfceb315f3752aa5051f414c91f73372029e5af637453b4bdef7b54
3
+ metadata.gz: 62d90db3919f2557e6a3934726d251dac71b5abf48a2c7b1984dd32b3ee96852
4
+ data.tar.gz: 44cb5c724e536949afe34291907838a747fd8342e7c84bbbfad2cb61a2746a53
5
5
  SHA512:
6
- metadata.gz: abca2321498fde096259461b5573b483d3b046ac9c7cb2d297f23256b816e1daf78df99f1fb51bf680547294d4eb6a9d4c3f50d0a7d09f2be46ec00fa941c5e7
7
- data.tar.gz: 99860d8f90dda9c524c8996601bfb7cfecf49b6dc63951bcb28b1313e8bfe937bfd595bd7f82657686e23d92d940379c959bb056dcc4af144034f0e73f044ce7
6
+ metadata.gz: afd78f06f37d41d32da87073c979ede236aadcf9409ce7b4086ce5ecb232447efb0071007401cce4d556e6468e7af7743b4d4adaadf9f408e1882ce5767a8400
7
+ data.tar.gz: 41c442f96c4fb72594f9595d649a184e0447b1c168e114ea663d44cdc68d82e8393fd7c84f7ed5ae71d0816966fa7fb83b094b826cf8d16d5b5163e947e4ce6b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  ### master
4
4
 
5
+ ## v5.0.0, 2018-06-05
6
+ - Code cleanup
7
+ - Removal of legacy add hstore method
8
+ - Using execute and test properly so we can see what the gem is doing in the STDOUT
9
+ - Expanded remove_all task to actually cover everything
10
+ - Added deploy config option pg_generate_random_password, instead of using it by default when pg_password is excluded
11
+ - issues/53: Bug fixed for updates to the archetype when using random password
12
+ - projects/1: Prep for RSPEC testing project
13
+
5
14
  ## v4.9.1, 2018-06-04
6
15
  - Added back set :pg_ask_for_password, false and ask_for_or_generate_password
7
16
 
data/README.md CHANGED
@@ -1,10 +1,9 @@
1
1
  # Capistrano::PostgreSQL
2
2
 
3
- **Note: this plugin works only with Capistrano 3.** Plase check the capistrano
3
+ **Note: this plugin works only with Capistrano 3.** Please check the capistrano
4
4
  gem version you're using before installing this gem:
5
5
  `$ bundle show | grep capistrano`
6
-
7
- Plugin for Capistrano 2 [is here](https://github.com/bruno-/capistrano2-postgresql).
6
+ The plugin for Capistrano 2 [is here](https://github.com/bruno-/capistrano2-postgresql).
8
7
 
9
8
  ### About
10
9
 
@@ -14,11 +13,9 @@ tasks for PostgreSQL when deploying rails apps.
14
13
  Here are the specific things this plugin does for your capistrano deployment
15
14
  process:
16
15
 
17
- * creates a new PostgreSQL database and database user on the server
18
- * generates and populates `database.yml` file on all release nodes
19
- (no need to ssh to the server and do this manually!)
20
- * zero-config
21
- * support for multi-server setup: separate `db` and `app` nodes (from version 4.0)
16
+ * Creates a new PostgreSQL database and database user on the server
17
+ * Generates and populates `database.yml` file on all release nodes (using ssh)
18
+ * Support for multi-server setup: separate `db` and `app` nodes ( versions > 4.0 )
22
19
 
23
20
  **Note**: gem version 4 introduces some breaking changes. If you installed gem
24
21
  version 3 or below you might want to follow the
@@ -30,7 +27,7 @@ Put the following in your application's `Gemfile`:
30
27
 
31
28
  group :development do
32
29
  gem 'capistrano', '~> 3.2.0'
33
- gem 'capistrano-postgresql', '~> 4.8.0'
30
+ gem 'capistrano-postgresql', '~> 5.0.0'
34
31
  end
35
32
 
36
33
  Then:
@@ -39,31 +36,55 @@ Then:
39
36
 
40
37
  ### Usage
41
38
 
42
- If you're deploying a standard rails app, all you need to do is put
43
- the following in `Capfile` file:
39
+ In a standard RAILS app, you need to do is put the following in `Capfile` file:
44
40
 
45
41
  ```
46
42
  require 'capistrano/postgresql'
47
43
  ```
48
44
 
49
- * Make sure the `deploy_to` path exists and has the right privileges on the
50
- server (i.e. `/var/www/myapp`). Warning: The ~ symbol (i.e. `~/myapp`) is not supported.
51
- * Within your app/config/deploy/{env}.rb files, you need to specify at least one :app and one :db server.
52
- * It's also suggested to specify `:primary => true` on the end of your primary :db server line.
53
- * Optionally, you can run psql commands WITHOUT sudo if needed. Set the following (which defaults to false): `set :pg_without_sudo, true`
45
+ You need to include ONLY ONE of the following in your config/deploy/*.rb files:
46
+
47
+ ```
48
+ set :pg_password, ENV['DATABASE_USER_PASSWORD']
49
+ set :pg_ask_for_password, true
50
+ set :pg_generate_random_password, true
51
+ ```
52
+
53
+ Example config:
54
+
55
+ ```
56
+ server 'growtrader.dev', user: 'growtrader', roles: %w{app db}
57
+ set :stage, :development
58
+ set :branch, 'development'
59
+ # ==================
60
+ # Postgresql setup
61
+ set :pg_without_sudo, false
62
+ set :pg_host, 'growtrader.dev'
63
+ set :pg_database, 'growtrader'
64
+ set :pg_username, 'growtrader'
65
+ #set :pg_generate_random_password, true
66
+ #set :pg_ask_for_password, true
67
+ set :pg_password, ENV['GROWTRADER_PGPASS']
68
+ set :pg_extensions, ['citext','hstore']
69
+ set :pg_encoding, 'UTF-8'
70
+ set :pg_pool, '100'
71
+ ```
54
72
 
55
73
  Finally, to setup the server(s), run:
56
74
 
57
75
  $ bundle exec cap production setup
58
76
 
59
- ### Gotchas
77
+ ### Requirements
60
78
 
61
- Be sure to remove `config/database.yml` from your application's version control.
79
+ * Be sure to remove `config/database.yml` from your application's version control.
80
+ * Your pg_hba.conf must include `local all all trust`
81
+ * Make sure the `deploy_to` path exists and has the right privileges on your servers. The ~ symbol (i.e. `~/myapp`) is not supported.
82
+ * Within your app/config/deploy/{env}.rb files, you need to specify at least one :app and one :db server.
83
+ * If you have multiple :db role hosts, it's necessary to specify `:primary => true` on the end of your primary :db server.
62
84
 
63
85
  ### How it works
64
86
 
65
87
  [How the plugin works](https://github.com/capistrano-plugins/capistrano-postgresql/wiki/How-it-works)
66
- wiki page contains a list of actions the plugin executes.
67
88
 
68
89
  Read it only if you want to learn more about the plugin internals.
69
90
 
@@ -87,7 +108,7 @@ Check out [capistrano-plugins](https://github.com/capistrano-plugins) github org
87
108
 
88
109
  Contributions and improvements are very welcome.
89
110
 
90
- If something is not working for you, or you find a bug please report it.
111
+ If something is not working for you, or you find a bug, please report it.
91
112
 
92
113
  ### Thanks
93
114
 
@@ -4,6 +4,22 @@ module Capistrano
4
4
  module Postgresql
5
5
  module HelperMethods
6
6
 
7
+ def extension_exists?(extension)
8
+ psql 'test', fetch(:pg_system_db), '-tAc', %Q{"SELECT 1 FROM pg_extension WHERE extname='#{extension}';" | grep -q 1}
9
+ end
10
+
11
+ def remove_extensions
12
+ if Array( fetch(:pg_extensions) ).any?
13
+ on roles :db do
14
+ # remove in reverse order if extension is present
15
+ Array( fetch(:pg_extensions) ).reverse.each do |ext|
16
+ next if [nil, false, ""].include?(ext)
17
+ psql 'execute', fetch(:pg_system_db), '-c', %Q{"DROP EXTENSION IF EXISTS #{ext};"} if extension_exists?(ext)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
7
23
  def generate_database_yml_io(password=fetch(:pg_password))
8
24
  StringIO.open do |s|
9
25
  s.puts "#{fetch(:pg_env)}:"
@@ -26,10 +42,10 @@ module Capistrano
26
42
  def pg_template(update=false,archetype_file=nil)
27
43
  config_file = "#{fetch(:pg_templates_path)}/postgresql.yml.erb"
28
44
  if update
29
- raise('Updates need the original file to update from.') if archetype_file.nil?
45
+ raise('Regeneration of archetype database.yml need the original file to update from.') if archetype_file.nil?
30
46
  raise('Cannot update a custom postgresql.yml.erb file.') if File.exists?(config_file) # Skip custom postgresql.yml.erb if we're updating. It's not supported
31
47
  # Update yml file from settings
32
- if fetch(:pg_password).nil? && fetch(:pg_ask_for_password) == false # User isn't generating a random password or wanting to set it manually from prompt
48
+ if fetch(:pg_generate_random_password) || !fetch(:pg_password) # We need to prevent updating the archetype file if we've done a random or "ask"ed password
33
49
  current_password = archetype_file.split("\n").grep(/password/)[0].split('password:')[1].strip
34
50
  generate_database_yml_io(current_password)
35
51
  else
@@ -8,15 +8,15 @@ module Capistrano
8
8
  SecureRandom.hex(10)
9
9
  end
10
10
 
11
- # This method is invoked only if :pg_password is not already set in config/#{:stage}/deploy.rb. Directly setting :pg_password has precedence.
12
- def ask_for_or_generate_password
11
+ def pg_password_generate
13
12
  if fetch(:pg_ask_for_password)
14
13
  ask :pg_password, "Postgresql database password for the app: "
15
- else
14
+ elsif fetch(:pg_generate_random_password)
16
15
  set :pg_password, generate_random_password
16
+ else
17
+ set :pg_password, nil # Necessary for pg_template
17
18
  end
18
19
  end
19
-
20
20
  end
21
21
  end
22
22
  end
@@ -2,39 +2,28 @@ module Capistrano
2
2
  module Postgresql
3
3
  module PsqlHelpers
4
4
 
5
- def psql(*args)
6
- # Reminder: -u #{fetch(:pg_system_user)} seen below differs slightly from -U, an option on the psql command: https://www.postgresql.org/docs/9.6/static/app-psql.html
7
- args.unshift("-U #{fetch(:pg_system_user)}") if fetch(:pg_without_sudo) # Add the :pg_system_user to psql command since we aren't using sudo anymore
8
- # test :sudo, "-u #{fetch(:pg_system_user)} psql", *args
9
- cmd = [ :psql, *args ]
10
- cmd = [ :sudo, "-u #{fetch(:pg_system_user)}", *cmd ] unless fetch(:pg_without_sudo)
11
- test *cmd.flatten
12
- end
13
-
14
- # Runs psql on the application database
15
- def psql_on_app_db(*args)
16
- psql_on_db(fetch(:pg_database), *args)
5
+ def psql(type, database, *args)
6
+ cmd = [ :psql, "-d #{database}", *args ]
7
+ if fetch(:pg_without_sudo)
8
+ args.unshift("-U #{fetch(:pg_system_user)}") # Add the :pg_system_user to psql command since we aren't using sudo anymore
9
+ else
10
+ cmd = [:sudo, "-i -u #{fetch(:pg_system_user)}", *cmd]
11
+ end
12
+ if type == 'test'
13
+ test *cmd.flatten
14
+ else
15
+ execute *cmd.flatten
16
+ end
17
17
  end
18
18
 
19
- def db_user_exists?
20
- psql_on_db fetch(:pg_system_db),'-tAc', %Q{"SELECT 1 FROM pg_roles WHERE rolname='#{fetch(:pg_username)}';" | grep -q 1}
19
+ def database_user_exists?
20
+ psql 'test', fetch(:pg_system_db),'-tAc', %Q{"SELECT 1 FROM pg_roles WHERE rolname='#{fetch(:pg_username)}';" | grep -q 1}
21
21
  end
22
22
 
23
23
  def database_exists?
24
- psql_on_db fetch(:pg_system_db), '-tAc', %Q{"SELECT 1 FROM pg_database WHERE datname='#{fetch(:pg_database)}';" | grep -q 1}
24
+ psql 'test', fetch(:pg_system_db), '-tAc', %Q{"SELECT 1 FROM pg_database WHERE datname='#{fetch(:pg_database)}';" | grep -q 1}
25
25
  end
26
26
 
27
- private
28
-
29
- def psql_on_db(db_name, *args)
30
- args.unshift("-U #{fetch(:pg_system_user)}") if fetch(:pg_without_sudo) # Add the :pg_system_user to psql command since we aren't using sudo anymore
31
- cmd = [ :psql, "-d #{db_name}", *args ]
32
- cmd = [ :sudo, "-u #{fetch(:pg_system_user)}", *cmd ] unless fetch(:pg_without_sudo)
33
- puts "Executing #{cmd.flatten}"
34
- test *cmd.flatten
35
- #test :sudo, "-u #{fetch(:pg_system_user)} psql -d #{db_name}", *args
36
- end
37
-
38
27
  end
39
28
  end
40
29
  end
@@ -1,5 +1,5 @@
1
1
  module Capistrano
2
2
  module Postgresql
3
- VERSION = '4.9.2'
3
+ VERSION = '5.0.0'
4
4
  end
5
5
  end
@@ -13,8 +13,9 @@ namespace :load do
13
13
  set :pg_database, -> { "#{fetch(:application)}_#{fetch(:stage)}" }
14
14
  set :pg_pool, 5
15
15
  set :pg_username, -> { fetch(:pg_database) }
16
- set :pg_ask_for_password, false
17
- set :pg_password, -> { ask_for_or_generate_password }
16
+ set :pg_generate_random_password, nil
17
+ set :pg_ask_for_password, nil
18
+ set :pg_password, -> { pg_password_generate }
18
19
  set :pg_socket, ''
19
20
  set :pg_host, -> do # for multiple release nodes automatically use server hostname (IP?) in the database.yml
20
21
  release_roles(:all).count == 1 && release_roles(:all).first == primary(:db) ? 'localhost' : primary(:db).hostname
@@ -44,86 +45,58 @@ namespace :postgresql do
44
45
  # undocumented, for a reason: drops database. Use with care!
45
46
  task :remove_all do
46
47
  on release_roles :all do
47
- if test "[ -e #{database_yml_file} ]"
48
- execute :rm, database_yml_file
49
- end
48
+ execute :rm, database_yml_file if test "[ -e #{database_yml_file} ]"
50
49
  end
51
-
52
50
  on primary :db do
53
- if test "[ -e #{archetype_database_yml_file} ]"
54
- execute :rm, archetype_database_yml_file
55
- end
51
+ execute :rm, archetype_database_yml_file if test "[ -e #{archetype_database_yml_file} ]"
56
52
  end
57
-
58
53
  on roles :db do
59
- psql '-c', %Q{"DROP database \\"#{fetch(:pg_database)}\\";"}
60
- psql '-c', %Q{"DROP user \\"#{fetch(:pg_username)}\\";"}
54
+ psql'execute', fetch(:pg_system_db), '-c', %Q{"DROP database \\"#{fetch(:pg_database)}\\";"} if database_exists?
55
+ psql 'execute', fetch(:pg_system_db),'-c', %Q{"DROP user \\"#{fetch(:pg_username)}\\";"}if database_user_exists?
56
+ remove_extensions
61
57
  end
58
+ puts 'Removed database.yml from all hosts, Database, Database User, and Removed Extensions'
62
59
  end
63
60
 
64
61
  task :remove_app_database_yml_files do
65
62
  # We should never delete archetype files. The generate_database_yml_archetype task will handle updates
66
63
  on release_roles :app do
67
- if test "[ -e #{database_yml_file} ]"
68
- execute :rm, database_yml_file
69
- end
64
+ execute :rm, database_yml_file if test "[ -e #{database_yml_file} ]"
70
65
  end
71
66
  end
72
67
 
73
68
  desc 'Remove pg_extension from postgresql db'
74
69
  task :remove_extensions do
75
- next unless Array( fetch(:pg_extensions) ).any?
76
- on roles :db do
77
- # remove in reverse order if extension is present
78
- Array( fetch(:pg_extensions) ).reverse.each do |ext|
79
- psql_on_app_db '-c', %Q{"DROP EXTENSION IF EXISTS #{ext};"} unless [nil, false, ""].include?(ext)
80
- end
81
- end
82
- end
83
-
84
- desc 'Add the hstore extension to postgresql'
85
- task :add_hstore do
86
- next unless fetch(:pg_use_hstore)
87
- on roles :db do
88
- psql_on_app_db '-c', %Q{"CREATE EXTENSION IF NOT EXISTS hstore;"}
89
- end
70
+ remove_extensions
90
71
  end
91
72
 
92
73
  desc 'Add pg_extension to postgresql db'
93
74
  task :add_extensions do
94
- next unless Array( fetch(:pg_extensions) ).any?
95
75
  on roles :db do
96
- Array( fetch(:pg_extensions) ).each do |ext|
97
- next if [nil, false, ''].include?(ext)
98
- if psql_on_app_db '-c', %Q{"CREATE EXTENSION IF NOT EXISTS #{ext};"}
99
- puts "- Added extension #{ext} to #{fetch(:pg_database)}"
100
- else
101
- error "postgresql: adding extension #{ext} failed!"
102
- exit 1
76
+ if Array( fetch(:pg_extensions) ).any?
77
+ Array( fetch(:pg_extensions) ).each do |ext|
78
+ next if [nil, false, ''].include?(ext)
79
+ psql 'execute', fetch(:pg_system_db), '-c', %Q{"CREATE EXTENSION IF NOT EXISTS #{ext};"}unless extension_exists?(ext)
103
80
  end
104
81
  end
105
82
  end
106
83
  end
107
84
 
108
- desc 'Create database'
109
- task :create_database do
85
+ desc 'Create pg_username in database'
86
+ task :create_database_user do
110
87
  on roles :db do
111
- next if database_exists?
112
- unless psql_on_db fetch(:pg_system_db), '-c', %Q{"CREATE DATABASE \\"#{fetch(:pg_database)}\\" OWNER \\"#{fetch(:pg_username)}\\";"}
113
- error 'postgresql: creating database failed!'
114
- exit 1
88
+ unless database_user_exists?
89
+ # If you use CREATE USER instead of CREATE ROLE the LOGIN right is granted automatically; otherwise you must specify it in the WITH clause of the CREATE statement.
90
+ psql 'execute', fetch(:pg_system_db), '-c', %Q{"CREATE USER \\"#{fetch(:pg_username)}\\" PASSWORD '#{fetch(:pg_password)}';"}
115
91
  end
116
92
  end
117
93
  end
118
94
 
119
- desc 'Create DB user'
120
- task :create_db_user do
95
+ desc 'Create database'
96
+ task :create_database do
121
97
  on roles :db do
122
- next if db_user_exists?
123
- # If you use CREATE USER instead of CREATE ROLE the LOGIN right is granted automatically; otherwise you must specify it in the WITH clause of the CREATE statement.
124
- unless psql_on_db fetch(:pg_system_db), '-c', %Q{"CREATE USER \\"#{fetch(:pg_username)}\\" PASSWORD '#{fetch(:pg_password)}';"}
125
- error "postgresql: creating database user \"#{fetch(:pg_username)}\" failed!"
126
- exit 1
98
+ unless database_exists?
99
+ psql 'execute', fetch(:pg_system_db), '-c', %Q{"CREATE DATABASE \\"#{fetch(:pg_database)}\\" OWNER \\"#{fetch(:pg_username)}\\";"}
127
100
  end
128
101
  end
129
102
  end
@@ -148,7 +121,6 @@ namespace :postgresql do
148
121
  on primary :db do
149
122
  database_yml_contents = download! archetype_database_yml_file
150
123
  end
151
-
152
124
  on release_roles :all do
153
125
  execute :mkdir, '-pv', File.dirname(database_yml_file)
154
126
  Net::SCP.upload!(self.host.hostname, self.host.user, StringIO.new(database_yml_contents), database_yml_file)
@@ -163,26 +135,31 @@ namespace :postgresql do
163
135
 
164
136
  desc 'Postgresql setup tasks'
165
137
  task :setup do
166
- puts "* ============================= * \n All psql commands will be run #{fetch(:pg_without_sudo) ? 'without sudo' : 'with sudo'}\n You can modify this in your app/config/deploy/#{fetch(:rails_env)}.rb by setting the pg_without_sudo boolean \n* ============================= *"
138
+ puts "* ===== Postgresql Setup ===== *\n"
139
+ puts " All psql commands will be run #{fetch(:pg_without_sudo) ? 'without sudo' : 'with sudo'}\n You can modify this in your app/config/deploy/#{fetch(:rails_env)}.rb by setting the pg_without_sudo boolean.\n"
167
140
  if release_roles(:app).empty?
168
- puts "There are no servers in your app/config/deploy/#{fetch(:rails_env)}.rb with a :app role... Skipping Postgresql setup."
141
+ warn " WARNING: There are no servers in your app/config/deploy/#{fetch(:rails_env)}.rb with a :app role... Skipping Postgresql setup."
169
142
  else
170
143
  invoke 'postgresql:remove_app_database_yml_files' # Deletes old yml files from all servers. Allows you to avoid having to manually delete the files on your app servers to get a new pool size for example. Don't touch the archetype file to avoid deleting generated passwords.
171
144
  if release_roles(:db).empty? # Test to be sure we have a :db role host
172
- puts "There is no server in your app/config/deploy/#{fetch(:rails_env)}.rb with a :db role... Skipping Postgresql setup."
145
+ warn " WARNING: There is no server in your app/config/deploy/#{fetch(:rails_env)}.rb with a :db role... Skipping Postgresql setup."
146
+ elsif !fetch(:pg_password) && !fetch(:pg_generate_random_password) && !fetch(:pg_ask_for_password)
147
+ warn " WARNING: There is no :pg_password set in your app/config/deploy/#{fetch(:rails_env)}.rb.\n If you don't wish to set it, 'set :pg_generate_random_password, true' or 'set :pg_ask_for_password, true' are available!"
148
+ elsif fetch(:pg_generate_random_password) && fetch(:pg_ask_for_password)
149
+ warn " WARNING: You cannot have both :pg_generate_random_password and :pg_ask_for_password enabled in app/config/deploy/#{fetch(:rails_env)}.rb."
173
150
  else
174
- invoke 'postgresql:create_db_user'
151
+ invoke 'postgresql:create_database_user'
175
152
  invoke 'postgresql:create_database'
176
- invoke 'postgresql:add_hstore'
177
153
  invoke 'postgresql:add_extensions'
178
154
  invoke 'postgresql:generate_database_yml_archetype'
179
155
  invoke 'postgresql:generate_database_yml'
180
156
  end
181
157
  end
158
+ puts "* ============================= *"
182
159
  end
183
160
  end
184
161
 
185
162
  desc 'Server setup tasks'
186
163
  task :setup do
187
- invoke "postgresql:setup"
164
+ invoke 'postgresql:setup'
188
165
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-postgresql
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.9.2
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno Sutic
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-06-05 00:00:00.000000000 Z
12
+ date: 2018-06-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano