Submitter | Jun Wu |
---|---|
Date | Feb. 24, 2016, 10:30 p.m. |
Message ID | <fbc26e0249811675aaa7.1456353012@x1c> |
Download | mbox | patch |
Permalink | /patch/13375/ |
State | Superseded |
Commit | 53dc4aada2d9eeb93302caa5b7b9a244193f2f41 |
Delegated to: | Yuya Nishihara |
Headers | show |
Comments
On Wed, 24 Feb 2016 22:30:12 +0000, Jun Wu wrote: > # HG changeset patch > # User Jun Wu <quark@fb.com> > # Date 1456346139 0 > # Wed Feb 24 20:35:39 2016 +0000 > # Node ID fbc26e0249811675aaa764b7c74fabc46cd421e5 > # Parent 9c014b8b58c67018c6e5f897f1890162542868de > chgserver: add utilities to calculate confighash > > confighash is the hash of sensitive config items like [extensions], and > sensitive environment variables like HG*, LD_*, etc. The config items > can come from global, user, repo config, and command line flags. > > For chgserver, it is designed that once confighash changes, the server is > not qualified to serve its client and should redirect the client to a new > server. The server does not need to exit in this case, since it can still > be valid (have a matched confighash) to serve other chg clients. > > diff --git a/hgext/chgserver.py b/hgext/chgserver.py > --- a/hgext/chgserver.py > +++ b/hgext/chgserver.py > @@ -30,6 +30,7 @@ > > import SocketServer > import errno > +import hashlib > import os > import re > import signal > @@ -58,6 +59,36 @@ > > _log = commandserver.log > > +def _hashlist(items): > + """return sha256 hexdigest for a list""" > + return hashlib.sha256(str(items)).hexdigest() There are util.shaxxx functions, but sha256 isn't. Since we don't need cryptographic strength of sha256, we can pick one from util.shaxxx. > +# sensitive config sections affecting confighash > +_configsections = ['extensions', 'extdiff', 'experimental'] Let's start with ['extensions']. The other sections would need detailed comments. It's easy to add sections, but hard to remove them from the list. > +# sensitive environment variables affecting confighash > +_envre = re.compile('CHGHG|HG.*|LANG|LC_.*|LD.*|PATH|PYTHON.*|TERM(?:INFO)?' > + '|TZ') Missing '$' at the end? re.match() passes if a string starts with the pattern, but you seem to expect an exact match. But both LANG and LANGUAGE need to be caught. > +def _confighash(ui): > + """return a quick hash for detecting config/env changes > + > + confighash is the hash of sensitive config items and environment variables. > + > + for chgserver, it is designed that once confighash changes, the server is > + not qualified to serve its client and should redirect the client to a new > + server. different from mtimehash, confighash change will not mark the > + server outdated and exit since the user can have different configs at the > + same time. > + """ > + sectionitems = [] > + for section in _configsections: > + sectionitems.append(sorted(ui.configitems(section))) configitems() have a stable order. IIRC, we can't be 100% sure that the loading order of extensions never change the behavior. > + sectionhash = _hashlist(sectionitems) > + envitems = [(k, v) for k, v in os.environ.items() if _envre.match(k)] .iteritems() for now.
Patch
diff --git a/hgext/chgserver.py b/hgext/chgserver.py --- a/hgext/chgserver.py +++ b/hgext/chgserver.py @@ -30,6 +30,7 @@ import SocketServer import errno +import hashlib import os import re import signal @@ -58,6 +59,36 @@ _log = commandserver.log +def _hashlist(items): + """return sha256 hexdigest for a list""" + return hashlib.sha256(str(items)).hexdigest() + +# sensitive config sections affecting confighash +_configsections = ['extensions', 'extdiff', 'experimental'] + +# sensitive environment variables affecting confighash +_envre = re.compile('CHGHG|HG.*|LANG|LC_.*|LD.*|PATH|PYTHON.*|TERM(?:INFO)?' + '|TZ') + +def _confighash(ui): + """return a quick hash for detecting config/env changes + + confighash is the hash of sensitive config items and environment variables. + + for chgserver, it is designed that once confighash changes, the server is + not qualified to serve its client and should redirect the client to a new + server. different from mtimehash, confighash change will not mark the + server outdated and exit since the user can have different configs at the + same time. + """ + sectionitems = [] + for section in _configsections: + sectionitems.append(sorted(ui.configitems(section))) + sectionhash = _hashlist(sectionitems) + envitems = [(k, v) for k, v in os.environ.items() if _envre.match(k)] + envhash = _hashlist(sorted(envitems)) + return sectionhash[:6] + envhash[:6] + # copied from hgext/pager.py:uisetup() def _setuppagercmd(ui, options, cmd): if not ui.formatted():