You've already forked pg_probackup
							
							
				mirror of
				https://github.com/postgrespro/pg_probackup.git
				synced 2025-10-31 00:17:52 +02:00 
			
		
		
		
	Format change. pg_probackup.conf contains more info now. Options change: configure subcommand is implemented
This commit is contained in:
		
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| PROGRAM = pg_probackup | ||||
| OBJS = backup.o \ | ||||
| 	catalog.o \ | ||||
| 	configure.o \ | ||||
| 	data.o \ | ||||
| 	delete.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) 2015-2017, Postgres Professional | ||||
| @@ -30,11 +30,10 @@ do_init(void) | ||||
| { | ||||
| 	char		path[MAXPGPATH]; | ||||
| 	char		arclog_path_dir[MAXPGPATH]; | ||||
| 	FILE	   *fp; | ||||
| 	uint64		id; | ||||
|  | ||||
| 	struct dirent **dp; | ||||
| 	int results; | ||||
| 	pgBackupConfig *config = pgut_new(pgBackupConfig); | ||||
|  | ||||
| 	/* PGDATA is always required */ | ||||
| 	if (pgdata == NULL) | ||||
| @@ -49,7 +48,7 @@ do_init(void) | ||||
| 	} | ||||
|  | ||||
| 	/* Read system_identifier from PGDATA */ | ||||
| 	id = get_system_identifier(); | ||||
| 	system_identifier = get_system_identifier(); | ||||
|  | ||||
| 	/* create backup catalog root directory */ | ||||
| 	dir_create_dir(backup_path, DIR_PERMISSION); | ||||
| @@ -62,16 +61,14 @@ do_init(void) | ||||
| 	join_path_components(arclog_path_dir, backup_path, "wal"); | ||||
| 	dir_create_dir(arclog_path_dir, DIR_PERMISSION); | ||||
|  | ||||
| 	/* create BACKUP_CATALOG_CONF_FILE */ | ||||
| 	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)); | ||||
|  | ||||
| 	fprintf(fp, "system-identifier = %li\n", id); | ||||
| 	fprintf(fp, "\n"); | ||||
| 	fclose(fp); | ||||
| 	/* | ||||
| 	 * Wite initial config. system-identifier and pgdata are set in | ||||
| 	 * init subcommand and will never be updated. | ||||
| 	 */ | ||||
| 	pgBackupConfigInit(config); | ||||
| 	config->system_identifier = system_identifier; | ||||
| 	config->pgdata = pgdata; | ||||
| 	writeBackupCatalogConfigFile(config); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -90,10 +90,10 @@ static pgut_option options[] = | ||||
| 	/* other */ | ||||
| 	{ 'U', 15, "system-identifier",		&system_identifier,		SOURCE_FILE_STRICT }, | ||||
|  | ||||
| 	{ 's', 'd', "dbname"	, &pgut_dbname, SOURCE_CMDLINE }, | ||||
| 	{ 's', 'h', "host"		, &host, SOURCE_CMDLINE }, | ||||
| 	{ 's', 'p', "port"		, &port, SOURCE_CMDLINE }, | ||||
| 	{ 's', 'U', "username"	, &username, SOURCE_CMDLINE }, | ||||
| 	{ 's', 'd', "pgdatabase"	, &pgut_dbname, SOURCE_CMDLINE }, | ||||
| 	{ 's', 'h', "pghost"		, &host, SOURCE_CMDLINE }, | ||||
| 	{ 's', 'p', "pgport"		, &port, SOURCE_CMDLINE }, | ||||
| 	{ 's', 'U', "pguser"	, &username, SOURCE_CMDLINE }, | ||||
| 	{ 'b', 'q', "quiet"		, &quiet, SOURCE_CMDLINE }, | ||||
| 	{ 'b', 'v', "verbose"	, &verbose, SOURCE_CMDLINE }, | ||||
| 	{ 'B', 'w', "no-password"	, &prompt_password, SOURCE_CMDLINE }, | ||||
| @@ -148,9 +148,13 @@ main(int argc, char *argv[]) | ||||
| 	/* Parse command line arguments */ | ||||
| 	i = pgut_getopt(argc, argv, options); | ||||
|  | ||||
| 	/* BACKUP_PATH is always required */ | ||||
| 	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 | ||||
| 	{ | ||||
| 		char		path[MAXPGPATH]; | ||||
| @@ -162,8 +166,16 @@ main(int argc, char *argv[]) | ||||
| 		if (rc != -1 && !S_ISDIR(stat_buf.st_mode)) | ||||
| 			elog(ERROR, "-B, --backup-path must be a path to directory"); | ||||
|  | ||||
| 		join_path_components(path, backup_path, BACKUP_CATALOG_CONF_FILE); | ||||
| 		pgut_readopt(path, options, ERROR); | ||||
| 		/* Do not read options from file or env if we're going to set them */ | ||||
| 		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) | ||||
| @@ -225,19 +237,13 @@ main(int argc, char *argv[]) | ||||
| 		case DELETE: | ||||
| 			return do_delete(current.backup_id); | ||||
| 		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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -114,6 +114,19 @@ typedef enum ProbackupSubcmd | ||||
| #define INVALID_BACKUP_ID	 0 | ||||
| #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 */ | ||||
| typedef struct pgBackup | ||||
| { | ||||
| @@ -262,6 +275,13 @@ extern void opt_tablespace_map(pgut_option *opt, const char *arg); | ||||
| /* in init.c */ | ||||
| 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 */ | ||||
| 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; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Read options from environmental variables. | ||||
|  * Do not overwrite in option was already set via command line option. | ||||
|  */ | ||||
| static void | ||||
| option_from_env(pgut_option options[]) | ||||
| void | ||||
| pgut_getopt_env(pgut_option options[]) | ||||
| { | ||||
| 	size_t	i; | ||||
|  | ||||
| @@ -523,9 +519,6 @@ option_from_env(pgut_option options[]) | ||||
| 		if (opt->source > SOURCE_ENV || opt->allowed < SOURCE_ENV) | ||||
| 			continue; | ||||
|  | ||||
| 		if (strcmp(opt->lname, "backup-path") == 0) | ||||
| 			value = getenv("BACKUP_PATH"); | ||||
|  | ||||
| 		if (strcmp(opt->lname, "pgdata") == 0) | ||||
| 			value = getenv("PGDATA"); | ||||
| 		if (strcmp(opt->lname, "port") == 0) | ||||
| @@ -534,7 +527,7 @@ option_from_env(pgut_option options[]) | ||||
| 			value = getenv("PGHOST"); | ||||
| 		if (strcmp(opt->lname, "username") == 0) | ||||
| 			value = getenv("PGUSER"); | ||||
| 		if (strcmp(opt->lname, "dbname") == 0) | ||||
| 		if (strcmp(opt->lname, "pgdatabase") == 0) | ||||
| 		{ | ||||
| 			value = getenv("PGDATABASE"); | ||||
| 			if (value == NULL) | ||||
| @@ -575,9 +568,6 @@ pgut_getopt(int argc, char **argv, pgut_option options[]) | ||||
| 		assign_option(opt, optarg, SOURCE_CMDLINE); | ||||
| 	} | ||||
|  | ||||
| 	/* Read environment variables */ | ||||
| 	option_from_env(options); | ||||
|  | ||||
| 	init_cancel_handler(); | ||||
| 	atexit(on_cleanup); | ||||
|  | ||||
|   | ||||
| @@ -92,6 +92,7 @@ extern bool			interrupted; | ||||
| extern void help(bool details); | ||||
| 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_getopt_env(pgut_option options[]); | ||||
| extern void pgut_atexit_push(pgut_atexit_callback callback, void *userdata); | ||||
| extern void pgut_atexit_pop(pgut_atexit_callback callback, void *userdata); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user