You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 23 Next »

Design: Server-Dictated Configuration

Many software development shops of non-trivial size desire to have (and to the extent possible, to enforce) a uniform configuration environment among the various clients which commit to their repositories. Although these shops may have some ability to control the environment on the client machines (dictating software versions, etc), expecting humans to consistently set and maintain various runtime configuration parameters in accordance with corporate policy and on every repository-accessing client computer is both error-prone and unscalable.

Subversion already provides the means of enforcing much (but not all) of this configuration through the hook script mechanism, but at best this can only punish non-compliant client behavior and clumsily recommend configuration changes (which, again, a human must implement on their client computer). Allowing the administrator to store a default configuration on the server, which is automatically pushed to and honored by (well-behaved) clients, would save both time and frustration.

Behavioral specification

The high-level behavior for server-dictated configuration is relatively simple: the repository maintains a list of configuration parameters and values which, as necessary, the server provides to the client. The client, then, behaves in accordance with the server-dictated configuration.

Subversion could recognize multiple levels of possible hierarchy in the server-side configuration: server-wide, per repository, or per repository-path. The current plan is to allow configuration at the most granular level, per repository-path.

There are a number of configuration options that existing Subversion users and administrators might wish to have propagated from the server to the client. The following is a list of those that we know about, with some notes about scope and desired degrees of control:

Configuration

Scope

Enforceability

Notes

auto-props

per-directory

Enforceable via hook scripts

 

ignores

per-directory

Enforceable via hook scripts

 

use-commit-times

per-directory

Unenforceable

 

log message templates

per-directory

Enforceable via hook scripts

Doesn't fit the name=value configuration motif quite as readily as some of the others. Would a client need to override this?

store-plaintext-passwords

per-server

Unenforceable

Should it be possible to override this without hacking the client?

"Well-Behaved Clients" and "Trust, But Verify"

The configuration the server dictates can at best be only a suggestion to the client. Older clients will obviously not even understand the new dictates. As open source software, though, it is relatively easy for a malicious user to modify a client to ignore server-side suggestions. Given this reality, server-side enforcement of desired behaviors (where possible, and often via hook scripts) is still strongly recommended.

Server-client transmission mechanism

When connecting to a server which supports this feature, the server will provide to the client a SHA1 checksum of its configuration. A supporting client may then use that checksum (and the UUID of the repository) to compare against its own cached copy of the server configuration. If the checksums differ, the client will request a new configuration from the server.

Over ra-neon/ra-serf, the client will receive the server's configuration checksum as part of the OPTIONS response. It will request new configuration bits via a custom REPORT request aimed at the repos-global report target (the "me resource" for HTTPv2, the "default VCC" otherwise). ra-svn will behave similarly, using the initial handshake/feature negotiation phase for the server's checksum delivery, and a new query for the configuration fetch.

We plan to introduce a new capability string ("server-config") which clients should use to announce to the server that they will honor the server's dictated configuration. Administrators may choose to use that string presence/absence in the list of capabilities passed to the start-commit hook to determine whether to allow commits from certain clients.

Server-side Changes

Configuration storage

The most logical format for server-side configuration is to use the INI file format[1] which is already employed for several other purposes across Subversion. And the most logical location to put those INI files is in ${REPOS_PATH}/conf/ somewhere.

[1]The actual syntax is documented in the default README file created by Subversion in the per-user configuration area (e.g. %APPDATA%\Subversion\README.txt on Windows and ~/.subversion/README on *nix) or can be found in the Subversion source code in config_file.c – see svn_config_ensure().

Client-side Changes

API changes

svn_ra_open5 (svn_ra.h) will be introduced, differing from its predecessor by the addition of an svn_checksum_t ** return value.

/**
 * Open a repository access session to the repository at @a repos_URL,
 * or inform the caller regarding a correct URL by which to access
 * that repository.
 *
 * If @a repos_URL can be used successfully to access the repository,
 * set @a *session_p to an opaque object representing a repository
 * session for the repository and (if @a corrected_url is non-NULL)
 * set @a *corrected_url to NULL.  If there's a better URL that the
 * caller should try and @a corrected_url is non-NULL, set
 * @a *session_p to NULL and @a *corrected_url to the corrected URL.  If
 * there's a better URL that the caller should try, and @a
 * corrected_url is NULL, return an #SVN_ERR_RA_SESSION_URL_MISMATCH
 * error.  Allocate all returned items in @a pool.
 *
 * If @a config_checksum is not NULL, set @a *config_checksum to the SHA1
 * checksum of the repository's configuration.  (Clients should use this
 * value to determine if they need to request an updated copy of the
 * server-side configuration via @c svn_ra_get_repos_config().)
 *
 * Return @c SVN_ERR_RA_UUID_MISMATCH if @a uuid is non-NULL and not equal
 * to the UUID of the repository at @a repos_URL.
 *
 * @a callbacks/@a callback_baton is a table of callbacks provided by the
 * client; see @c svn_ra_callbacks2_t.
 *
 * @a config is a hash mapping <tt>const char *</tt> keys to
 * @c svn_config_t * values.  For example, the @c svn_config_t for the
 * "~/.subversion/config" file is under the key "config".
 *
 * All RA requests require a session; they will continue to
 * use @a pool for memory allocation.
 *
 * @see svn_client_open_ra_session().
 *
 * @since New in 1.8.
 */
svn_error_t *
svn_ra_open5(svn_ra_session_t **session_p,
             const char **corrected_url,
             svn_checksum_t **config_checksum,
             const char *repos_URL,
             const char *uuid,
             const svn_ra_callbacks2_t *callbacks,
             void *callback_baton,
             apr_hash_t *config,
             apr_pool_t *pool);

Of course, svn_ra_open4() will then be deprecated and made into a wrapper around svn_ra_open5() which passed NULL for the 'config_checksum' parameter.

Additionally, we'll introduce a new API function, svn_ra_get_repos_config():

/* Set *repos_config to a string representing the repository configuration
   for the repository associated with RA_SESSION, allocated from POOL. */
svn_error_t *
svn_ra_get_repos_config(const svn_string_t **repos_config,
                        svn_ra_session_t *ra_session,
                        apr_pool_t *pool);

Cache storage

The client current maintains a configuration in two files, ${HOME}/.subversion/confi_g and _${HOME}/.subversion/servers. This feature will introduce the ${HOME}/.subversion/repos/ directory (%APPDATA%\Subversion\repos on Windows), which will hold additional subdirectories keyed on the UUID of the repository. It is in this subdirectory that the cached version of the repository configuration will be stored. To facilitate path-specific configuration within a repository, the typical section names of the configuration bits will be combined with the subtree path to which the options therein apply. For example:

$ cat ${HOME}/13f79535-47bb-0310-9956-ffa450edef68/config
[miscellany:/]
enable-auto-props = no

[miscellany:/subversion]
enable-auto-props = yes

[auto-props:/subversion]
*.c = svn:mime-type=text/x-csrc;svn:eol-style=native;svn:keywords=Author Date Id Rev URL
*.html = svn:mime-type=text/html;; charset=UTF-8;svn:eol-style=native

...
$

Configuration hierarchy

Server-dictated configuration will be the highest priority configuration recognized by well-behaved Subversion clients, excepting per-use overrides (ala --config-option). Only specific options will be made available for server-dictated configuration though. Also, only certain of the server-dictated configuration options will be overridable at all. These details will be governed by hardcoded client-side whitelists.

So, the order in which specific configuration options will be honored where found is:

  1. Per-use overrides (--config-option) -- If permitted by whitelist
  2. Server-dictated configuration
  3. Per-user runtime configuration (${HOME}/.subversion/*)
  4. The per-user Registry values (Windows Only)
  5. Per-machine runtime configuration (/etc/subversion/*)
  6. The system-wide Registry values (Windows Only)

Concerns

Most of this idea of server-dictated configuration seems sane. But there's one bit that stands out as flatly ridiculous – the server dictating how the client stores authentication credentials. No matter how I look at this, it feels wrong. Not just wrong, but unique amongst open source client/server software. What's more, I'm concerned that by the time any client would have consulted the server to ask about its configuration, it will have already cached the very authentication credentials it just used to talk to that server. ~cmpilato

Deferred Goals

As with any long desired feature (issue #1974 is over seven years old) there are differing opinions on what "Server Dictacted Configuration" should entail. This section tracks functionality we are currently not planning to implement in the first phase – Obviously this is subject to change.

  1. New Server-Side Enforcement: Other than the existing hook script infrastructure there are no plans for additional server-side enforcement of the server-dictated configuration.
  2. True Server-Wide Config: Setting a consistent configuration for all repositories on a given server will be accomplished by using consistent configs for each repository; there are no plans for a dedicated server-wide config. Administrators are already used to having configuration duplicated across many repositories (hook scripts, authz files, etc.), so we suspect it's no showstopper if "server" configuration is done by ensuring that every repository is properly configured.
  3. Reworking the client-side local configuration to support similar hierarchies of configuration. Today, the local configuration is largely universal in terms of remote scope – changes to the configuration apply to all working copies of all repositories on all servers. (Some exceptions exist in the 'servers' file, but those are largely disinteresting for our purpose.) If the client had access to hierarchical configuration, users could configure such things as "in all working copies of ${ASF_REPOS_UUID}:/subversion, do not store pristines".

Related Issues

Other Related Resources

  • No labels