b6b9c4b6a503 — Alain Leufroy 3 years ago
reset: add command

This command is really usefull when we are using containers to tests things.
2 files changed, 62 insertions(+), 6 deletions(-)

M overlayctl
M test_overlayctl.py
M overlayctl +38 -6
@@ 599,10 599,7 @@ def creater(name, lowers, start=None, pe
         logger.warning("Use `overlayctl start %s` to start the overlay.", layer.name)
 
 
-def deleter(name):
-    """Delete a managed overlay and related folder/files"""
-    lowers = set(chain(*(x.lowers for x in _iter_layers_simple())))
-    layer = build_layer(name)
+def _delete_layer(layer):
     if not layer.is_managed():
         logger.info("\"%s\" not managed. Nothing to do.", layer.name)
         return

          
@@ 611,11 608,26 @@ def deleter(name):
         # XXX allow this with automatic updates.
         raise DeletionError(
             "\"%s\" is a lower directory of another overlay: %s"
-            % (name, ', '.join(x.name for x in descendants))
+            % (layer.name, ', '.join(x.name for x in descendants))
         )
     layer.delete()
+
+
+def deleter(name):
+    """Delete a managed overlay and related folder/files"""
+    _delete_layer(build_layer(name))
     systemctl.daemon_reload()
-    logger.info("\"%s\" deleted", layer.name)
+    logger.info("\"%s\" deleted", name)
+
+
+def reseter(name):
+    """Delete then re-create an overlay preserving the configuration."""
+    layer = build_layer(name)
+    _delete_layer(layer)
+    layer.dump()
+    systemctl.daemon_reload()
+    layer.start()
+
 
 
 def _get_editor_on_file(filename):

          
@@ 917,6 929,26 @@ def main():
 
     delete.set_defaults(func=_deleter)
 
+    # reset
+    reset = subparser.add_parser(
+        'reset',
+        help="Reset the overlay",
+        description="Quick alias for `delete`, `create` then `start` preserving the configuration.",
+    )
+    reset.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 _reseter(args):
+        reseter(args.mountdir)
+
+    reset.set_defaults(func=_reseter)
+
+
     # list
     list = subparser.add_parser(
         'list',

          
M test_overlayctl.py +24 -0
@@ 289,6 289,30 @@ class TestDelete(BaseTest):
         overlayctl.deleter('layer1')
 
 
+class TestReset(BaseTest):
+    """Test for the `reset` command."""
+
+    def test_reset_a_layer(self):
+        # Reseting a layer cleans up the upper/work directories, the
+        # info file, the .automount and the .mount systemd. unit file.
+        # Then recreate them.
+        self.systemctl.status.return_value = {'Active': 'inactive'}
+        self.get_mount_dir('archbase').mkdir()
+        overlayctl.creater('lower1', lowers=('archbase',))
+        overlayctl.creater('lower2', lowers=('archbase',))
+        overlayctl.creater('test', lowers=['lower1', 'lower2'])
+        lower1_file = self.get_upper_dir('lower1') / 'lower1'
+        lower2_file = self.get_upper_dir('lower2') / 'lower2'
+        test_file = self.get_upper_dir('test') / 'test'
+        lower1_file.write_text('1')
+        lower2_file.write_text('1')
+        test_file.write_text('1')
+        overlayctl.reseter('test')
+        self.assertTrue(lower1_file.exists())
+        self.assertTrue(lower2_file.exists())
+        self.assertFalse(test_file.exists())
+
+
 class TestStart(BaseTest):
     """Tests for the `start` command."""