1
0
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:
Anastasia 2017-04-19 16:47:41 +03:00
parent 12cc3a1491
commit 1edaabf130
7 changed files with 186 additions and 46 deletions

View File

@ -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
View 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
View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

View File

@ -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);