From: | Andres Freund <andres(at)anarazel(dot)de> |
---|---|
To: | Curt Tilmes <curt(at)tilmes(dot)org> |
Cc: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Re: [PATCH] Find additional connection service files in pg_service.conf.d directory |
Date: | 2018-03-01 08:53:25 |
Message-ID: | 20180301085325.k2r6i546t37pbmf5@alap3.anarazel.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi,
On 2018-01-12 09:53:51 -0500, Curt Tilmes wrote:
> I love centralizing connection service definitions in
> <sysconfdir>/pg_service.conf, but for a
> large enterprise, sometimes we have multiple sets of connection
> service definitions
> independently managed.
>
> The convention widely adopted for this type of thing is to allow
> multiple config files to be in
> a directory, usually the '.d' version of the config filename. See, for example:
>
> What do you think?
Seems like a reasonable idea to me.
> @@ -4492,10 +4493,14 @@ parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
> {
> const char *service = conninfo_getval(options, "service");
> char serviceFile[MAXPGPATH];
> + char serviceDirPath[MAXPGPATH];
> char *env;
> bool group_found = false;
> int status;
> struct stat stat_buf;
> + DIR *serviceDir;
> + struct dirent *direntry;
> +
>
> /*
> * We have to special-case the environment variable PGSERVICE here, since
> @@ -4539,21 +4544,45 @@ next_file:
> snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
> getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
> if (stat(serviceFile, &stat_buf) != 0)
> + goto conf_dir;
> +
> + status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
> + if (group_found || status != 0)
> + return status;
> +
> +conf_dir:
> +
This is already pretty crufty, can't we make this look a bit prettier,
rather than extending this approach?
> + /*
> + * Try every file in pg_service.conf.d/*
> + */
> + snprintf(serviceDirPath, MAXPGPATH, "%s/pg_service.conf.d",
> + getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR);
> +
> + if (stat(serviceDirPath, &stat_buf) != 0 || !S_ISDIR(stat_buf.st_mode) ||
> + (serviceDir = opendir(serviceDirPath)) == NULL)
> goto last_file;
This looks a bit ugly.
> - status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found);
> - if (status != 0)
> - return status;
> + while ((direntry = readdir(serviceDir)) != NULL)
So there's no really well defined order in which we parse these?
> + {
> + snprintf(serviceFile, MAXPGPATH, "%s/%s", serviceDirPath, direntry->d_name);
> +
In my experience with such .conf.d directories it's very useful to
filter names not matching a common pattern. Otherwise you end up with
editor tempfiles and such being used, which gets confusing.
> + if (stat(serviceFile, &stat_buf) != 0 || !S_ISREG(stat_buf.st_mode) ||
> + access(serviceFile, R_OK))
> + continue;
This doesn't look particularly pretty, but ...
Greetings,
Andres Freund
From | Date | Subject | |
---|---|---|---|
Next Message | Andres Freund | 2018-03-01 08:57:44 | Re: PATCH: pgbench - break out timing data for initialization phases |
Previous Message | Andres Freund | 2018-03-01 08:34:04 | Re: PATCH: pgbench - option to build using ppoll() for larger connection counts |