2014-11-04 10:03:09 +03:00
|
|
|
# Copyright 2014 Facebook Inc.
|
|
|
|
#
|
2017-06-15 14:20:52 +03:00
|
|
|
"""upload useful diagnostics and give instructions for asking for help
|
2014-11-04 10:03:09 +03:00
|
|
|
|
2017-06-15 14:20:52 +03:00
|
|
|
[rage]
|
|
|
|
# Name of the rpm binary
|
|
|
|
rpmbin = rpm
|
|
|
|
"""
|
2018-03-01 23:23:39 +03:00
|
|
|
import subprocess
|
2017-06-15 14:20:52 +03:00
|
|
|
|
|
|
|
from functools import partial
|
2014-11-04 10:03:09 +03:00
|
|
|
from mercurial.i18n import _
|
2017-03-07 12:27:12 +03:00
|
|
|
from mercurial import (
|
|
|
|
bookmarks,
|
2018-03-09 19:56:07 +03:00
|
|
|
cmdutil,
|
2017-03-07 12:27:12 +03:00
|
|
|
commands,
|
|
|
|
encoding,
|
|
|
|
error,
|
2018-03-01 23:23:39 +03:00
|
|
|
progress,
|
|
|
|
pycompat,
|
2017-05-22 23:38:37 +03:00
|
|
|
registrar,
|
2018-03-01 23:23:39 +03:00
|
|
|
scmutil,
|
|
|
|
util)
|
|
|
|
|
2018-01-24 23:30:25 +03:00
|
|
|
from . import (
|
2017-12-15 17:38:23 +03:00
|
|
|
shareutil,
|
2016-07-08 15:15:42 +03:00
|
|
|
)
|
rage: use conduit instead of arc cli
Summary:
The arc cli often depends on some checked-in code. If the repo is in a bad
state (when `hg rage` is most often needed), then arc may fail to load. A
less flaky approach is to create the paste by calling conduit directly instead
of relying on the arc cli.
* The paste now has a title – it's "hg rage for path/to/repo".
* If the paste creation fails, then the rage content is saved to a temp file.
Test Plan:
Confirmed that the paste and the temp files had the `hg rage` content:
* Success:
```
$ hg rage
Please post your problem and the following link at xxx (xxx) for help:
xxx/P58168469
```
* Failures:
```
# Missing "hosts" in ~/.arcconfig:
$ hg rage
arcconfig configuration problem.
No paste was created.
Saved contents to /var/folders/jr/_rg2cglx58z6_fnksmnlmc2w71b1w9/T/hg-rage-fMVgGr
# Bad "user" in ~/.arcconfig:
$ hg rage
Error talking to phabricator.
No paste was created.
Saved contents to /var/folders/jr/_rg2cglx58z6_fnksmnlmc2w71b1w9/T/hg-rage-HeWjHA
# Off the corporate network:
$ hg rage
Bad response from phabricator.
No paste was created.
Saved contents to/var/folders/jr/_rg2cglx58z6_fnksmnlmc2w71b1w9/T/hg-rage-x4IBMT
```
Reviewers: #mercurial, medson, rmcelroy, mitrandir
Reviewed By: medson, rmcelroy, mitrandir
Subscribers: #mercurial, mitrandir, rmcelroy, medson, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D5793911
Tasks: T19966776
Signature: 5793911:1504883514:29dc2c388819ba0d570a69f97eacb77884a2f983
2017-09-09 01:11:06 +03:00
|
|
|
import os, socket, re, tempfile, time, traceback
|
2014-11-04 10:03:09 +03:00
|
|
|
|
2018-01-24 23:30:25 +03:00
|
|
|
from .remotefilelog import (
|
2017-10-31 06:48:06 +03:00
|
|
|
constants,
|
|
|
|
shallowutil
|
|
|
|
)
|
|
|
|
|
2014-11-04 10:03:09 +03:00
|
|
|
cmdtable = {}
|
2017-05-22 23:38:37 +03:00
|
|
|
command = registrar.command(cmdtable)
|
rage: silence exceptions when reading details
Summary:
rage is a basic tool to collect diagnostic information that should not break.
To ensure it works all the time, this patch:
- unbreaks hg rage from upstream change dad6404ccd
- wraps every non-trivial functions with `try`, `catch`
- adds a naive test about `hg rage --preview`
Test Plan:
Run `test-rage.t`. Comment out `import blackbox` and check:
```
hg blackbox -l20:
---------------------------
(Failed. See footnote [1])
[1]: global name 'blackbox' is not defined
Traceback (most recent call last):
File "/home/quark/fb-hgext/rage.py", line 22, in _failsafe
return func()
File "/home/quark/fb-hgext/rage.py", line 97, in <lambda>
_failsafe(lambda: hgcmd(blackbox.blackbox, limit=20))),
NameError: global name 'blackbox' is not defined
```
Reviewers: #sourcecontrol, wez, ttung, durham
Reviewed By: durham
Subscribers: durham, wez, mjpieters
Differential Revision: https://phabricator.fb.com/D2928778
Tasks: 10028490
Signature: t1:2928778:1455240651:d39ceed5d045e279160690e0a93a4e326d307db3
2016-02-12 00:00:33 +03:00
|
|
|
_failsafeerrors = []
|
|
|
|
|
|
|
|
def _failsafe(func):
|
|
|
|
try:
|
|
|
|
return func()
|
|
|
|
except Exception as ex:
|
|
|
|
index = len(_failsafeerrors) + 1
|
|
|
|
message = "[%d]: %s\n%s\n" % (index, str(ex), traceback.format_exc())
|
|
|
|
_failsafeerrors.append(message)
|
|
|
|
return '(Failed. See footnote [%d])' % index
|
|
|
|
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
def shcmd(cmd, input=None, check=True, keeperr=True):
|
|
|
|
_, _, _, p = util.popen4(cmd)
|
|
|
|
out, err = p.communicate(input)
|
|
|
|
if check and p.returncode:
|
|
|
|
raise error.Abort(cmd + ' error: ' + err)
|
|
|
|
elif keeperr:
|
|
|
|
out += err
|
|
|
|
return out
|
|
|
|
|
2016-05-03 18:12:06 +03:00
|
|
|
def which(name):
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
""" """
|
2017-01-03 16:59:55 +03:00
|
|
|
for p in encoding.environ.get('PATH', '/bin').split(pycompat.ospathsep):
|
2016-05-03 18:12:06 +03:00
|
|
|
path = os.path.join(p, name)
|
|
|
|
if os.path.exists(path):
|
|
|
|
return path
|
|
|
|
return None
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
|
|
|
|
rageopts = [('p', 'preview', None,
|
|
|
|
_('print diagnostic information without doing arc paste'))]
|
2016-05-03 18:12:06 +03:00
|
|
|
if which('oncalls'):
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
rageopts.append(('', 'oncall', None,
|
|
|
|
_('file a task for source control oncall')))
|
|
|
|
|
|
|
|
def localconfig(ui):
|
|
|
|
result = []
|
|
|
|
for section, name, value in ui.walkconfig():
|
|
|
|
source = ui.configsource(section, name)
|
|
|
|
if source.find('/etc/') == -1 and source.find('/default.d/') == -1:
|
|
|
|
result.append('%s.%s=%s # %s' % (section, name, value, source))
|
|
|
|
return result
|
|
|
|
|
2016-04-28 21:13:28 +03:00
|
|
|
def obsoleteinfo(repo, hgcmd):
|
|
|
|
"""Return obsolescence markers that are relevant to smartlog revset"""
|
|
|
|
unfi = repo.unfiltered()
|
|
|
|
revs = scmutil.revrange(unfi, ["smartlog()"])
|
|
|
|
hashes = '|'.join(unfi[rev].hex() for rev in revs)
|
2018-03-09 19:56:07 +03:00
|
|
|
markers = hgcmd('debugobsolete', rev=[])
|
2016-04-28 21:13:28 +03:00
|
|
|
pat = re.compile('(^.*(?:'+hashes+').*$)', re.MULTILINE)
|
|
|
|
relevant = pat.findall(markers)
|
|
|
|
return "\n".join(relevant)
|
|
|
|
|
2016-05-03 18:00:35 +03:00
|
|
|
def usechginfo():
|
|
|
|
"""FBONLY: Information about whether chg is enabled"""
|
|
|
|
files = {
|
|
|
|
'system': '/etc/mercurial/usechg',
|
|
|
|
'user': os.path.expanduser('~/.usechg'),
|
|
|
|
}
|
|
|
|
result = []
|
|
|
|
for name, path in files.items():
|
|
|
|
if os.path.exists(path):
|
|
|
|
with open(path) as f:
|
|
|
|
value = f.read().strip()
|
|
|
|
else:
|
|
|
|
value = '(not set)'
|
|
|
|
result.append('%s: %s' % (name, value))
|
|
|
|
return '\n'.join(result)
|
|
|
|
|
2017-06-15 14:20:52 +03:00
|
|
|
def rpminfo(ui):
|
2016-05-03 18:12:06 +03:00
|
|
|
"""FBONLY: Information about RPM packages"""
|
|
|
|
result = set()
|
2017-06-15 14:20:52 +03:00
|
|
|
rpmbin = ui.config('rage', 'rpmbin', 'rpm')
|
2016-05-03 18:12:06 +03:00
|
|
|
for name in ['hg', 'hg.real']:
|
|
|
|
path = which(name)
|
|
|
|
if not path:
|
|
|
|
continue
|
2017-06-15 14:20:52 +03:00
|
|
|
result.add(shcmd('%s -qf %s' % (rpmbin, path), check=False))
|
2016-05-03 18:12:06 +03:00
|
|
|
return ''.join(result)
|
|
|
|
|
2017-11-03 19:34:36 +03:00
|
|
|
def infinitepushbackuplogs(ui, repo):
|
|
|
|
"""Contents of recent infinitepush log files."""
|
|
|
|
logdir = ui.config('infinitepushbackup', 'logdir')
|
|
|
|
if not logdir:
|
|
|
|
return "infinitepushbackup.logdir not set"
|
|
|
|
try:
|
|
|
|
username = util.shortuser(ui.username())
|
|
|
|
except Exception:
|
|
|
|
username = 'unknown'
|
|
|
|
userlogdir = os.path.join(logdir, username)
|
|
|
|
if not os.path.exists(userlogdir):
|
|
|
|
return "log directory does not exist: %s" % userlogdir
|
|
|
|
|
|
|
|
# Log filenames are the reponame with the date (YYYYMMDD) appended.
|
|
|
|
reponame = os.path.basename(repo.origroot)
|
|
|
|
logfiles = sorted([f for f in os.listdir(userlogdir)
|
|
|
|
if f[:-8] == reponame])
|
|
|
|
if not logfiles:
|
|
|
|
return "no log files found for %s in %s" % (reponame, userlogdir)
|
|
|
|
|
|
|
|
# Display the last 100 lines from the most recent log files.
|
|
|
|
logs = []
|
|
|
|
linelimit = 100
|
|
|
|
for logfile in reversed(logfiles):
|
|
|
|
loglines = open(os.path.join(userlogdir, logfile)).readlines()
|
|
|
|
linecount = len(loglines)
|
|
|
|
if linecount > linelimit:
|
|
|
|
logcontent = ' '.join(loglines[-linelimit:])
|
|
|
|
logs.append("%s (first %s lines omitted):\n %s\n"
|
|
|
|
% (logfile, linecount - linelimit, logcontent))
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
logcontent = ' '.join(loglines)
|
|
|
|
logs.append("%s:\n %s\n" % (logfile, logcontent))
|
|
|
|
linelimit -= linecount
|
|
|
|
return ''.join(reversed(logs))
|
|
|
|
|
2018-03-12 12:52:27 +03:00
|
|
|
def readfsmonitorstate(repo):
|
|
|
|
file = repo.vfs('fsmonitor.state', 'rb')
|
|
|
|
return file.read()
|
|
|
|
|
2018-03-01 23:23:39 +03:00
|
|
|
def _makerage(ui, repo, **opts):
|
2017-12-15 17:38:23 +03:00
|
|
|
srcrepo = shareutil.getsrcrepo(repo)
|
2015-03-08 22:22:25 +03:00
|
|
|
def format(pair, basic=True):
|
|
|
|
if basic:
|
|
|
|
fmt = "%s: %s\n"
|
|
|
|
else:
|
|
|
|
fmt = "%s:\n---------------------------\n%s\n"
|
|
|
|
return fmt % pair
|
|
|
|
|
2018-03-09 19:56:07 +03:00
|
|
|
def hgcmd(cmdname, *args, **additional_opts):
|
|
|
|
cmd, opts = cmdutil.getcmdanddefaultopts(cmdname, commands.table)
|
|
|
|
opts.update(additional_opts)
|
|
|
|
|
2016-09-29 21:19:52 +03:00
|
|
|
_repo = repo
|
|
|
|
if '_repo' in opts:
|
|
|
|
_repo = opts['_repo']
|
|
|
|
del opts['_repo']
|
|
|
|
ui.pushbuffer(error=True)
|
2017-08-31 00:05:55 +03:00
|
|
|
try:
|
2018-03-09 19:56:07 +03:00
|
|
|
cmd(ui, _repo, *args, **opts)
|
2017-08-31 00:05:55 +03:00
|
|
|
finally:
|
|
|
|
return ui.popbuffer()
|
2015-03-08 22:22:25 +03:00
|
|
|
|
2017-12-15 17:38:23 +03:00
|
|
|
def hgsrcrepofile(filename):
|
|
|
|
if srcrepo.vfs.exists(filename):
|
|
|
|
return srcrepo.vfs(filename).read()
|
2017-11-03 19:34:36 +03:00
|
|
|
else:
|
2017-12-15 17:38:23 +03:00
|
|
|
return "File not found: %s" % srcrepo.vfs.join(filename)
|
2017-11-03 19:34:36 +03:00
|
|
|
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
if opts.get('oncall') and opts.get('preview'):
|
|
|
|
raise error.Abort('--preview and --oncall cannot be used together')
|
2015-03-08 22:22:25 +03:00
|
|
|
|
|
|
|
basic = [
|
|
|
|
('date', time.ctime()),
|
2017-01-20 17:23:56 +03:00
|
|
|
('unixname', encoding.environ.get('LOGNAME')),
|
2015-03-08 22:22:25 +03:00
|
|
|
('hostname', socket.gethostname()),
|
rage: silence exceptions when reading details
Summary:
rage is a basic tool to collect diagnostic information that should not break.
To ensure it works all the time, this patch:
- unbreaks hg rage from upstream change dad6404ccd
- wraps every non-trivial functions with `try`, `catch`
- adds a naive test about `hg rage --preview`
Test Plan:
Run `test-rage.t`. Comment out `import blackbox` and check:
```
hg blackbox -l20:
---------------------------
(Failed. See footnote [1])
[1]: global name 'blackbox' is not defined
Traceback (most recent call last):
File "/home/quark/fb-hgext/rage.py", line 22, in _failsafe
return func()
File "/home/quark/fb-hgext/rage.py", line 97, in <lambda>
_failsafe(lambda: hgcmd(blackbox.blackbox, limit=20))),
NameError: global name 'blackbox' is not defined
```
Reviewers: #sourcecontrol, wez, ttung, durham
Reviewed By: durham
Subscribers: durham, wez, mjpieters
Differential Revision: https://phabricator.fb.com/D2928778
Tasks: 10028490
Signature: t1:2928778:1455240651:d39ceed5d045e279160690e0a93a4e326d307db3
2016-02-12 00:00:33 +03:00
|
|
|
('repo location', _failsafe(lambda: repo.root)),
|
|
|
|
('active bookmark',
|
|
|
|
_failsafe(lambda: bookmarks._readactive(repo, repo._bookmarks))),
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
('hg version', _failsafe(
|
|
|
|
lambda: __import__('mercurial.__version__').__version__.version)),
|
|
|
|
('obsstore size', _failsafe(
|
2018-02-16 20:28:28 +03:00
|
|
|
lambda: str(srcrepo.vfs.stat('store/obsstore').st_size))),
|
2015-03-08 22:22:25 +03:00
|
|
|
]
|
|
|
|
|
2018-03-01 23:23:39 +03:00
|
|
|
oldcolormode = ui._colormode
|
2015-03-08 22:22:25 +03:00
|
|
|
ui._colormode = None
|
|
|
|
|
|
|
|
detailed = [
|
rage: silence exceptions when reading details
Summary:
rage is a basic tool to collect diagnostic information that should not break.
To ensure it works all the time, this patch:
- unbreaks hg rage from upstream change dad6404ccd
- wraps every non-trivial functions with `try`, `catch`
- adds a naive test about `hg rage --preview`
Test Plan:
Run `test-rage.t`. Comment out `import blackbox` and check:
```
hg blackbox -l20:
---------------------------
(Failed. See footnote [1])
[1]: global name 'blackbox' is not defined
Traceback (most recent call last):
File "/home/quark/fb-hgext/rage.py", line 22, in _failsafe
return func()
File "/home/quark/fb-hgext/rage.py", line 97, in <lambda>
_failsafe(lambda: hgcmd(blackbox.blackbox, limit=20))),
NameError: global name 'blackbox' is not defined
```
Reviewers: #sourcecontrol, wez, ttung, durham
Reviewed By: durham
Subscribers: durham, wez, mjpieters
Differential Revision: https://phabricator.fb.com/D2928778
Tasks: 10028490
Signature: t1:2928778:1455240651:d39ceed5d045e279160690e0a93a4e326d307db3
2016-02-12 00:00:33 +03:00
|
|
|
('df -h', _failsafe(lambda: shcmd('df -h', check=False))),
|
2018-03-09 19:56:07 +03:00
|
|
|
('hg sl (filtered)',
|
|
|
|
_failsafe(lambda: hgcmd('smartlog', template='{hsl}'))),
|
2017-11-03 19:34:36 +03:00
|
|
|
# unfiltered smartlog for recent hidden changesets, including full
|
|
|
|
# node identity
|
2017-03-07 12:27:12 +03:00
|
|
|
('hg sl (unfiltered)', _failsafe(lambda: hgcmd(
|
2018-03-09 19:56:07 +03:00
|
|
|
'smartlog', _repo=repo.unfiltered(), template='{node}\n{hsl}'))),
|
|
|
|
# smartlog as the user sees it
|
2015-03-08 22:22:25 +03:00
|
|
|
('first 20 lines of "hg status"',
|
2018-03-09 19:56:07 +03:00
|
|
|
_failsafe(lambda: '\n'.join(hgcmd('status').splitlines()[:20]))),
|
|
|
|
('hg blackbox -l60', _failsafe(lambda: hgcmd('blackbox', limit=60))),
|
|
|
|
('hg summary', _failsafe(lambda: hgcmd('summary'))),
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
('hg config (local)', _failsafe(lambda: '\n'.join(localconfig(ui)))),
|
2018-03-09 19:56:07 +03:00
|
|
|
('hg sparse', _failsafe(lambda: hgcmd('sparse'))),
|
2016-05-03 18:00:35 +03:00
|
|
|
('usechg', _failsafe(usechginfo)),
|
2017-06-15 14:20:52 +03:00
|
|
|
('rpm info', _failsafe(partial(rpminfo, ui))),
|
2017-04-19 13:18:04 +03:00
|
|
|
('klist', _failsafe(lambda: shcmd('klist', check=False))),
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
('ifconfig', _failsafe(lambda: shcmd('ifconfig'))),
|
|
|
|
('airport', _failsafe(
|
|
|
|
lambda: shcmd('/System/Library/PrivateFrameworks/Apple80211.' +
|
|
|
|
'framework/Versions/Current/Resources/airport ' +
|
|
|
|
'--getinfo', check=False))),
|
2016-04-28 21:13:28 +03:00
|
|
|
('hg debugobsolete <smartlog>',
|
|
|
|
_failsafe(lambda: obsoleteinfo(repo, hgcmd))),
|
2017-11-03 19:34:36 +03:00
|
|
|
('infinitepush backup state',
|
2017-12-15 17:38:23 +03:00
|
|
|
_failsafe(lambda: hgsrcrepofile('infinitepushbackupstate'))),
|
2017-11-03 19:34:36 +03:00
|
|
|
('infinitepush backup logs',
|
|
|
|
_failsafe(lambda: infinitepushbackuplogs(ui, repo))),
|
2018-03-09 19:56:07 +03:00
|
|
|
('hg config (all)', _failsafe(lambda: hgcmd('config'))),
|
2018-03-12 12:52:27 +03:00
|
|
|
('fsmonitor state', _failsafe(lambda: readfsmonitorstate(repo)))
|
2015-03-08 22:22:25 +03:00
|
|
|
]
|
|
|
|
|
2018-03-01 23:23:39 +03:00
|
|
|
msg = ''
|
|
|
|
|
2017-10-31 06:48:06 +03:00
|
|
|
if util.safehasattr(repo, 'name'):
|
|
|
|
# Add the contents of both local and shared pack directories.
|
|
|
|
packlocs = {
|
|
|
|
'local': lambda category: shallowutil.getlocalpackpath(
|
|
|
|
repo.svfs.vfs.base, category),
|
|
|
|
'shared': lambda category: shallowutil.getcachepackpath(repo,
|
|
|
|
category),
|
|
|
|
}
|
|
|
|
|
|
|
|
for loc, getpath in packlocs.iteritems():
|
|
|
|
for category in constants.ALL_CATEGORIES:
|
|
|
|
path = getpath(category)
|
|
|
|
detailed.append((
|
|
|
|
"%s packs (%s)" % (loc, constants.getunits(category)),
|
|
|
|
"%s:\n%s" %
|
2017-11-15 08:32:54 +03:00
|
|
|
(path, _failsafe(lambda: shcmd("ls -lhS %s" % path)))
|
2017-10-31 06:48:06 +03:00
|
|
|
))
|
|
|
|
|
2016-06-07 21:40:24 +03:00
|
|
|
# This is quite slow, so we don't want to do it by default
|
|
|
|
if ui.configbool("rage", "fastmanifestcached", False):
|
|
|
|
detailed.append(
|
|
|
|
('hg sl -r "fastmanifestcached()"',
|
2018-03-09 19:56:07 +03:00
|
|
|
_failsafe(lambda: hgcmd('smartlog',
|
2016-06-07 21:40:24 +03:00
|
|
|
rev=["fastmanifestcached()"]))),
|
|
|
|
)
|
|
|
|
|
Refactoring rage.py
Summary:
A couple of clean-ups for rage.py. They are small and easy to review so I'm doing it in one diff:
- Change the default behavior to print instructions asking for help in the support group.
Since only about 20 hg rage (not counting test ones) tasks are created last year.
The old behavior of creating tasks is still accessible by using the `--oncall` flag.
- Collect more information:
- `hg sparse`
- `hg version`
- `obsstore size`
- `rpm -q mercurial`
- network information
- short `hg config` only including local configs
- Adjust the order of detailed message, move hg config down since it's very long.
- Remove atexit error printer. Instead, put them in rage info directly.
- Fix code style: remove underscores in variable names, remove unnecessary indentation.
- Mark it FBONLY since it uses `tasks` and `oncalls` which are not available outside.
Test Plan:
Make sure these all work as expected:
hg rage
hg rage --preview
hg rage --oncall
Reviewers: #sourcecontrol, ttung, rmcelroy
Reviewed By: rmcelroy
Subscribers: ikostia, ttung, rmcelroy, simonfar, mjpieters, sid0
Differential Revision: https://phabricator.fb.com/D3138673
Tasks: 10654995, 10332733
Signature: t1:3138673:1461070413:4547d8b7e438035d6af73a49094c10eab725af0d
2016-04-19 16:04:42 +03:00
|
|
|
msg = '\n'.join(map(format, basic)) + '\n' +\
|
|
|
|
'\n'.join(map(lambda x: format(x, False), detailed))
|
|
|
|
if _failsafeerrors:
|
|
|
|
msg += '\n' + '\n'.join(_failsafeerrors)
|
|
|
|
|
2018-03-01 23:23:39 +03:00
|
|
|
ui._colormode = oldcolormode
|
|
|
|
return msg
|
|
|
|
|
|
|
|
@command('^rage', rageopts, _('hg rage'))
|
|
|
|
def rage(ui, repo, *pats, **opts):
|
|
|
|
"""collect useful diagnostics for asking help from the source control team
|
|
|
|
|
|
|
|
The rage command collects useful diagnostic information.
|
|
|
|
|
|
|
|
By default, the information will be uploaded to Phabricator and
|
|
|
|
instructions about how to ask for help will be printed.
|
|
|
|
|
|
|
|
After submitting to Phabricator, it prints configerable advice::
|
|
|
|
|
2018-03-06 03:51:55 +03:00
|
|
|
[rage]
|
2018-03-01 23:23:39 +03:00
|
|
|
advice = Please see our FAQ guide: https://...
|
|
|
|
|
|
|
|
"""
|
|
|
|
with progress.spinner(ui, "Generating paste"):
|
|
|
|
msg = _makerage(ui, repo, **opts)
|
|
|
|
|
2015-12-03 05:44:42 +03:00
|
|
|
if opts.get('preview'):
|
2017-08-31 00:05:55 +03:00
|
|
|
ui.write('%s\n' % msg)
|
2015-12-03 05:44:42 +03:00
|
|
|
return
|
|
|
|
|
2018-03-01 23:23:39 +03:00
|
|
|
with progress.spinner(ui, "Saving paste"):
|
|
|
|
p = subprocess.Popen(
|
|
|
|
['arc', 'paste', '--lang', 'hgrage' , '--title', 'hgrage'],
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stdin=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE)
|
|
|
|
out, err = p.communicate(input=msg + '\n')
|
|
|
|
ret = p.returncode
|
|
|
|
|
2017-12-21 06:01:30 +03:00
|
|
|
if ret:
|
rage: use conduit instead of arc cli
Summary:
The arc cli often depends on some checked-in code. If the repo is in a bad
state (when `hg rage` is most often needed), then arc may fail to load. A
less flaky approach is to create the paste by calling conduit directly instead
of relying on the arc cli.
* The paste now has a title – it's "hg rage for path/to/repo".
* If the paste creation fails, then the rage content is saved to a temp file.
Test Plan:
Confirmed that the paste and the temp files had the `hg rage` content:
* Success:
```
$ hg rage
Please post your problem and the following link at xxx (xxx) for help:
xxx/P58168469
```
* Failures:
```
# Missing "hosts" in ~/.arcconfig:
$ hg rage
arcconfig configuration problem.
No paste was created.
Saved contents to /var/folders/jr/_rg2cglx58z6_fnksmnlmc2w71b1w9/T/hg-rage-fMVgGr
# Bad "user" in ~/.arcconfig:
$ hg rage
Error talking to phabricator.
No paste was created.
Saved contents to /var/folders/jr/_rg2cglx58z6_fnksmnlmc2w71b1w9/T/hg-rage-HeWjHA
# Off the corporate network:
$ hg rage
Bad response from phabricator.
No paste was created.
Saved contents to/var/folders/jr/_rg2cglx58z6_fnksmnlmc2w71b1w9/T/hg-rage-x4IBMT
```
Reviewers: #mercurial, medson, rmcelroy, mitrandir
Reviewed By: medson, rmcelroy, mitrandir
Subscribers: #mercurial, mitrandir, rmcelroy, medson, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D5793911
Tasks: T19966776
Signature: 5793911:1504883514:29dc2c388819ba0d570a69f97eacb77884a2f983
2017-09-09 01:11:06 +03:00
|
|
|
fd, tmpname = tempfile.mkstemp(prefix='hg-rage-')
|
|
|
|
with os.fdopen(fd, r'w') as tmpfp:
|
|
|
|
tmpfp.write(msg)
|
2018-03-01 23:23:39 +03:00
|
|
|
ui.write(_('Failed to post the diagnostic paste to Phabricator, '
|
|
|
|
'but its contents have been written to:\n\n'))
|
|
|
|
ui.write(_(' %s\n') % tmpname, label='rage.link')
|
|
|
|
ui.write(_('\nPlease include this file in the %s.\n') %
|
|
|
|
ui.config('ui', 'supportcontact'))
|
2017-12-21 06:01:30 +03:00
|
|
|
else:
|
2018-03-01 23:23:39 +03:00
|
|
|
ui.write(_('Please post in %s with the following link:\n\n')
|
|
|
|
% (ui.config('ui', 'supportcontact')))
|
|
|
|
ui.write(' ' + out + '\n', label='rage.link')
|
2018-03-06 03:51:55 +03:00
|
|
|
ui.write(ui.config('rage', 'advice', '') + '\n')
|
2018-03-01 23:23:39 +03:00
|
|
|
|
|
|
|
colortable = {
|
|
|
|
'rage.link': 'blue bold',
|
|
|
|
}
|