@@ 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',
@@ 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."""