# HG changeset patch # User Alain Leufroy # Date 1616182223 -3600 # Fri Mar 19 20:30:23 2021 +0100 # Node ID a52a839f52559176145a2f4c847a9cdcdd89cb0e # Parent b6b9c4b6a50341eb32a565575722b169a9c452b4 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. diff --git a/overlayctl b/overlayctl --- a/overlayctl +++ b/overlayctl @@ -22,12 +22,14 @@ 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 @@ """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 @@ 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 @@ 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',