inspec 0.29.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -2
- data/Rakefile +53 -0
- data/docs/cli.rst +442 -0
- data/examples/inheritance/inspec.yml +3 -0
- data/inspec.gemspec +1 -0
- data/lib/inspec/cli.rb +10 -1
- data/lib/inspec/completions/bash.sh.erb +45 -0
- data/lib/inspec/completions/zsh.sh.erb +61 -0
- data/lib/inspec/dependencies.rb +307 -0
- data/lib/inspec/dsl.rb +5 -20
- data/lib/inspec/env_printer.rb +149 -0
- data/lib/inspec/errors.rb +17 -0
- data/lib/inspec/metadata.rb +4 -0
- data/lib/inspec/profile.rb +12 -0
- data/lib/inspec/profile_context.rb +5 -2
- data/lib/inspec/shell.rb +7 -2
- data/lib/inspec/shell_detector.rb +90 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/resources/postgres.rb +94 -12
- data/lib/resources/registry_key.rb +106 -27
- data/lib/utils/hash_map.rb +37 -0
- data/test/bench/startup.flat.txt +998 -0
- data/test/bench/startup.graph.html +71420 -0
- data/test/bench/startup.grind.dat +103554 -0
- data/test/bench/startup.stack.html +25015 -0
- data/test/bench/startup/startup.flat.txt +1005 -0
- data/test/bench/startup/startup.graph.html +71958 -0
- data/test/bench/startup/startup.grind.dat +101602 -0
- data/test/bench/startup/startup.stack.html +24516 -0
- data/test/cookbooks/os_prepare/metadata.rb +1 -0
- data/test/cookbooks/os_prepare/recipes/file.rb +5 -0
- data/test/cookbooks/os_prepare/recipes/registry_key.rb +13 -0
- data/test/docker_run.rb +3 -1
- data/test/functional/inheritance_test.rb +26 -13
- data/test/helper.rb +2 -2
- data/test/integration/default/file_spec.rb +16 -0
- data/test/integration/default/powershell_spec.rb +4 -1
- data/test/integration/default/registry_key_spec.rb +47 -4
- data/test/integration/default/secpol_spec.rb +4 -1
- data/test/integration/default/wmi_spec.rb +4 -1
- data/test/unit/mock/profiles/resource-tiny/inspec.yml +10 -0
- data/test/unit/mock/profiles/resource-tiny/libraries/resource.rb +3 -0
- data/test/unit/shell_detector_test.rb +78 -0
- metadata +47 -4
- data/docs/ctl_inspec.rst +0 -247
data/lib/inspec/dsl.rb
CHANGED
@@ -6,12 +6,12 @@
|
|
6
6
|
|
7
7
|
module Inspec::DSL
|
8
8
|
def require_controls(id, &block)
|
9
|
-
opts = { profile_id: id, include_all: false, backend: @backend, conf: @conf }
|
9
|
+
opts = { profile_id: id, include_all: false, backend: @backend, conf: @conf, dependencies: @dependencies }
|
10
10
|
::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
|
11
11
|
end
|
12
12
|
|
13
13
|
def include_controls(id, &block)
|
14
|
-
opts = { profile_id: id, include_all: true, backend: @backend, conf: @conf }
|
14
|
+
opts = { profile_id: id, include_all: true, backend: @backend, conf: @conf, dependencies: @dependencies }
|
15
15
|
::Inspec::DSL.load_spec_files_for_profile(self, opts, &block)
|
16
16
|
end
|
17
17
|
|
@@ -33,8 +33,9 @@ module Inspec::DSL
|
|
33
33
|
|
34
34
|
def self.load_spec_files_for_profile(bind_context, opts, &block)
|
35
35
|
# get all spec files
|
36
|
-
target =
|
37
|
-
|
36
|
+
target = opts[:dependencies].list[opts[:profile_id]] ||
|
37
|
+
fail("Can't find profile #{opts[:profile_id].inspect}, please add it as a dependency.")
|
38
|
+
profile = Inspec::Profile.for_target(target.path, opts)
|
38
39
|
context = load_profile_context(opts[:profile_id], profile, opts)
|
39
40
|
|
40
41
|
# if we don't want all the rules, then just make 1 pass to get all rule_IDs
|
@@ -62,22 +63,6 @@ module Inspec::DSL
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
|
-
def self.get_reference_profile(id, opts)
|
66
|
-
profiles_path = opts['profiles_path'] ||
|
67
|
-
fail('You must supply a --profiles-path to inherit from other profiles.')
|
68
|
-
abs_path = File.expand_path(profiles_path.to_s)
|
69
|
-
unless File.directory? abs_path
|
70
|
-
fail("Cannot find profiles path #{abs_path}")
|
71
|
-
end
|
72
|
-
|
73
|
-
id_path = File.join(abs_path, id)
|
74
|
-
unless File.directory? id_path
|
75
|
-
fail("Cannot find referenced profile #{id} in #{id_path}")
|
76
|
-
end
|
77
|
-
|
78
|
-
id_path
|
79
|
-
end
|
80
|
-
|
81
66
|
def self.load_profile_context(id, profile, opts)
|
82
67
|
ctx = Inspec::ProfileContext.new(id, opts[:backend], opts[:conf])
|
83
68
|
profile.libraries.each do |path, content|
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'inspec/shell_detector'
|
3
|
+
require 'erb'
|
4
|
+
require 'shellwords'
|
5
|
+
|
6
|
+
module Inspec
|
7
|
+
class EnvPrinter
|
8
|
+
def initialize(command_class, shell = nil)
|
9
|
+
if !shell
|
10
|
+
@detected = true
|
11
|
+
@shell = Inspec::ShellDetector.new.shell
|
12
|
+
else
|
13
|
+
@shell = shell
|
14
|
+
end
|
15
|
+
@command_class = command_class
|
16
|
+
end
|
17
|
+
|
18
|
+
def print_and_exit!
|
19
|
+
exit_no_shell if !have_shell?
|
20
|
+
exit_no_completion if !have_shell_completion?
|
21
|
+
|
22
|
+
print_completion_for_shell
|
23
|
+
print_detection_warning($stdout) if @detected
|
24
|
+
print_usage_guidance
|
25
|
+
exit 0
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def print_completion_for_shell
|
31
|
+
erb = ERB.new(File.read(completion_template_path), nil, '-')
|
32
|
+
puts erb.result(TemplateContext.new(@command_class).get_bindings)
|
33
|
+
end
|
34
|
+
|
35
|
+
def have_shell?
|
36
|
+
! (@shell.nil? || @shell.empty?)
|
37
|
+
end
|
38
|
+
|
39
|
+
def have_shell_completion?
|
40
|
+
File.exist?(completion_template_path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def completion_dir
|
44
|
+
File.join(File.dirname(__FILE__), 'completions')
|
45
|
+
end
|
46
|
+
|
47
|
+
def completion_template_path
|
48
|
+
File.join(completion_dir, "#{@shell}.sh.erb")
|
49
|
+
end
|
50
|
+
|
51
|
+
def shells_with_completions
|
52
|
+
Dir.glob("#{completion_dir}/*.sh.erb").map { |f| File.basename(f, '.sh.erb') }
|
53
|
+
end
|
54
|
+
|
55
|
+
def print_usage_guidance
|
56
|
+
puts <<EOF
|
57
|
+
# To use this, eval it in your shell
|
58
|
+
#
|
59
|
+
# eval "$(inspec env #{@shell})"
|
60
|
+
#
|
61
|
+
#
|
62
|
+
EOF
|
63
|
+
end
|
64
|
+
|
65
|
+
def print_detection_warning(device)
|
66
|
+
device.puts <<EOF
|
67
|
+
#
|
68
|
+
# The shell #{@shell} was auto-detected. If this is incorrect, please
|
69
|
+
# specify a shell explicitly by running:
|
70
|
+
#
|
71
|
+
# inspec env SHELLNAME
|
72
|
+
#
|
73
|
+
# Currently supported shells are: #{shells_with_completions.join(', ')}
|
74
|
+
#
|
75
|
+
EOF
|
76
|
+
end
|
77
|
+
|
78
|
+
def exit_no_completion
|
79
|
+
$stderr.puts "# No completion script for #{@shell}!"
|
80
|
+
print_detection_warning($stderr) if @detected
|
81
|
+
exit 1
|
82
|
+
end
|
83
|
+
|
84
|
+
def exit_no_shell
|
85
|
+
if @detected
|
86
|
+
$stderr.puts '# Unable to automatically detect shell and no shell was provided.'
|
87
|
+
end
|
88
|
+
$stderr.puts <<EOF
|
89
|
+
#
|
90
|
+
# Please provide the name of your shell via the command line:
|
91
|
+
#
|
92
|
+
# inspec env SHELLNAME
|
93
|
+
#
|
94
|
+
# Currently supported shells are: #{shells_with_completions.join(', ')}
|
95
|
+
EOF
|
96
|
+
exit 1
|
97
|
+
end
|
98
|
+
|
99
|
+
class TemplateContext
|
100
|
+
def initialize(command_class)
|
101
|
+
@command_class = command_class
|
102
|
+
end
|
103
|
+
|
104
|
+
def get_bindings # rubocop:disable Style/AccessorMethodName
|
105
|
+
binding
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# The following functions all assume that @command_class
|
110
|
+
# is something that provides a Thor-like API
|
111
|
+
#
|
112
|
+
def top_level_commands
|
113
|
+
commands_for_thor_class(@command_class)
|
114
|
+
end
|
115
|
+
|
116
|
+
def top_level_commands_with_descriptions
|
117
|
+
descript_lines_for_class(@command_class)
|
118
|
+
end
|
119
|
+
|
120
|
+
def subcommands_with_commands
|
121
|
+
ret = {}
|
122
|
+
@command_class.subcommand_classes.each do |k, v|
|
123
|
+
ret[k] = commands_for_thor_class(v)
|
124
|
+
end
|
125
|
+
ret
|
126
|
+
end
|
127
|
+
|
128
|
+
def subcommands_with_commands_and_descriptions
|
129
|
+
ret = {}
|
130
|
+
@command_class.subcommand_classes.each do |k, v|
|
131
|
+
ret[k] = descript_lines_for_class(v)
|
132
|
+
end
|
133
|
+
ret
|
134
|
+
end
|
135
|
+
|
136
|
+
def commands_for_thor_class(thor_class)
|
137
|
+
thor_class.all_commands.values.map { |c| c.usage.split.first }
|
138
|
+
end
|
139
|
+
|
140
|
+
def descript_lines_for_class(thor_class)
|
141
|
+
thor_class.all_commands.values.map { |c| descript_line_for_command(c) }
|
142
|
+
end
|
143
|
+
|
144
|
+
def descript_line_for_command(c)
|
145
|
+
"#{c.usage.split.first}:#{Shellwords.escape(c.description)}"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
module Inspec
|
6
|
+
class Error < StandardError; end
|
7
|
+
|
8
|
+
# dependency resolution
|
9
|
+
class CyclicDependencyError < Error; end
|
10
|
+
class VersionConflict < Error
|
11
|
+
attr_reader :conflicts
|
12
|
+
def initialize(conflicts, msg = nil)
|
13
|
+
super(msg)
|
14
|
+
@conflicts = conflicts
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/inspec/metadata.rb
CHANGED
@@ -36,6 +36,10 @@ module Inspec
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def dependencies
|
40
|
+
params[:depends] || []
|
41
|
+
end
|
42
|
+
|
39
43
|
def supports(sth, version = nil)
|
40
44
|
# Ignore supports with metadata.rb. This file is legacy and the way it
|
41
45
|
# it handles `supports` deprecated. A deprecation warning will be printed
|
data/lib/inspec/profile.rb
CHANGED
@@ -8,6 +8,7 @@ require 'inspec/polyfill'
|
|
8
8
|
require 'inspec/fetcher'
|
9
9
|
require 'inspec/source_reader'
|
10
10
|
require 'inspec/metadata'
|
11
|
+
require 'inspec/dependencies'
|
11
12
|
|
12
13
|
module Inspec
|
13
14
|
class Profile # rubocop:disable Metrics/ClassLength
|
@@ -206,6 +207,10 @@ module Inspec
|
|
206
207
|
true
|
207
208
|
end
|
208
209
|
|
210
|
+
def locked_dependencies
|
211
|
+
@locked_dependencies ||= load_dependencies
|
212
|
+
end
|
213
|
+
|
209
214
|
private
|
210
215
|
|
211
216
|
# Create an archive name for this profile and an additional options
|
@@ -290,5 +295,12 @@ module Inspec
|
|
290
295
|
}
|
291
296
|
groups[file][:controls].push(id)
|
292
297
|
end
|
298
|
+
|
299
|
+
def load_dependencies
|
300
|
+
cwd = File.directory?(@target) ? @target : nil
|
301
|
+
res = Inspec::Dependencies.new(cwd, nil)
|
302
|
+
res.vendor(metadata.dependencies)
|
303
|
+
res
|
304
|
+
end
|
293
305
|
end
|
294
306
|
end
|
@@ -22,6 +22,8 @@ module Inspec
|
|
22
22
|
@backend = backend
|
23
23
|
@conf = conf.dup
|
24
24
|
@rules = {}
|
25
|
+
@dependencies = {}
|
26
|
+
@dependencies = conf['profile'].locked_dependencies unless conf['profile'].nil?
|
25
27
|
@require_loader = ::Inspec::RequireLoader.new
|
26
28
|
@attributes = []
|
27
29
|
reload_dsl
|
@@ -30,7 +32,7 @@ module Inspec
|
|
30
32
|
def reload_dsl
|
31
33
|
resources_dsl = Inspec::Resource.create_dsl(@backend)
|
32
34
|
ctx = create_context(resources_dsl, rule_context(resources_dsl))
|
33
|
-
@profile_context = ctx.new(@backend, @conf, @require_loader)
|
35
|
+
@profile_context = ctx.new(@backend, @conf, @dependencies, @require_loader)
|
34
36
|
end
|
35
37
|
|
36
38
|
def load_libraries(libs)
|
@@ -136,9 +138,10 @@ module Inspec
|
|
136
138
|
include Inspec::DSL
|
137
139
|
include resources_dsl
|
138
140
|
|
139
|
-
def initialize(backend, conf, require_loader) # rubocop:disable Lint/NestedMethodDefinition, Lint/DuplicateMethods
|
141
|
+
def initialize(backend, conf, dependencies, require_loader) # rubocop:disable Lint/NestedMethodDefinition, Lint/DuplicateMethods
|
140
142
|
@backend = backend
|
141
143
|
@conf = conf
|
144
|
+
@dependencies = dependencies
|
142
145
|
@require_loader = require_loader
|
143
146
|
@skip_profile = false
|
144
147
|
end
|
data/lib/inspec/shell.rb
CHANGED
@@ -32,7 +32,7 @@ module Inspec
|
|
32
32
|
|
33
33
|
# configure pry shell prompt
|
34
34
|
Pry.config.prompt_name = 'inspec'
|
35
|
-
Pry.prompt = [proc { "\e[0;32m#{Pry.config.prompt_name}
|
35
|
+
Pry.prompt = [proc { "#{readline_ignore("\e[0;32m")}#{Pry.config.prompt_name}> #{readline_ignore("\e[0m")}" }]
|
36
36
|
|
37
37
|
# Add a help menu as the default intro
|
38
38
|
Pry.hooks.add_hook(:before_session, :intro) do
|
@@ -40,8 +40,12 @@ module Inspec
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
def readline_ignore(code)
|
44
|
+
"\001#{code}\002"
|
45
|
+
end
|
46
|
+
|
43
47
|
def mark(x)
|
44
|
-
"\033[1m#{x}\033[0m"
|
48
|
+
"#{readline_ignore("\033[1m")}#{x}#{readline_ignore("\033[0m")}"
|
45
49
|
end
|
46
50
|
|
47
51
|
def print_example(example)
|
@@ -83,6 +87,7 @@ You can use resources in this environment to test the target machine. For exampl
|
|
83
87
|
|
84
88
|
You are currently running on:
|
85
89
|
|
90
|
+
OS platform: #{mark ctx.os[:name] || 'unknown'}
|
86
91
|
OS family: #{mark ctx.os[:family] || 'unknown'}
|
87
92
|
OS release: #{mark ctx.os[:release] || 'unknown'}
|
88
93
|
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'etc'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
module Inspec
|
6
|
+
#
|
7
|
+
# ShellDetector attempts to detect the shell the invoking user is
|
8
|
+
# running by checking:
|
9
|
+
#
|
10
|
+
# - The command of our parent
|
11
|
+
# - The SHELL environment variable
|
12
|
+
# - The shell returned by getpwuid for our process UID
|
13
|
+
#
|
14
|
+
# Since none of these methods is fullproof, the detected shell is
|
15
|
+
# verified against a list of known shells before being returned to
|
16
|
+
# the caller.
|
17
|
+
#
|
18
|
+
class ShellDetector
|
19
|
+
NOT_DETECTED = Object.new.freeze
|
20
|
+
KNOWN_SHELLS = %w{bash zsh ksh csh sh fish}.freeze
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@shell = NOT_DETECTED
|
24
|
+
end
|
25
|
+
|
26
|
+
def shell
|
27
|
+
@shell = detect if !detected?(@shell)
|
28
|
+
@shell
|
29
|
+
end
|
30
|
+
|
31
|
+
def shell!
|
32
|
+
@shell = detect
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def detect
|
38
|
+
# Most of our detection code assumes a unix-like environment
|
39
|
+
return nil if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
40
|
+
|
41
|
+
shellpath = detect_by_ppid
|
42
|
+
|
43
|
+
if shellpath.nil? || shellpath.empty? || !known_shell?(shellpath)
|
44
|
+
shellpath = detect_by_env
|
45
|
+
end
|
46
|
+
|
47
|
+
if shellpath.nil? || shellpath.empty? || !known_shell?(shellpath)
|
48
|
+
shellpath = detect_by_getpwuid
|
49
|
+
end
|
50
|
+
|
51
|
+
shellname(shellpath) if known_shell?(shellpath)
|
52
|
+
end
|
53
|
+
|
54
|
+
def detected?(arg)
|
55
|
+
arg != NOT_DETECTED
|
56
|
+
end
|
57
|
+
|
58
|
+
def detect_by_ppid
|
59
|
+
ppid = Process.ppid
|
60
|
+
if Dir.exist?('/proc')
|
61
|
+
File.readlink("/proc/#{ppid}/exe")
|
62
|
+
else
|
63
|
+
`ps -cp #{ppid} -o command=`.chomp
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def detect_by_env
|
68
|
+
ENV['SHELL']
|
69
|
+
end
|
70
|
+
|
71
|
+
def detect_by_getpwuid
|
72
|
+
Etc.getpwuid(Process.uid).shell
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Strip any leading path elements
|
77
|
+
#
|
78
|
+
def shellname(shellpath)
|
79
|
+
shellpath.split('/').last
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Only return shells that we know about, just to be sure we never
|
84
|
+
# do anything very silly.
|
85
|
+
#
|
86
|
+
def known_shell?(shell)
|
87
|
+
KNOWN_SHELLS.include?(shellname(shell))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/inspec/version.rb
CHANGED
data/lib/resources/postgres.rb
CHANGED
@@ -12,29 +12,111 @@ module Inspec::Resources
|
|
12
12
|
def initialize
|
13
13
|
os = inspec.os
|
14
14
|
if os.debian?
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
#
|
16
|
+
# https://wiki.debian.org/PostgreSql
|
17
|
+
#
|
18
|
+
# Debian allows multiple versions of postgresql to be
|
19
|
+
# installed as well as multiple "clusters" to be configured.
|
20
|
+
#
|
21
|
+
version = version_from_dir('/etc/postgresql')
|
22
|
+
cluster = cluster_from_dir("/etc/postgresql/#{version}")
|
23
|
+
@conf_dir = "/etc/postgresql/#{version}/#{cluster}"
|
24
|
+
@data_dir = "/var/lib/postgresql/#{version}/#{cluster}"
|
19
25
|
elsif os.redhat?
|
20
|
-
|
21
|
-
|
22
|
-
|
26
|
+
#
|
27
|
+
# /var/lib/pgsql/data is the default data directory on RHEL6
|
28
|
+
# and RHEL7. However, PR #824 explicitly added version-based
|
29
|
+
# directories. Thus, we call #version_from_dir unless it looks
|
30
|
+
# like we are using unversioned directories.
|
31
|
+
#
|
32
|
+
# TODO(ssd): This has the potential to be noisy because of the
|
33
|
+
# warning in version_from_dir. We should determine which case
|
34
|
+
# is more common and only warn in the less common case.
|
35
|
+
#
|
36
|
+
version = if inspec.directory('/var/lib/pgsql/data').exist?
|
37
|
+
warn 'Found /var/lib/pgsql/data. Assuming postgresql install uses un-versioned directories.'
|
38
|
+
nil
|
39
|
+
else
|
40
|
+
version_from_dir('/var/lib/pgsql/')
|
41
|
+
end
|
42
|
+
|
43
|
+
@data_dir = File.join('/var/lib/pgsql/', version.to_s, 'data')
|
23
44
|
elsif os[:name] == 'arch'
|
24
|
-
|
45
|
+
#
|
46
|
+
# https://wiki.archlinux.org/index.php/PostgreSQL
|
47
|
+
#
|
48
|
+
# The archlinux wiki points to /var/lib/postgresql/data as the
|
49
|
+
# main data directory.
|
50
|
+
#
|
25
51
|
@data_dir = '/var/lib/postgres/data'
|
26
|
-
@conf_dir = '/var/lib/postgres/data'
|
27
52
|
else
|
28
|
-
|
29
|
-
|
30
|
-
|
53
|
+
#
|
54
|
+
# According to https://www.postgresql.org/docs/9.5/static/creating-cluster.html
|
55
|
+
#
|
56
|
+
# > There is no default, although locations such as
|
57
|
+
# > /usr/local/pgsql/data or /var/lib/pgsql/data are popular.
|
58
|
+
#
|
59
|
+
@data_dir = '/var/lib/pgsql/data'
|
31
60
|
end
|
32
61
|
|
62
|
+
@service = 'postgresql'
|
63
|
+
@conf_dir ||= @data_dir
|
64
|
+
verify_dirs
|
33
65
|
@conf_path = File.join @conf_dir, 'postgresql.conf'
|
34
66
|
end
|
35
67
|
|
36
68
|
def to_s
|
37
69
|
'PostgreSQL'
|
38
70
|
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def verify_dirs
|
75
|
+
if !inspec.directory(@conf_dir).exist?
|
76
|
+
warn "Default postgresql configuration directory: #{@conf_dir} does not exist. Postgresql may not be installed or we've misidentified the configuration directory."
|
77
|
+
end
|
78
|
+
|
79
|
+
if !inspec.directory(@data_dir).exist?
|
80
|
+
warn "Default postgresql data directory: #{@data_dir} does not exist. Postgresql may not be installed or we've misidentified the data directory."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def version_from_dir(dir)
|
85
|
+
dirs = inspec.command("ls -d #{dir}/*/").stdout
|
86
|
+
entries = dirs.lines.count
|
87
|
+
case entries
|
88
|
+
when 0
|
89
|
+
warn "Could not determine version of installed postgresql by inspecting #{dir}"
|
90
|
+
nil
|
91
|
+
when 1
|
92
|
+
warn "Using #{dirs}: #{dir_to_version(dirs)}"
|
93
|
+
dir_to_version(dirs)
|
94
|
+
else
|
95
|
+
warn "Multiple versions of postgresql installed or incorrect base dir #{dir}"
|
96
|
+
first = dir_to_version(dirs.lines.first)
|
97
|
+
warn "Using the first version found: #{first}"
|
98
|
+
first
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def dir_to_version(dir)
|
103
|
+
dir.chomp.split('/').last
|
104
|
+
end
|
105
|
+
|
106
|
+
def cluster_from_dir(dir)
|
107
|
+
# Main is the default cluster name on debian use it if it
|
108
|
+
# exists.
|
109
|
+
if inspec.directory("#{dir}/main").exist?
|
110
|
+
'main'
|
111
|
+
else
|
112
|
+
dirs = inspec.command("ls -d #{dir}/*/").stdout.lines
|
113
|
+
first = dirs.first.chomp.split('/').last
|
114
|
+
if dirs.count > 1
|
115
|
+
warn "Multiple postgresql clusters configured or incorrect base dir #{dir}"
|
116
|
+
warn "Using the first directory found: #{first}"
|
117
|
+
end
|
118
|
+
first
|
119
|
+
end
|
120
|
+
end
|
39
121
|
end
|
40
122
|
end
|