Skip to content
  • Gregory Haskins's avatar
    [FAB-3160] Provide config-relative path feature · 8ce10737
    Gregory Haskins authored
    The primary goal of this patch is to create the notion of a
    "config-relative" path reference.  For example, a configuration file
    "/etc/foo/bar.yaml" that contains a key "bat" with a value
    "baz/blaz/blamo" can be used to specify that "baz/blaz/blamo" should
    be considered relative to the configuration file itself.  In this case,
    it would be expected to be found at /etc/foo/baz/blaz/blamo.  FAB-2037
    does a much more thorough job of explaining the rationale on why
    config-relative is considered important/good-form.
    This is in stark contrast to what we have today, which is a jumbled
    mess of assumed GOPATH relative, CWD relative, ENVVAR absolute and
    sometimes even ENVVAR relative.  Therefore, an additional positive
    side-effect of this endeavor is that this patch also substantially
    cleans up some technical debt that had been accumulating in the tree
    for some time related to ad-hoc pathing, DRY violations, and just
    general inconsistencies in how configuration files were managed.
    Design Details
    This patch refactors the basic configuration system into the notion of
    a tree rooted at a configuration-path.  By default, this path is
    $GOROOT/..../fabric/sampleconfig during dev/test and
    /etc/hyperledger/fabric during runtime.  The root may be overridden
    at any time by specifying the environment variable FABRIC_CFG_PATH.
    (Note that this variable unifies and replaces the former PEER_CFG_PATH
    The dev/test environment will operate out of the ./fabric/sampleconfig
    configuration root.  The build-system will package that root into
    /etc/hyperledger/fabric in the runtime context with the intention of
    the end-user/admin/deployer replacing parts or all of the sampleconfig
    to suit their application.
    Since configuration-relative paths are now possible, the configuration
    files may reference other relative files and they will behave
    appropriately regardless of the context in which they are executed.
    For example, consider the files ./sampleconfig/tls/server.[crt|key].
    A configuration file may contain a key "tls/server.key" and the system
    will properly resolve this relative file even at runtime. This is (IMO)
    far more natural than assuming a path is relative to the CWD of where
    the command is executed, which is how most of the system behaves today
    (or requires awkward and very specific ENVVAR overrides).
    This will be conducive to something like a package-installer
    (e.g. RPM/DEB) or a docker environment to augment/replace elements
    of the configuration root and to freely move the configuration around
    as the package/deployer sees fit.
    As an example, a deployment on Kubernetes might opt to volume mount
    /etc/hyperledger/fabric to replace the entire config, or it might just use
    a secrets mount on /etc/hyperledger/fabric/peer/tls.  An RPM packager
    might opt to install the configuration files in the default
    /etc/hyperledger/fabric, whereas an unprivledged user might install them
    in ~/hyperledger.  The point is, it shouldn't matter where they are and the
    user shouldn't need a PhD in CORE_* variables to get it to work.
    This is part of an overall effort to improve the user-experience as we
    march towards a v1.0 release.
    Fixes FAB-3169 as part of FAB-2037
    Change-Id: I5f47f554c2f956ec2e1afebd9bd82b0bbb62892a
    Signed-off-by: default avatarGreg Haskins <>