Support glob pattern matching for config include files (#8980)
This will allow distros to use an "include conf.d/*.conf" statement in the default configuration file which will facilitate customization across upgrades/downgrades. The change itself is trivial: instead of opening an individual file, the glob call creates a vector of files to open, and each file is opened in turn, and its content is added to the configuration.
This commit is contained in:
parent
362786c58a
commit
c2b93ff83f
@ -32,8 +32,17 @@
|
|||||||
# If instead you are interested in using includes to override configuration
|
# If instead you are interested in using includes to override configuration
|
||||||
# options, it is better to use include as the last line.
|
# options, it is better to use include as the last line.
|
||||||
#
|
#
|
||||||
|
# Included paths may contain wildcards. All files matching the wildcards will
|
||||||
|
# be included in alphabetical order.
|
||||||
|
# Note that if an include path contains a wildcards but no files match it when
|
||||||
|
# the server is started, the include statement will be ignored and no error will
|
||||||
|
# be emitted. It is safe, therefore, to include wildcard files from empty
|
||||||
|
# directories.
|
||||||
|
#
|
||||||
# include /path/to/local.conf
|
# include /path/to/local.conf
|
||||||
# include /path/to/other.conf
|
# include /path/to/other.conf
|
||||||
|
# include /path/to/fragments/*.conf
|
||||||
|
#
|
||||||
|
|
||||||
################################## MODULES #####################################
|
################################## MODULES #####################################
|
||||||
|
|
||||||
|
41
src/config.c
41
src/config.c
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <glob.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
* Config file name-value maps.
|
* Config file name-value maps.
|
||||||
@ -648,9 +650,46 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options) {
|
|||||||
sds config = sdsempty();
|
sds config = sdsempty();
|
||||||
char buf[CONFIG_MAX_LINE+1];
|
char buf[CONFIG_MAX_LINE+1];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
glob_t globbuf;
|
||||||
|
|
||||||
/* Load the file content */
|
/* Load the file content */
|
||||||
if (filename) {
|
if (filename) {
|
||||||
|
|
||||||
|
/* The logic for handling wildcards has slightly different behavior in cases where
|
||||||
|
* there is a failure to locate the included file.
|
||||||
|
* Whether or not a wildcard is specified, we should ALWAYS log errors when attempting
|
||||||
|
* to open included config files.
|
||||||
|
*
|
||||||
|
* However, we desire a behavioral difference between instances where a wildcard was
|
||||||
|
* specified and those where it hasn't:
|
||||||
|
* no wildcards : attempt to open the specified file and fail with a logged error
|
||||||
|
* if the file cannot be found and opened.
|
||||||
|
* with wildcards : attempt to glob the specified pattern; if no files match the
|
||||||
|
* pattern, then gracefully continue on to the next entry in the
|
||||||
|
* config file, as if the current entry was never encountered.
|
||||||
|
* This will allow for empty conf.d directories to be included. */
|
||||||
|
|
||||||
|
if (strchr(filename, '*') || strchr(filename, '?') || strchr(filename, '[')) {
|
||||||
|
/* A wildcard character detected in filename, so let us use glob */
|
||||||
|
if (glob(filename, 0, NULL, &globbuf) == 0) {
|
||||||
|
|
||||||
|
for (size_t i = 0; i < globbuf.gl_pathc; i++) {
|
||||||
|
if ((fp = fopen(globbuf.gl_pathv[i], "r")) == NULL) {
|
||||||
|
serverLog(LL_WARNING,
|
||||||
|
"Fatal error, can't open config file '%s': %s",
|
||||||
|
globbuf.gl_pathv[i], strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
while(fgets(buf,CONFIG_MAX_LINE+1,fp) != NULL)
|
||||||
|
config = sdscat(config,buf);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
globfree(&globbuf);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No wildcard in filename means we can use the original logic to read and
|
||||||
|
* potentially fail traditionally */
|
||||||
if ((fp = fopen(filename, "r")) == NULL) {
|
if ((fp = fopen(filename, "r")) == NULL) {
|
||||||
serverLog(LL_WARNING,
|
serverLog(LL_WARNING,
|
||||||
"Fatal error, can't open config file '%s': %s",
|
"Fatal error, can't open config file '%s': %s",
|
||||||
@ -661,6 +700,8 @@ void loadServerConfig(char *filename, char config_from_stdin, char *options) {
|
|||||||
config = sdscat(config,buf);
|
config = sdscat(config,buf);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Append content from stdin */
|
/* Append content from stdin */
|
||||||
if (config_from_stdin) {
|
if (config_from_stdin) {
|
||||||
serverLog(LL_WARNING,"Reading config from stdin");
|
serverLog(LL_WARNING,"Reading config from stdin");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user