Previously, blackbox always appends to blackbox.log and creates the
directory for that file on demand. That could be an issue if:
1. chg starts from `$REPO` directory, so `ui._bbrepo` is set.
2. `rm -rf $REPO`.
3. `chg init $REPO`, blackbox writes something and `init` will fail
because `$REPO` directory is non-empty.
This patch fixes that by verifying whether vfs exists before re-using it.
Differential Revision: https://phab.mercurial-scm.org/D768
`lastui` decides where (where is the `.hg`) to use if the current `ui`
object does not have a `_bbrepo` associated. Previously it only gets set in
`ui.log`, which means unless a `ui` with repo associated calls `log` with
tracked event, blackbox does not know where to write its log. This patch
makes `reposetup` set `lastui` so it so we could log some more events (see
test changes).
Differential Revision: https://phab.mercurial-scm.org/D655
It seems cleaner to just remove `_partialinit`, `copy`, `__init__`. This
patch makes it so by using `getattr` in `log` so those fields do not need to
be existed.
Differential Revision: https://phab.mercurial-scm.org/D652
Having the blackbox file objects cached in `ui._bbfp` could in theory be
troublesome if multiple processes (ex. chg servers) have file objects
referring to a same file. (Although I spent some time and failed to build a
convincing test case)
This patch makes blackbox re-open the file every time to make the situation
better. Ideally we also need proper locking.
The caching logic traces back to the commit introducing blackbox
(18242716a). That commit does not have details about why caching is
necessary. Consider the fact that blackbox logs are not many, it seems fine
to remove the fp cache to be more confident.
Differential Revision: https://phab.mercurial-scm.org/D650
The added test will show:
$ $PYTHON showsize.py .hg/blackbox*
.hg/blackbox.log: < 500
.hg/blackbox.log.1: < 500
.hg/blackbox.log.2: < 500
.hg/blackbox.log.3: < 500
.hg/blackbox.log.4: < 500
.hg/blackbox.log.5: >= 500
with previous code.
The issue is caused by blackbox caching file objects *by path*, and the
rotation size check could run on a wrong file object (i.e. it should check
"blackbox.log", but `filehandles["blackbox.log"]` contains a file object
that has been renamed to "blackbox.log.5").
This patch removes the "filehandlers" global cache added by 39bd7b0c79fe to
solve the issue.
I think the original patch was trying to make different ui objects use a same
file object if their blackbox.log path is the same. In theory it could also
be problematic in the rotation case. Anyway, that should become unnecessary
after D650.
Differential Revision: https://phab.mercurial-scm.org/D648
When the appropriate developer warnings are enabled, We wrap 'repo.vfs.audit' to
check for locks when accessing file in '.hg' for writing. Another changeset will
add a 'ward' for the store vfs (svfs).
This check system has caught a handful of locking issues that have been fixed
in previous series (mostly in 4.0). I expect another batch to be caught in third
party extensions.
We introduce two real exceptions from extensions 'blackbox.log' (because a lot of
read-only operations add entry to it), and 'last-email.txt' (because 'hg email'
is currently a read only operation and there is value to keep it this way).
In addition we are currently allowing bisect to operate outside of the lock
because the current code is a bit hard to get properly locked for now. Multiple
clean up have been made but there is still a couple of them to do and the freeze
is coming.
Now that the default value is also converted we can use a human readable version
for it. This will be useful if we start to automatically display the default
config value in various place.
cmdutil.command wasn't a member of the registrar framework only for a
historical reason. Let's make that happen. This patch keeps cmdutil.command
as an alias for extension compatibility.
I've caught multiple extensions in the wild lying about being
'internal', so it's time to move the goalposts on people. Goalpost
moving will continue until third party extensions stop trying to
defeat the system.
It's possible for the blackboxui code to do a "del self._bbvfs", then ui.copy()
or similar attempt will fail. It will also fail when constructing a blackboxui
from a non-blackbox ui.
This patch fixes the issue by not assuming any _bb* attr is set.
Without this, anyone creating a ui object using: uimod.ui()
skips the blackbox.
Also, anyone doing ui.copy() skipped the blackbox.
Unfortunately, the ui object lifestyle is a bit messy,
the first one that's created is never actually initialized
with subclasses, instead pieces of the subclass are adopted
into the primal ui object. In order to handle this, a
_partialinit method will be called to ensure that the
blackboxui is properly initialized.
Without this, the last logged entry didn't have access to
the repository, and thus couldn't report its version
(and especially that an add or similar dirtied it).
A side-effect is that one repo leaks until process exit...
Without this, while you could see the list of commands run,
it wasn't possible to identify what they were doing, because commads
could rely on revsets (including remote input which varies over time).
There are multiple ui objects in Mercurial that can relate to a repository,
before this change, each one would have its own file pointer, which
results in unfortunate logging behavior.
Also, any log rotation results would be bad because only the
active blackboxui object's file pointer would be refreshed.
Note that this does not prevent two long running hg commands for the same
repository from causing problems.
Without this, when there are multiple ui views, each blackbox
will have its own file handle, and the logging will be in
a really bad order.
Also, because of the way blackbox works, it never closes its
file handles, which means the last output before exit is
often lost.
This adds the process id to the line header for the blackbox output. This is
useful for distinguishing processes when using the blackbox on a server and many
processes are writing to the blackbox at once.
Python 2.6 introduced the "except type as instance" syntax, replacing
the "except type, instance" syntax that came before. Python 3 dropped
support for the latter syntax. Since we no longer support Python 2.4 or
2.5, we have no need to continue supporting the "except type, instance".
This patch mass rewrites the exception syntax to be Python 2.6+ and
Python 3 compatible.
This patch was produced by running `2to3 -f except -w -n .`.
Extension authors (notably at companies using hg) have been
cargo-culting the `testedwith = 'internal'` bit from hg's own
extensions, which then defeats our "file bugs over here" logic in
dispatch. Let's be more aggressive about trying to give extension
authors a hint about what testedwith should say.
This change touches every module in which repository.opener was being used, and
changes it for the equivalent repository.vfs. This is meant to make it easier
to split the repository.vfs into several separate vfs.
It should now be possible to remove localrepo.opener.
In the tests some scripts call reposetup with the base ui instead of the
one the extensions have modified. This causes an exception in
blackbox.reposetup since it expected a method to be there. So I just
check for it first. This only happened when the blackbox extension
was enabled during tests.
If enabled, log rotation prevents the amount of space used by the
blackbox log from growing without bound. This becomes important in
cases where there are a lot of busy repositories managed by humans
and automation on many machines.
In large deployments, we cannot reasonably track all the repos where
blackbox logs need to be managed, so it is safer to have blackbox
manage its own logs than to move responsibility to an external tool
such as logrotate.
This change adds two configuration keys:
* blackbox.maxsize is the maximum allowable size of the current log
* blackbox.maxfiles is the number of log files to maintain
Previously, we opened the log file when creating a repo object. This
was inefficient (not all repo creation is going to result in a need to
log something), but more importantly it broke subrepo updates when used
on NFS.
* perform an update in the master repo that triggers a subrepo clone
* empty subrepo already exists, and has an open, empty blackbox.log file
due to it being opened eagerly/prematurely
* hg decides to blow away the skeletal subrepo (see use of shutil.rmtree
in subrepo._get)
* we crash, due to NFS treating a delete of an open file as really a
rename to a hidden ".nfs" file
Now that we open the blackbox log file on demand, no file exists at the
time the empty subrepo is deleted, so the above problem does not occur.