Initial Chef repository

This commit is contained in:
Greg Karékinian
2015-07-21 19:45:23 +02:00
parent 7e5401fc71
commit ee4079fa85
1151 changed files with 185163 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
if not %w(jessie squeeze wheezy sid lucid precise saucy trusty utopic).include? node['postgresql']['pgdg']['release_apt_codename']
raise "Not supported release by PGDG apt repository"
end
include_recipe 'apt'
file "remove deprecated Pitti PPA apt repository" do
action :delete
path "/etc/apt/sources.list.d/pitti-postgresql-ppa"
end
apt_repository 'apt.postgresql.org' do
uri 'http://apt.postgresql.org/pub/repos/apt'
distribution "#{node['postgresql']['pgdg']['release_apt_codename']}-pgdg"
components ['main', node['postgresql']['version']]
key 'https://www.postgresql.org/media/keys/ACCC4CF8.asc'
action :add
end

View File

@@ -0,0 +1,32 @@
#
# Cookbook Name:: postgresql
# Recipe:: client
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if platform_family?('debian') && node['postgresql']['version'].to_f > 9.3
node.default['postgresql']['enable_pgdg_apt'] = true
end
if(node['postgresql']['enable_pgdg_apt']) and platform_family?('debian')
include_recipe 'postgresql::apt_pgdg_postgresql'
end
if(node['postgresql']['enable_pgdg_yum']) and platform_family?('rhel')
include_recipe 'postgresql::yum_pgdg_postgresql'
end
node['postgresql']['client']['packages'].each do |pg_pack|
package pg_pack
end

View File

@@ -0,0 +1,148 @@
#
# Cookbook Name:: postgresql
# Recipe:: config_initdb
# Author:: David Crane (<davidc@donorschoose.org>)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#######
# Load the locale_date_order() and select_default_timezone(tzdir)
# methods from libraries/default.rb
::Chef::Recipe.send(:include, Opscode::PostgresqlHelpers)
#######
# This recipe is derived from the setup_config() source code in the
# PostgreSQL initdb utility. It determines postgresql.conf settings that
# conform to the system's locale and timezone configuration, and also
# sets the error reporting and logging settings.
#
# See http://doxygen.postgresql.org/initdb_8c_source.html for the
# original initdb source code.
#
# By examining the system configuration, this recipe will set the
# following node.default['postgresql']['config'] attributes:
#
# - Locale and Formatting -
# * datestyle
# * lc_messages
# * lc_monetary
# * lc_numeric
# * lc_time
# * default_text_search_config
#
# - Timezone Conversion -
# * log_timezone
# * timezone
#
# In addition, this recipe will recommend the same error reporting and
# logging settings that initdb provided. These settings do differ from
# the PostgreSQL default settings, which would log to stderr only. The
# initdb settings rotate 7 days of log files named postgresql-Mon.log,
# etc. through these node.default['postgresql']['config'] attributes:
#
# - Where to Log -
# * log_destination = 'stderr'
# * log_directory = 'pg_log'
# * log_filename = 'postgresql-%a.log'
# (Default was: postgresql-%Y-%m-%d_%H%M%S.log)
# * logging_collector = true # on
# (Turned on to capture stderr logging and redirect into log files)
# (Default was: false # off)
# * log_rotation_age = 1d
# * log_rotation_size = 0
# (Default was: 10MB)
# * log_truncate_on_rotation = true # on
# (Default was: false # off)
#######
# Locale Configuration
# See libraries/default.rb for the locale_date_order() method.
node.default['postgresql']['config']['datestyle'] = "iso, #{locale_date_order()}"
# According to the locale(1) manpage, the locale settings are determined
# by environment variables according to the following precedence:
# LC_ALL > (LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME) > LANG.
node.default['postgresql']['config']['lc_messages'] =
[ ENV['LC_ALL'], ENV['LC_MESSAGES'], ENV['LANG'] ].compact.first
node.default['postgresql']['config']['lc_monetary'] =
[ ENV['LC_ALL'], ENV['LC_MONETARY'], ENV['LANG'] ].compact.first
node.default['postgresql']['config']['lc_numeric'] =
[ ENV['LC_ALL'], ENV['LC_NUMERIC'], ENV['LANG'] ].compact.first
node.default['postgresql']['config']['lc_time'] =
[ ENV['LC_ALL'], ENV['LC_TIME'], ENV['LANG'] ].compact.first
node.default['postgresql']['config']['default_text_search_config'] =
case ENV['LANG']
when /da_.*/
'pg_catalog.danish'
when /nl_.*/
'pg_catalog.dutch'
when /en_.*/
'pg_catalog.english'
when /fi_.*/
'pg_catalog.finnish'
when /fr_.*/
'pg_catalog.french'
when /de_.*/
'pg_catalog.german'
when /hu_.*/
'pg_catalog.hungarian'
when /it_.*/
'pg_catalog.italian'
when /no_.*/
'pg_catalog.norwegian'
when /pt_.*/
'pg_catalog.portuguese'
when /ro_.*/
'pg_catalog.romanian'
when /ru_.*/
'pg_catalog.russian'
when /es_.*/
'pg_catalog.spanish'
when /sv_.*/
'pg_catalog.swedish'
when /tr_.*/
'pg_catalog.turkish'
else
nil
end
#######
# Timezone Configuration
# Determine the name of the system's default timezone and specify node
# defaults for the postgresql.cof settings. If the timezone cannot be
# identified, do as initdb would do: leave it unspecified so PostgreSQL
# uses it's internal default of GMT.
tzdirpath = pg_TZDIR() # See libraries/default.rb
default_timezone = select_default_timezone(tzdirpath) # See libraries/default.rb
if !default_timezone.nil?
node.default['postgresql']['config']['log_timezone'] = default_timezone
node.default['postgresql']['config']['timezone'] = default_timezone
end
#######
# - Where to Log -
node.default['postgresql']['config']['log_destination'] = 'stderr'
node.default['postgresql']['config']['log_directory'] = 'pg_log'
node.default['postgresql']['config']['log_filename'] = 'postgresql-%a.log'
node.default['postgresql']['config']['logging_collector'] = true # on
node.default['postgresql']['config']['log_rotation_age'] = '1d'
node.default['postgresql']['config']['log_rotation_size'] = 0
node.default['postgresql']['config']['log_truncate_on_rotation'] = true # on

View File

@@ -0,0 +1,284 @@
#
# Cookbook Name:: postgresql
# Recipe:: config_pgtune
# Author:: David Crane (<davidc@donorschoose.org>)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#######
# Load the binaryround(value) method from libraries/default.rb
::Chef::Recipe.send(:include, Opscode::PostgresqlHelpers)
#######
# This recipe is based on Greg Smith's pgtune script (the Feb 1, 2012
# version at https://github.com/gregs1104/pgtune). Introduction: pgtune
# takes the wimpy default postgresql.conf and expands the database
# server to be as powerful as the hardware it's being deployed on.
#
# The default postgresql.conf aims at a system with approximately 128MB
# of RAM. This recipe recommends a baseline configuration in the right
# general range for a dedicated Postgresql system.
#
# This recipe takes three optional parameters that may be passed in as
# node['postgresql']['config_pgtune'] attributes:
# * db_type -- Specifies database type as one of: dw, oltp,
# web, mixed, desktop. If not specified, the default is mixed.
# * max_connections -- Specifies number of maximum connections
# expected. If not specified, it depends on database type.
# * total_memory -- Specifies total system memory. If not specified,
# it will be detected from the Ohai automatic attributes.
#
# Using those inputs, this recipe will compute and set the following
# node.default['postgresql']['config'] attributes:
# * max_connections
# * shared_buffers
# * effective_cache_size
# * work_mem
# * maintenance_work_mem
# * checkpoint_segments
# * checkpoint_completion_target
# * wal_buffers
# * default_statistics_target
#
# This recipe deviates from the original pgtune script for 2 settings:
# shared_buffers is capped for large memory systems (which Greg
# mentioned in a TODO.rst) and wal_buffers will auto-tune starting with
# 9.1 (which is a feature that Greg built into Postgresql).
#######
# These are the workload characteristics of the five database types
# that can be specified as node['postgresql']['config_pgtune']['db_type']:
#
# dw -- Data Warehouse
# * Typically I/O- or RAM-bound
# * Large bulk loads of data
# * Large complex reporting queries
# * Also called "Decision Support" or "Business Intelligence"
#
# oltp -- Online Transaction Processing
# * Typically CPU- or I/O-bound
# * DB slightly larger than RAM to 1TB
# * 20-40% small data write queries
# * Some long transactions and complex read queries
#
# web -- Web Application
# * Typically CPU-bound
# * DB much smaller than RAM
# * 90% or more simple queries
#
# mixed -- Mixed DW and OLTP characteristics
# * A wide mixture of queries
#
# desktop -- Not a dedicated database
# * A general workstation, perhaps for a developer
# Parse out db_type option, or use default.
db_type = 'mixed'
if (node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('db_type'))
db_type = node['postgresql']['config_pgtune']['db_type']
if (!(["dw","oltp","web","mixed","desktop"].include?(db_type)))
Chef::Log.fatal([
"Bad value (#{db_type})",
"for node['postgresql']['config_pgtune']['db_type'] attribute.",
"Valid values are one of dw, oltp, web, mixed, desktop."
].join(' '))
raise
end
end
# Parse out max_connections option, or use a value based on db_type.
con =
{ "web" => 200,
"oltp" => 300,
"dw" => 20,
"mixed" => 80,
"desktop" => 5
}.fetch(db_type)
if (node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('max_connections'))
max_connections = node['postgresql']['config_pgtune']['max_connections'].to_i
if max_connections <= 0
Chef::Log.fatal([
"Bad value (#{max_connections})",
"for node['postgresql']['config_pgtune']['max_connections'] attribute.",
"Valid values are non-zero integers only."
].join(' '))
raise
end
con = max_connections
end
# Parse out total_memory option, or use value detected by Ohai.
total_memory = node['memory']['total']
# Override max_connections with a node attribute if DevOps desires.
# For example, on a system *not* dedicated to Postgresql.
if (node['postgresql'].attribute?('config_pgtune') && node['postgresql']['config_pgtune'].attribute?('total_memory'))
total_memory = node['postgresql']['config_pgtune']['total_memory']
if (total_memory.match(/\A[1-9]\d*kB\Z/) == nil)
Chef::Application.fatal!([
"Bad value (#{total_memory})",
"for node['postgresql']['config_pgtune']['total_memory'] attribute.",
"Valid values are non-zero integers followed by kB (e.g., 49416564kB)."
].join(' '))
end
end
# Ohai reports node[:memory][:total] in kB, as in "921756kB"
mem = total_memory.split("kB")[0].to_i / 1024 # in MB
#######
# RAM-related settings computed as in Greg Smith's pgtune script.
# Remember that con and mem were either chosen above based on the
# db_type or the actual total memory, or were passed in attributes.
# (1) max_connections
# Sets the maximum number of concurrent connections.
node.default['postgresql']['config']['max_connections'] = con
# The calculations for the next four settings would not be optimal
# for low memory systems. In that case, the calculation is skipped,
# leaving the built-in Postgresql settings, which are actually
# intended for those low memory systems.
if (mem >= 256)
# (2) shared_buffers
# Sets the number of shared memory buffers used by the server.
shared_buffers =
{ "web" => mem/4,
"oltp" => mem/4,
"dw" => mem/4,
"mixed" => mem/4,
"desktop" => mem/16
}.fetch(db_type)
# Robert Haas has advised to cap the size of shared_buffers based on
# the memory architecture: 2GB on 32-bit and 8GB on 64-bit machines.
# http://rhaas.blogspot.com/2012/03/tuning-sharedbuffers-and-walbuffers.html
case node['kernel']['machine']
when "i386" # 32-bit machines
if shared_buffers > 2*1024
shared_buffers = 2*1024
end
when "x86_64" # 64-bit machines
if shared_buffers > 8*1024
shared_buffers = 8*1024
end
end
node.default['postgresql']['config']['shared_buffers'] = binaryround(shared_buffers*1024*1024)
# (3) effective_cache_size
# Sets the planner's assumption about the size of the disk cache.
# That is, the portion of the kernel's disk cache that will be
# used for PostgreSQL data files.
effective_cache_size =
{ "web" => mem * 3 / 4,
"oltp" => mem * 3 / 4,
"dw" => mem * 3 / 4,
"mixed" => mem * 3 / 4,
"desktop" => mem / 4
}.fetch(db_type)
node.default['postgresql']['config']['effective_cache_size'] = binaryround(effective_cache_size*1024*1024)
# (4) work_mem
# Sets the maximum memory to be used for query workspaces.
mem_con_v = (mem.to_f / con).ceil
work_mem =
{ "web" => mem_con_v,
"oltp" => mem_con_v,
"dw" => mem_con_v / 2,
"mixed" => mem_con_v / 2,
"desktop" => mem_con_v / 6
}.fetch(db_type)
node.default['postgresql']['config']['work_mem'] = binaryround(work_mem*1024*1024)
# (5) maintenance_work_mem
# Sets the maximum memory to be used for maintenance operations.
# This includes operations such as VACUUM and CREATE INDEX.
maintenance_work_mem =
{ "web" => mem / 16,
"oltp" => mem / 16,
"dw" => mem / 8,
"mixed" => mem / 16,
"desktop" => mem / 16
}.fetch(db_type)
# Cap maintenence RAM at 1GB on servers with lots of memory
if (maintenance_work_mem > 1*1024)
maintenance_work_mem = 1*1024
end
node.default['postgresql']['config']['maintenance_work_mem'] = binaryround(maintenance_work_mem*1024*1024)
end
#######
# Checkpoint-related parameters that affect transaction rate and
# maximum tolerable recovery playback time.
# (6) checkpoint_segments
# Sets the maximum distance in log segments between automatic WAL checkpoints.
checkpoint_segments =
{ "web" => 8,
"oltp" => 16,
"dw" => 64,
"mixed" => 16,
"desktop" => 3
}.fetch(db_type)
node.default['postgresql']['config']['checkpoint_segments'] = checkpoint_segments
# (7) checkpoint_completion_target
# Time spent flushing dirty buffers during checkpoint, as fraction
# of checkpoint interval.
checkpoint_completion_target =
{ "web" => "0.7",
"oltp" => "0.9",
"dw" => "0.9",
"mixed" => "0.9",
"desktop" => "0.5"
}.fetch(db_type)
node.default['postgresql']['config']['checkpoint_completion_target'] = checkpoint_completion_target
# (8) wal_buffers
# Sets the number of disk-page buffers in shared memory for WAL.
# Starting with 9.1, wal_buffers will auto-tune if set to the -1 default.
# For 8.X and 9.0, it needed to be specified, which pgtune did as follows.
if node['postgresql']['version'].to_f < 9.1
wal_buffers = 512 * checkpoint_segments
# The pgtune seems to use 1kB units for wal_buffers
node.default['postgresql']['config']['wal_buffers'] = binaryround(wal_buffers*1024)
else
node.default['postgresql']['config']['wal_buffers'] = "-1"
end
# (9) default_statistics_target
# Sets the default statistics target. This applies to table columns
# that have not had a column-specific target set via
# ALTER TABLE SET STATISTICS.
default_statistics_target =
{ "web" => 100,
"oltp" => 100,
"dw" => 500,
"mixed" => 100,
"desktop" => 100
}.fetch(db_type)
node.default['postgresql']['config']['default_statistics_target'] = default_statistics_target

View File

@@ -0,0 +1,44 @@
#
# Cookbook Name:: postgresql
# Recipe:: contrib
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
db_name = node['postgresql']['database_name']
# Install the PostgreSQL contrib package(s) from the distribution,
# as specified by the node attributes.
node['postgresql']['contrib']['packages'].each do |pg_pack|
package pg_pack
end
include_recipe "postgresql::server"
# Install PostgreSQL contrib extentions into the database, as specified by the
# node attribute node['postgresql']['database_name'].
if (node['postgresql']['contrib'].attribute?('extensions'))
node['postgresql']['contrib']['extensions'].each do |pg_ext|
bash "install-#{pg_ext}-extension" do
user 'postgres'
code <<-EOH
echo 'CREATE EXTENSION IF NOT EXISTS "#{pg_ext}";' | psql -d "#{db_name}"
EOH
action :run
::Chef::Resource.send(:include, Opscode::PostgresqlHelpers)
not_if {extension_installed?(pg_ext)}
end
end
end

View File

@@ -0,0 +1,18 @@
#
# Cookbook Name:: postgresql
# Recipe:: default
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include_recipe "postgresql::client"

View File

@@ -0,0 +1,117 @@
#
# Cookbook Name:: postgresql
# Recipe:: ruby
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Load the pgdgrepo_rpm_info method from libraries/default.rb
::Chef::Recipe.send(:include, Opscode::PostgresqlHelpers)
begin
require 'pg'
rescue LoadError
if platform_family?('ubuntu', 'debian')
e = execute 'apt-get update' do
action :nothing
end
e.run_action(:run) unless ::File.exists?('/var/lib/apt/periodic/update-success-stamp')
end
node.set['build-essential']['compile_time'] = true
include_recipe "build-essential"
include_recipe "postgresql::client"
if node['postgresql']['enable_pgdg_yum']
repo_rpm_url, repo_rpm_filename, repo_rpm_package = pgdgrepo_rpm_info
include_recipe "postgresql::yum_pgdg_postgresql"
resources("remote_file[#{Chef::Config[:file_cache_path]}/#{repo_rpm_filename}]").run_action(:create)
resources("package[#{repo_rpm_package}]").run_action(:install)
ENV['PATH'] = "/usr/pgsql-#{node['postgresql']['version']}/bin:#{ENV['PATH']}"
end
if node['postgresql']['enable_pgdg_apt']
include_recipe "postgresql::apt_pgdg_postgresql"
resources("file[remove deprecated Pitti PPA apt repository]").run_action(:delete)
resources("apt_repository[apt.postgresql.org]").run_action(:add)
end
node['postgresql']['client']['packages'].each do |pg_pack|
resources("package[#{pg_pack}]").run_action(:install)
end
begin
chef_gem "pg"
rescue Gem::Installer::ExtensionBuildError, Mixlib::ShellOut::ShellCommandFailed => e
# Are we an omnibus install?
raise if RbConfig.ruby.scan(%r{(chef|opscode)}).empty?
# Still here, must be omnibus. Lets make this thing install!
Chef::Log.warn 'Failed to properly build pg gem. Forcing properly linking and retrying (omnibus fix)'
gem_dir = e.message.scan(%r{will remain installed in ([^ ]+)}).flatten.first
raise unless gem_dir
gem_name = File.basename(gem_dir)
ext_dir = File.join(gem_dir, 'ext')
gem_exec = File.join(File.dirname(RbConfig.ruby), 'gem')
new_content = <<-EOS
require 'rbconfig'
%w(
configure_args
LIBRUBYARG_SHARED
LIBRUBYARG_STATIC
LIBRUBYARG
LDFLAGS
).each do |key|
RbConfig::CONFIG[key].gsub!(/-Wl[^ ]+( ?\\/[^ ]+)?/, '')
RbConfig::MAKEFILE_CONFIG[key].gsub!(/-Wl[^ ]+( ?\\/[^ ]+)?/, '')
end
RbConfig::CONFIG['RPATHFLAG'] = ''
RbConfig::MAKEFILE_CONFIG['RPATHFLAG'] = ''
EOS
new_content << File.read(extconf_path = File.join(ext_dir, 'extconf.rb'))
File.open(extconf_path, 'w') do |file|
file.write(new_content)
end
lib_builder = execute 'generate pg gem Makefile' do
# [COOK-3490] pg gem install requires full path on RHEL
command "PATH=$PATH:/usr/pgsql-#{node['postgresql']['version']}/bin #{RbConfig.ruby} extconf.rb"
cwd ext_dir
action :nothing
end
lib_builder.run_action(:run)
lib_maker = execute 'make pg gem lib' do
command 'make'
cwd ext_dir
action :nothing
end
lib_maker.run_action(:run)
lib_installer = execute 'install pg gem lib' do
command 'make install'
cwd ext_dir
action :nothing
end
lib_installer.run_action(:run)
spec_installer = execute 'install pg spec' do
command "#{gem_exec} spec ./cache/#{gem_name}.gem --ruby > ./specifications/#{gem_name}.gemspec"
cwd File.join(gem_dir, '..', '..')
action :nothing
end
spec_installer.run_action(:run)
Chef::Log.warn 'Installation of pg gem successful!'
end
end

View File

@@ -0,0 +1,89 @@
#
# Cookbook Name:: postgresql
# Recipe:: server
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
::Chef::Recipe.send(:include, Opscode::OpenSSL::Password)
include_recipe "postgresql::client"
# randomly generate postgres password, unless using solo - see README
if Chef::Config[:solo]
missing_attrs = %w{
postgres
}.select do |attr|
node['postgresql']['password'][attr].nil?
end.map { |attr| "node['postgresql']['password']['#{attr}']" }
if !missing_attrs.empty?
Chef::Log.fatal([
"You must set #{missing_attrs.join(', ')} in chef-solo mode.",
"For more information, see https://github.com/opscode-cookbooks/postgresql#chef-solo-note"
].join(' '))
raise
end
else
# TODO: The "secure_password" is randomly generated plain text, so it
# should be converted to a PostgreSQL specific "encrypted password" if
# it should actually install a password (as opposed to disable password
# login for user 'postgres'). However, a random password wouldn't be
# useful if it weren't saved as clear text in Chef Server for later
# retrieval.
unless node.key?('postgresql') && node['postgresql'].key?('password') && node['postgresql']['password'].key?('postgres')
node.set_unless['postgresql']['password']['postgres'] = secure_password
node.save
end
end
# Include the right "family" recipe for installing the server
# since they do things slightly differently.
case node['platform_family']
when "rhel", "fedora", "suse"
include_recipe "postgresql::server_redhat"
when "debian"
include_recipe "postgresql::server_debian"
end
# Versions prior to 9.2 do not have a config file option to set the SSL
# key and cert path, and instead expect them to be in a specific location.
if node['postgresql']['version'].to_f < 9.2 && node['postgresql']['config'].attribute?('ssl_cert_file')
link ::File.join(node['postgresql']['config']['data_directory'], 'server.crt') do
to node['postgresql']['config']['ssl_cert_file']
end
end
if node['postgresql']['version'].to_f < 9.2 && node['postgresql']['config'].attribute?('ssl_key_file')
link ::File.join(node['postgresql']['config']['data_directory'], 'server.key') do
to node['postgresql']['config']['ssl_key_file']
end
end
# NOTE: Consider two facts before modifying "assign-postgres-password":
# (1) Passing the "ALTER ROLE ..." through the psql command only works
# if passwordless authorization was configured for local connections.
# For example, if pg_hba.conf has a "local all postgres ident" rule.
# (2) It is probably fruitless to optimize this with a not_if to avoid
# setting the same password. This chef recipe doesn't have access to
# the plain text password, and testing the encrypted (md5 digest)
# version is not straight-forward.
bash "assign-postgres-password" do
user 'postgres'
code <<-EOH
echo "ALTER ROLE postgres ENCRYPTED PASSWORD '#{node['postgresql']['password']['postgres']}';" | psql -p #{node['postgresql']['config']['port']}
EOH
action :run
not_if "ls #{node['postgresql']['config']['data_directory']}/recovery.conf"
only_if { node['postgresql']['assign_postgres_password'] }
end

View File

@@ -0,0 +1,34 @@
#
# Cookbook Name:: postgresql
# Recipe:: server
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
change_notify = node['postgresql']['server']['config_change_notify']
template "#{node['postgresql']['dir']}/postgresql.conf" do
source "postgresql.conf.erb"
owner "postgres"
group "postgres"
mode 0600
notifies change_notify, 'service[postgresql]', :immediately
end
template "#{node['postgresql']['dir']}/pg_hba.conf" do
source "pg_hba.conf.erb"
owner "postgres"
group "postgres"
mode 00600
notifies change_notify, 'service[postgresql]', :immediately
end

View File

@@ -0,0 +1,38 @@
#
# Cookbook Name:: postgresql
# Recipe:: server
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include_recipe "postgresql::client"
node['postgresql']['server']['packages'].each do |pg_pack|
package pg_pack
end
include_recipe "postgresql::server_conf"
service "postgresql" do
service_name node['postgresql']['server']['service_name']
supports :restart => true, :status => true, :reload => true
action [:enable, :start]
end
execute 'Set locale and Create cluster' do
command 'export LC_ALL=C; /usr/bin/pg_createcluster --start ' + node['postgresql']['version'] + ' main'
action :run
not_if { ::File.directory?('/etc/postgresql/' + node['postgresql']['version'] + '/main') }
end

View File

@@ -0,0 +1,100 @@
#
# Cookbook Name:: postgresql
# Recipe:: server
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include_recipe "postgresql::client"
svc_name = node['postgresql']['server']['service_name']
dir = node['postgresql']['dir']
initdb_locale = node['postgresql']['initdb_locale']
# Create a group and user like the package will.
# Otherwise the templates fail.
group "postgres" do
gid 26
end
user "postgres" do
shell "/bin/bash"
comment "PostgreSQL Server"
home "/var/lib/pgsql"
gid "postgres"
system true
uid 26
supports :manage_home => false
end
directory dir do
owner "postgres"
group "postgres"
recursive true
action :create
end
node['postgresql']['server']['packages'].each do |pg_pack|
package pg_pack
end
# Starting with Fedora 16, the pgsql sysconfig files are no longer used.
# The systemd unit file does not support 'initdb' or 'upgrade' actions.
# Use the postgresql-setup script instead.
unless platform_family?("fedora") and node['platform_version'].to_i >= 16
directory "/etc/sysconfig/pgsql" do
mode "0644"
recursive true
action :create
end
template "/etc/sysconfig/pgsql/#{svc_name}" do
source "pgsql.sysconfig.erb"
mode "0644"
notifies :restart, "service[postgresql]", :delayed
end
end
if platform_family?("fedora") and node['platform_version'].to_i >= 16
execute "postgresql-setup initdb #{svc_name}" do
not_if { ::FileTest.exist?(File.join(dir, "PG_VERSION")) }
end
elsif platform?("redhat") and node['platform_version'].to_i >= 7
execute "postgresql#{node['postgresql']['version'].split('.').join}-setup initdb #{svc_name}" do
not_if { ::FileTest.exist?(File.join(dir, "PG_VERSION")) }
end
else !platform_family?("suse")
execute "/sbin/service #{svc_name} initdb #{initdb_locale}" do
not_if { ::FileTest.exist?(File.join(dir, "PG_VERSION")) }
end
end
include_recipe "postgresql::server_conf"
service "postgresql" do
service_name svc_name
supports :restart => true, :status => true, :reload => true
action [:enable, :start]
end

View File

@@ -0,0 +1,45 @@
#
# Cookbook Name:: postgresql
# Recipe::yum_pgdg_postgresql
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#######
# Load the pgdgrepo_rpm_info method from libraries/default.rb
::Chef::Recipe.send(:include, Opscode::PostgresqlHelpers)
######################################
# Install the "PostgreSQL RPM Building Project - Yum Repository" through
# the repo_rpm_url determined with pgdgrepo_rpm_info method from
# libraries/default.rb. The /etc/yum.repos.d/pgdg-*.repo
# will provide postgresql9X packages, but you may need to exclude
# postgresql packages from the repository of the distro in order to use
# PGDG repository properly. Conflicts will arise if postgresql9X does
# appear in your distro's repo and you want a more recent patch level.
repo_rpm_url, repo_rpm_filename, repo_rpm_package = pgdgrepo_rpm_info
# Download the PGDG repository RPM as a local file
remote_file "#{Chef::Config[:file_cache_path]}/#{repo_rpm_filename}" do
source repo_rpm_url
mode "0644"
end
# Install the PGDG repository RPM from the local file
# E.g., /etc/yum.repos.d/pgdg-91-centos.repo
package repo_rpm_package do
provider Chef::Provider::Package::Rpm
source "#{Chef::Config[:file_cache_path]}/#{repo_rpm_filename}"
action :install
end