Module: ForemanMaintain::Concerns::BaseDatabase

Defined in:
lib/foreman_maintain/concerns/base_database.rb

Instance Method Summary collapse

Instance Method Details

#backup_dirObject

TODO: remove the backup file path tools from here. Lib Utils::Backup?



108
109
110
# File 'lib/foreman_maintain/concerns/base_database.rb', line 108

def backup_dir
  @backup_dir ||= File.expand_path(ForemanMaintain.config.db_backup_dir)
end

#backup_local(backup_file, extra_tar_options = {}) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/foreman_maintain/concerns/base_database.rb', line 91

def backup_local(backup_file, extra_tar_options = {})
  dir = extra_tar_options.fetch(:data_dir, data_dir)
  restore_dir = extra_tar_options.fetch(:restore_dir, data_dir)
  command = extra_tar_options.fetch(:command, 'create')

  FileUtils.cd(dir) do
    tar_options = {
      :archive => backup_file,
      :command => command,
      :transform => "s,^,#{restore_dir[1..]},S",
      :files => '*',
    }.merge(extra_tar_options)
    feature(:tar).run(tar_options)
  end
end

#configurationObject

Raises:

  • (NotImplementedError)


40
41
42
# File 'lib/foreman_maintain/concerns/base_database.rb', line 40

def configuration
  raise NotImplementedError
end

#data_dirObject



4
5
6
7
8
9
10
# File 'lib/foreman_maintain/concerns/base_database.rb', line 4

def data_dir
  if debian_or_ubuntu?
    deb_postgresql_data_dir
  else
    '/var/lib/pgsql/data/'
  end
end

#db_version(config = configuration) ⇒ Object



125
126
127
128
129
130
131
132
133
134
# File 'lib/foreman_maintain/concerns/base_database.rb', line 125

def db_version(config = configuration)
  if ping(config)
    # Note - t removes headers, -A removes alignment whitespace
    server_version_cmd = psql_command(config) + ' -c "SHOW server_version" -t -A'
    version_string = execute!(server_version_cmd, :hidden_patterns => [config['password']])
    version(version_string)
  else
    raise_service_error
  end
end

#deb_postgresql_config_dirsObject



34
35
36
37
38
# File 'lib/foreman_maintain/concerns/base_database.rb', line 34

def deb_postgresql_config_dirs
  deb_postgresql_versions.map do |ver|
    "/etc/postgresql/#{ver}/main/"
  end
end

#deb_postgresql_data_dirObject



12
13
14
15
16
# File 'lib/foreman_maintain/concerns/base_database.rb', line 12

def deb_postgresql_data_dir
  deb_postgresql_versions.map do |ver|
    "/var/lib/postgresql/#{ver}/main/"
  end
end

#deb_postgresql_versionsObject



18
19
20
21
22
23
24
# File 'lib/foreman_maintain/concerns/base_database.rb', line 18

def deb_postgresql_versions
  installed_pkgs = package_manager.list_installed_packages('${binary:Package}\n')
  @deb_postgresql_versions ||= installed_pkgs.grep(/^postgresql-\d+$/).map do |name|
    name.split('-').last
  end
  @deb_postgresql_versions
end

#dropdb(config = configuration) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/foreman_maintain/concerns/base_database.rb', line 112

def dropdb(config = configuration)
  if local?
    execute!("runuser - postgres -c 'dropdb #{config['database']}'")
  else
    delete_statement = psql(<<-SQL)
      select string_agg('drop table if exists \"' || tablename || '\" cascade;', '')
      from pg_tables
      where schemaname = 'public';
    SQL
    psql(delete_statement)
  end
end

#dump_db(file, config = configuration) ⇒ Object



72
73
74
# File 'lib/foreman_maintain/concerns/base_database.rb', line 72

def dump_db(file, config = configuration)
  execute!(dump_command(config) + " > #{file}", :hidden_patterns => [config['password']])
end

#local?(config = configuration) ⇒ Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/foreman_maintain/concerns/base_database.rb', line 44

def local?(config = configuration)
  ['localhost', '127.0.0.1', `hostname`.strip].include?(config['host'])
end

#ping(config = configuration) ⇒ Object



66
67
68
69
70
# File 'lib/foreman_maintain/concerns/base_database.rb', line 66

def ping(config = configuration)
  execute?(psql_command(config),
    :stdin => 'SELECT 1 as ping',
    :hidden_patterns => [config['password']])
end

#postgresql_confObject



26
27
28
29
30
31
32
# File 'lib/foreman_maintain/concerns/base_database.rb', line 26

def postgresql_conf
  return "#{data_dir}/postgresql.conf" if el?

  deb_postgresql_config_dirs.map do |conf_dir|
    "#{conf_dir}postgresql.conf"
  end
end

#psql(query, config = configuration) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/foreman_maintain/concerns/base_database.rb', line 56

def psql(query, config = configuration)
  if ping(config)
    execute(psql_command(config),
      :stdin => query,
      :hidden_patterns => [config['password']])
  else
    raise_service_error
  end
end

#psql_cmd_available?Boolean

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/foreman_maintain/concerns/base_database.rb', line 136

def psql_cmd_available?
  exit_status, _output = execute_with_status('which psql')
  exit_status == 0
end

#query(sql, config = configuration) ⇒ Object



48
49
50
# File 'lib/foreman_maintain/concerns/base_database.rb', line 48

def query(sql, config = configuration)
  parse_csv(query_csv(sql, config))
end

#query_csv(sql, config = configuration) ⇒ Object



52
53
54
# File 'lib/foreman_maintain/concerns/base_database.rb', line 52

def query_csv(sql, config = configuration)
  psql(%{COPY (#{sql}) TO STDOUT WITH CSV HEADER}, config)
end

#raise_psql_missing_errorObject

Raises:



141
142
143
144
# File 'lib/foreman_maintain/concerns/base_database.rb', line 141

def raise_psql_missing_error
  raise Error::Fail, 'The psql command not found.'\
          ' Make sure system has psql utility installed.'
end

#restore_dump(file, localdb, config = configuration) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/foreman_maintain/concerns/base_database.rb', line 76

def restore_dump(file, localdb, config = configuration)
  if localdb
    dump_cmd = "runuser - postgres -c 'pg_restore -C -d postgres #{file}'"
    execute!(dump_cmd)
  else
    # TODO: figure out how to completely ignore errors. Currently this
    # sometimes exits with 1 even though errors are ignored by pg_restore
    dump_cmd = base_command(config, 'pg_restore') +
               ' --no-privileges --clean --disable-triggers -n public ' \
               "-d #{config['database']} #{file}"
    execute!(dump_cmd, :hidden_patterns => [config['password']],
      :valid_exit_statuses => [0, 1])
  end
end