78c3464d21b0 — Alain Leufroy 3 years ago
editer: user is the boss

In a few situation, OverlayFS is ok with that.
If the user insists, let's do it.
2 files changed, 28 insertions(+), 9 deletions(-)

M overlayctl
M test_overlayctl.py
M overlayctl +17 -9
@@ 604,19 604,20 @@ def _get_editor_on_file(filename):
     Popen(cmd, shell=True).wait()
 
 
-def editer(name, appended=None, prepended=None, removed=None):
+def editer(name, appended=None, prepended=None, removed=None, keep_others=False):
     """Ask user to edit lowers of the given overlay name, rewrite
     the metadata and unit files accordingly, finaly retart systemd units
     of the edited overlay.
     """
     layer = build_layer(name)
-    to_stop = [layer for layer in _iter_descendants(layer) if layer.automountunit.is_active()]
-    if to_stop:
-        # XXX automatic stop/start
-        logger.error(
-            'You should prefere to stop the following overlays: \n\n%s\n',
-            ', '.join(x.name for x in to_stop))
-        return
+    if not keep_others:
+        to_stop = [layer for layer in _iter_descendants(layer) if layer.automountunit.is_active()]
+        if to_stop:
+            # XXX automatic stop/start
+            logger.error(
+                'You should prefere to stop the following overlays: \n\n%s\n',
+                ', '.join(x.name for x in to_stop))
+            return
     if not appended and not prepended and not removed:
         with NamedTemporaryFile() as fobj:
             fobj.write(b'# -*- encoding: utf-8 -*-\n')

          
@@ 1018,6 1019,13 @@ def main():
         '-d', '--delete', action='append', help="append the following names",
     )
     edit.add_argument(
+        '--keep-others', '-K',
+        action='store_true',
+        default=False,
+        help=('do not check if descendant overlays are started '
+              '(may produce inconsistant behaviours)')
+    )
+    edit.add_argument(
         'mountdir',
         metavar='MOUNTDIR',
         help=(

          
@@ 1027,7 1035,7 @@ def main():
     )
 
     def _editer(args):
-        editer(args.mountdir, args.append, args.prepend, args.delete)
+        editer(args.mountdir, args.append, args.prepend, args.delete, args.keep_others)
 
     edit.set_defaults(func=_editer)
 

          
M test_overlayctl.py +11 -0
@@ 482,6 482,17 @@ class TestEdit(BaseTest):
         overlayctl.editer('lower', removed=['base'])
         self.check_mount_unit('lower', [self.get_mount_dir('base')])
 
+    def test_editing_layer_with_active_descendant(self):
+        # Because OverlayFS does not like it, we protect users from
+        # having broken mount point. But if the user is ok with that, let's do it.
+        self.get_mount_dir('base').mkdir()
+        overlayctl.creater('lower', ['base'])
+        overlayctl.creater('layer', ['lower'])
+        self.systemctl.reset_mock()
+        self.systemctl.status.return_value = {'Active': 'active'}
+        overlayctl.editer('lower', removed=['base'], keep_others=True)
+        self.check_mount_unit('lower', [])
+
 
 class TestMove(BaseTest):
     """Tests for the `move` command."""