mirror of
https://github.com/facebook/sapling.git
synced 2024-10-12 17:58:27 +03:00
a574573d52
Summary: Add `hg fs stats` for the edenfs stats commands. Reviewed By: chadaustin Differential Revision: D14007060 fbshipit-source-id: 453133d04867a90fd7a40bc05288e35ae56fad93
256 lines
6.6 KiB
Python
256 lines
6.6 KiB
Python
# commands/fs.py - commands for controlling the edenfs daemon
|
|
#
|
|
# Copyright 2019 Facebook, Inc.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2 or any later version.
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import errno
|
|
import subprocess
|
|
|
|
from .. import cmdutil, error, registrar
|
|
from ..i18n import _
|
|
|
|
|
|
command = registrar.command()
|
|
|
|
|
|
@command("fs", [], subonly=True, norepo=True)
|
|
def fs(ui, **opts):
|
|
"""control the edenfs daemon"""
|
|
|
|
|
|
table = {}
|
|
subcmd = fs.subcommand(
|
|
table,
|
|
categories=[
|
|
("Start and stop the edenfs daemon", ["start", "stop", "restart"]),
|
|
("Maintenance for the edenfs daemon", ["check", "doctor", "gc"]),
|
|
],
|
|
)
|
|
|
|
|
|
def _calledenfsctl(ui, command, args=None, opts=None):
|
|
cmd = ["edenfsctl"] + command.split()
|
|
if opts:
|
|
commandopts = cmdutil.findsubcmd(command.split(), table)[3][1]
|
|
for commandopt in commandopts:
|
|
name = commandopt[1]
|
|
key = name.replace("-", "_")
|
|
if key in opts:
|
|
value = opts[key]
|
|
default = commandopt[2]
|
|
if value:
|
|
if default in (None, True, False):
|
|
cmd.append("--%s" % name)
|
|
else:
|
|
cmd.append("--%s=%s" % (name, value))
|
|
if args:
|
|
cmd.extend(args)
|
|
ui.debug("calling '%s'...\n" % (" ".join(cmd)))
|
|
try:
|
|
return subprocess.call(cmd)
|
|
except OSError as e:
|
|
if e.errno == errno.ENOENT:
|
|
raise error.Abort(
|
|
_("'edenfsctl' not found"),
|
|
hint=_(
|
|
"ensure edenfs is installed and its tools are available in the system path"
|
|
),
|
|
)
|
|
else:
|
|
raise
|
|
|
|
|
|
@subcmd(
|
|
"check|fsck",
|
|
[
|
|
(
|
|
"",
|
|
"force",
|
|
None,
|
|
_("force a check even on checkouts that appear to be mounted"),
|
|
)
|
|
]
|
|
+ cmdutil.dryrunopts,
|
|
)
|
|
def check(ui, repo, **opts):
|
|
"""check the filesystem of a virtual checkout"""
|
|
args = [repo.root]
|
|
if ui.verbose:
|
|
args.append("--verbose")
|
|
if opts["dry_run"]:
|
|
# edenfsctl uses a different name for --dry-run
|
|
args.append("--check-only")
|
|
opts["dry_run"] = False
|
|
return _calledenfsctl(ui, "fsck", args, opts=opts)
|
|
|
|
|
|
@subcmd("chown", [], "UID GID")
|
|
def chown(ui, repo, uid, gid):
|
|
"""change the ownership of a virtual checkout
|
|
|
|
Reassigns ownership of a virtual checkout to the specified user and group.
|
|
"""
|
|
return _calledenfsctl(ui, "chown", [repo.root, uid, gid])
|
|
|
|
|
|
@subcmd("config", [], norepo=True)
|
|
def config(ui):
|
|
"""show the edenfs daemon configuration"""
|
|
return _calledenfsctl(ui, "config")
|
|
|
|
|
|
@subcmd(
|
|
"doctor",
|
|
[("n", "dry-run", None, _("do not try to fix any issues, only report them"))],
|
|
norepo=True,
|
|
)
|
|
def doctor(ui, **opts):
|
|
"""debug and fix issues with the edenfs daemon"""
|
|
return _calledenfsctl(ui, "doctor", opts=opts)
|
|
|
|
|
|
@subcmd("gc", [], norepo=True)
|
|
def gc(ui, **opts):
|
|
"""minimize disk and memory usage by freeing caches"""
|
|
return _calledenfsctl(ui, "gc")
|
|
|
|
|
|
@subcmd("info", [])
|
|
def info(ui, repo, **opts):
|
|
"""show details about the virtual checkout"""
|
|
return _calledenfsctl(ui, "info", [repo.root])
|
|
|
|
|
|
@subcmd("list", [("", "json", None, _("list checkouts in JSON format"))], norepo=True)
|
|
def list_(ui, **opts):
|
|
"""list available virtual checkouts"""
|
|
return _calledenfsctl(ui, "list", opts=opts)
|
|
|
|
|
|
@subcmd(
|
|
"prefetch",
|
|
[
|
|
(
|
|
"",
|
|
"pattern-file",
|
|
"",
|
|
_("specify a file that lists patterns or files to match, one per line"),
|
|
_("FILE"),
|
|
),
|
|
("", "silent", None, _("do not print the names of the matching files")),
|
|
("", "no-prefetch", None, _("do not prefetch, just match the names")),
|
|
],
|
|
_("[PATTERN]..."),
|
|
)
|
|
def prefetch(ui, repo, *patterns, **opts):
|
|
"""prefetch content for files"""
|
|
return _calledenfsctl(
|
|
ui, "prefetch", ["--repo", repo.root] + list(patterns), opts=opts
|
|
)
|
|
|
|
|
|
@subcmd(
|
|
"remove|rm",
|
|
[
|
|
(
|
|
"y",
|
|
"yes",
|
|
None,
|
|
_("do not prompt for confirmation before removing the checkout"),
|
|
)
|
|
],
|
|
)
|
|
def remove(ui, repo, **opts):
|
|
"""remove a virtual checkout"""
|
|
return _calledenfsctl(ui, "remove", [repo.root], opts=opts)
|
|
|
|
|
|
@subcmd(
|
|
"restart", [("", "graceful", None, _("perform a graceful restart"))], norepo=True
|
|
)
|
|
def restart(ui, **opts):
|
|
"""restart the edenfs daemon
|
|
|
|
Run "@prog@ fs restart --graceful" to perform a graceful restart. The
|
|
new edenfs daemon will take over the existing edenfs mount points with
|
|
minimal disruption to clients. Open file handles will continue to work
|
|
across the restart.
|
|
"""
|
|
return _calledenfsctl(ui, "restart", opts=opts)
|
|
|
|
|
|
@subcmd("start", norepo=True)
|
|
def start(ui, **opts):
|
|
"""start the edenfs daemon"""
|
|
return _calledenfsctl(ui, "start")
|
|
|
|
|
|
@subcmd("stats", subonly=True, norepo=True)
|
|
def stats(ui, **opts):
|
|
"""print statistics for the edenfs daemon"""
|
|
|
|
|
|
statscmd = stats.subcommand()
|
|
|
|
|
|
@statscmd(
|
|
"io", [("A", "all", None, "show status for all the system calls")], norepo=True
|
|
)
|
|
def statsio(ui, **opts):
|
|
"""show information about the number of I/O calls"""
|
|
return _calledenfsctl(ui, "stats io", opts=opts)
|
|
|
|
|
|
@statscmd(
|
|
"latency", [("A", "all", None, "show status for all the system calls")], norepo=True
|
|
)
|
|
def statslatency(ui, **opts):
|
|
"""show information about the latency of I/O calls"""
|
|
return _calledenfsctl(ui, "stats latency", opts=opts)
|
|
|
|
|
|
@statscmd("memory", [], norepo=True)
|
|
def statsmemory(ui, **opts):
|
|
"""show memory statistics for the edenfs daemon"""
|
|
return _calledenfsctl(ui, "stats memory")
|
|
|
|
|
|
@statscmd("thrift", [], norepo=True)
|
|
def statsthrift(ui, **opts):
|
|
"""show the number of received thrift calls"""
|
|
return _calledenfsctl(ui, "stats thrift")
|
|
|
|
|
|
@statscmd("thriftlatency|thrift-latency", [], norepo=True)
|
|
def statsthriftlatency(ui, **opts):
|
|
"""show the latency of received thrift calls"""
|
|
return _calledenfsctl(ui, "stats thrift-latency")
|
|
|
|
|
|
@subcmd("status", norepo=True)
|
|
def status(ui, **opts):
|
|
"""check the health of the edenfs daemon"""
|
|
return _calledenfsctl(ui, "status")
|
|
|
|
|
|
@subcmd("stop", norepo=True)
|
|
def stop(ui, **opts):
|
|
"""stop the edenfs daemon"""
|
|
return _calledenfsctl(ui, "stop")
|
|
|
|
|
|
@subcmd("top", norepo=True)
|
|
def top(ui, **opts):
|
|
"""monitor virtual checkout accesses by process"""
|
|
return _calledenfsctl(ui, "top")
|
|
|
|
|
|
@subcmd("version", norepo=True)
|
|
def version(ui, **opts):
|
|
"""show version information for the edenfs daemon"""
|
|
return _calledenfsctl(ui, "version")
|