Skip to content

Commit

Permalink
Add functions to schedule or cancel a revert
Browse files Browse the repository at this point in the history
Signed-off-by: mulhern <[email protected]>
  • Loading branch information
mulkieran committed Jul 23, 2024
1 parent 960854f commit e1c771e
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/stratis_cli/_actions/_logical.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from .._constants import Id, IdType
from .._errors import (
StratisCliEngineError,
StratisCliFsMergeRequestedChangeError,
StratisCliFsSizeLimitChangeError,
StratisCliIncoherenceError,
StratisCliNoChangeError,
Expand Down Expand Up @@ -336,3 +337,59 @@ def unset_size_limit(namespace):
raise StratisCliFsSizeLimitChangeError(None)

Filesystem.Properties.SizeLimit.Set(get_object(fs_object_path), (False, ""))

@staticmethod
def schedule_revert(namespace):
"""
Schedule reverting a snapshot into its origin.
"""
# pylint: disable=import-outside-toplevel
from ._data import Filesystem, MOFilesystem, ObjectManager, filesystems, pools

proxy = get_object(TOP_OBJECT)
managed_objects = ObjectManager.Methods.GetManagedObjects(proxy, {})
(pool_object_path, _) = next(
pools(props={"Name": namespace.pool_name})
.require_unique_match(True)
.search(managed_objects)
)
(fs_object_path, fs_info) = next(
filesystems(props={"Name": namespace.fs_name, "Pool": pool_object_path})
.require_unique_match(True)
.search(managed_objects)
)

merge_requested = MOFilesystem(fs_info).MergeRequested()

if bool(merge_requested):
raise StratisCliFsMergeRequestedChangeError(True)

Filesystem.Properties.MergeRequested.Set(get_object(fs_object_path), True)

@staticmethod
def cancel_revert(namespace):
"""
Cancel reverting a snapshot into its origin.
"""
# pylint: disable=import-outside-toplevel
from ._data import Filesystem, MOFilesystem, ObjectManager, filesystems, pools

proxy = get_object(TOP_OBJECT)
managed_objects = ObjectManager.Methods.GetManagedObjects(proxy, {})
(pool_object_path, _) = next(
pools(props={"Name": namespace.pool_name})
.require_unique_match(True)
.search(managed_objects)
)
(fs_object_path, fs_info) = next(
filesystems(props={"Name": namespace.fs_name, "Pool": pool_object_path})
.require_unique_match(True)
.search(managed_objects)
)

merge_requested = MOFilesystem(fs_info).MergeRequested()

if not bool(merge_requested):
raise StratisCliFsMergeRequestedChangeError(False)

Filesystem.Properties.MergeRequested.Set(get_object(fs_object_path), False)
12 changes: 12 additions & 0 deletions src/stratis_cli/_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,18 @@ def __str__(self):
return f"Filesystem's size limit is exactly {self.value}"


class StratisCliFsMergeRequestedChangeError(StratisCliNoPropertyChangeError):
"""
Raised when the user requests the same filesystems MergeRequested value
that the filesystem already has.
"""

def __str__(self):
if self.value:
return "Filesystem is already scheduled for a revert operation."
return "Filesystem is not currently scheduled for a revert operation."


class StratisCliHasCacheChangeError(StratisCliNoPropertyChangeError):
"""
Raised when the user request cache initialization, but a cache is already
Expand Down
38 changes: 38 additions & 0 deletions src/stratis_cli/_parser/_logical.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,44 @@ def verify(self, namespace, parser):
"func": LogicalActions.unset_size_limit,
},
),
(
"schedule-revert",
{
"help": "Schedule a revert operation for this snapshot into its origin",
"args": [
(
"pool_name",
{
"help": "Name of the pool the filesystem is part of",
},
),
(
"fs_name",
{"help": "Name of the filesystem to change"},
),
],
"func": LogicalActions.schedule_revert,
},
),
(
"cancel-revert",
{
"help": "Cancel a previously scheduled revert operation",
"args": [
(
"pool_name",
{
"help": "Name of the pool the filesystem is part of",
},
),
(
"fs_name",
{"help": "Name of the filesystem to change"},
),
],
"func": LogicalActions.cancel_revert,
},
),
(
"debug",
{
Expand Down
73 changes: 73 additions & 0 deletions tests/whitebox/integration/logical/test_cancel_revert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Copyright 2023 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Test 'cancel-revert'.
"""

# isort: LOCAL
from stratis_cli import StratisCliErrorCodes
from stratis_cli._errors import StratisCliFsMergeRequestedChangeError

from .._misc import RUNNER, TEST_RUNNER, SimTestCase, device_name_list

_DEVICE_STRATEGY = device_name_list(1)
_ERROR = StratisCliErrorCodes.ERROR


class FsCancelRevertTestCase(SimTestCase):
"""
Test canceling a filesystem revert.
"""

_MENU = ["--propagate", "filesystem", "cancel-revert"]
_POOLNAME = "pool"
_FSNAME = "nofs"

def setUp(self):
"""
Start the stratisd daemon with the simulator.
"""
super().setUp()
command_line = ["pool", "create", self._POOLNAME] + _DEVICE_STRATEGY()
RUNNER(command_line)

command_line = [
"filesystem",
"create",
self._POOLNAME,
self._FSNAME,
]
RUNNER(command_line)

def test_cancel_revert_when_unscheduled(self):
"""
Cancelling an unscheduled revert should fail.
"""
command_line = self._MENU + [self._POOLNAME, self._FSNAME]
self.check_error(StratisCliFsMergeRequestedChangeError, command_line, _ERROR)

def test_cancel_revert(self):
"""
Cancelling a scheduled revert should succeed.
"""
command_line = [
"--propagate",
"filesystem",
"schedule-revert",
self._POOLNAME,
self._FSNAME,
]
RUNNER(command_line)
command_line = self._MENU + [self._POOLNAME, self._FSNAME]
TEST_RUNNER(command_line)
72 changes: 72 additions & 0 deletions tests/whitebox/integration/logical/test_schedule_revert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2023 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Test 'schedule-revert'.
"""

# isort: LOCAL
from stratis_cli import StratisCliErrorCodes
from stratis_cli._errors import StratisCliFsMergeRequestedChangeError

from .._misc import RUNNER, TEST_RUNNER, SimTestCase, device_name_list

_DEVICE_STRATEGY = device_name_list(1)
_ERROR = StratisCliErrorCodes.ERROR


class FsScheduleRevertTestCase(SimTestCase):
"""
Test scheduling a revert for a filesystem.
"""

_MENU = ["--propagate", "filesystem", "schedule-revert"]
_POOLNAME = "pool"
_FSNAME = "nofs"

def setUp(self):
"""
Start the stratisd daemon with the simulator.
"""
super().setUp()
command_line = ["pool", "create", self._POOLNAME] + _DEVICE_STRATEGY()
RUNNER(command_line)

command_line = [
"filesystem",
"create",
self._POOLNAME,
self._FSNAME,
]
RUNNER(command_line)

def test_schedule_revert_twice(self):
"""
Scheduling a revert twice should fail.
"""
command_line = [
"--propagate",
"filesystem",
"schedule-revert",
self._POOLNAME,
self._FSNAME,
]
RUNNER(command_line)
self.check_error(StratisCliFsMergeRequestedChangeError, command_line, _ERROR)

def test_schedule_revert_once(self):
"""
Scheduling a revert once should succeed.
"""
command_line = self._MENU + [self._POOLNAME, self._FSNAME]
TEST_RUNNER(command_line)

0 comments on commit e1c771e

Please sign in to comment.