1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00
pgbackrest/lib/BackRest/Config.pm

376 lines
14 KiB
Perl
Raw Normal View History

2014-12-16 00:20:42 +02:00
####################################################################################################################################
# CONFIG MODULE
####################################################################################################################################
package BackRest::Config;
use threads;
use strict;
use warnings;
use Carp;
use Pod::Usage;
2014-12-16 00:20:42 +02:00
use File::Basename;
2014-12-16 19:41:54 +02:00
use Getopt::Long;
2014-12-16 00:20:42 +02:00
use lib dirname($0) . '/../lib';
use BackRest::Utility;
use Exporter qw(import);
2014-12-16 19:41:54 +02:00
our @EXPORT = qw(config_load config_key_load operation_get operation_set param_get
2014-12-19 00:05:06 +02:00
FILE_MANIFEST FILE_VERSION FILE_POSTMASTER_PID
PATH_LATEST
2014-12-19 00:05:06 +02:00
OP_ARCHIVE_GET OP_ARCHIVE_PUSH OP_BACKUP OP_RESTORE OP_EXPIRE
2014-12-16 19:41:54 +02:00
BACKUP_TYPE_FULL BACKUP_TYPE_DIFF BACKUP_TYPE_INCR
PARAM_CONFIG PARAM_STANZA PARAM_TYPE PARAM_REMAP PARAM_SET PARAM_NO_START_STOP PARAM_THREAD PARAM_FORCE
PARAM_VERSION PARAM_HELP PARAM_TEST PARAM_TEST_DELAY PARAM_TEST_NO_FORK
2014-12-16 00:20:42 +02:00
CONFIG_SECTION_COMMAND CONFIG_SECTION_COMMAND_OPTION CONFIG_SECTION_LOG CONFIG_SECTION_BACKUP
CONFIG_SECTION_RESTORE CONFIG_SECTION_ARCHIVE CONFIG_SECTION_RETENTION CONFIG_SECTION_STANZA
2014-12-16 00:20:42 +02:00
CONFIG_KEY_USER CONFIG_KEY_HOST CONFIG_KEY_PATH
CONFIG_KEY_THREAD_MAX CONFIG_KEY_THREAD_TIMEOUT CONFIG_KEY_HARDLINK CONFIG_KEY_ARCHIVE_REQUIRED
CONFIG_KEY_ARCHIVE_MAX_MB CONFIG_KEY_START_FAST CONFIG_KEY_COMPRESS_ASYNC
CONFIG_KEY_LEVEL_FILE CONFIG_KEY_LEVEL_CONSOLE
CONFIG_KEY_COMPRESS CONFIG_KEY_CHECKSUM CONFIG_KEY_PSQL CONFIG_KEY_REMOTE
CONFIG_KEY_FULL_RETENTION CONFIG_KEY_DIFFERENTIAL_RETENTION CONFIG_KEY_ARCHIVE_RETENTION_TYPE
CONFIG_KEY_ARCHIVE_RETENTION);
2014-12-19 00:05:06 +02:00
####################################################################################################################################
# File/path constants
####################################################################################################################################
use constant
{
FILE_MANIFEST => 'backup.manifest',
FILE_VERSION => 'version',
FILE_POSTMASTER_PID => 'postmaster.pid',
PATH_LATEST => 'latest'
2014-12-19 00:05:06 +02:00
};
2014-12-16 00:20:42 +02:00
####################################################################################################################################
2014-12-16 19:41:54 +02:00
# Operation constants - basic operations that are allowed in backrest
####################################################################################################################################
use constant
{
OP_ARCHIVE_GET => 'archive-get',
OP_ARCHIVE_PUSH => 'archive-push',
OP_BACKUP => 'backup',
OP_RESTORE => 'restore',
OP_EXPIRE => 'expire'
2014-12-16 19:41:54 +02:00
};
####################################################################################################################################
# BACKUP Type Constants
####################################################################################################################################
use constant
{
BACKUP_TYPE_FULL => 'full',
BACKUP_TYPE_DIFF => 'diff',
BACKUP_TYPE_INCR => 'incr'
};
####################################################################################################################################
# Parameter constants
####################################################################################################################################
use constant
{
PARAM_CONFIG => 'config',
PARAM_STANZA => 'stanza',
PARAM_TYPE => 'type',
PARAM_NO_START_STOP => 'no-start-stop',
PARAM_REMAP => 'remap',
PARAM_SET => 'set',
PARAM_THREAD => 'thread',
2014-12-16 19:41:54 +02:00
PARAM_FORCE => 'force',
PARAM_VERSION => 'version',
PARAM_HELP => 'help',
PARAM_TEST => 'test',
PARAM_TEST_DELAY => 'test-delay',
PARAM_TEST_NO_FORK => 'no-fork'
};
####################################################################################################################################
# Configuration constants
2014-12-16 00:20:42 +02:00
####################################################################################################################################
use constant
{
CONFIG_SECTION_COMMAND => 'command',
CONFIG_SECTION_COMMAND_OPTION => 'command:option',
CONFIG_SECTION_LOG => 'log',
CONFIG_SECTION_BACKUP => 'backup',
CONFIG_SECTION_RESTORE => 'restore',
2014-12-16 00:20:42 +02:00
CONFIG_SECTION_ARCHIVE => 'archive',
CONFIG_SECTION_RETENTION => 'retention',
CONFIG_SECTION_STANZA => 'stanza',
CONFIG_KEY_USER => 'user',
CONFIG_KEY_HOST => 'host',
CONFIG_KEY_PATH => 'path',
CONFIG_KEY_THREAD_MAX => 'thread-max',
CONFIG_KEY_THREAD_TIMEOUT => 'thread-timeout',
CONFIG_KEY_HARDLINK => 'hardlink',
CONFIG_KEY_ARCHIVE_REQUIRED => 'archive-required',
CONFIG_KEY_ARCHIVE_MAX_MB => 'archive-max-mb',
CONFIG_KEY_START_FAST => 'start-fast',
CONFIG_KEY_COMPRESS_ASYNC => 'compress-async',
CONFIG_KEY_LEVEL_FILE => 'level-file',
CONFIG_KEY_LEVEL_CONSOLE => 'level-console',
CONFIG_KEY_COMPRESS => 'compress',
CONFIG_KEY_CHECKSUM => 'checksum',
CONFIG_KEY_PSQL => 'psql',
CONFIG_KEY_REMOTE => 'remote',
CONFIG_KEY_FULL_RETENTION => 'full-retention',
CONFIG_KEY_DIFFERENTIAL_RETENTION => 'differential-retention',
CONFIG_KEY_ARCHIVE_RETENTION_TYPE => 'archive-retention-type',
CONFIG_KEY_ARCHIVE_RETENTION => 'archive-retention'
};
####################################################################################################################################
# Global variables
####################################################################################################################################
my %oConfig; # Configuration hash
2014-12-16 19:41:54 +02:00
my %oParam = (); # Parameter hash
my $strOperation; # Operation (backup, archive-get, ...)
2014-12-16 00:20:42 +02:00
####################################################################################################################################
# CONFIG_LOAD
#
# Load config file.
####################################################################################################################################
sub config_load
{
my $strFile = shift; # Full path to ini file to load from
2014-12-16 19:41:54 +02:00
# Default for general parameters
param_set(PARAM_NO_START_STOP, false); # Do not perform start/stop backup (and archive-required gets set to false)
param_set(PARAM_FORCE, false); # Force an action that would not normally be allowed (varies by action)
param_set(PARAM_VERSION, false); # Display version and exit
param_set(PARAM_HELP, false); # Display help and exit
# Defaults for test parameters - not for general use
param_set(PARAM_TEST_NO_FORK, false); # Prevents the archive process from forking when local archiving is enabled
param_set(PARAM_TEST, false); # Enters test mode - not harmful, but adds special logging and pauses for unit testing
param_set(PARAM_TEST_DELAY, 5); # Seconds to delay after a test point (default is not enough for manual tests)
# Get command line parameters
GetOptions (\%oParam, PARAM_CONFIG . '=s', PARAM_STANZA . '=s', PARAM_TYPE . '=s', PARAM_REMAP . '=s%', PARAM_SET . '=s',
PARAM_THREAD . '=s', PARAM_NO_START_STOP, PARAM_FORCE, PARAM_VERSION, PARAM_HELP,
2014-12-16 19:41:54 +02:00
PARAM_TEST, PARAM_TEST_DELAY . '=s', PARAM_TEST_NO_FORK)
or pod2usage(2);
# Display version and exit if requested
if (param_get(PARAM_VERSION) || param_get(PARAM_HELP))
{
print 'pg_backrest ' . version_get() . "\n";
if (!param_get(PARAM_HELP))
{
exit 0;
}
}
# Display help and exit if requested
if (param_get(PARAM_HELP))
{
print "\n";
pod2usage();
}
2014-12-16 19:41:54 +02:00
# Get and validate the operation
$strOperation = $ARGV[0];
if (!defined($strOperation))
{
confess &log(ERROR, 'operation is not defined');
}
if ($strOperation ne OP_ARCHIVE_GET &&
$strOperation ne OP_ARCHIVE_PUSH &&
$strOperation ne OP_BACKUP &&
$strOperation ne OP_RESTORE &&
2014-12-16 19:41:54 +02:00
$strOperation ne OP_EXPIRE)
{
confess &log(ERROR, "invalid operation ${strOperation}");
}
# Type should only be specified for backups
if (defined(param_get(PARAM_TYPE)) && $strOperation ne OP_BACKUP)
{
confess &log(ERROR, 'type can only be specified for the backup operation')
}
# Set the backup type
if ($strOperation ne OP_BACKUP)
2014-12-16 00:20:42 +02:00
{
2014-12-16 19:41:54 +02:00
if (!defined(param_get(PARAM_TYPE)))
{
param_set(PARAM_TYPE, BACKUP_TYPE_INCR);
}
elsif (param_get(PARAM_TYPE) ne BACKUP_TYPE_FULL && param_get(PARAM_TYPE) ne BACKUP_TYPE_DIFF &&
param_get(PARAM_TYPE) ne BACKUP_TYPE_INCR)
{
confess &log(ERROR, 'backup type must be full, diff (differential), incr (incremental)');
}
2014-12-16 00:20:42 +02:00
}
# Validate thread parameter
if (defined(param_get(PARAM_THREAD)) && !(param_get(PARAM_THREAD) >= 1))
{
confess &log(ERROR, 'thread parameter should be >= 1');
}
# Get configuration parameter and load it
2014-12-16 19:41:54 +02:00
if (!defined(param_get(PARAM_CONFIG)))
{
param_set(PARAM_CONFIG, '/etc/pg_backrest.conf');
}
ini_load(param_get(PARAM_CONFIG), \%oConfig);
2014-12-16 00:20:42 +02:00
# Load and check the cluster
2014-12-16 19:41:54 +02:00
if (!defined(param_get(PARAM_STANZA)))
2014-12-16 00:20:42 +02:00
{
confess 'a backup stanza must be specified';
}
# If this is a restore, then try to default config
if (!defined(config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH)))
{
$oConfig{'global:restore'}{path} = config_key_load(CONFIG_SECTION_BACKUP, CONFIG_KEY_PATH);
if (!defined(config_key_load(CONFIG_SECTION_RESTORE, CONFIG_KEY_PATH)))
{
$oConfig{'global:restore'}{path} = config_key_load(CONFIG_SECTION_ARCHIVE, CONFIG_KEY_PATH);
}
}
2014-12-16 00:20:42 +02:00
# Set the log levels
log_level_set(uc(config_key_load(CONFIG_SECTION_LOG, CONFIG_KEY_LEVEL_FILE, true, INFO)),
uc(config_key_load(CONFIG_SECTION_LOG, CONFIG_KEY_LEVEL_CONSOLE, true, ERROR)));
2014-12-16 19:41:54 +02:00
# Set test parameters
test_set(param_get(PARAM_TEST), param_get(PARAM_TEST_DELAY));
2014-12-16 00:20:42 +02:00
}
####################################################################################################################################
# CONFIG_KEY_LOAD - Get a value from the config and be sure that it is defined (unless bRequired is false)
####################################################################################################################################
sub config_key_load
{
my $strSection = shift;
my $strKey = shift;
my $bRequired = shift;
my $strDefault = shift;
# Default is that the key is not required
if (!defined($bRequired))
{
$bRequired = false;
}
my $strValue;
# Look in the default stanza section
if ($strSection eq CONFIG_SECTION_STANZA)
{
2014-12-16 19:41:54 +02:00
$strValue = $oConfig{param_get(PARAM_STANZA)}{"${strKey}"};
2014-12-16 00:20:42 +02:00
}
# Else look in the supplied section
else
{
# First check the stanza section
2014-12-16 19:41:54 +02:00
$strValue = $oConfig{param_get(PARAM_STANZA) . ":${strSection}"}{"${strKey}"};
2014-12-16 00:20:42 +02:00
# If the stanza section value is undefined then check global
if (!defined($strValue))
{
$strValue = $oConfig{"global:${strSection}"}{"${strKey}"};
}
}
if (!defined($strValue) && $bRequired)
{
if (defined($strDefault))
{
return $strDefault;
}
confess &log(ERROR, 'config value ' . (defined($strSection) ? $strSection : '[stanza]') . "->${strKey} is undefined");
}
if ($strSection eq CONFIG_SECTION_COMMAND)
{
my $strOption = config_key_load(CONFIG_SECTION_COMMAND_OPTION, $strKey);
if (defined($strOption))
{
$strValue =~ s/\%option\%/${strOption}/g;
}
}
return $strValue;
}
2014-12-16 19:41:54 +02:00
####################################################################################################################################
# OPERATION_GET
#
# Get the current operation.
####################################################################################################################################
sub operation_get
{
return $strOperation;
}
####################################################################################################################################
# OPERATION_SET
#
# Set current operation (usually for triggering follow-on operations).
####################################################################################################################################
sub operation_set
{
my $strValue = shift;
$strOperation = $strValue;
}
####################################################################################################################################
# PARAM_GET
#
# Get param value.
####################################################################################################################################
sub param_get
{
my $strParam = shift;
return $oParam{$strParam};
}
####################################################################################################################################
# PARAM_SET
#
# Set param value.
####################################################################################################################################
sub param_set
{
my $strParam = shift;
my $strValue = shift;
$oParam{$strParam} = $strValue;
}
2014-12-16 00:20:42 +02:00
1;