a52a839f5255 — Alain Leufroy 3 years ago
show: add command to display useful information about the layer

Having an easy way to retrieve the unit names is useful when trying to manually start them.

To debug the layer, it is useful to display the mount command.
1 files changed, 60 insertions(+), 0 deletions(-)

M overlayctl
M overlayctl +60 -0
@@ 22,12 22,14 @@ import re
 import shutil
 import sys
 from collections import OrderedDict, defaultdict
+from configparser import ConfigParser
 from contextlib import contextmanager
 from functools import lru_cache
 from itertools import chain
 from pathlib import Path
 from subprocess import PIPE, Popen
 from tempfile import NamedTemporaryFile
+from textwrap import dedent
 
 try:
     from colorama import Back, Fore, Style, init

          
@@ 365,6 367,13 @@ class GenericUnit:
         """Return True if the unit is active."""
         return 'active' in systemctl.status(self.path.name)['Active'].split()
 
+    def load_config(self):
+        """Return a ConfigParser object containing the unit content."""
+        config = ConfigParser()
+        with self.path.open() as fobj:
+            config.read_file(fobj)
+        return config
+
 
 class MountUnit(GenericUnit):
     """Systemd mount unit."""

          
@@ 744,6 753,37 @@ def lister(unit_name, ordered_deps, reve
         raise NoResult("No overlay matches.")
 
 
+def shower(name):
+    layer = build_layer(name)
+    if not layer.mountdir.exists():
+        logger.error('Not found.')
+        return
+    if not layer.is_managed():
+        logger.warning('Not managed.')
+        return
+    lowers = ', '.join(x.name for x in layer.lowers)
+
+    ascendants = ', '.join(x.name for x in layer.get_ascendants())
+    descendants = ', '.join(x.name for x in _iter_descendants(layer))
+    config = layer.mountunit.load_config()
+    command = ' '.join([
+        'mount', config['Mount']['What'],
+        '-t', config['Mount']['Type'],
+        '-o', config['Mount']['Options'],
+        config['Mount']['Where']])
+    print(dedent(f'''\
+              {Style.BRIGHT}Name{Style.RESET_ALL}: {layer.name}
+         {Style.BRIGHT}Mount dir{Style.RESET_ALL}: {layer.mountdir}
+            {Style.BRIGHT}Lowers{Style.RESET_ALL}: {lowers}
+        {Style.BRIGHT}Ascendants{Style.RESET_ALL}: {ascendants}
+       {Style.BRIGHT}Descendants{Style.RESET_ALL}: {descendants}
+    {Style.BRIGHT}Automount unit{Style.RESET_ALL}: {layer.automountunit.path}
+        {Style.BRIGHT}Mount unit{Style.RESET_ALL}: {layer.mountunit.path}
+             {Style.BRIGHT}Mount{Style.RESET_ALL}: {command}
+           {Style.BRIGHT}Unmount{Style.RESET_ALL}: {layer.mountdir}\
+    '''))
+
+
 def deplacer(oldname, newname, interrupt=False, preserve=False):
     # Checks
     _new = Layer(newname)

          
@@ 1027,6 1067,26 @@ def main():
 
     list.set_defaults(func=_lister)
 
+    # Info
+    show = subparser.add_parser(
+        'show',
+        help="Show property of a layer.",
+        description="Show detailled information about the lower configuration.",
+    )
+    show.add_argument(
+        'mountdir',
+        metavar='MOUNTDIR',
+        help=(
+            "overlay mount point. If just a name (without any \"%s\"), "
+            "it is assumed to be %s/{MOUNTDIR}" % (os.path.sep, MOUNTDIR)
+        ),
+    )
+
+    def _shower(args):
+        shower(args.mountdir)
+
+    show.set_defaults(func=_shower)
+
     # edit
     edit = subparser.add_parser(
         'edit',