from-scratch 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Berksfile.lock +11 -0
  4. data/chefignore +1 -0
  5. data/cookbooks/apt/CHANGELOG.md +248 -0
  6. data/cookbooks/apt/README.md +294 -0
  7. data/cookbooks/apt/attributes/default.rb +51 -0
  8. data/cookbooks/apt/files/default/15update-stamp +1 -0
  9. data/cookbooks/apt/files/default/apt-proxy-v2.conf +50 -0
  10. data/cookbooks/apt/libraries/helpers.rb +61 -0
  11. data/cookbooks/apt/libraries/matchers.rb +17 -0
  12. data/cookbooks/apt/libraries/network.rb +31 -0
  13. data/cookbooks/apt/metadata.json +1 -0
  14. data/cookbooks/apt/providers/preference.rb +84 -0
  15. data/cookbooks/apt/providers/repository.rb +246 -0
  16. data/cookbooks/apt/recipes/cacher-client.rb +83 -0
  17. data/cookbooks/apt/recipes/cacher-ng.rb +43 -0
  18. data/cookbooks/apt/recipes/default.rb +112 -0
  19. data/cookbooks/apt/recipes/unattended-upgrades.rb +47 -0
  20. data/cookbooks/apt/resources/preference.rb +37 -0
  21. data/cookbooks/apt/resources/repository.rb +60 -0
  22. data/cookbooks/apt/templates/debian-6.0/acng.conf.erb +173 -0
  23. data/cookbooks/apt/templates/default/01proxy.erb +9 -0
  24. data/cookbooks/apt/templates/default/10recommends.erb +3 -0
  25. data/cookbooks/apt/templates/default/20auto-upgrades.erb +2 -0
  26. data/cookbooks/apt/templates/default/50unattended-upgrades.erb +68 -0
  27. data/cookbooks/apt/templates/default/acng.conf.erb +275 -0
  28. data/cookbooks/apt/templates/default/unattended-upgrades.seed.erb +1 -0
  29. data/cookbooks/apt/templates/ubuntu-10.04/acng.conf.erb +269 -0
  30. data/cookbooks/build-essential/CHANGELOG.md +136 -0
  31. data/cookbooks/build-essential/README.md +108 -0
  32. data/cookbooks/build-essential/attributes/default.rb +20 -0
  33. data/cookbooks/build-essential/libraries/matchers.rb +5 -0
  34. data/cookbooks/build-essential/libraries/timing.rb +124 -0
  35. data/cookbooks/build-essential/libraries/xcode_command_line_tools.rb +210 -0
  36. data/cookbooks/build-essential/metadata.json +1 -0
  37. data/cookbooks/build-essential/recipes/_debian.rb +28 -0
  38. data/cookbooks/build-essential/recipes/_fedora.rb +32 -0
  39. data/cookbooks/build-essential/recipes/_freebsd.rb +24 -0
  40. data/cookbooks/build-essential/recipes/_mac_os_x.rb +22 -0
  41. data/cookbooks/build-essential/recipes/_omnios.rb +33 -0
  42. data/cookbooks/build-essential/recipes/_rhel.rb +36 -0
  43. data/cookbooks/build-essential/recipes/_smartos.rb +27 -0
  44. data/cookbooks/build-essential/recipes/_solaris2.rb +48 -0
  45. data/cookbooks/build-essential/recipes/_suse.rb +29 -0
  46. data/cookbooks/build-essential/recipes/default.rb +29 -0
  47. data/cookbooks/chef-sugar/CHANGELOG.md +159 -0
  48. data/cookbooks/chef-sugar/README.md +464 -0
  49. data/cookbooks/chef-sugar/metadata.json +1 -0
  50. data/cookbooks/chef-sugar/recipes/default.rb +34 -0
  51. data/cookbooks/openssl/CHANGELOG.md +30 -0
  52. data/cookbooks/openssl/README.md +115 -0
  53. data/cookbooks/openssl/attributes/default.rb +21 -0
  54. data/cookbooks/openssl/libraries/secure_password.rb +37 -0
  55. data/cookbooks/openssl/metadata.json +31 -0
  56. data/cookbooks/openssl/providers/x509.rb +94 -0
  57. data/cookbooks/openssl/recipes/default.rb +18 -0
  58. data/cookbooks/openssl/recipes/upgrade.rb +39 -0
  59. data/cookbooks/openssl/resources/x509.rb +16 -0
  60. data/cookbooks/postgresql/CHANGELOG.md +220 -0
  61. data/cookbooks/postgresql/README.md +464 -0
  62. data/cookbooks/postgresql/attributes/default.rb +549 -0
  63. data/cookbooks/postgresql/files/default/tests/minitest/apt_pgdg_postgresql_test.rb +39 -0
  64. data/cookbooks/postgresql/files/default/tests/minitest/default_test.rb +27 -0
  65. data/cookbooks/postgresql/files/default/tests/minitest/ruby_test.rb +28 -0
  66. data/cookbooks/postgresql/files/default/tests/minitest/server_test.rb +43 -0
  67. data/cookbooks/postgresql/files/default/tests/minitest/support/helpers.rb +29 -0
  68. data/cookbooks/postgresql/libraries/default.rb +377 -0
  69. data/cookbooks/postgresql/metadata.json +56 -0
  70. data/cookbooks/postgresql/recipes/apt_pgdg_postgresql.rb +18 -0
  71. data/cookbooks/postgresql/recipes/client.rb +32 -0
  72. data/cookbooks/postgresql/recipes/config_initdb.rb +148 -0
  73. data/cookbooks/postgresql/recipes/config_pgtune.rb +284 -0
  74. data/cookbooks/postgresql/recipes/contrib.rb +44 -0
  75. data/cookbooks/postgresql/recipes/default.rb +18 -0
  76. data/cookbooks/postgresql/recipes/ruby.rb +117 -0
  77. data/cookbooks/postgresql/recipes/server.rb +89 -0
  78. data/cookbooks/postgresql/recipes/server_conf.rb +34 -0
  79. data/cookbooks/postgresql/recipes/server_debian.rb +38 -0
  80. data/cookbooks/postgresql/recipes/server_redhat.rb +100 -0
  81. data/cookbooks/postgresql/recipes/yum_pgdg_postgresql.rb +45 -0
  82. data/cookbooks/postgresql/templates/default/pg_hba.conf.erb +35 -0
  83. data/cookbooks/postgresql/templates/default/pgsql.sysconfig.erb +4 -0
  84. data/cookbooks/postgresql/templates/default/postgresql.conf.erb +21 -0
  85. data/cookbooks/scratchify/.chef/knife.rb +2 -5
  86. data/cookbooks/scratchify/Berksfile +2 -1
  87. data/cookbooks/scratchify/Berksfile.lock +11 -0
  88. data/cookbooks/scratchify/README.md +34 -17
  89. data/cookbooks/scratchify/bin/scratchify +1 -1
  90. data/cookbooks/scratchify/chefignore +1 -0
  91. data/cookbooks/scratchify/from-scratch.gemspec +2 -5
  92. data/cookbooks/scratchify/lib/from-scratch.rb +25 -0
  93. data/cookbooks/scratchify/lib/{from/scratch → from-scratch}/version.rb +1 -1
  94. data/cookbooks/scratchify/metadata.json +2 -1
  95. data/cookbooks/scratchify/templates/node.json.erb +34 -0
  96. data/cookbooks/scratchify/templates/user.json.erb +6 -0
  97. data/lib/from-scratch.rb +2 -2
  98. data/lib/from-scratch/version.rb +1 -1
  99. data/templates/node.json.erb +6 -3
  100. metadata +85 -10
  101. data/cookbooks/scratchify/bin/console +0 -14
  102. data/cookbooks/scratchify/bin/setup +0 -7
  103. data/cookbooks/scratchify/data_bags/users/deploy.json +0 -6
  104. data/cookbooks/scratchify/environments/.gitkeep +0 -0
  105. data/cookbooks/scratchify/lib/from/scratch.rb +0 -31
  106. data/cookbooks/scratchify/lib/from/scratch/interviewer.rb +0 -35
  107. data/cookbooks/scratchify/nodes/normfood.ru.json +0 -75
  108. data/cookbooks/scratchify/roles/.gitkeep +0 -0
@@ -0,0 +1,39 @@
1
+ #
2
+ # Copyright 2012, Opscode, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require File.expand_path('../support/helpers', __FILE__)
18
+
19
+ describe 'postgresql::apt_pgdg_postgresql' do
20
+ include Helpers::Postgresql
21
+
22
+ it 'removes the Pitti PPA sources.list' do
23
+ skip unless %w{debian}.include?(node['platform_family'])
24
+ file("/etc/apt/sources.list.d/pitti-postgresql-ppa").wont_exist
25
+ end
26
+ it 'creates the PGDG apt sources.list' do
27
+ skip unless %w{debian}.include?(node['platform_family'])
28
+ file("/etc/apt/sources.list.d/apt.postgresql.org.list").must_exist
29
+ end
30
+
31
+ it 'installs postgresql-client-9.3' do
32
+ package("postgresql-client-9.3").must_be_installed
33
+ end
34
+
35
+ it 'makes psql version 9.3 available' do
36
+ psql = shell_out("psql --version")
37
+ assert psql.stdout.include?("psql (PostgreSQL) 9.3")
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ #
2
+ # Copyright 2012, Opscode, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require File.expand_path('../support/helpers', __FILE__)
18
+
19
+ describe 'postgresql::default' do
20
+ include Helpers::Postgresql
21
+
22
+ it 'installs the postgresql client packages' do
23
+ node['postgresql']['client']['packages'].each do |pkg|
24
+ package(pkg).must_be_installed
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,28 @@
1
+ #
2
+ # Cookbook Name:: postgresql_test
3
+ # Recipe:: default
4
+ #
5
+ # Copyright 2012, Opscode, Inc.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ require File.expand_path('../support/helpers', __FILE__)
21
+
22
+ describe 'postgresql::ruby' do
23
+ include Helpers::Postgresql
24
+
25
+ it 'installs the pg gem in Chefs ruby environment' do
26
+ assert Gem::Specification.all_names.grep("pg-.*")
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ #
2
+ # Copyright 2012, Opscode, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require File.expand_path('../support/helpers', __FILE__)
18
+
19
+ describe 'postgresql::server' do
20
+ include Helpers::Postgresql
21
+
22
+ it 'installs the postgresql server packages' do
23
+ node['postgresql']['server']['packages'].each do |pkg|
24
+ package(pkg).must_be_installed
25
+ end
26
+ end
27
+
28
+ it 'runs the postgresql service' do
29
+ service((node['postgresql']['server']['service_name'] || 'postgresql')).must_be_running
30
+ end
31
+
32
+ it 'can connect to postgresql' do
33
+ require 'pg'
34
+ conn = PG::Connection.new(
35
+ :host => 'localhost',
36
+ :port => '5432',
37
+ :password => node['postgresql']['password']['postgres'],
38
+ :user => "postgres"
39
+ )
40
+ assert_match(/localhost/, conn.host)
41
+ end
42
+
43
+ end
@@ -0,0 +1,29 @@
1
+ #
2
+ # Cookbook Name:: postgresql_test
3
+ # Recipe:: default
4
+ #
5
+ # Copyright 2012, Opscode, Inc.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+ module Helpers
21
+ module Postgresql
22
+ require 'chef/mixin/shell_out'
23
+ include Chef::Mixin::ShellOut
24
+ include MiniTest::Chef::Assertions
25
+ include MiniTest::Chef::Context
26
+ include MiniTest::Chef::Resources
27
+
28
+ end
29
+ end
@@ -0,0 +1,377 @@
1
+ #
2
+ # Cookbook Name:: postgresql
3
+ # Library:: default
4
+ # Author:: David Crane (<davidc@donorschoose.org>)
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ include Chef::Mixin::ShellOut
20
+
21
+ module Opscode
22
+ module PostgresqlHelpers
23
+
24
+ #######
25
+ # Function to truncate value to 4 significant bits, render human readable.
26
+ # Used in recipes/config_initdb.rb to set this attribute:
27
+ #
28
+ # The memory settings (shared_buffers, effective_cache_size, work_mem,
29
+ # maintenance_work_mem and wal_buffers) will be rounded down to keep
30
+ # the 4 most significant bits, so that SHOW will be likely to use a
31
+ # larger divisor. The output is actually a human readable string that
32
+ # ends with "GB", "MB" or "kB" if over 1023, exactly what Postgresql
33
+ # will expect in a postgresql.conf setting. The output may be up to
34
+ # 6.25% less than the original value because of the rounding.
35
+ def binaryround(value)
36
+
37
+ # Keep a multiplier which grows through powers of 1
38
+ multiplier = 1
39
+
40
+ # Truncate value to 4 most significant bits
41
+ while value >= 16
42
+ value = (value / 2).floor
43
+ multiplier = multiplier * 2
44
+ end
45
+
46
+ # Factor any remaining powers of 2 into the multiplier
47
+ while value == 2*((value / 2).floor)
48
+ value = (value / 2).floor
49
+ multiplier = multiplier * 2
50
+ end
51
+
52
+ # Factor enough powers of 2 back into the value to
53
+ # leave the multiplier as a power of 1024 that can
54
+ # be represented as units of "GB", "MB" or "kB".
55
+ if multiplier >= 1024*1024*1024
56
+ while multiplier > 1024*1024*1024
57
+ value = 2*value
58
+ multiplier = (multiplier/2).floor
59
+ end
60
+ multiplier = 1
61
+ units = "GB"
62
+
63
+ elsif multiplier >= 1024*1024
64
+ while multiplier > 1024*1024
65
+ value = 2*value
66
+ multiplier = (multiplier/2).floor
67
+ end
68
+ multiplier = 1
69
+ units = "MB"
70
+
71
+ elsif multiplier >= 1024
72
+ while multiplier > 1024
73
+ value = 2*value
74
+ multiplier = (multiplier/2).floor
75
+ end
76
+ multiplier = 1
77
+ units = "kB"
78
+
79
+ else
80
+ units = ""
81
+ end
82
+
83
+ # Now we can return a nice human readable string.
84
+ return "#{multiplier * value}#{units}"
85
+ end
86
+
87
+ #######
88
+ # Locale Configuration
89
+
90
+ # Function to test the date order.
91
+ # Used in recipes/config_initdb.rb to set this attribute:
92
+ # node.default['postgresql']['config']['datestyle']
93
+ def locale_date_order
94
+ # Test locale conversion of mon=11, day=22, year=33
95
+ testtime = DateTime.new(2033,11,22,0,0,0,"-00:00")
96
+ #=> #<DateTime: 2033-11-22T00:00:00-0000 ...>
97
+
98
+ # %x - Preferred representation for the date alone, no time
99
+ res = testtime.strftime("%x")
100
+
101
+ if res.nil?
102
+ return 'mdy'
103
+ end
104
+
105
+ posM = res.index("11")
106
+ posD = res.index("22")
107
+ posY = res.index("33")
108
+
109
+ if (posM.nil? || posD.nil? || posY.nil?)
110
+ return 'mdy'
111
+ elseif (posY < posM && posM < posD)
112
+ return 'ymd'
113
+ elseif (posD < posM)
114
+ return 'dmy'
115
+ else
116
+ return 'mdy'
117
+ end
118
+ end
119
+
120
+ #######
121
+ # Timezone Configuration
122
+ require 'find'
123
+
124
+ # Function to determine where the system stored shared timezone data.
125
+ # Used in recipes/config_initdb.rb to detemine where it should have
126
+ # select_default_timezone(tzdir) search.
127
+ def pg_TZDIR()
128
+ # System time zone conversions are controlled by a timezone data file
129
+ # identified through environment variables (TZ and TZDIR) and/or file
130
+ # and directory naming conventions specific to the Linux distribution.
131
+ # Each of these timezone names will have been loaded into the PostgreSQL
132
+ # pg_timezone_names view by the package maintainer.
133
+ #
134
+ # Instead of using the timezone name configured as the system default,
135
+ # the PostgreSQL server uses ones named in postgresql.conf settings
136
+ # (timezone and log_timezone). The initdb utility does initialize those
137
+ # settings to the timezone name that corresponds to the system default.
138
+ #
139
+ # The system's timezone name is actually a filename relative to the
140
+ # shared zoneinfo directory. That is usually /usr/share/zoneinfo, but
141
+ # it was /usr/lib/zoneinfo in older distributions and can be anywhere
142
+ # if specified by the environment variable TZDIR. The tzset(3) manpage
143
+ # seems to indicate the following precedence:
144
+ tzdir = nil
145
+ if ::File.directory?("/usr/lib/zoneinfo")
146
+ tzdir = "/usr/lib/zoneinfo"
147
+ else
148
+ share_path = [ ENV['TZDIR'], "/usr/share/zoneinfo" ].compact.first
149
+ if ::File.directory?(share_path)
150
+ tzdir = share_path
151
+ end
152
+ end
153
+ return tzdir
154
+ end
155
+
156
+ #######
157
+ # Function to support select_default_timezone(tzdir), which is
158
+ # used in recipes/config_initdb.rb.
159
+ def validate_zone(tzname)
160
+ # PostgreSQL does not support leap seconds, so this function tests
161
+ # the usual Linux tzname convention to avoid a misconfiguration.
162
+ # Assume that the tzdata package maintainer has kept all timezone
163
+ # data files with support for leap seconds is kept under the
164
+ # so-named "right/" subdir of the shared zoneinfo directory.
165
+ #
166
+ # The original PostgreSQL initdb is not Unix-specific, so it did a
167
+ # very complicated, thorough test in its pg_tz_acceptable() function
168
+ # that I could not begin to understand how to do in ruby :).
169
+ #
170
+ # Testing the tzname is good enough, since a misconfiguration
171
+ # will result in an immediate fatal error when the PostgreSQL
172
+ # service is started, with pgstartup.log messages such as:
173
+ # LOG: time zone "right/US/Eastern" appears to use leap seconds
174
+ # DETAIL: PostgreSQL does not support leap seconds.
175
+
176
+ if tzname.index("right/") == 0
177
+ return false
178
+ else
179
+ return true
180
+ end
181
+ end
182
+
183
+ # Function to support select_default_timezone(tzdir), which is
184
+ # used in recipes/config_initdb.rb.
185
+ def scan_available_timezones(tzdir)
186
+ # There should be an /etc/localtime zoneinfo file that is a link to
187
+ # (or a copy of) a timezone data file under tzdir, which should have
188
+ # been installed under the "share" directory by the tzdata package.
189
+ #
190
+ # The initdb utility determines which shared timezone file is being
191
+ # used as the system's default /etc/localtime. The timezone name is
192
+ # the timezone file path relative to the tzdir.
193
+
194
+ bestzonename = nil
195
+
196
+ if (tzdir.nil?)
197
+ Chef::Log.error("The zoneinfo directory not found (looked for /usr/share/zoneinfo and /usr/lib/zoneinfo)")
198
+ elsif !::File.exists?("/etc/localtime")
199
+ Chef::Log.error("The system zoneinfo file not found (looked for /etc/localtime)")
200
+ elsif ::File.directory?("/etc/localtime")
201
+ Chef::Log.error("The system zoneinfo file not found (/etc/localtime is a directory instead)")
202
+ elsif ::File.symlink?("/etc/localtime")
203
+ # PostgreSQL initdb doesn't use the symlink target, but this
204
+ # certainly will make sense to any system administrator. A full
205
+ # scan of the tzdir to find the shortest filename could result
206
+ # "US/Eastern" instead of "America/New_York" as bestzonename,
207
+ # in spite of what the sysadmin had specified in the symlink.
208
+ # (There are many duplicates under tzdir, with the same timezone
209
+ # content appearing as an average of 2-3 different file names.)
210
+ path = ::File.readlink("/etc/localtime")
211
+ bestzonename = path.gsub("#{tzdir}/","")
212
+ else # /etc/localtime is a file, so scan for it under tzdir
213
+ localtime_content = File.read("/etc/localtime")
214
+
215
+ Find.find(tzdir) do |path|
216
+ # Only consider files (skip directories or symlinks)
217
+ if !::File.directory?(path) && !::File.symlink?(path)
218
+ # Ignore any file named "posixrules" or "localtime"
219
+ if ::File.basename(path) != "posixrules" && ::File.basename(path) != "localtime"
220
+ # Do consider if content exactly matches /etc/localtime.
221
+ if localtime_content == File.read(path)
222
+ tzname = path.gsub("#{tzdir}/","")
223
+ if validate_zone(tzname)
224
+ if (bestzonename.nil? ||
225
+ tzname.length < bestzonename.length ||
226
+ (tzname.length == bestzonename.length &&
227
+ (tzname <=> bestzonename) < 0)
228
+ )
229
+ bestzonename = tzname
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ return bestzonename
239
+ end
240
+
241
+ # Function to support select_default_timezone(tzdir), which is
242
+ # used in recipes/config_initdb.rb.
243
+ def identify_system_timezone(tzdir)
244
+ resultbuf = scan_available_timezones(tzdir)
245
+
246
+ if !resultbuf.nil?
247
+ # Ignore Olson's rather silly "Factory" zone; use GMT instead
248
+ if (resultbuf <=> "Factory") == 0
249
+ resultbuf = nil
250
+ end
251
+
252
+ else
253
+ # Did not find the timezone. Fallback to use a GMT zone. Note that the
254
+ # Olson timezone database names the GMT-offset zones in POSIX style: plus
255
+ # is west of Greenwich.
256
+ testtime = DateTime.now
257
+ std_ofs = testtime.strftime("%:z").split(":")[0].to_i
258
+
259
+ resultbuf = [
260
+ "Etc/GMT",
261
+ (-std_ofs > 0) ? "+" : "",
262
+ (-std_ofs).to_s
263
+ ].join('')
264
+ end
265
+
266
+ return resultbuf
267
+ end
268
+
269
+ #######
270
+ # Function to determine the name of the system's default timezone.
271
+ # Used in recipes/config_initdb.rb to set these attributes:
272
+ # node.default['postgresql']['config']['log_timezone']
273
+ # node.default['postgresql']['config']['timezone']
274
+ def select_default_timezone(tzdir)
275
+
276
+ system_timezone = nil
277
+
278
+ # Check TZ environment variable
279
+ tzname = ENV['TZ']
280
+ if !tzname.nil? && !tzname.empty? && validate_zone(tzname)
281
+ system_timezone = tzname
282
+
283
+ else
284
+ # Nope, so try to identify system timezone from /etc/localtime
285
+ tzname = identify_system_timezone(tzdir)
286
+ if validate_zone(tzname)
287
+ system_timezone = tzname
288
+ end
289
+ end
290
+
291
+ return system_timezone
292
+ end
293
+
294
+ #######
295
+ # Function to determine the name of the system's default timezone.
296
+ def get_result_orig(query)
297
+ # query could be a String or an Array of String
298
+ if (query.is_a?(String))
299
+ stdin = query
300
+ else
301
+ stdin = query.join("\n")
302
+ end
303
+ @get_result ||= begin
304
+ cmd = shell_out("cat", :input => stdin)
305
+ cmd.stdout
306
+ end
307
+ end
308
+
309
+ #######
310
+ # Function to execute an SQL statement in the default database.
311
+ # Input: Query could be a single String or an Array of String.
312
+ # Output: A String with |-separated columns and \n-separated rows.
313
+ # Note an empty output could mean psql couldn't connect.
314
+ # This is easiest for 1-field (1-row, 1-col) results, otherwise
315
+ # it will be complex to parse the results.
316
+ def execute_sql(query)
317
+ db_name = node['postgresql']['database_name']
318
+ # query could be a String or an Array of String
319
+ statement = query.is_a?(String) ? query : query.join("\n")
320
+ @execute_sql ||= begin
321
+ cmd = shell_out("psql -q --tuples-only --no-align -d #{db_name} -f -",
322
+ :user => "postgres",
323
+ :input => statement
324
+ )
325
+ # If psql fails, generally the postgresql service is down.
326
+ # Instead of aborting chef with a fatal error, let's just
327
+ # pass these non-zero exitstatus back as empty cmd.stdout.
328
+ if (cmd.exitstatus() == 0 and !cmd.stderr.empty?)
329
+ # An SQL failure is still a zero exitstatus, but then the
330
+ # stderr explains the error, so let's rais that as fatal.
331
+ Chef::Log.fatal("psql failed executing this SQL statement:\n#{statement}")
332
+ Chef::Log.fatal(cmd.stderr)
333
+ raise "SQL ERROR"
334
+ end
335
+ cmd.stdout.chomp
336
+ end
337
+ end
338
+
339
+ #######
340
+ # Function to determine if a standard contrib extension is already installed.
341
+ # Input: Extension name
342
+ # Output: true or false
343
+ # Best use as a not_if gate on bash "install-#{pg_ext}-extension" resource.
344
+ def extension_installed?(pg_ext)
345
+ @extension_installed ||= begin
346
+ installed=execute_sql("select 'installed' from pg_extension where extname = '#{pg_ext}';")
347
+ installed =~ /^installed$/
348
+ end
349
+ end
350
+
351
+ ######################################
352
+ # Function to build information needed to install RPM for PGDG yum repository,
353
+ # since PGDG supports several versions of PostgreSQL, platforms, platform versions
354
+ # and architectures.
355
+ # Links to RPMs for installation are in an attribute so that new versions/platforms
356
+ # can be more easily added. (See attributes/default.rb)
357
+ def pgdgrepo_rpm_info
358
+ repo_rpm_url = node['postgresql']['pgdg']['repo_rpm_url'].
359
+ fetch(node['postgresql']['version']). # e.g., fetch for "9.1"
360
+ fetch(node['platform']). # e.g., fetch for "centos"
361
+ fetch(node['platform_version'].to_f.to_i.to_s). # e.g., fetch for "5" (truncated "5.7")
362
+ fetch(node['kernel']['machine']) # e.g., fetch for "i386" or "x86_64"
363
+
364
+ # Extract the filename portion from the URL for the PGDG repository RPM.
365
+ # E.g., repo_rpm_filename = "pgdg-centos92-9.2-6.noarch.rpm"
366
+ repo_rpm_filename = File.basename(repo_rpm_url)
367
+
368
+ # Extract the package name from the URL for the PGDG repository RPM.
369
+ # E.g., repo_rpm_package = "pgdg-centos92"
370
+ repo_rpm_package = repo_rpm_filename.split(/-/,3)[0..1].join('-')
371
+
372
+ return [ repo_rpm_url, repo_rpm_filename, repo_rpm_package ]
373
+ end
374
+
375
+ # End the Opscode::PostgresqlHelpers module
376
+ end
377
+ end