├── .gitignore ├── Gemfile ├── Gemfile.lock ├── MIT-LICENSE ├── README.md ├── Rakefile ├── Vagrantfile ├── app.rb ├── config.ru ├── config ├── database.yml ├── environments.rb ├── mapping.rb └── newrelic.yml ├── db ├── migrate │ └── 20141020110537_issues.rb └── schema.rb ├── models ├── github_issue.rb ├── issue.rb └── redmine_issue.rb └── provisioning ├── playbook.yml └── roles └── postgresql ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── defaults └── main.yml ├── handlers └── main.yml ├── meta └── main.yml ├── tasks ├── configure.yml ├── databases.yml ├── extensions.yml ├── extensions │ ├── contrib.yml │ ├── dev_headers.yml │ └── postgis.yml ├── install.yml ├── main.yml ├── monit.yml └── users.yml ├── templates ├── etc_monit_conf.d_postgresql.j2 ├── pg_hba.conf.j2 └── postgresql.conf.j2 └── test.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | .DS_Store 3 | .env 4 | *.log -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "sinatra", "~> 1.4.5" 4 | gem "activerecord", "~> 3.2.19" 5 | gem "sinatra-activerecord", "~> 2.0.2" 6 | gem "rake", "~> 10.3.2" 7 | gem "pg", "~> 0.17.1" 8 | gem "httparty", "~> 0.13.1" 9 | gem "racksh" 10 | gem 'newrelic_rpm' 11 | 12 | group :development do 13 | gem "pry" 14 | gem "dotenv" 15 | end 16 | 17 | ruby "2.1.2" 18 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | activemodel (3.2.19) 5 | activesupport (= 3.2.19) 6 | builder (~> 3.0.0) 7 | activerecord (3.2.19) 8 | activemodel (= 3.2.19) 9 | activesupport (= 3.2.19) 10 | arel (~> 3.0.2) 11 | tzinfo (~> 0.3.29) 12 | activesupport (3.2.19) 13 | i18n (~> 0.6, >= 0.6.4) 14 | multi_json (~> 1.0) 15 | arel (3.0.3) 16 | builder (3.0.4) 17 | coderay (1.1.0) 18 | dotenv (1.0.2) 19 | httparty (0.13.1) 20 | json (~> 1.8) 21 | multi_xml (>= 0.5.2) 22 | i18n (0.6.11) 23 | json (1.8.1) 24 | method_source (0.8.2) 25 | multi_json (1.10.1) 26 | multi_xml (0.5.5) 27 | newrelic_rpm (3.9.6.257) 28 | pg (0.17.1) 29 | pry (0.10.1) 30 | coderay (~> 1.1.0) 31 | method_source (~> 0.8.1) 32 | slop (~> 3.4) 33 | rack (1.5.2) 34 | rack-protection (1.5.3) 35 | rack 36 | rack-test (0.6.2) 37 | rack (>= 1.0) 38 | racksh (1.0.0) 39 | rack (>= 1.0) 40 | rack-test (>= 0.5) 41 | rake (10.3.2) 42 | sinatra (1.4.5) 43 | rack (~> 1.4) 44 | rack-protection (~> 1.4) 45 | tilt (~> 1.3, >= 1.3.4) 46 | sinatra-activerecord (2.0.2) 47 | activerecord (>= 3.2) 48 | sinatra (~> 1.0) 49 | slop (3.6.0) 50 | tilt (1.4.1) 51 | tzinfo (0.3.41) 52 | 53 | PLATFORMS 54 | ruby 55 | 56 | DEPENDENCIES 57 | activerecord (~> 3.2.19) 58 | dotenv 59 | httparty (~> 0.13.1) 60 | newrelic_rpm 61 | pg (~> 0.17.1) 62 | pry 63 | racksh 64 | rake (~> 10.3.2) 65 | sinatra (~> 1.4.5) 66 | sinatra-activerecord (~> 2.0.2) 67 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Guillaume Montard 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Purpose 2 | 3 | This Project let you **Sync Redmine issues with Github issues** with some caveats (on purpose). 4 | 5 | ### Why ? 6 | 7 | [We](http://www.vodeclic.com) use Redmine as a bug reporter for our internal and non technical teams and our developers manage them on Github for a better development workflow. 8 | 9 | ### How it work? 10 | 11 | - First an issue has to be created on Redmine 12 | - If the issue has a specific status (ID) then it's synced to Github 13 | - If you modify the issue on Redmine those fields will reflect on Github: 14 | - Title 15 | - Description 16 | - Assignee 17 | - Status (open or closed on Github) 18 | - Priority (as a label) 19 | - Comments / Attached file (will update issue description) 20 | 21 | - If you modify the issue on Github those fields will reflect on Redmine: 22 | - Assignee 23 | - Status (as open or closed) 24 | 25 | If you'd like to change those behaviors it should be pretty straightford to do so, do not hesitate to fork the project. 26 | 27 | ### Requirements 28 | 29 | #### On Redmine 30 | 31 | - You need a Redmine install >= 2.4, [REST Api](http://www.redmine.org/projects/redmine/wiki/Rest_api) enabled and the [Redmine Webhook](https://github.com/suer/redmine_webhook) plugin. 32 | - Configure the Redmine Webhook URL to point to this App install (*http://your-app-install/redmine_hebook*) 33 | 34 | #### On Github 35 | 36 | - Create a [Github personnal access token](https://github.com/settings/tokens/new) with rights on *Repo* checkbox 37 | - Configure a Webhook URL for your Github repo to point to this App install (http://your-app-install/github_hebook) 38 | - Go to your repository setting (https://github.com/username/repo/settings/hooks), click "Add webhook", in the *Payload URL* field use this App URL (**http://your-app-install/github_hebook**), check event *Issues* and activate it. 39 | 40 | #### Configure the Application 41 | 42 | In order to sync data between Redmine and Github we need a way to map some fields, this is the role of the *config/mapping.rb* file, you should edit it: 43 | ~~~ruby 44 | # config/mapping.rb 45 | # On those hash, keys refer to Redmine ID and value to Github corresponding one 46 | 47 | ## Github doesn't handle priority so it will be converted to labels 48 | def priority 49 | { 50 | 1 => "Low", 51 | 2 => "Normal", 52 | 3 => "High", 53 | 4 => "Urgent" 54 | } 55 | end 56 | 57 | ## Map Redmine user to Github user 58 | def assignee 59 | { 60 | 1 => "gmontard" 61 | } 62 | end 63 | 64 | ## Map Redmine status to Github status (which can only be closed or open) 65 | def status 66 | { 67 | 1 => "closed", 68 | 2 => "open" 69 | } 70 | end 71 | 72 | ## Default label for all issues 73 | def default_label 74 | "Bug" 75 | end 76 | ~~~ 77 | 78 | - You need to setup those environments variables in order for the App to work: 79 | ~~~console 80 | DATABASE_URL # Database URL (ex: postgres://localhost/issue-sync-redmine-github) 81 | DATABASE_NAME # Database name 82 | DATABASE_USERNAME # Database username (ex: postgres) 83 | DATABASE_PASSWORD # Database password 84 | DATABASE_HOST # Database host (ex: localhost) 85 | REDMINE_URL # Your Redmine Public base URL 86 | REDMINE_API_KEY # Your Redmine API Key is available on your account page (*/my/account*) 87 | GITHUB_API_KEY # Your Github access token 88 | GITHUB_OWNER # Your Github Username 89 | GITHUB_REPO # Your Github project Repo (for ex: *gmontard/issue-sync-redmine-github*) 90 | NEWRELIC_API_KEY # NewRelic API KEY 91 | ~~~ 92 | 93 | - In development you should creare a *.env* file and set those variables (see section *Running in Development*) 94 | 95 | - In production, if you use Heroku as mentioned below we'll use *heroku config* command (see section *Deploy on Heroku*) 96 | 97 | 98 | ### Running in Development 99 | 100 | - Build the Box: 101 | ~~~console 102 | vagrant up --provision 103 | vagrant ssh 104 | ~~~ 105 | 106 | - Edit the *config/mapping* file and create a *.env* file, below some default env variables: 107 | ~~~console 108 | DATABASE_URL=postgres://localhost/issue-sync-redmine-github 109 | DATABASE_NAME=issue-sync-redmine-github 110 | DATABASE_USERNAME=postgres 111 | DATABASE_PASSWORD= 112 | DATABASE_HOST=localhost 113 | ~~~ 114 | 115 | - Finish to configure the application: 116 | ~~~console 117 | bundle install 118 | bundle exec rake db:create 119 | bundle exec rake db:migrate 120 | rackup 121 | ~~~ 122 | 123 | - Also a console is available: 124 | ~~~console 125 | racksh 126 | ~~~ 127 | 128 | 129 | ### Deploy on Heroku 130 | 131 | - Login through Heroku and create your heroku App: 132 | ~~~console 133 | heroku login 134 | heroku create 135 | ~~~ 136 | 137 | - Add Postgresql Add-on 138 | ~~~console 139 | heroku addons:add heroku-postgresql 140 | ~~~ 141 | 142 | - Retrieve Postgresql Credentials 143 | ~~~console 144 | heroku config 145 | #ex: => postgres://gvupfefeizddbfk:zURnLz87hjhfegsLjpl-DZ@ec2-5455-24-51-1.compute-1.amazonaws.com:5432/jfkej87jhfp9 146 | ~~~ 147 | 148 | - Set the environments variables on Heroku: 149 | ~~~console 150 | heroku config:set DATABASE_URL=postgres://gvupfefeizddbfk:zURnLz87hjhfegsLjpl-DZ@ec2-5455-24-51-1.compute-1.amazonaws.com:5432/jfkej87jhfp9 151 | heroku config:set DATABASE_NAME=jfkej87jhfp9 152 | heroku config:set DATABASE_USERNAME=gvupfefeizddbfk 153 | heroku config:set DATABASE_PASSWORD=zURnLz87hjhfegsLjpl-DZ-bD 154 | heroku config:set DATABASE_HOST=ec2-5455-24-51-1.compute-1.amazonaws.com 155 | heroku config:set REDMINE_URL= 156 | heroku config:set REDMINE_API_KEY= 157 | heroku config:set GITHUB_OWNER= 158 | heroku config:set GITHUB_REPO= 159 | heroku config:set GITHUB_API_KEY= 160 | heroku config:set NEWRELIC_API_KEY= 161 | ~~~ 162 | 163 | - Deploy in production and run migrations 164 | ~~~console 165 | git push heroku master && heroku run rake db:migrate 166 | ~~~ 167 | 168 | 169 | ### Useful commands on Heroku 170 | 171 | - Watching logs 172 | ~~~console 173 | heroku logs --tail 174 | ~~~ 175 | 176 | - Restarting the App 177 | ~~~console 178 | heroku restart 179 | ~~~ 180 | 181 | - Running rake command 182 | ~~~console 183 | heroku run rake COMMAND 184 | ~~~ 185 | 186 | - Launching ruby console 187 | ~~~console 188 | heroku run racksh 189 | ~~~ 190 | 191 | 192 | *Do not forget to configure Webhook URL on Redmine and Github according to *Requirements* section above.* 193 | 194 | 195 | ### Technology 196 | 197 | - Ruby 2.1 198 | - Sinatra 199 | - Postgresql 200 | 201 | 202 | ### License 203 | 204 | Copyright © 2014 Guillaume Montard and Vodeclic SAS released under the MIT license 205 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | begin 2 | require 'dotenv' 3 | Dotenv.load 4 | rescue LoadError => e 5 | puts "DotEnv not loaded, it's OK if you are in Production" 6 | end 7 | 8 | require "sinatra/activerecord/rake" 9 | require "./app" 10 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | ##### Custom Settings #### 9 | private_ip = ENV['VAGRANT_PRIVATE_IP'] || "10.0.0.102" 10 | cpu = ENV['VAGRANT_CPU'] || 4 11 | ram = ENV['VAGRANT_MEMORY'] || 4096 12 | 13 | config.vm.hostname = "vodev-box" 14 | 15 | config.vm.network "private_network", ip: private_ip 16 | 17 | config.vm.network "public_network", bridge: "en0: Ethernet" 18 | 19 | config.ssh.forward_agent = true 20 | #config.ssh.private_key_path = "~/.ssh/id_rsa" 21 | 22 | config.vm.synced_folder ".", "/vagrant", type: "nfs" 23 | 24 | if Vagrant.has_plugin?("vagrant-cachier") 25 | # Configure cached packages to be shared between instances of the same base box. 26 | # More info on http://fgrehm.viewdocs.io/vagrant-cachier/usage 27 | config.cache.scope = :box 28 | config.cache.enable :apt 29 | config.cache.enable :gem 30 | config.cache.synced_folder_opts = { 31 | type: :nfs, 32 | mount_options: ['rw', 'vers=3', 'tcp', 'nolock'] 33 | } 34 | end 35 | 36 | # PostgreSQL was using LATIN1 instead of UTF-8 as a server_encoding value 37 | config.vm.provision :shell, :inline => "echo 'LC_ALL=\"en_US.UTF-8\"' > /etc/default/locale" 38 | 39 | # Provider-specific configuration. 40 | # For VirtualBox: 41 | config.vm.provider :virtualbox do |vm, override| 42 | override.vm.box = "precise64" 43 | override.vm.box_url = "http://files.vagrantup.com/precise64.box" 44 | vm.customize ["modifyvm", :id, "--memory", ram] 45 | vm.customize ["modifyvm", :id, "--cpus", cpu] 46 | #vm.gui = true # for debug 47 | end 48 | 49 | config.vm.provision "ansible" do |ansible| 50 | ansible.playbook = "provisioning/playbook.yml" 51 | ansible.sudo = true 52 | ansible.limit = "all" 53 | ansible.verbose = 'v' 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra' 2 | require 'newrelic_rpm' 3 | require 'httparty' 4 | require 'pry' if development? 5 | require 'sinatra/activerecord' 6 | require './config/environments' 7 | require './config/mapping' 8 | require './models/redmine_issue' 9 | require './models/github_issue' 10 | require './models/issue' 11 | 12 | @@mapping = Mapping.new 13 | 14 | get '/' do 15 | content_type :json 16 | Issue.order("ID DESC").all.to_json 17 | end 18 | 19 | post '/redmine_hook' do 20 | data = JSON.parse request.body.read 21 | redmine = RedmineIssue.new(data) 22 | 23 | issue = Issue.where(redmine_id: redmine.id).first 24 | 25 | if issue.present? 26 | ## Update on Github if exist 27 | issue.update_on_github(redmine) 28 | else 29 | ## Only create Issue on Github when status is validated 30 | if redmine.open? 31 | issue = Issue.create(redmine_id: redmine.id) 32 | issue.create_on_github(redmine) 33 | end 34 | end 35 | 36 | "OK" 37 | end 38 | 39 | post '/github_hook' do 40 | data = JSON.parse(request.body.read) 41 | github = GithubIssue.new(data) 42 | 43 | issue = Issue.where(github_id: github.id).first 44 | 45 | ## Issue already created on Redmine 46 | if issue.present? 47 | issue.update_on_redmine(github) 48 | end 49 | 50 | "OK" 51 | end 52 | 53 | after do 54 | # Close the connection after the request is done so that we don't 55 | # deplete the ActiveRecord connection pool. 56 | ActiveRecord::Base.connection.close 57 | end 58 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | begin 2 | require 'dotenv' 3 | Dotenv.load 4 | rescue LoadError => e 5 | puts "DotEnv not loaded, it's OK if you are in Production" 6 | end 7 | 8 | require './app' 9 | run Sinatra::Application 10 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: postgresql 3 | database: <%=ENV['DATABASE_NAME']%> 4 | username: <%=ENV['DATABASE_USERNAME']%> 5 | password: <%=ENV['DATABASE_PASSWORD']%> 6 | host: <%=ENV['DATABASE_HOST']%> 7 | -------------------------------------------------------------------------------- /config/environments.rb: -------------------------------------------------------------------------------- 1 | #These Settings Establish the Proper Database Connection for Heroku Postgres 2 | #The environment variable DATABASE_URL should be in the following format: 3 | # => postgres://{user}:{password}@{host}:{port}/path 4 | #This is automatically configured on Heroku, you only need to worry if you also 5 | #want to run your app locally 6 | configure :production, :development do 7 | db = URI.parse(ENV['DATABASE_URL'] ||= "postgres://localhost") 8 | 9 | ActiveRecord::Base.establish_connection( 10 | :adapter => db.scheme == 'postgres' ? 'postgresql' : db.scheme, 11 | :host => db.host, 12 | :username => db.user, 13 | :password => db.password, 14 | :database => db.path[1..-1], 15 | :encoding => 'utf8' 16 | ) 17 | end 18 | -------------------------------------------------------------------------------- /config/mapping.rb: -------------------------------------------------------------------------------- 1 | class Mapping 2 | 3 | attr_reader :priority, :assignee, :status 4 | 5 | def initialize 6 | end 7 | 8 | def priority 9 | { 10 | 1 => "Low", 11 | 2 => "Normal", 12 | 3 => "High", 13 | 4 => "Urgent" 14 | } 15 | end 16 | 17 | def assignee 18 | { 19 | 1 => "gmontard" 20 | } 21 | end 22 | 23 | def status 24 | { 25 | 1 => "closed", 26 | 2 => "open" 27 | } 28 | end 29 | 30 | def default_label 31 | "Bug" 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /config/newrelic.yml: -------------------------------------------------------------------------------- 1 | # 2 | # This file configures the New Relic Agent. New Relic monitors Ruby, Java, 3 | # .NET, PHP, Python and Node applications with deep visibility and low 4 | # overhead. For more information, visit www.newrelic.com. 5 | # 6 | # Generated November 03, 2014 7 | # 8 | # This configuration file is custom generated for app30886981@heroku.com 9 | 10 | 11 | # Here are the settings that are common to all environments 12 | common: &default_settings 13 | # ============================== LICENSE KEY =============================== 14 | 15 | # You must specify the license key associated with your New Relic 16 | # account. This key binds your Agent's data to your account in the 17 | # New Relic service. 18 | license_key: <%=ENV['NEWRELIC_API_KEY']%> 19 | 20 | # Agent Enabled (Ruby/Rails Only) 21 | # Use this setting to force the agent to run or not run. 22 | # Default is 'auto' which means the agent will install and run only 23 | # if a valid dispatcher such as Mongrel is running. This prevents 24 | # it from running with Rake or the console. Set to false to 25 | # completely turn the agent off regardless of the other settings. 26 | # Valid values are true, false and auto. 27 | # 28 | # agent_enabled: auto 29 | 30 | # Application Name Set this to be the name of your application as 31 | # you'd like it show up in New Relic. The service will then auto-map 32 | # instances of your application into an "application" on your 33 | # dashboard page. If you want to map this instance into multiple 34 | # apps, like "AJAX Requests" and "All UI" then specify a semicolon 35 | # separated list of up to three distinct names, or a yaml list. 36 | # Defaults to the capitalized RAILS_ENV or RACK_ENV (i.e., 37 | # Production, Staging, etc) 38 | # 39 | # Example: 40 | # 41 | # app_name: 42 | # - Ajax Service 43 | # - All Services 44 | # 45 | # Caution: If you change this name, a new application will appear in the New 46 | # Relic user interface with the new name, and data will stop reporting to the 47 | # app with the old name. 48 | # 49 | # See https://newrelic.com/docs/site/renaming-applications for more details 50 | # on renaming your New Relic applications. 51 | # 52 | app_name: issue-sync-redmine-github 53 | 54 | # When "true", the agent collects performance data about your 55 | # application and reports this data to the New Relic service at 56 | # newrelic.com. This global switch is normally overridden for each 57 | # environment below. (formerly called 'enabled') 58 | monitor_mode: true 59 | 60 | # Developer mode should be off in every environment but 61 | # development as it has very high overhead in memory. 62 | developer_mode: false 63 | 64 | # The newrelic agent generates its own log file to keep its logging 65 | # information separate from that of your application. Specify its 66 | # log level here. 67 | log_level: info 68 | 69 | # Optionally set the path to the log file This is expanded from the 70 | # root directory (may be relative or absolute, e.g. 'log/' or 71 | # '/var/log/') The agent will attempt to create this directory if it 72 | # does not exist. 73 | # log_file_path: 'log' 74 | 75 | # Optionally set the name of the log file, defaults to 'newrelic_agent.log' 76 | # log_file_name: 'newrelic_agent.log' 77 | 78 | # The newrelic agent communicates with the service via https by default. This 79 | # prevents eavesdropping on the performance metrics transmitted by the agent. 80 | # The encryption required by SSL introduces a nominal amount of CPU overhead, 81 | # which is performed asynchronously in a background thread. If you'd prefer 82 | # to send your metrics over http uncomment the following line. 83 | # ssl: false 84 | 85 | #============================== Browser Monitoring =============================== 86 | # New Relic Real User Monitoring gives you insight into the performance real users are 87 | # experiencing with your website. This is accomplished by measuring the time it takes for 88 | # your users' browsers to download and render your web pages by injecting a small amount 89 | # of JavaScript code into the header and footer of each page. 90 | browser_monitoring: 91 | # By default the agent automatically injects the monitoring JavaScript 92 | # into web pages. Set this attribute to false to turn off this behavior. 93 | auto_instrument: true 94 | 95 | # Proxy settings for connecting to the New Relic server. 96 | # 97 | # If a proxy is used, the host setting is required. Other settings 98 | # are optional. Default port is 8080. 99 | # 100 | # proxy_host: hostname 101 | # proxy_port: 8080 102 | # proxy_user: 103 | # proxy_pass: 104 | 105 | # The agent can optionally log all data it sends to New Relic servers to a 106 | # separate log file for human inspection and auditing purposes. To enable this 107 | # feature, change 'enabled' below to true. 108 | # See: https://newrelic.com/docs/ruby/audit-log 109 | audit_log: 110 | enabled: false 111 | 112 | # Tells transaction tracer and error collector (when enabled) 113 | # whether or not to capture HTTP params. When true, frameworks can 114 | # exclude HTTP parameters from being captured. 115 | # Rails: the RoR filter_parameter_logging excludes parameters 116 | # Java: create a config setting called "ignored_params" and set it to 117 | # a comma separated list of HTTP parameter names. 118 | # ex: ignored_params: credit_card, ssn, password 119 | capture_params: false 120 | 121 | # Transaction tracer captures deep information about slow 122 | # transactions and sends this to the New Relic service once a 123 | # minute. Included in the transaction is the exact call sequence of 124 | # the transactions including any SQL statements issued. 125 | transaction_tracer: 126 | 127 | # Transaction tracer is enabled by default. Set this to false to 128 | # turn it off. This feature is only available at the Professional 129 | # and above product levels. 130 | enabled: true 131 | 132 | # Threshold in seconds for when to collect a transaction 133 | # trace. When the response time of a controller action exceeds 134 | # this threshold, a transaction trace will be recorded and sent to 135 | # New Relic. Valid values are any float value, or (default) "apdex_f", 136 | # which will use the threshold for an dissatisfying Apdex 137 | # controller action - four times the Apdex T value. 138 | transaction_threshold: apdex_f 139 | 140 | # When transaction tracer is on, SQL statements can optionally be 141 | # recorded. The recorder has three modes, "off" which sends no 142 | # SQL, "raw" which sends the SQL statement in its original form, 143 | # and "obfuscated", which strips out numeric and string literals. 144 | record_sql: obfuscated 145 | 146 | # Threshold in seconds for when to collect stack trace for a SQL 147 | # call. In other words, when SQL statements exceed this threshold, 148 | # then capture and send to New Relic the current stack trace. This is 149 | # helpful for pinpointing where long SQL calls originate from. 150 | stack_trace_threshold: 0.500 151 | 152 | # Determines whether the agent will capture query plans for slow 153 | # SQL queries. Only supported in mysql and postgres. Should be 154 | # set to false when using other adapters. 155 | # explain_enabled: true 156 | 157 | # Threshold for query execution time below which query plans will 158 | # not be captured. Relevant only when `explain_enabled` is true. 159 | # explain_threshold: 0.5 160 | 161 | # Error collector captures information about uncaught exceptions and 162 | # sends them to New Relic for viewing 163 | error_collector: 164 | 165 | # Error collector is enabled by default. Set this to false to turn 166 | # it off. This feature is only available at the Professional and above 167 | # product levels. 168 | enabled: true 169 | 170 | # To stop specific errors from reporting to New Relic, set this property 171 | # to comma-separated values. Default is to ignore routing errors, 172 | # which are how 404's get triggered. 173 | ignore_errors: "ActionController::RoutingError,Sinatra::NotFound" 174 | 175 | # If you're interested in capturing memcache keys as though they 176 | # were SQL uncomment this flag. Note that this does increase 177 | # overhead slightly on every memcached call, and can have security 178 | # implications if your memcached keys are sensitive 179 | # capture_memcache_keys: true 180 | 181 | # Application Environments 182 | # ------------------------------------------ 183 | # Environment-specific settings are in this section. 184 | # For Rails applications, RAILS_ENV is used to determine the environment. 185 | # For Java applications, pass -Dnewrelic.environment to set 186 | # the environment. 187 | 188 | # NOTE if your application has other named environments, you should 189 | # provide newrelic configuration settings for these environments here. 190 | 191 | development: 192 | <<: *default_settings 193 | # Turn on communication to New Relic service in development mode 194 | monitor_mode: true 195 | app_name: My Application (Development) 196 | 197 | # Rails Only - when running in Developer Mode, the New Relic Agent will 198 | # present performance information on the last 100 transactions you have 199 | # executed since starting the mongrel. 200 | # NOTE: There is substantial overhead when running in developer mode. 201 | # Do not use for production or load testing. 202 | developer_mode: true 203 | 204 | test: 205 | <<: *default_settings 206 | # It almost never makes sense to turn on the agent when running 207 | # unit, functional or integration tests or the like. 208 | monitor_mode: false 209 | 210 | # Turn on the agent in production for 24x7 monitoring. NewRelic 211 | # testing shows an average performance impact of < 5 ms per 212 | # transaction, you can leave this on all the time without 213 | # incurring any user-visible performance degradation. 214 | production: 215 | <<: *default_settings 216 | monitor_mode: true 217 | 218 | # Many applications have a staging environment which behaves 219 | # identically to production. Support for that environment is provided 220 | # here. By default, the staging environment has the agent turned on. 221 | staging: 222 | <<: *default_settings 223 | monitor_mode: true 224 | app_name: My Application (Staging) 225 | -------------------------------------------------------------------------------- /db/migrate/20141020110537_issues.rb: -------------------------------------------------------------------------------- 1 | class Issues < ActiveRecord::Migration 2 | def change 3 | create_table :issues do |t| 4 | t.integer :github_id 5 | t.integer :redmine_id 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20141020110537) do 15 | 16 | create_table "issues", :force => true do |t| 17 | t.integer "github_id" 18 | t.integer "redmine_id" 19 | t.datetime "created_at", :null => false 20 | t.datetime "updated_at", :null => false 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /models/github_issue.rb: -------------------------------------------------------------------------------- 1 | class GithubIssue 2 | 3 | def initialize(data) 4 | @raw_data = data 5 | @issue = data["issue"] 6 | @comment = data["comment"] 7 | end 8 | 9 | def id 10 | @id ||= @issue["number"] 11 | end 12 | 13 | def status 14 | @status ||= @issue["state"] 15 | end 16 | 17 | def assignee 18 | @assignee ||= @issue["assignee"]["login"] rescue nil 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /models/issue.rb: -------------------------------------------------------------------------------- 1 | class Issue < ActiveRecord::Base 2 | 3 | validates_uniqueness_of :redmine_id, :github_id, :allow_nil => true 4 | 5 | def update_on_redmine(github) 6 | options = redmine_options(github) 7 | HTTParty.put("#{ENV['REDMINE_URL']}/issues/#{self.redmine_id}.json?key=#{ENV['REDMINE_API_KEY']}", options) 8 | end 9 | 10 | def create_on_github(redmine) 11 | options = github_options(redmine) 12 | res = HTTParty.post("https://api.github.com/repos/#{ENV['GITHUB_REPO']}/issues", options) 13 | self.github_id = res["number"] 14 | self.save 15 | end 16 | 17 | def update_on_github(redmine) 18 | options = github_options(redmine) 19 | HTTParty.patch("https://api.github.com/repos/#{ENV['GITHUB_REPO']}/issues/#{github_id}", options) 20 | end 21 | 22 | private 23 | def github_options(redmine) 24 | github_params.merge!({ 25 | body: { 26 | title: redmine.title, 27 | body: redmine.formated_description, 28 | state: @@mapping.status[redmine.status], 29 | labels: [@@mapping.default_label, redmine.priority].compact, 30 | assignee: redmine.assignee 31 | }.to_json 32 | }) 33 | end 34 | 35 | def github_params 36 | { 37 | headers: { 38 | "Accept" => "application/vnd.github.v3+json", 39 | "User-Agent" => ENV['GITHUB_OWNER'] 40 | }, 41 | basic_auth: { 42 | username: ENV['GITHUB_API_KEY'], 43 | password: "x-oauth-basic" 44 | } 45 | } 46 | end 47 | 48 | def redmine_options(github) 49 | { 50 | body: { 51 | issue: { 52 | status_id: @@mapping.status.key(github.status), 53 | assigned_to_id: @@mapping.assignee.key(github.assignee), 54 | } 55 | } 56 | } 57 | end 58 | 59 | end 60 | -------------------------------------------------------------------------------- /models/redmine_issue.rb: -------------------------------------------------------------------------------- 1 | class RedmineIssue 2 | 3 | attr_accessor :issue 4 | 5 | def initialize(data) 6 | @raw_data = data["payload"] 7 | @issue = api["issue"] 8 | end 9 | 10 | def id 11 | @id ||= @raw_data["issue"]["id"] 12 | end 13 | 14 | def api 15 | @api ||= HTTParty.get("#{ENV['REDMINE_URL']}/issues/#{id}.json?key=#{ENV['REDMINE_API_KEY']}&include=attachments,journals") 16 | end 17 | 18 | def title 19 | @title ||= issue["subject"] 20 | end 21 | 22 | def description 23 | @description ||= issue["description"] 24 | end 25 | 26 | def status 27 | @status ||= issue["status"]["id"] 28 | end 29 | 30 | def author 31 | @author ||= issue["author"]["name"] 32 | end 33 | 34 | def attachments 35 | @attachments ||= get_attachments 36 | end 37 | 38 | def comments 39 | @comments ||= get_comments 40 | end 41 | 42 | def priority 43 | @priority ||= @@mapping.priority[api["issue"]["priority"]["id"].to_i] rescue nil 44 | end 45 | 46 | def assignee 47 | @assignee ||= @@mapping.assignee[api["issue"]["assigned_to"]["id"].to_i] rescue nil 48 | end 49 | 50 | def formated_description 51 | data = String.new 52 | 53 | data += "*This issue was generated automatically from Redmine* 54 | 55 | **Author**: #{author} 56 | **Issue URL**: http://#{ENV['REDMINE_URL']}/issues/#{id} 57 | 58 | -- 59 | #### Description 60 | 61 | #{description} 62 | " 63 | 64 | attachments.each{|attachment| 65 | data += " 66 | Attachment: #{attachment})" 67 | } 68 | 69 | if comments.present? 70 | 71 | data += " 72 | \n 73 | -- 74 | #### Comments" 75 | 76 | comments.each_with_index{|comment, i| 77 | data += "\n *#{comment[:author]} - #{comment[:date].to_date}* 78 | #{comment[:comment]}\n\n--" 79 | } 80 | end 81 | 82 | data += "\n\n*Comment issue here: #{ENV['REDMINE_URL']}/issues/#{id}*" 83 | 84 | return(data) 85 | end 86 | 87 | def open? 88 | status == @@mapping.status.key("open") 89 | end 90 | 91 | private 92 | def get_attachments 93 | api["issue"]["attachments"].map{|attachment| 94 | attachment["content_url"] 95 | } 96 | end 97 | 98 | def get_comments 99 | api["issue"]["journals"].map{|journal| 100 | if journal["notes"].present? 101 | { 102 | comment: journal["notes"], 103 | author: journal["user"]["name"], 104 | date: journal["created_on"] 105 | } 106 | end 107 | }.compact! 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /provisioning/playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | remote_user: vagrant 4 | vars: 5 | postgresql_version: 9.3 6 | postgresql_encoding: 'UTF-8' 7 | postgresql_locale: 'en_US.UTF-8' 8 | postgresql_admin_user: "postgres" 9 | postgresql_default_auth_method: "trust" 10 | 11 | postgresql_databases: 12 | - name: issue-sync-redmine-github 13 | 14 | postgresql_users: 15 | - name: vagrant 16 | 17 | rvm1_rubies: 18 | - 'ruby-2.1.2' 19 | rvm1_install_flags: '--auto-dotfiles --user-install' 20 | rvm1_install_path: '/home/{{ ansible_ssh_user }}/.rvm' 21 | 22 | 23 | pre_tasks: 24 | - locale_gen: name=en_US.UTF-8 state=present 25 | 26 | - apt: update_cache=yes cache_valid_time=3600 27 | 28 | - name: Install base packages 29 | action: apt pkg={{item}} state=installed 30 | with_items: 31 | - vim 32 | - ftp 33 | - git 34 | - zip 35 | - unzip 36 | - htop 37 | - tree 38 | - curl 39 | - build-essential 40 | - libxml2-dev 41 | - libxslt1-dev 42 | - wget 43 | 44 | roles: 45 | - { role: rvm_io.rvm1-ruby, tags: ruby, sudo: false } 46 | - postgresql 47 | 48 | tasks: 49 | 50 | - name: rvm | source rvm to .profile 51 | lineinfile: dest=/home/{{ansible_ssh_user}}/.profile state=present regexp='\.rvm\/scripts' line='test -f $HOME/.rvm/scripts/rvm && source $HOME/.rvm/scripts/rvm' 52 | sudo: false 53 | 54 | - name: bashrc | /vagrant as default directory 55 | shell: echo "cd /vagrant" >> /home/vagrant/.bashrc 56 | sudo: false 57 | 58 | - name: bashrc | set LC_ALL 59 | shell: echo "export LC_ALL=en_US.UTF-8" >> /home/vagrant/.bashrc 60 | sudo: false 61 | 62 | - name: bashrc | set LANG 63 | shell: echo "export LANG=en_US.UTF-8" >> /home/vagrant/.bashrc 64 | sudo: false 65 | 66 | - name: Install postgresql Dev package 67 | action: apt pkg={{item}} state=installed 68 | with_items: 69 | - postgresql-server-dev-9.3 70 | 71 | - name: Install Heroku Toolbelt 72 | shell: wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh 73 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .AppleDouble 3 | .LSOverride 4 | Icon 5 | ._* 6 | .Spotlight-V100 7 | .Trashes 8 | .vagrant 9 | test 10 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | before_install: 5 | - sudo apt-get update -qq 6 | - sudo apt-get install -qq python-apt python-pycurl 7 | install: 8 | - pip install ansible==1.5.0 9 | script: 10 | - echo localhost > inventory 11 | - ansible-playbook --syntax-check -i inventory test.yml 12 | - ansible-playbook -i inventory test.yml --connection=local --sudo 13 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2014 Pieterjan Vandaele 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/README.md: -------------------------------------------------------------------------------- 1 | ## ANXS - PostgreSQL [![Build Status](https://travis-ci.org/ANXS/postgresql.png)](https://travis-ci.org/ANXS/postgresql) 2 | 3 | Ansible role which installs and configures PostgreSQL, extensions, databases and users. 4 | 5 | 6 | #### Requirements & Dependencies 7 | - Tested on Ansible 1.4 or higher. 8 | - ANXS.monit ([Galaxy](https://galaxy.ansible.com/list#/roles/502)/[GH](https://github.com/ANXS/monit)) if you want monit protection (in that case, you should set `monit_protection: true`) 9 | 10 | 11 | #### Variables 12 | 13 | ```yaml 14 | # Basic settings 15 | postgresql_version: 9.3 16 | postgresql_encoding: 'UTF-8' 17 | postgresql_locale: 'en_US.UTF-8' 18 | 19 | postgresql_admin_user: "postgres" 20 | postgresql_default_auth_method: "trust" 21 | 22 | postgresql_cluster_name: "main" 23 | postgresql_cluster_reset: false 24 | 25 | # List of databases to be created (optional) 26 | postgresql_databases: 27 | - name: foobar 28 | hstore: yes # flag to install the hstore extension on this database (yes/no) 29 | uuid_ossp: yes # flag to install the uuid-ossp extension on this database (yes/no) 30 | 31 | # List of users to be created (optional) 32 | postgresql_users: 33 | - name: baz 34 | pass: pass 35 | encrypted: no # denotes if the password is already encrypted. 36 | 37 | # List of user privileges to be applied (optional) 38 | postgresql_user_privileges: 39 | - name: baz # user name 40 | db: foobar # database 41 | priv: "ALL" # privilege string format: example: INSERT,UPDATE/table:SELECT/anothertable:ALL 42 | ``` 43 | 44 | There's a lot more knobs and bolts to set, which you can find in the defaults/main.yml 45 | 46 | 47 | #### License 48 | 49 | Licensed under the MIT License. See the LICENSE file for details. 50 | 51 | #### Thanks 52 | 53 | To the contributors: 54 | - [Ralph von der Heyden](https://github.com/ralph) 55 | 56 | 57 | #### Feedback, bug-reports, requests, ... 58 | 59 | Are [welcome](https://github.com/ANXS/postgresql/issues)! 60 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/defaults/main.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/defaults/main.yml 2 | 3 | # Basic settings 4 | postgresql_version: 9.3 5 | postgresql_encoding: 'UTF-8' 6 | postgresql_locale: 'en_US.UTF-8' 7 | 8 | postgresql_admin_user: "postgres" 9 | postgresql_default_auth_method: "trust" 10 | 11 | postgresql_cluster_name: "main" 12 | postgresql_cluster_reset: false 13 | 14 | # Extensions 15 | postgresql_ext_install_contrib: no 16 | postgresql_ext_install_dev_headers: no 17 | postgresql_ext_install_postgis: no 18 | 19 | postgresql_ext_postgis_version: "2.1" # be careful: check whether the postgresql/postgis versions work together 20 | 21 | # List of databases to be created (optional) 22 | postgresql_databases: [] 23 | 24 | # List of users to be created (optional) 25 | postgresql_users: [] 26 | 27 | # List of user privileges to be applied (optional) 28 | postgresql_user_privileges: [] 29 | 30 | # pg_hba.conf 31 | postgresql_pg_hba_default: 32 | - { type: local, database: all, user: '{{ postgresql_admin_user }}', address: '', method: '{{ postgresql_default_auth_method }}', comment: '' } 33 | - { type: local, database: all, user: all, address: '', method: '{{ postgresql_default_auth_method }}', comment: '"local" is for Unix domain socket connections only' } 34 | - { type: host, database: all, user: all, address: '127.0.0.1/32', method: '{{ postgresql_default_auth_method }}', comment: 'IPv4 local connections:' } 35 | - { type: host, database: all, user: all, address: '::1/128', method: '{{ postgresql_default_auth_method }}', comment: 'IPv6 local connections:' } 36 | 37 | postgresql_pg_hba_passwd_hosts: [] 38 | postgresql_pg_hba_trust_hosts: [] 39 | postgresql_pg_hba_custom: [] 40 | 41 | 42 | # postgresql.conf 43 | 44 | #------------------------------------------------------------------------------ 45 | # FILE LOCATIONS 46 | #------------------------------------------------------------------------------ 47 | 48 | # Location of postgres configuration files here 49 | postgresql_conf_directory: "/etc/postgresql/{{postgresql_version}}/{{postgresql_cluster_name}}" 50 | # HBA (Host Based Authentication) file 51 | postgresql_hba_file: "{{postgresql_conf_directory}}/pg_hba.conf" 52 | # Ident configuration file 53 | postgresql_ident_file: "{{postgresql_conf_directory}}/pg_ident.conf" 54 | # Use data in another directory 55 | postgresql_data_directory: "/var/lib/postgresql/{{postgresql_version}}/{{postgresql_cluster_name}}" 56 | # If external_pid_file is not explicitly set, on extra PID file is written 57 | postgresql_external_pid_file: "/var/run/postgresql/{{postgresql_version}}-{{postgresql_cluster_name}}.pid" 58 | 59 | #------------------------------------------------------------------------------ 60 | # CONNECTIONS AND AUTHENTICATION 61 | #------------------------------------------------------------------------------ 62 | 63 | postgresql_listen_addresses: 64 | - localhost 65 | postgresql_port: 5432 66 | 67 | postgresql_max_connections: 100 68 | postgresql_superuser_reserved_connections: 3 69 | 70 | postgresql_unix_socket_directories: 71 | - /var/run/postgresql 72 | postgresql_unix_socket_group: '' 73 | postgresql_unix_socket_permissions: '0777' # begin with 0 to use octal notation 74 | 75 | # Automatic pg_ctl configuration. Specify a list of options containing 76 | # cluster specific options to be passed to pg_ctl(1). 77 | postgresql_pg_ctl_options: [] 78 | 79 | postgresql_bonjour: off # advertise server via Bonjour 80 | postgresql_bonjour_name: '' # defaults to the computer name 81 | 82 | 83 | # - Security and Authentication - 84 | 85 | postgresql_authentication_timeout: 60s 86 | postgresql_ssl: off 87 | postgresql_ssl_ciphers: 88 | - 'DEFAULT' 89 | - '!LOW' 90 | - '!EXP' 91 | - '!MD5' 92 | - '@STRENGTH' 93 | postgresql_ssl_renegotiation_limit: 512MB # amount of data between renegotiations 94 | postgresql_ssl_cert_file: /etc/ssl/certs/ssl-cert-snakeoil.pem 95 | postgresql_ssl_key_file: /etc/ssl/private/ssl-cert-snakeoil.key 96 | postgresql_ssl_ca_file: '' 97 | postgresql_ssl_crl_file: '' 98 | postgresql_password_encryption: on 99 | postgresql_db_user_namespace: off 100 | 101 | # Kerberos and GSSAPI 102 | postgresql_krb_server_keyfile: '' 103 | postgresql_krb_srvname: postgres 104 | postgresql_krb_caseins_users: off 105 | 106 | # TCP Keepalives, 0 selects the system default (in seconds) 107 | postgresql_tcp_keepalives_idle: 0 108 | postgresql_tcp_keepalives_interval: 0 109 | postgresql_tcp_keepalives_count: 0 110 | 111 | 112 | #------------------------------------------------------------------------------ 113 | # RESOURCE USAGE (except WAL) 114 | #------------------------------------------------------------------------------ 115 | 116 | # - Memory - 117 | 118 | postgresql_shared_buffers: 128MB # min 128kB 119 | postgresql_temp_buffers: 8MB # min 800kB 120 | 121 | # Note: Increasing max_prepared_transactions costs ~600 bytes of shared memory 122 | # per transaction slot, plus lock space (see max_locks_per_transaction). 123 | # It is not advisable to set max_prepared_transactions nonzero unless you 124 | # actively intend to use prepared transactions. 125 | postgresql_max_prepared_transactions: 0 # zero disables the feature 126 | 127 | postgresql_work_mem: 1MB # min 64kB 128 | postgresql_maintenance_work_mem: 16MB # min 1MB 129 | postgresql_max_stack_depth: 2MB # min 100kB 130 | 131 | 132 | # - Disk - 133 | 134 | # limits per-session temp file space in kB, or -1 for no limit 135 | postgresql_temp_file_limit: -1 136 | 137 | 138 | # - Kernel Resource Usage - 139 | 140 | postgresql_max_files_per_process: 1000 # min 25 141 | postgresql_shared_preload_libraries: [] 142 | 143 | 144 | # - Cost-Based Vacuum Delay - 145 | 146 | postgresql_vacuum_cost_delay: 0 # 0-100 milliseconds 147 | postgresql_vacuum_cost_page_hit: 1 # 0-10000 credits 148 | postgresql_vacuum_cost_page_miss: 10 # 0-10000 credits 149 | postgresql_vacuum_cost_page_dirty: 20 # 0-10000 credits 150 | postgresql_vacuum_cost_limit: 200 # 1-10000 credits 151 | 152 | 153 | # - Background Writer - 154 | 155 | postgresql_bgwriter_delay: 200ms # 10-10000ms between rounds 156 | postgresql_bgwriter_lru_maxpages: 100 # 0-1000 max buffers written/round 157 | postgresql_bgwriter_lru_multiplier: 2.0 # 0-10.0 multipler on buffers scanned/round 158 | 159 | 160 | # - Asynchronous Behavior - 161 | 162 | postgresql_effective_io_concurrency: 1 # 1-1000; 0 disables prefetching 163 | 164 | 165 | #------------------------------------------------------------------------------ 166 | # WRITE AHEAD LOG 167 | #------------------------------------------------------------------------------ 168 | 169 | # - Settings - 170 | 171 | postgresql_wal_level: minimal # minimal, archive, or hot_standby 172 | postgresql_fsync: on # turns forced synchronization on or off 173 | 174 | # Synchronization level: 175 | # - off 176 | # - local 177 | # - remote_write 178 | # - on 179 | postgresql_synchronous_commit: on 180 | 181 | # The default is the first option supported by the operating system: 182 | # - open_datasync 183 | # - fdatasync (default on Linux) 184 | # - fsync 185 | # - fsync_writethrough 186 | # - open_sync 187 | postgresql_wal_sync_method: fsync 188 | 189 | # recover from partial page writes 190 | postgresql_full_page_writes: on 191 | 192 | postgresql_wal_buffers: -1 # min 32kB, -1 sets based on shared_buffers 193 | postgresql_wal_writer_delay: 200ms # 1-10000 milliseconds 194 | postgresql_commit_delay: 0 # range 0-100000, in microseconds 195 | postgresql_commit_siblings: 5 # range 1-1000 196 | 197 | 198 | # - Checkpoints - 199 | 200 | postgresql_checkpoint_segments: 3 # in logfile segments, min 1, 16MB each 201 | postgresql_checkpoint_timeout: 5min # range 30s-1h 202 | postgresql_checkpoint_completion_target: 0.5 # checkpoint target duration, 0.0 - 1.0 203 | postgresql_checkpoint_warning: 30s # 0 disables 204 | 205 | 206 | # - Archiving - 207 | 208 | # allows archiving to be done 209 | postgresql_archive_mode: off 210 | 211 | # Command to use to archive a logfile segment. 212 | # Placeholders: %p = path of file to archive 213 | # %f = file name only 214 | # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' 215 | postgresql_archive_command: '' 216 | 217 | # force a logfile segment switch after this 218 | postgresql_archive_timeout: 0 219 | 220 | 221 | #------------------------------------------------------------------------------ 222 | # REPLICATION 223 | #------------------------------------------------------------------------------ 224 | 225 | # - Sending Server(s) - 226 | 227 | # Set these on the master and on any standby that will send replication data. 228 | 229 | # max number of walsender processes 230 | postgresql_max_wal_senders: 0 231 | 232 | postgresql_wal_keep_segments: 0 # in logfile segments, 16MB each; 0 disables 233 | postgresql_wal_sender_timeout: 60s # in milliseconds; 0 disables 234 | 235 | 236 | # - Master Server - 237 | 238 | # These settings are ignored on a standby server. 239 | 240 | # Standby servers that provide sync rep. 241 | # Comma-separated list of application_name from standby(s) 242 | postgresql_synchronous_standby_names: [] # '*' means 'all' 243 | 244 | # number of xacts by which cleanup is delayed 245 | postgresql_vacuum_defer_cleanup_age: 0 246 | 247 | 248 | # - Standby Servers - 249 | 250 | # "on" allows queries during recovery 251 | postgresql_hot_standby: off 252 | # max delay before canceling queries when reading WAL from archive 253 | postgresql_max_standby_archive_delay: 30s # -1 allows indefinite delay 254 | # max delay before canceling queries when reading streaming WAL; 255 | postgresql_max_standby_streaming_delay: 30s # -1 allows indefinite delay 256 | # send replies at least this often 257 | postgresql_wal_receiver_status_interval: 10s # 0 disables 258 | # send info from standby to prevent query conflicts 259 | postgresql_hot_standby_feedback: off 260 | #time that receiver waits for communication from master in milliseconds 261 | postgresql_wal_receiver_timeout: 60s 262 | 263 | 264 | #------------------------------------------------------------------------------ 265 | # QUERY TUNING 266 | #------------------------------------------------------------------------------ 267 | 268 | # - Planner Method Configuration - 269 | 270 | postgresql_enable_bitmapscan: on 271 | postgresql_enable_hashagg: on 272 | postgresql_enable_hashjoin: on 273 | postgresql_enable_indexscan: on 274 | postgresql_enable_indexonlyscan: on 275 | postgresql_enable_material: on 276 | postgresql_enable_mergejoin: on 277 | postgresql_enable_nestloop: on 278 | postgresql_enable_seqscan: on 279 | postgresql_enable_sort: on 280 | postgresql_enable_tidscan: on 281 | 282 | 283 | # - Planner Cost Constants - 284 | 285 | postgresql_seq_page_cost: 1.0 # measured on an arbitrary scale 286 | postgresql_random_page_cost: 4.0 # same scale as above 287 | postgresql_cpu_tuple_cost: 0.01 # same scale as above 288 | postgresql_cpu_index_tuple_cost: 0.005 # same scale as above 289 | postgresql_cpu_operator_cost: 0.0025 # same scale as above 290 | postgresql_effective_cache_size: 128MB 291 | 292 | 293 | # - Genetic Query Optimizer - 294 | 295 | postgresql_geqo: on 296 | postgresql_geqo_threshold: 12 297 | postgresql_geqo_effort: 5 # range 1-10 298 | postgresql_geqo_pool_size: 0 # selects default based on effort 299 | postgresql_geqo_generations: 0 # selects default based on effort 300 | postgresql_geqo_selection_bias: 2.0 # range 1.5-2.0 301 | postgresql_geqo_seed: 0.0 # range 0.0-1.0 302 | 303 | 304 | # - Other Planner Options - 305 | 306 | postgresql_default_statistics_target: 100 # range 1-10000 307 | postgresql_constraint_exclusion: partition # on, off, or partition 308 | postgresql_cursor_tuple_fraction: 0.1 # range 0.0-1.0 309 | postgresql_from_collapse_limit: 8 310 | postgresql_join_collapse_limit: 8 # 1 disables collapsing of explicit 311 | 312 | 313 | #------------------------------------------------------------------------------ 314 | # ERROR REPORTING AND LOGGING 315 | #------------------------------------------------------------------------------ 316 | 317 | # - Where to Log - 318 | 319 | # Valid values are combinations of stderr, csvlog, syslog, and eventlog. 320 | # depending on platform. Csvlog requires logging_collector to be on. 321 | postgresql_log_destination: stderr 322 | 323 | # Enable capturing of stderr and csvlog into log files. 324 | # Required to be on for csvlogs. 325 | postgresql_logging_collector: off 326 | 327 | # These are only used if logging_collector is on: 328 | 329 | # Directory where log files are written, can be absolute or relative to PGDATA 330 | postgresql_log_directory: pg_log 331 | # Log file name pattern, can include strftime() escapes 332 | postgresql_log_filename: postgresql-%Y-%m-%d_%H%M%S.log 333 | postgresql_log_file_mode: '0600' # begin with 0 to use octal notation 334 | # If on, an existing log file with the same name as the new log file will be 335 | # truncated rather than appended to. But such truncation only occurs on 336 | # time-driven rotation, not on restarts or size-driven rotation. Default is 337 | # off, meaning append to existing files in all cases. 338 | postgresql_log_truncate_on_rotation: off 339 | # Automatic rotation of logfiles will happen after that time. 340 | postgresql_log_rotation_age: 1d 341 | # Automatic rotation of logfiles will happen after that much log output. 342 | postgresql_log_rotation_size: 10MB 343 | 344 | # These are relevant when logging to syslog: 345 | postgresql_syslog_facility: LOCAL0 346 | postgresql_syslog_ident: postgres 347 | # This is only relevant when logging to eventlog (win32): 348 | postgresql_event_source: PostgreSQL 349 | 350 | 351 | # - When to Log - 352 | 353 | # Values in order of decreasing detail: 354 | # - debug5 355 | # - debug4 356 | # - debug3 357 | # - debug2 358 | # - debug1 359 | # - log 360 | # - notice 361 | # - warning 362 | # - error 363 | postgresql_client_min_messages: notice 364 | 365 | # Values in order of decreasing detail: 366 | # - debug5 367 | # - debug4 368 | # - debug3 369 | # - debug2 370 | # - debug1 371 | # - info 372 | # - notice 373 | # - warning 374 | # - error 375 | # - log 376 | # - fatal 377 | # - panic 378 | postgresql_log_min_messages: warning 379 | 380 | # Values in order of decreasing detail: 381 | # - debug5 382 | # - debug4 383 | # - debug3 384 | # - debug2 385 | # - debug1 386 | # - info 387 | # - notice 388 | # - warning 389 | # - error 390 | # - log 391 | # - fatal 392 | # - panic (effectively off) 393 | postgresql_log_min_error_statement: error 394 | 395 | # -1 is disabled, 0 logs all statements and their durations, > 0 logs only 396 | # statements running at least this number of milliseconds 397 | postgresql_log_min_duration_statement: -1 398 | 399 | 400 | # - What to Log - 401 | 402 | postgresql_debug_print_parse: off 403 | postgresql_debug_print_rewritten: off 404 | postgresql_debug_print_plan: off 405 | postgresql_debug_pretty_print: on 406 | postgresql_log_checkpoints: off 407 | postgresql_log_connections: off 408 | postgresql_log_disconnections: off 409 | postgresql_log_duration: off 410 | postgresql_log_error_verbosity: default # terse, default, or verbose messages 411 | postgresql_log_hostname: off 412 | 413 | # Special values: 414 | # %a = application name 415 | # %u = user name 416 | # %d = database name 417 | # %r = remote host and port 418 | # %h = remote host 419 | # %p = process ID 420 | # %t = timestamp without milliseconds 421 | # %m = timestamp with milliseconds 422 | # %i = command tag 423 | # %e = SQL state 424 | # %c = session ID 425 | # %l = session line number 426 | # %s = sessioan start timestamp 427 | # %v = virtual transaction ID 428 | # %x = transaction ID (0 if none) 429 | # %q = stop here in non-session 430 | # processes 431 | # %% = '%' 432 | postgresql_log_line_prefix: '%t ' 433 | 434 | # log lock waits >= deadlock_timeout 435 | postgresql_log_lock_waits: off 436 | postgresql_log_statement: none # none, ddl, mod, all 437 | # log temporary files equal or larger 438 | postgresql_log_temp_files: -1 439 | postgresql_log_timezone: UTC 440 | 441 | 442 | #------------------------------------------------------------------------------ 443 | # RUNTIME STATISTICS 444 | #------------------------------------------------------------------------------ 445 | 446 | # - Query/Index Statistics Collector - 447 | 448 | postgresql_track_activities: on 449 | postgresql_track_counts: on 450 | postgresql_track_io_timing: off 451 | postgresql_track_functions: none # none, pl, all 452 | postgresql_track_activity_query_size: 1024 453 | postgresql_update_process_title: on 454 | postgresql_stats_temp_directory: pg_stat_tmp 455 | 456 | 457 | # - Statistics Monitoring - 458 | 459 | postgresql_log_parser_stats: off 460 | postgresql_log_planner_stats: off 461 | postgresql_log_executor_stats: off 462 | postgresql_log_statement_stats: off 463 | 464 | 465 | #------------------------------------------------------------------------------ 466 | # AUTOVACUUM PARAMETERS 467 | #------------------------------------------------------------------------------ 468 | 469 | # Enable autovacuum subprocess? 'on' requires track_counts to also be on. 470 | postgresql_autovacuum: on 471 | # -1 disables, 0 logs all actions and their durations, > 0 logs only 472 | # actions running at least this number of milliseconds. 473 | postgresql_log_autovacuum_min_duration: -1 474 | # max number of autovacuum subprocesses 475 | postgresql_autovacuum_max_workers: 3 476 | # time between autovacuum runs 477 | postgresql_autovacuum_naptime: 1min 478 | # min number of row updates before vacuum 479 | postgresql_autovacuum_vacuum_threshold: 50 480 | # min number of row updates before analyze 481 | postgresql_autovacuum_analyze_threshold: 50 482 | # fraction of table size before vacuum 483 | postgresql_autovacuum_vacuum_scale_factor: 0.2 484 | # fraction of table size before analyze 485 | postgresql_autovacuum_analyze_scale_factor: 0.1 486 | # maximum XID age before forced vacuum 487 | postgresql_autovacuum_freeze_max_age: 200000000 488 | # default vacuum cost delay for autovacuum, in milliseconds 489 | postgresql_autovacuum_vacuum_cost_delay: 20ms 490 | # default vacuum cost limit for autovacuum, 491 | postgresql_autovacuum_vacuum_cost_limit: -1 492 | 493 | 494 | #------------------------------------------------------------------------------ 495 | # CLIENT CONNECTION DEFAULTS 496 | #------------------------------------------------------------------------------ 497 | 498 | # - Statement Behavior - 499 | 500 | postgresql_search_path: # schema names 501 | - '"$user"' 502 | - public 503 | postgresql_default_tablespace: '' # a tablespace name, '' uses the default 504 | postgresql_temp_tablespaces: [] # a list of tablespace names 505 | 506 | postgresql_check_function_bodies: on 507 | postgresql_default_transaction_isolation: read committed 508 | postgresql_default_transaction_read_only: off 509 | postgresql_default_transaction_deferrable: off 510 | postgresql_session_replication_role: origin 511 | 512 | postgresql_statement_timeout: 0 # in milliseconds, 0 is disabled 513 | postgresql_lock_timeout: 0 # in milliseconds, 0 is disabled 514 | postgresql_vacuum_freeze_min_age: 50000000 515 | postgresql_vacuum_freeze_table_age: 150000000 516 | 517 | postgresql_bytea_output: hex # hex, escape 518 | postgresql_xmlbinary: base64 519 | postgresql_xmloption: content 520 | 521 | 522 | # - Locale and Formatting - 523 | 524 | postgresql_datestyle: 525 | - iso 526 | - mdy 527 | postgresql_intervalstyle: postgres 528 | postgresql_timezone: UTC 529 | 530 | # Select the set of available time zone abbreviations. Currently, there are: 531 | # Default 532 | # Australia 533 | # India 534 | # You can create your own file in `share/timezonesets/`. 535 | postgresql_timezone_abbreviations: Default 536 | 537 | postgresql_extra_float_digits: 0 # min -15, max 3 538 | postgresql_client_encoding: sql_ascii # 'sql_ascii' actually defaults to database encoding 539 | 540 | # These settings are initialized by initdb, but they can be changed. 541 | 542 | # locale for system error message 543 | postgresql_lc_messages: en_US.UTF-8 544 | # locale for monetary formatting 545 | postgresql_lc_monetary: en_US.UTF-8 546 | # locale for number formatting 547 | postgresql_lc_numeric: en_US.UTF-8 548 | # locale for time formatting 549 | postgresql_lc_time: en_US.UTF-8 550 | 551 | postgresql_default_text_search_config: pg_catalog.english 552 | 553 | postgresql_dynamic_library_path: '$libdir' 554 | postgresql_local_preload_libraries: [] 555 | 556 | 557 | #------------------------------------------------------------------------------ 558 | # LOCK MANAGEMENT 559 | #------------------------------------------------------------------------------ 560 | 561 | postgresql_deadlock_timeout: 1s 562 | postgresql_max_locks_per_transaction: 64 # min 10 563 | 564 | # Note: Each lock table slot uses ~270 bytes of shared memory, and there are 565 | # max_locks_per_transaction * (max_connections + max_prepared_transactions) 566 | # lock table slots. 567 | postgresql_max_pred_locks_per_transaction: 64 # min 10 568 | 569 | 570 | #------------------------------------------------------------------------------ 571 | # VERSION/PLATFORM COMPATIBILITY 572 | #------------------------------------------------------------------------------ 573 | 574 | # - Previous PostgreSQL Versions - 575 | 576 | postgresql_array_nulls: on 577 | postgresql_backslash_quote: safe_encoding # on, off, or safe_encoding 578 | postgresql_default_with_oids: off 579 | postgresql_escape_string_warning: on 580 | postgresql_lo_compat_privileges: off 581 | postgresql_quote_all_identifiers: off 582 | postgresql_sql_inheritance: on 583 | postgresql_standard_conforming_strings: on 584 | postgresql_synchronize_seqscans: on 585 | 586 | 587 | # - Other Platforms and Clients - 588 | 589 | postgresql_transform_null_equals: off 590 | 591 | 592 | #------------------------------------------------------------------------------ 593 | # ERROR HANDLING 594 | #------------------------------------------------------------------------------ 595 | 596 | # Terminate session on any error? 597 | postgresql_exit_on_error: off 598 | # Reinitialize after backend crash? 599 | postgresql_restart_after_crash: on 600 | 601 | 602 | 603 | 604 | postgresql_env: 605 | LC_ALL: "{{ postgresql_locale }}" 606 | LC_LCTYPE: "{{ postgresql_locale }}" 607 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/handlers/main.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/handlers/main.yml 2 | 3 | - name: restart postgresql 4 | service: 5 | name: postgresql 6 | state: restarted 7 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/meta/main.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/meta/main.yml 2 | 3 | galaxy_info: 4 | author: pjan vandaele 5 | company: ANXS 6 | description: "Install and configure PostgreSQL, dependencies, extensions, databases and users." 7 | min_ansible_version: 1.4 8 | license: MIT 9 | platforms: 10 | - name: Ubuntu 11 | versions: 12 | - all 13 | categories: 14 | - database 15 | - database:sql 16 | 17 | dependencies: [] 18 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/configure.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/configure.yml 2 | 3 | - name: PostgreSQL | Make sure the postgres data directory exists 4 | file: 5 | path: "{{postgresql_data_directory}}" 6 | owner: "{{postgresql_admin_user}}" 7 | group: "{{postgresql_admin_user}}" 8 | state: directory 9 | mode: 0700 10 | 11 | - name: PostgreSQL | Reset the cluster - drop the existing one 12 | shell: pg_dropcluster --stop {{postgresql_version}} {{postgresql_cluster_name}} 13 | sudo: yes 14 | sudo_user: postgres 15 | when: postgresql_cluster_reset 16 | 17 | - name: PostgreSQL | Reset the cluster - create a new one (with specified encoding and locale) 18 | shell: pg_createcluster --start --locale {{postgresql_locale}} -e {{postgresql_encoding}} -d {{postgresql_data_directory}} {{postgresql_version}} {{postgresql_cluster_name}} 19 | sudo: yes 20 | sudo_user: postgres 21 | when: postgresql_cluster_reset 22 | 23 | - name: PostgreSQL | Update configuration - pt. 1 (pg_hba.conf) 24 | template: 25 | src: pg_hba.conf.j2 26 | dest: "{{postgresql_conf_directory}}/pg_hba.conf" 27 | owner: "{{postgresql_admin_user}}" 28 | group: "{{postgresql_admin_user}}" 29 | mode: 0640 30 | register: postgresql_configuration_pt1 31 | 32 | - name: PostgreSQL | Update configuration - pt. 2 (postgresql.conf) 33 | template: 34 | src: postgresql.conf.j2 35 | dest: "{{postgresql_conf_directory}}/postgresql.conf" 36 | owner: "{{postgresql_admin_user}}" 37 | group: "{{postgresql_admin_user}}" 38 | mode: 0640 39 | register: postgresql_configuration_pt2 40 | 41 | - name: PostgreSQL | Create folder for additional configuration files 42 | file: 43 | name: "{{postgresql_conf_directory}}/conf.d" 44 | state: directory 45 | owner: "{{postgresql_admin_user}}" 46 | group: "{{postgresql_admin_user}}" 47 | mode: 0755 48 | 49 | - name: PostgreSQL | Restart PostgreSQL 50 | service: 51 | name: postgresql 52 | state: restarted 53 | when: postgresql_configuration_pt1.changed or postgresql_configuration_pt2.changed 54 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/databases.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/databases.yml 2 | 3 | - name: PostgreSQL | Ensure PostgreSQL is running 4 | service: 5 | name: postgresql 6 | state: started 7 | 8 | - name: PostgreSQL | Make sure the PostgreSQL databases are present 9 | postgresql_db: 10 | name: "{{item.name}}" 11 | encoding: "{{postgresql_encoding}}" 12 | lc_collate: "{{postgresql_locale}}" 13 | lc_ctype: "{{postgresql_locale}}" 14 | template: "template0" 15 | state: present 16 | with_items: postgresql_databases 17 | when: postgresql_databases|length > 0 18 | 19 | - name: PostgreSQL | Add hstore to the databases with the requirement 20 | sudo: yes 21 | sudo_user: "{{postgresql_admin_user}}" 22 | shell: "psql {{item.name}} -c 'CREATE EXTENSION IF NOT EXISTS hstore;'" 23 | with_items: postgresql_databases 24 | when: item.hstore is defined and item.hstore 25 | 26 | - name: PostgreSQL | Add uuid-ossp to the database with the requirement 27 | sudo: yes 28 | sudo_user: "{{postgresql_admin_user}}" 29 | shell: "psql {{item.name}} -c 'CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";'" 30 | with_items: postgresql_databases 31 | when: item.uuid_ossp is defined and item.uuid_ossp 32 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/extensions.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/extensions.yml 2 | 3 | - include: extensions/contrib.yml 4 | when: postgresql_ext_install_contrib 5 | - include: extensions/dev_headers.yml 6 | when: postgresql_ext_install_dev_headers 7 | - include: extensions/postgis.yml 8 | when: postgresql_ext_install_postgis 9 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/extensions/contrib.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/extensions/contrib.yml 2 | 3 | - name: PostgreSQL | Extensions | Make sure the postgres contrib extensions are installed 4 | apt: 5 | name: "postgresql-contrib-{{postgresql_version}}" 6 | state: present 7 | notify: 8 | - restart postgresql 9 | 10 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/extensions/dev_headers.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/extensions/dev_headers.yml 2 | 3 | - name: PostgreSQL | Extensions | Make sure the development headers are installed 4 | apt: 5 | name: libpq-dev 6 | state: present 7 | notify: 8 | - restart postgresql 9 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/extensions/postgis.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/extensions/postgis.yml 2 | 3 | - name: PostgreSQL | Extensions | Make sure the postgis extensions are installed 4 | apt: 5 | name: "{{item}}" 6 | state: present 7 | with_items: 8 | - libgeos-c1 9 | - "postgresql-{{postgresql_version}}-postgis-{{postgresql_ext_postgis_version}}" 10 | notify: 11 | - restart postgresql 12 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/install.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/install.yml 2 | 3 | - name: PostgreSQL | Make sure the dependencies are installed 4 | apt: 5 | pkg: "{{item}}" 6 | state: present 7 | with_items: ["python-psycopg2", "python-pycurl"] 8 | 9 | - name: PostgreSQL | Add PostgreSQL repository apt-key 10 | apt_key: 11 | id: ACCC4CF8 12 | url: "https://www.postgresql.org/media/keys/ACCC4CF8.asc" 13 | state: present 14 | 15 | - name: PostgreSQL | Add PostgreSQL repository 16 | apt_repository: 17 | repo: 'deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main' 18 | state: present 19 | 20 | - name: PostgreSQL | Install PostgreSQL 21 | apt: 22 | name: "{{item}}" 23 | state: present 24 | environment: postgresql_env 25 | with_items: 26 | - "postgresql-{{postgresql_version}}" 27 | - "postgresql-client-{{postgresql_version}}" 28 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/main.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/main.yml 2 | 3 | - include: install.yml 4 | tags: [postgresql, postgresql-install] 5 | 6 | - include: extensions.yml 7 | tags: [postgresql, postgresql-extensions] 8 | 9 | - include: configure.yml 10 | tags: [postgresql, postgresql-configure] 11 | 12 | - include: databases.yml 13 | tags: [postgresql, postgresql-databases] 14 | 15 | - include: users.yml 16 | tags: [postgresql, postgresql-users] 17 | 18 | - include: monit.yml 19 | when: monit_protection is defined and monit_protection == true 20 | tags: [postgresql, postgresql-monit] 21 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/monit.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/monit.yml 2 | 3 | - name: PostgreSQL | (Monit) Copy the postgresql monit service file 4 | template: 5 | src: etc_monit_conf.d_postgresql.j2 6 | dest: /etc/monit/conf.d/postgresql 7 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/tasks/users.yml: -------------------------------------------------------------------------------- 1 | # file: postgresql/tasks/users.yml 2 | 3 | - name: PostgreSQL | Ensure PostgreSQL is running 4 | service: 5 | name: postgresql 6 | state: started 7 | 8 | - name: PostgreSQL | Make sure the PostgreSQL users are present 9 | postgresql_user: 10 | name: "{{item.name}}" 11 | password: "{{item.pass | default('pass')}}" 12 | state: present 13 | login_host: "{{item.host | default('localhost')}}" 14 | with_items: postgresql_users 15 | when: postgresql_users|length > 0 16 | 17 | - name: PostgreSQL | Update the user privileges 18 | postgresql_user: 19 | name: "{{item.name}}" 20 | db: "{{item.db}}" 21 | priv: "{{item.priv | default('ALL')}}" 22 | state: present 23 | login_host: "{{item.host | default('localhost')}}" 24 | with_items: postgresql_user_privileges 25 | when: postgresql_users|length > 0 26 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/templates/etc_monit_conf.d_postgresql.j2: -------------------------------------------------------------------------------- 1 | check process postgresql with pidfile /var/run/postgresql/{{postgresql_version}}-{{postgresql_cluster_name}}.pid 2 | group database 3 | start program = "/etc/init.d/postgresql start" 4 | stop program = "/etc/init.d/postgresql stop" 5 | if failed host localhost port 5432 protocol pgsql then restart 6 | if 5 restarts within 5 cycles then timeout 7 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/templates/pg_hba.conf.j2: -------------------------------------------------------------------------------- 1 | # PostgreSQL Client Authentication Configuration File 2 | # =================================================== 3 | # 4 | # Refer to the "Client Authentication" section in the PostgreSQL 5 | # documentation for a complete description of this file. A short 6 | # synopsis follows. 7 | # 8 | # This file controls: which hosts are allowed to connect, how clients 9 | # are authenticated, which PostgreSQL user names they can use, which 10 | # databases they can access. Records take one of these forms: 11 | # 12 | # local DATABASE USER METHOD [OPTIONS] 13 | # host DATABASE USER ADDRESS METHOD [OPTIONS] 14 | # hostssl DATABASE USER ADDRESS METHOD [OPTIONS] 15 | # hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] 16 | # 17 | # TYPE DATABASE USER ADDRESS METHOD 18 | 19 | # Default: 20 | {% for connection in postgresql_pg_hba_default %} 21 | # {{connection.comment}} 22 | {{connection.type}} {{connection.database}} {{connection.user}} {{connection.address}} {{connection.method}} 23 | {% endfor %} 24 | 25 | # Password hosts 26 | {% for host in postgresql_pg_hba_passwd_hosts %} 27 | host all all {{host}} password 28 | {% endfor %} 29 | 30 | # Trusted hosts 31 | {% for host in postgresql_pg_hba_trust_hosts %} 32 | host all all {{host}} trust 33 | {% endfor %} 34 | 35 | # User custom 36 | {% for connection in postgresql_pg_hba_custom %} 37 | # {{connection.comment}} 38 | {{connection.type}} {{connection.database}} {{connection.user}} {{connection.address}} {{connection.method}} 39 | {% endfor %} 40 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/templates/postgresql.conf.j2: -------------------------------------------------------------------------------- 1 | # ----------------------------- 2 | # PostgreSQL configuration file 3 | # ----------------------------- 4 | # 5 | # This file consists of lines of the form: 6 | # 7 | # name = value 8 | # 9 | # (The "=" is optional.) Whitespace may be used. Comments are introduced with 10 | # "#" anywhere on a line. The complete list of parameter names and allowed 11 | # values can be found in the PostgreSQL documentation. 12 | # 13 | # The commented-out settings shown in this file represent the default values. 14 | # Re-commenting a setting is NOT sufficient to revert it to the default value; 15 | # you need to reload the server. 16 | # 17 | # This file is read on server startup and when the server receives a SIGHUP 18 | # signal. If you edit the file on a running system, you have to SIGHUP the 19 | # server for the changes to take effect, or use "pg_ctl reload". Some 20 | # parameters, which are marked below, require a server shutdown and restart to 21 | # take effect. 22 | # 23 | # Any parameter can also be given as a command-line option to the server, e.g., 24 | # "postgres -c log_connections=on". Some parameters can be changed at run time 25 | # with the "SET" SQL command. 26 | # 27 | # Memory units: kB = kilobytes Time units: ms = milliseconds 28 | # MB = megabytes s = seconds 29 | # GB = gigabytes min = minutes 30 | # h = hours 31 | # d = days 32 | 33 | 34 | #------------------------------------------------------------------------------ 35 | # FILE LOCATIONS 36 | #------------------------------------------------------------------------------ 37 | 38 | data_directory = '{{postgresql_data_directory}}' 39 | 40 | hba_file = '{{postgresql_hba_file}}' 41 | 42 | ident_file = '{{postgresql_ident_file}}' 43 | 44 | external_pid_file = '{{postgresql_external_pid_file}}' 45 | 46 | 47 | #------------------------------------------------------------------------------ 48 | # CONNECTIONS AND AUTHENTICATION 49 | #------------------------------------------------------------------------------ 50 | 51 | listen_addresses = '{{postgresql_listen_addresses|join(',')}}' 52 | port = {{postgresql_port}} 53 | 54 | max_connections = {{postgresql_max_connections}} 55 | superuser_reserved_connections = {{postgresql_superuser_reserved_connections}} 56 | 57 | unix_socket_directories = '{{postgresql_unix_socket_directories|join(',')}}' 58 | unix_socket_group = '{{postgresql_unix_socket_group}}' 59 | unix_socket_permissions = {{postgresql_unix_socket_permissions}} 60 | 61 | bonjour = {{'on' if postgresql_bonjour else 'off'}} 62 | bonjour_name = '{{postgresql_bonjour_name}}' 63 | 64 | 65 | # - Security and Authentication - 66 | 67 | authentication_timeout = {{postgresql_authentication_timeout}} 68 | ssl = {{'on' if postgresql_ssl else 'off'}} 69 | ssl_ciphers = '{{postgresql_ssl_ciphers|join(':')}}' 70 | ssl_renegotiation_limit = {{postgresql_ssl_renegotiation_limit}} 71 | ssl_cert_file = '{{postgresql_ssl_cert_file}}' 72 | ssl_key_file = '{{postgresql_ssl_key_file}}' 73 | ssl_ca_file = '{{postgresql_ssl_ca_file}}' 74 | ssl_crl_file = '{{postgresql_ssl_crl_file}}' 75 | password_encryption = {{'on' if postgresql_password_encryption else 'off'}} 76 | db_user_namespace = {{'on' if postgresql_db_user_namespace else 'off'}} 77 | 78 | # Kerberos and GSSAPI 79 | krb_server_keyfile = '{{postgresql_krb_server_keyfile}}' 80 | krb_srvname = '{{postgresql_krb_srvname}}' 81 | krb_caseins_users = {{'on' if postgresql_db_user_namespace else 'off'}} 82 | 83 | # TCP Keepalives, 0 selects the system default 84 | tcp_keepalives_idle = {{postgresql_tcp_keepalives_idle}} 85 | tcp_keepalives_interval = {{postgresql_tcp_keepalives_interval}} 86 | tcp_keepalives_count = {{postgresql_tcp_keepalives_count}} 87 | 88 | 89 | #------------------------------------------------------------------------------ 90 | # RESOURCE USAGE (except WAL) 91 | #------------------------------------------------------------------------------ 92 | 93 | # - Memory - 94 | 95 | shared_buffers = {{postgresql_shared_buffers}} 96 | temp_buffers = {{postgresql_temp_buffers}} 97 | 98 | max_prepared_transactions = {{postgresql_max_prepared_transactions}} 99 | 100 | work_mem = {{postgresql_work_mem}} 101 | maintenance_work_mem = {{postgresql_maintenance_work_mem}} 102 | max_stack_depth = {{postgresql_max_stack_depth}} 103 | 104 | 105 | # - Disk - 106 | 107 | temp_file_limit = {{postgresql_temp_file_limit}} 108 | 109 | 110 | # - Kernel Resource Usage - 111 | 112 | max_files_per_process = {{postgresql_max_files_per_process}} 113 | shared_preload_libraries = '{{postgresql_shared_preload_libraries|join(',')}}' 114 | 115 | 116 | # - Cost-Based Vacuum Delay - 117 | 118 | vacuum_cost_delay = {{postgresql_vacuum_cost_delay}} 119 | vacuum_cost_page_hit = {{postgresql_vacuum_cost_page_hit}} 120 | vacuum_cost_page_miss = {{postgresql_vacuum_cost_page_miss}} 121 | vacuum_cost_page_dirty = {{postgresql_vacuum_cost_page_dirty}} 122 | vacuum_cost_limit = {{postgresql_vacuum_cost_limit}} 123 | 124 | 125 | # - Background Writer - 126 | 127 | bgwriter_delay = {{postgresql_bgwriter_delay}} 128 | bgwriter_lru_maxpages = {{postgresql_bgwriter_lru_maxpages}} 129 | bgwriter_lru_multiplier = {{postgresql_bgwriter_lru_multiplier}} 130 | 131 | 132 | # - Asynchronous Behavior - 133 | 134 | effective_io_concurrency = {{postgresql_effective_io_concurrency}} 135 | 136 | 137 | #------------------------------------------------------------------------------ 138 | # WRITE AHEAD LOG 139 | #------------------------------------------------------------------------------ 140 | 141 | # - Settings - 142 | 143 | wal_level = {{postgresql_wal_level}} 144 | fsync = {{'on' if postgresql_fsync else 'off'}} 145 | 146 | synchronous_commit = {{postgresql_synchronous_commit}} 147 | 148 | wal_sync_method = {{postgresql_wal_sync_method}} 149 | 150 | full_page_writes = {{'on' if postgresql_full_page_writes else 'off'}} 151 | 152 | wal_buffers = {{postgresql_wal_buffers}} 153 | wal_writer_delay = {{postgresql_wal_writer_delay}} 154 | commit_delay = {{postgresql_commit_delay}} 155 | commit_siblings = {{postgresql_commit_siblings}} 156 | 157 | 158 | # - Checkpoints - 159 | 160 | checkpoint_segments = {{postgresql_checkpoint_segments}} 161 | checkpoint_timeout = {{postgresql_checkpoint_timeout}} 162 | checkpoint_completion_target = {{postgresql_checkpoint_completion_target}} 163 | checkpoint_warning = {{postgresql_checkpoint_warning}} 164 | 165 | 166 | # - Archiving - 167 | 168 | archive_mode = {{'on' if postgresql_archive_mode else 'off'}} 169 | archive_command = '{{postgresql_archive_command}}' 170 | archive_timeout = {{postgresql_archive_timeout}} 171 | 172 | 173 | #------------------------------------------------------------------------------ 174 | # REPLICATION 175 | #------------------------------------------------------------------------------ 176 | 177 | # - Sending Server(s) - 178 | 179 | max_wal_senders = {{postgresql_max_wal_senders}} 180 | wal_keep_segments = {{postgresql_wal_keep_segments}} 181 | wal_sender_timeout = {{postgresql_wal_sender_timeout}} 182 | 183 | 184 | # - Master Server - 185 | 186 | synchronous_standby_names = '{{postgresql_synchronous_standby_names|join(',')}}' 187 | 188 | vacuum_defer_cleanup_age = {{postgresql_vacuum_defer_cleanup_age}} 189 | 190 | 191 | # - Standby Servers - 192 | 193 | hot_standby = {{'on' if postgresql_hot_standby else 'off'}} 194 | max_standby_archive_delay = {{postgresql_max_standby_archive_delay}} 195 | max_standby_streaming_delay = {{postgresql_max_standby_streaming_delay}} 196 | wal_receiver_status_interval = {{postgresql_wal_receiver_status_interval}} 197 | hot_standby_feedback = {{'on' if postgresql_hot_standby_feedback or 'off'}} 198 | wal_receiver_timeout = {{postgresql_wal_receiver_timeout}} 199 | 200 | 201 | #------------------------------------------------------------------------------ 202 | # QUERY TUNING 203 | #------------------------------------------------------------------------------ 204 | 205 | # - Planner Method Configuration - 206 | 207 | enable_bitmapscan = {{'on' if postgresql_enable_bitmapscan else 'off'}} 208 | enable_hashagg = {{'on' if postgresql_enable_hashagg else 'off'}} 209 | enable_hashjoin = {{'on' if postgresql_enable_hashjoin else 'off'}} 210 | enable_indexscan = {{'on' if postgresql_enable_indexscan else 'off'}} 211 | enable_indexonlyscan = {{'on' if postgresql_enable_indexonlyscan else 'off'}} 212 | enable_material = {{'on' if postgresql_enable_material else 'off'}} 213 | enable_mergejoin = {{'on' if postgresql_enable_mergejoin else 'off'}} 214 | enable_nestloop = {{'on' if postgresql_enable_nestloop else 'off'}} 215 | enable_seqscan = {{'on' if postgresql_enable_seqscan else 'off'}} 216 | enable_sort = {{'on' if postgresql_enable_sort else 'off'}} 217 | enable_tidscan = {{'on' if postgresql_enable_tidscan else 'off'}} 218 | 219 | 220 | # - Planner Cost Constants - 221 | 222 | seq_page_cost = {{postgresql_seq_page_cost}} 223 | random_page_cost = {{postgresql_random_page_cost}} 224 | cpu_tuple_cost = {{postgresql_cpu_tuple_cost}} 225 | cpu_index_tuple_cost = {{postgresql_cpu_index_tuple_cost}} 226 | cpu_operator_cost = {{postgresql_cpu_operator_cost}} 227 | effective_cache_size = {{postgresql_effective_cache_size}} 228 | 229 | 230 | # - Genetic Query Optimizer - 231 | 232 | geqo = {{'on' if postgresql_enable_tidscan else 'off'}} 233 | geqo_threshold = {{postgresql_geqo_threshold}} 234 | geqo_effort = {{postgresql_geqo_effort}} 235 | geqo_pool_size = {{postgresql_geqo_pool_size}} 236 | geqo_generations = {{postgresql_geqo_generations}} 237 | geqo_selection_bias = {{postgresql_geqo_selection_bias}} 238 | geqo_seed = {{postgresql_geqo_seed}} 239 | 240 | 241 | # - Other Planner Options - 242 | 243 | default_statistics_target = {{postgresql_default_statistics_target}} 244 | constraint_exclusion = {{postgresql_constraint_exclusion}} 245 | cursor_tuple_fraction = {{postgresql_cursor_tuple_fraction}} 246 | from_collapse_limit = {{postgresql_from_collapse_limit}} 247 | join_collapse_limit = {{postgresql_join_collapse_limit}} 248 | 249 | 250 | #------------------------------------------------------------------------------ 251 | # ERROR REPORTING AND LOGGING 252 | #------------------------------------------------------------------------------ 253 | 254 | # - Where to Log - 255 | 256 | log_destination = '{{postgresql_log_destination}}' 257 | 258 | logging_collector = {{'on' if postgresql_logging_collector else 'off'}} 259 | 260 | log_directory = '{{postgresql_log_directory}}' 261 | log_filename = '{{postgresql_log_filename}}' 262 | log_file_mode = {{postgresql_log_file_mode}} 263 | log_truncate_on_rotation = {{'on' if postgresql_log_truncate_on_rotation else 'off'}} 264 | log_rotation_age = {{postgresql_log_rotation_age}} 265 | log_rotation_size = {{postgresql_log_rotation_size}} 266 | 267 | syslog_facility = '{{postgresql_syslog_facility}}' 268 | syslog_ident = '{{postgresql_syslog_ident}}' 269 | 270 | event_source = '{{postgresql_event_source}}' 271 | 272 | 273 | # - When to Log - 274 | 275 | client_min_messages = {{postgresql_client_min_messages}} 276 | 277 | log_min_messages = {{postgresql_log_min_messages}} 278 | log_min_error_statement = {{postgresql_log_min_error_statement}} 279 | log_min_duration_statement = {{postgresql_log_min_duration_statement}} 280 | 281 | 282 | # - What to Log - 283 | 284 | debug_print_parse = {{'on' if postgresql_debug_print_parse else 'off'}} 285 | debug_print_rewritten = {{'on' if postgresql_debug_print_rewritten else 'off'}} 286 | debug_print_plan = {{'on' if postgresql_debug_print_plan else 'off'}} 287 | debug_pretty_print = {{'on' if postgresql_debug_pretty_print else 'off'}} 288 | log_checkpoints = {{'on' if postgresql_log_checkpoints else 'off'}} 289 | log_connections = {{'on' if postgresql_log_connections else 'off'}} 290 | log_disconnections = {{'on' if postgresql_log_disconnections else 'off'}} 291 | log_duration = {{'on' if postgresql_log_duration else 'off'}} 292 | log_error_verbosity = {{postgresql_log_error_verbosity}} # terse, default, or verbose messages 293 | log_hostname = {{'on' if postgresql_log_duration else 'off'}} 294 | log_line_prefix = '{{postgresql_log_line_prefix}}' 295 | log_lock_waits = {{'on' if postgresql_log_lock_waits else 'off'}} 296 | log_statement = '{{postgresql_log_statement}}' 297 | log_temp_files = {{postgresql_log_temp_files}} 298 | log_timezone = '{{postgresql_log_timezone}}' 299 | 300 | 301 | #------------------------------------------------------------------------------ 302 | # RUNTIME STATISTICS 303 | #------------------------------------------------------------------------------ 304 | 305 | # - Query/Index Statistics Collector - 306 | 307 | track_activities = {{'on' if postgresql_track_activities else 'off'}} 308 | track_counts = {{'on' if postgresql_track_counts else 'off'}} 309 | track_io_timing = {{'on' if postgresql_track_io_timing else 'off'}} 310 | track_functions = {{postgresql_track_functions}} # none, pl, all 311 | track_activity_query_size = {{postgresql_track_activity_query_size}} 312 | update_process_title = {{'on' if postgresql_update_process_title else 'off'}} 313 | stats_temp_directory = '{{postgresql_stats_temp_directory}}' 314 | 315 | 316 | # - Statistics Monitoring - 317 | 318 | log_parser_stats = {{'on' if postgresql_log_parser_stats else 'off'}} 319 | log_planner_stats = {{'on' if postgresql_log_planner_stats else 'off'}} 320 | log_executor_stats = {{'on' if postgresql_log_executor_stats else 'off'}} 321 | log_statement_stats = {{'on' if postgresql_log_statement_stats else 'off'}} 322 | 323 | 324 | #------------------------------------------------------------------------------ 325 | # AUTOVACUUM PARAMETERS 326 | #------------------------------------------------------------------------------ 327 | 328 | autovacuum = {{'on' if postgresql_autovacuum else 'off'}} 329 | log_autovacuum_min_duration = {{postgresql_log_autovacuum_min_duration}} 330 | autovacuum_max_workers = {{postgresql_autovacuum_max_workers}} 331 | autovacuum_naptime = {{postgresql_autovacuum_naptime}} 332 | autovacuum_vacuum_threshold = {{postgresql_autovacuum_vacuum_threshold}} 333 | autovacuum_analyze_threshold = {{postgresql_autovacuum_analyze_threshold}} 334 | autovacuum_vacuum_scale_factor = {{postgresql_autovacuum_vacuum_scale_factor}} 335 | autovacuum_analyze_scale_factor = {{postgresql_autovacuum_analyze_scale_factor}} 336 | autovacuum_freeze_max_age = {{postgresql_autovacuum_freeze_max_age}} 337 | autovacuum_vacuum_cost_delay = {{postgresql_autovacuum_vacuum_cost_delay}} 338 | autovacuum_vacuum_cost_limit = {{postgresql_autovacuum_vacuum_cost_limit}} 339 | 340 | 341 | #------------------------------------------------------------------------------ 342 | # CLIENT CONNECTION DEFAULTS 343 | #------------------------------------------------------------------------------ 344 | 345 | # - Statement Behavior - 346 | 347 | search_path = '{{postgresql_search_path|join(',')}}' 348 | default_tablespace = '{{postgresql_default_tablespace}}' 349 | temp_tablespaces = '{{postgresql_temp_tablespaces|join(',')}}' 350 | 351 | check_function_bodies = {{'on' if postgresql_check_function_bodies else 'off'}} 352 | default_transaction_isolation = '{{postgresql_default_transaction_isolation}}' 353 | default_transaction_read_only = {{'on' if postgresql_default_transaction_read_only else 'off'}} 354 | default_transaction_deferrable = {{'on' if postgresql_default_transaction_deferrable else 'off'}} 355 | session_replication_role = '{{postgresql_session_replication_role}}' 356 | 357 | statement_timeout = {{postgresql_statement_timeout}} 358 | lock_timeout = {{postgresql_lock_timeout}} 359 | vacuum_freeze_min_age = {{postgresql_vacuum_freeze_min_age}} 360 | vacuum_freeze_table_age = {{postgresql_vacuum_freeze_table_age}} 361 | 362 | bytea_output = '{{postgresql_bytea_output}}' 363 | xmlbinary = '{{postgresql_xmlbinary}}' 364 | xmloption = '{{postgresql_xmloption}}' 365 | 366 | 367 | # - Locale and Formatting - 368 | 369 | datestyle = '{{postgresql_datestyle|join(',')}}' 370 | intervalstyle = '{{postgresql_intervalstyle}}' 371 | timezone = '{{postgresql_timezone}}' 372 | 373 | timezone_abbreviations = '{{postgresql_timezone_abbreviations}}' 374 | 375 | extra_float_digits = {{postgresql_extra_float_digits}} 376 | client_encoding = {{postgresql_client_encoding}} 377 | 378 | lc_messages = '{{postgresql_lc_messages}}' 379 | lc_monetary = '{{postgresql_lc_monetary}}' 380 | lc_numeric = '{{postgresql_lc_numeric}}' 381 | lc_time = '{{postgresql_lc_time}}' 382 | 383 | default_text_search_config = '{{postgresql_default_text_search_config}}' 384 | 385 | dynamic_library_path = '{{postgresql_dynamic_library_path}}' 386 | local_preload_libraries = '{{postgresql_local_preload_libraries|join(',')}}' 387 | 388 | 389 | #------------------------------------------------------------------------------ 390 | # LOCK MANAGEMENT 391 | #------------------------------------------------------------------------------ 392 | 393 | deadlock_timeout = {{postgresql_deadlock_timeout}} 394 | max_locks_per_transaction = {{postgresql_max_locks_per_transaction}} 395 | 396 | max_pred_locks_per_transaction = {{postgresql_max_pred_locks_per_transaction}} 397 | 398 | 399 | #------------------------------------------------------------------------------ 400 | # VERSION/PLATFORM COMPATIBILITY 401 | #------------------------------------------------------------------------------ 402 | 403 | # - Previous PostgreSQL Versions - 404 | 405 | array_nulls = {{'on' if postgresql_array_nulls else 'off'}} 406 | backslash_quote = {{postgresql_backslash_quote}} # on, off, or safe_encoding 407 | default_with_oids = {{'on' if postgresql_default_with_oids else 'off'}} 408 | escape_string_warning = {{'on' if postgresql_escape_string_warning else 'off'}} 409 | lo_compat_privileges = {{'on' if postgresql_lo_compat_privileges else 'off'}} 410 | quote_all_identifiers = {{'on' if postgresql_quote_all_identifiers else 'off'}} 411 | sql_inheritance = {{'on' if postgresql_sql_inheritance else 'off'}} 412 | standard_conforming_strings = {{'on' if postgresql_standard_conforming_strings else 'off'}} 413 | synchronize_seqscans = {{'on' if postgresql_synchronize_seqscans else 'off'}} 414 | 415 | 416 | # - Other Platforms and Clients - 417 | 418 | transform_null_equals = {{'on' if postgresql_transform_null_equals else 'off'}} 419 | 420 | 421 | #------------------------------------------------------------------------------ 422 | # ERROR HANDLING 423 | #------------------------------------------------------------------------------ 424 | 425 | exit_on_error = {{'on' if postgresql_exit_on_error else 'off'}} 426 | restart_after_crash = {{'on' if postgresql_restart_after_crash else 'off'}} 427 | 428 | 429 | #------------------------------------------------------------------------------ 430 | # CONFIG FILE INCLUDES 431 | #------------------------------------------------------------------------------ 432 | 433 | # These options allow settings to be loaded from files other than the 434 | # default postgresql.conf. 435 | 436 | include_dir = 'conf.d' # include files ending in '.conf' from 437 | # directory 'conf.d' 438 | #include_if_exists = 'exists.conf' # include file only if it exists 439 | #include = 'special.conf' # include file 440 | 441 | 442 | #------------------------------------------------------------------------------ 443 | # CUSTOMIZED OPTIONS 444 | #------------------------------------------------------------------------------ 445 | 446 | # Add settings for extensions here 447 | -------------------------------------------------------------------------------- /provisioning/roles/postgresql/test.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | vars_files: 3 | - 'defaults/main.yml' 4 | tasks: 5 | - include: 'tasks/main.yml' 6 | handlers: 7 | - include: 'handlers/main.yml' 8 | --------------------------------------------------------------------------------