mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2024-11-24 08:52:38 +02:00
Format change. pg_probackup.conf contains more info now. Options change: configure subcommand is implemented
This commit is contained in:
parent
12cc3a1491
commit
1edaabf130
1
Makefile
1
Makefile
@ -1,6 +1,7 @@
|
|||||||
PROGRAM = pg_probackup
|
PROGRAM = pg_probackup
|
||||||
OBJS = backup.o \
|
OBJS = backup.o \
|
||||||
catalog.o \
|
catalog.o \
|
||||||
|
configure.o \
|
||||||
data.o \
|
data.o \
|
||||||
delete.o \
|
delete.o \
|
||||||
dir.o \
|
dir.o \
|
||||||
|
125
configure.c
Normal file
125
configure.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* configure.c: - manage backup catalog.
|
||||||
|
*
|
||||||
|
* Portions Copyright (c) 2017-2017, Postgres Professional
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pg_probackup.h"
|
||||||
|
|
||||||
|
/* Set configure options */
|
||||||
|
int
|
||||||
|
do_configure(bool show_only)
|
||||||
|
{
|
||||||
|
pgBackupConfig *config = readBackupCatalogConfigFile();
|
||||||
|
if (pgdata)
|
||||||
|
config->pgdata = pgdata;
|
||||||
|
if (pgut_dbname)
|
||||||
|
config->pgdatabase = pgut_dbname;
|
||||||
|
if (host)
|
||||||
|
config->pghost = host;
|
||||||
|
if (port)
|
||||||
|
config->pgport = port;
|
||||||
|
if (username)
|
||||||
|
config->pguser = username;
|
||||||
|
|
||||||
|
if (retention_redundancy)
|
||||||
|
config->retention_redundancy = retention_redundancy;
|
||||||
|
if (retention_window)
|
||||||
|
config->retention_window = retention_window;
|
||||||
|
|
||||||
|
if (show_only)
|
||||||
|
writeBackupCatalogConfig(stderr, config);
|
||||||
|
else
|
||||||
|
writeBackupCatalogConfigFile(config);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pgBackupConfigInit(pgBackupConfig *config)
|
||||||
|
{
|
||||||
|
config->system_identifier = 0;
|
||||||
|
config->pgdata = NULL;
|
||||||
|
config->pgdatabase = NULL;
|
||||||
|
config->pghost = NULL;
|
||||||
|
config->pgport = NULL;
|
||||||
|
config->pguser = NULL;
|
||||||
|
|
||||||
|
config->retention_redundancy = 0;
|
||||||
|
config->retention_window = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
writeBackupCatalogConfig(FILE *out, pgBackupConfig *config)
|
||||||
|
{
|
||||||
|
fprintf(out, "#Backup instance info\n");
|
||||||
|
fprintf(out, "PGDATA = %s\n", config->pgdata);
|
||||||
|
fprintf(out, "system-identifier = %li\n", config->system_identifier);
|
||||||
|
|
||||||
|
fprintf(out, "#Connection parameters:\n");
|
||||||
|
if (config->pgdatabase)
|
||||||
|
fprintf(out, "PGDATABASE = %s\n", config->pgdatabase);
|
||||||
|
if (config->pghost)
|
||||||
|
fprintf(out, "PGHOST = %s\n", config->pghost);
|
||||||
|
if (config->pgport)
|
||||||
|
fprintf(out, "PGPORT = %s\n", config->pgport);
|
||||||
|
if (config->pguser)
|
||||||
|
fprintf(out, "PGUSER = %s\n", config->pguser);
|
||||||
|
fprintf(out, "#Retention parameters:\n");
|
||||||
|
if (config->retention_redundancy)
|
||||||
|
fprintf(out, "retention-redundancy = %u\n", config->retention_redundancy);
|
||||||
|
if (config->retention_window)
|
||||||
|
fprintf(out, "retention-window = %u\n", config->retention_window);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
writeBackupCatalogConfigFile(pgBackupConfig *config)
|
||||||
|
{
|
||||||
|
char path[MAXPGPATH];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
join_path_components(path, backup_path, BACKUPS_DIR);
|
||||||
|
join_path_components(path, backup_path, BACKUP_CATALOG_CONF_FILE);
|
||||||
|
fp = fopen(path, "wt");
|
||||||
|
if (fp == NULL)
|
||||||
|
elog(ERROR, "cannot create %s: %s",
|
||||||
|
BACKUP_CATALOG_CONF_FILE, strerror(errno));
|
||||||
|
|
||||||
|
writeBackupCatalogConfig(fp, config);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pgBackupConfig*
|
||||||
|
readBackupCatalogConfigFile(void)
|
||||||
|
{
|
||||||
|
pgBackupConfig *config = pgut_new(pgBackupConfig);
|
||||||
|
char path[MAXPGPATH];
|
||||||
|
|
||||||
|
pgut_option options[] =
|
||||||
|
{
|
||||||
|
/* configure options */
|
||||||
|
{ 'U', 0, "system-identifier", &(config->system_identifier), SOURCE_FILE_STRICT },
|
||||||
|
{ 's', 0, "pgdata", &(config->pgdata), SOURCE_FILE_STRICT },
|
||||||
|
{ 's', 0, "pgdatabase", &(config->pgdatabase), SOURCE_FILE_STRICT },
|
||||||
|
{ 's', 0, "pghost", &(config->pghost), SOURCE_FILE_STRICT },
|
||||||
|
{ 's', 0, "pgport", &(config->pgport), SOURCE_FILE_STRICT },
|
||||||
|
{ 's', 0, "pguser", &(config->pguser), SOURCE_FILE_STRICT },
|
||||||
|
{ 'u', 0, "retention-redundancy", &(config->retention_redundancy),SOURCE_FILE_STRICT },
|
||||||
|
{ 'u', 0, "retention-window", &(config->retention_window), SOURCE_FILE_STRICT },
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
join_path_components(path, backup_path, BACKUPS_DIR);
|
||||||
|
join_path_components(path, backup_path, BACKUP_CATALOG_CONF_FILE);
|
||||||
|
|
||||||
|
pgBackupConfigInit(config);
|
||||||
|
pgut_readopt(path, options, ERROR);
|
||||||
|
|
||||||
|
return config;
|
||||||
|
|
||||||
|
}
|
25
init.c
25
init.c
@ -1,6 +1,6 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* init.c: manage backup catalog.
|
* init.c: - initialize backup catalog.
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
* Portions Copyright (c) 2009-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||||
* Portions Copyright (c) 2015-2017, Postgres Professional
|
* Portions Copyright (c) 2015-2017, Postgres Professional
|
||||||
@ -30,11 +30,10 @@ do_init(void)
|
|||||||
{
|
{
|
||||||
char path[MAXPGPATH];
|
char path[MAXPGPATH];
|
||||||
char arclog_path_dir[MAXPGPATH];
|
char arclog_path_dir[MAXPGPATH];
|
||||||
FILE *fp;
|
|
||||||
uint64 id;
|
|
||||||
|
|
||||||
struct dirent **dp;
|
struct dirent **dp;
|
||||||
int results;
|
int results;
|
||||||
|
pgBackupConfig *config = pgut_new(pgBackupConfig);
|
||||||
|
|
||||||
/* PGDATA is always required */
|
/* PGDATA is always required */
|
||||||
if (pgdata == NULL)
|
if (pgdata == NULL)
|
||||||
@ -49,7 +48,7 @@ do_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read system_identifier from PGDATA */
|
/* Read system_identifier from PGDATA */
|
||||||
id = get_system_identifier();
|
system_identifier = get_system_identifier();
|
||||||
|
|
||||||
/* create backup catalog root directory */
|
/* create backup catalog root directory */
|
||||||
dir_create_dir(backup_path, DIR_PERMISSION);
|
dir_create_dir(backup_path, DIR_PERMISSION);
|
||||||
@ -62,16 +61,14 @@ do_init(void)
|
|||||||
join_path_components(arclog_path_dir, backup_path, "wal");
|
join_path_components(arclog_path_dir, backup_path, "wal");
|
||||||
dir_create_dir(arclog_path_dir, DIR_PERMISSION);
|
dir_create_dir(arclog_path_dir, DIR_PERMISSION);
|
||||||
|
|
||||||
/* create BACKUP_CATALOG_CONF_FILE */
|
/*
|
||||||
join_path_components(path, backup_path, BACKUP_CATALOG_CONF_FILE);
|
* Wite initial config. system-identifier and pgdata are set in
|
||||||
fp = fopen(path, "wt");
|
* init subcommand and will never be updated.
|
||||||
if (fp == NULL)
|
*/
|
||||||
elog(ERROR, "cannot create %s: %s",
|
pgBackupConfigInit(config);
|
||||||
BACKUP_CATALOG_CONF_FILE, strerror(errno));
|
config->system_identifier = system_identifier;
|
||||||
|
config->pgdata = pgdata;
|
||||||
fprintf(fp, "system-identifier = %li\n", id);
|
writeBackupCatalogConfigFile(config);
|
||||||
fprintf(fp, "\n");
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -90,10 +90,10 @@ static pgut_option options[] =
|
|||||||
/* other */
|
/* other */
|
||||||
{ 'U', 15, "system-identifier", &system_identifier, SOURCE_FILE_STRICT },
|
{ 'U', 15, "system-identifier", &system_identifier, SOURCE_FILE_STRICT },
|
||||||
|
|
||||||
{ 's', 'd', "dbname" , &pgut_dbname, SOURCE_CMDLINE },
|
{ 's', 'd', "pgdatabase" , &pgut_dbname, SOURCE_CMDLINE },
|
||||||
{ 's', 'h', "host" , &host, SOURCE_CMDLINE },
|
{ 's', 'h', "pghost" , &host, SOURCE_CMDLINE },
|
||||||
{ 's', 'p', "port" , &port, SOURCE_CMDLINE },
|
{ 's', 'p', "pgport" , &port, SOURCE_CMDLINE },
|
||||||
{ 's', 'U', "username" , &username, SOURCE_CMDLINE },
|
{ 's', 'U', "pguser" , &username, SOURCE_CMDLINE },
|
||||||
{ 'b', 'q', "quiet" , &quiet, SOURCE_CMDLINE },
|
{ 'b', 'q', "quiet" , &quiet, SOURCE_CMDLINE },
|
||||||
{ 'b', 'v', "verbose" , &verbose, SOURCE_CMDLINE },
|
{ 'b', 'v', "verbose" , &verbose, SOURCE_CMDLINE },
|
||||||
{ 'B', 'w', "no-password" , &prompt_password, SOURCE_CMDLINE },
|
{ 'B', 'w', "no-password" , &prompt_password, SOURCE_CMDLINE },
|
||||||
@ -148,9 +148,13 @@ main(int argc, char *argv[])
|
|||||||
/* Parse command line arguments */
|
/* Parse command line arguments */
|
||||||
i = pgut_getopt(argc, argv, options);
|
i = pgut_getopt(argc, argv, options);
|
||||||
|
|
||||||
/* BACKUP_PATH is always required */
|
|
||||||
if (backup_path == NULL)
|
if (backup_path == NULL)
|
||||||
elog(ERROR, "required parameter not specified: BACKUP_PATH (-B, --backup-path)");
|
{
|
||||||
|
/* Try to read BACKUP_PATH from environment variable */
|
||||||
|
backup_path = getenv("BACKUP_PATH");
|
||||||
|
if (backup_path == NULL)
|
||||||
|
elog(ERROR, "required parameter not specified: BACKUP_PATH (-B, --backup-path)");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char path[MAXPGPATH];
|
char path[MAXPGPATH];
|
||||||
@ -162,8 +166,16 @@ main(int argc, char *argv[])
|
|||||||
if (rc != -1 && !S_ISDIR(stat_buf.st_mode))
|
if (rc != -1 && !S_ISDIR(stat_buf.st_mode))
|
||||||
elog(ERROR, "-B, --backup-path must be a path to directory");
|
elog(ERROR, "-B, --backup-path must be a path to directory");
|
||||||
|
|
||||||
join_path_components(path, backup_path, BACKUP_CATALOG_CONF_FILE);
|
/* Do not read options from file or env if we're going to set them */
|
||||||
pgut_readopt(path, options, ERROR);
|
if (backup_subcmd != CONFIGURE)
|
||||||
|
{
|
||||||
|
/* Read options from configuration file */
|
||||||
|
join_path_components(path, backup_path, BACKUP_CATALOG_CONF_FILE);
|
||||||
|
pgut_readopt(path, options, ERROR);
|
||||||
|
|
||||||
|
/* Read environment variables */
|
||||||
|
pgut_getopt_env(options);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (backup_id_string_param != NULL)
|
if (backup_id_string_param != NULL)
|
||||||
@ -225,19 +237,13 @@ main(int argc, char *argv[])
|
|||||||
case DELETE:
|
case DELETE:
|
||||||
return do_delete(current.backup_id);
|
return do_delete(current.backup_id);
|
||||||
case CONFIGURE:
|
case CONFIGURE:
|
||||||
elog(ERROR, "not implemented yet");
|
/* TODO fixit */
|
||||||
|
if (argc == 4)
|
||||||
|
return do_configure(true);
|
||||||
|
else
|
||||||
|
return do_configure(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (pg_strcasecmp(cmd, "retention") == 0)
|
|
||||||
// {
|
|
||||||
// if (subcmd == NULL)
|
|
||||||
// elog(ERROR, "you must specify retention command");
|
|
||||||
// else if (pg_strcasecmp(subcmd, "show") == 0)
|
|
||||||
// return do_retention_show();
|
|
||||||
// else if (pg_strcasecmp(subcmd, "purge") == 0)
|
|
||||||
// return do_retention_purge();
|
|
||||||
// }
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,6 +114,19 @@ typedef enum ProbackupSubcmd
|
|||||||
#define INVALID_BACKUP_ID 0
|
#define INVALID_BACKUP_ID 0
|
||||||
#define BYTES_INVALID (-1)
|
#define BYTES_INVALID (-1)
|
||||||
|
|
||||||
|
typedef struct pgBackupConfig
|
||||||
|
{
|
||||||
|
uint64 system_identifier;
|
||||||
|
char *pgdata;
|
||||||
|
const char *pgdatabase;
|
||||||
|
const char *pghost;
|
||||||
|
const char *pgport;
|
||||||
|
const char *pguser;
|
||||||
|
|
||||||
|
uint32 retention_redundancy;
|
||||||
|
uint32 retention_window;
|
||||||
|
} pgBackupConfig;
|
||||||
|
|
||||||
/* Information about single backup stored in backup.conf */
|
/* Information about single backup stored in backup.conf */
|
||||||
typedef struct pgBackup
|
typedef struct pgBackup
|
||||||
{
|
{
|
||||||
@ -262,6 +275,13 @@ extern void opt_tablespace_map(pgut_option *opt, const char *arg);
|
|||||||
/* in init.c */
|
/* in init.c */
|
||||||
extern int do_init(void);
|
extern int do_init(void);
|
||||||
|
|
||||||
|
/* in configure.c */
|
||||||
|
extern int do_configure(bool show_only);
|
||||||
|
extern void pgBackupConfigInit(pgBackupConfig *config);
|
||||||
|
extern void writeBackupCatalogConfig(FILE *out, pgBackupConfig *config);
|
||||||
|
extern void writeBackupCatalogConfigFile(pgBackupConfig *config);
|
||||||
|
extern pgBackupConfig* readBackupCatalogConfigFile(void);
|
||||||
|
|
||||||
/* in show.c */
|
/* in show.c */
|
||||||
extern int do_show(time_t requested_backup_id);
|
extern int do_show(time_t requested_backup_id);
|
||||||
|
|
||||||
|
16
pgut/pgut.c
16
pgut/pgut.c
@ -505,12 +505,8 @@ longopts_to_optstring(const struct option opts[])
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void
|
||||||
* Read options from environmental variables.
|
pgut_getopt_env(pgut_option options[])
|
||||||
* Do not overwrite in option was already set via command line option.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
option_from_env(pgut_option options[])
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@ -523,9 +519,6 @@ option_from_env(pgut_option options[])
|
|||||||
if (opt->source > SOURCE_ENV || opt->allowed < SOURCE_ENV)
|
if (opt->source > SOURCE_ENV || opt->allowed < SOURCE_ENV)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp(opt->lname, "backup-path") == 0)
|
|
||||||
value = getenv("BACKUP_PATH");
|
|
||||||
|
|
||||||
if (strcmp(opt->lname, "pgdata") == 0)
|
if (strcmp(opt->lname, "pgdata") == 0)
|
||||||
value = getenv("PGDATA");
|
value = getenv("PGDATA");
|
||||||
if (strcmp(opt->lname, "port") == 0)
|
if (strcmp(opt->lname, "port") == 0)
|
||||||
@ -534,7 +527,7 @@ option_from_env(pgut_option options[])
|
|||||||
value = getenv("PGHOST");
|
value = getenv("PGHOST");
|
||||||
if (strcmp(opt->lname, "username") == 0)
|
if (strcmp(opt->lname, "username") == 0)
|
||||||
value = getenv("PGUSER");
|
value = getenv("PGUSER");
|
||||||
if (strcmp(opt->lname, "dbname") == 0)
|
if (strcmp(opt->lname, "pgdatabase") == 0)
|
||||||
{
|
{
|
||||||
value = getenv("PGDATABASE");
|
value = getenv("PGDATABASE");
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
@ -575,9 +568,6 @@ pgut_getopt(int argc, char **argv, pgut_option options[])
|
|||||||
assign_option(opt, optarg, SOURCE_CMDLINE);
|
assign_option(opt, optarg, SOURCE_CMDLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read environment variables */
|
|
||||||
option_from_env(options);
|
|
||||||
|
|
||||||
init_cancel_handler();
|
init_cancel_handler();
|
||||||
atexit(on_cleanup);
|
atexit(on_cleanup);
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ extern bool interrupted;
|
|||||||
extern void help(bool details);
|
extern void help(bool details);
|
||||||
extern int pgut_getopt(int argc, char **argv, pgut_option options[]);
|
extern int pgut_getopt(int argc, char **argv, pgut_option options[]);
|
||||||
extern void pgut_readopt(const char *path, pgut_option options[], int elevel);
|
extern void pgut_readopt(const char *path, pgut_option options[], int elevel);
|
||||||
|
extern void pgut_getopt_env(pgut_option options[]);
|
||||||
extern void pgut_atexit_push(pgut_atexit_callback callback, void *userdata);
|
extern void pgut_atexit_push(pgut_atexit_callback callback, void *userdata);
|
||||||
extern void pgut_atexit_pop(pgut_atexit_callback callback, void *userdata);
|
extern void pgut_atexit_pop(pgut_atexit_callback callback, void *userdata);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user