Projects/Profile Includes
An announcement has been sent to krbdev@mit.edu starting a review of this project. That review will conclude on 2010-08-27.
Comments can be sent to krbdev@mit.edu.
Background
In a July 2010 mailing list discussion about dynamic module discovery, consensus was reached that the profile library should gain support for include-file functionality with the ability to include a variable set of files within a directory. This project is to add that support.
Interface Design
A profile file may contain a line "include FILENAME". FILENAME is read, and line from the file are parsed as if they belonged to the original profile file. If FILENAME does not exist or cannot be read, profile parsing fails.
A profile file may include a line "includedir DIRNAME". If DIRNAME does not exist or is unreadable, profile parsing fails. Files within DIRNAME, whose names consist only of alphanumeric characters and underscores, are read and parsed as if they belonged to the original profile file. The naming restrictions are to avoid parsing editor backup files, .rpmsave files, and the like. If any file cannot be read, profile parsing fails.
An included file may add variable assignments to an existing section simply by switching to that section and making variable assignments within it. This functionality already exists within the profile library.
Currently there is no way to remove or replace an existing value from within an included file. This project does not propose to add that functionality.
Currently, the profile library recognizes when a profile file changes by stat()ing the file on each profile_get_value() call (though no more than once per second). If the file has changed, it is reread. The profile library will not automatically recognize when included files have changed.
The profile library has support for writing a profile file to disk using profile_flush() or a similar function. If such a function is used, the profile contents will be "flattened" into one file with no include directives. This is consistent with other limitations of profile_flush() such as not remembering comments.
Implementation Design
All necessary changes can be made within util/profile/prof_parse.c.
The main body of profile_parse_file() needs to be split out to allow parsing a file's contents into an already existing state structure. The new helper function has the signature:
static errcode_t parse_file(FILE *f, struct parse_state *state);
parse_line() recognizes lines beginning with "include" or "includedir" and passes the following text to new functions profile_include_file() and profile_include_dir().
Rationale
- The original version of this proposal included glob pattern support. This was discarded in favor of "includedir" in order to simplify error cases and sidestep any portability issues of relying on the POSIX.2 glob() function.
- Several syntax options for the include directive were considered, such as "#include FILENAME" (masquerading as a comment to old versions of the library), [include FILENAME] (masquerading as a section name), "@include FILENAME" (not masquerading as anything, but reducing the likelihood of conflicting with an initial comment of an existing profile), and "[libdefaults] include = FILENAME". Rough consensus was that the simple "include FILENAME" was best.
- Several options were considered for handling the case of a profile including a relative pathname, since it is not generally useful in production to include a profile path relative to the process's current working directory. Rough consensus was that it was best to ignore the problem; including relative paths can be useful for testing.
- Strict error handling is employed in order to quickly identify cases where included files are readable by root and not other users.