-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
The mentioned issue / pull request made it clear to me that its very well possible for these (well intentioned) sanity checks to fail. Nevertheless I'm not inclined to just remove them. I do believe the changes here and in daa41a2 suitably accommodate the use case described in issue 18.
- Loading branch information
Showing
4 changed files
with
174 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# rotate-backups: Simple command line interface for backup rotation. | ||
# | ||
# Author: Peter Odding <[email protected]> | ||
# Last Change: August 2, 2018 | ||
# Last Change: February 12, 2020 | ||
# URL: https://github.com/xolox/python-rotate-backups | ||
|
||
""" | ||
|
@@ -143,17 +143,6 @@ | |
same name in system-wide configuration files. For more details refer to the | ||
online documentation. | ||
-u, --use-sudo | ||
Enable the use of `sudo' to rotate backups in directories that are not | ||
readable and/or writable for the current user (or the user logged in to a | ||
remote system over SSH). | ||
-n, --dry-run | ||
Don't make any changes, just print what would be done. This makes it easy | ||
to evaluate the impact of a rotation scheme without losing any backups. | ||
-C, --removal-command=CMD | ||
Change the command used to remove backups. The value of CMD defaults to | ||
|
@@ -165,6 +154,26 @@ | |
single 'rmdir' command (even though according to POSIX semantics this | ||
command should refuse to remove nonempty directories, but I digress). | ||
-u, --use-sudo | ||
Enable the use of `sudo' to rotate backups in directories that are not | ||
readable and/or writable for the current user (or the user logged in to a | ||
remote system over SSH). | ||
-f, --force | ||
If a sanity check fails an error is reported and the program aborts. You | ||
can use --force to continue with backup rotation instead. Sanity checks | ||
are done to ensure that the given DIRECTORY exists, is readable and is | ||
writable. If the --removal-command option is given then the last sanity | ||
check (that the given location is writable) is skipped (because custom | ||
removal commands imply custom semantics). | ||
-n, --dry-run | ||
Don't make any changes, just print what would be done. This makes it easy | ||
to evaluate the impact of a rotation scheme without losing any backups. | ||
-v, --verbose | ||
Increase logging verbosity (can be repeated). | ||
|
@@ -214,11 +223,11 @@ def main(): | |
selected_locations = [] | ||
# Parse the command line arguments. | ||
try: | ||
options, arguments = getopt.getopt(sys.argv[1:], 'M:H:d:w:m:y:I:x:jpri:c:r:uC:nvqh', [ | ||
options, arguments = getopt.getopt(sys.argv[1:], 'M:H:d:w:m:y:I:x:jpri:c:r:uC:fnvqh', [ | ||
'minutely=', 'hourly=', 'daily=', 'weekly=', 'monthly=', 'yearly=', | ||
'include=', 'exclude=', 'parallel', 'prefer-recent', 'relaxed', | ||
'ionice=', 'config=', 'use-sudo', 'dry-run', 'removal-command=', | ||
'verbose', 'quiet', 'help', | ||
'ionice=', 'config=', 'removal-command=', 'use-sudo', 'force', | ||
'dry-run', 'verbose', 'quiet', 'help', | ||
]) | ||
for option, value in options: | ||
if option in ('-M', '--minutely'): | ||
|
@@ -248,15 +257,17 @@ def main(): | |
kw['io_scheduling_class'] = value | ||
elif option in ('-c', '--config'): | ||
kw['config_file'] = parse_path(value) | ||
elif option in ('-C', '--removal-command'): | ||
removal_command = shlex.split(value) | ||
logger.info("Using custom removal command: %s", removal_command) | ||
kw['removal_command'] = removal_command | ||
elif option in ('-u', '--use-sudo'): | ||
use_sudo = True | ||
elif option in ('-f', '--force'): | ||
kw['force'] = True | ||
elif option in ('-n', '--dry-run'): | ||
logger.info("Performing a dry run (because of %s option) ..", option) | ||
kw['dry_run'] = True | ||
elif option in ('-C', '--removal-command'): | ||
removal_command = shlex.split(value) | ||
logger.info("Using custom removal command: %s", removal_command) | ||
kw['removal_command'] = removal_command | ||
elif option in ('-v', '--verbose'): | ||
coloredlogs.increase_verbosity() | ||
elif option in ('-q', '--quiet'): | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
# Test suite for the `rotate-backups' Python package. | ||
# | ||
# Author: Peter Odding <[email protected]> | ||
# Last Change: February 11, 2020 | ||
# Last Change: February 12, 2020 | ||
# URL: https://github.com/xolox/python-rotate-backups | ||
|
||
"""Test suite for the `rotate-backups` package.""" | ||
|
@@ -13,6 +13,7 @@ | |
import os | ||
|
||
# External dependencies. | ||
from executor import ExternalCommandFailed | ||
from executor.contexts import RemoteContext | ||
from humanfriendly.testing import TemporaryDirectory, TestCase, run_cli, touch | ||
from six.moves import configparser | ||
|
@@ -393,6 +394,15 @@ def test_removal_command(self): | |
commands = program.rotate_backups(root, prepare=True) | ||
assert any(cmd.command_line[0] == 'rmdir' for cmd in commands) | ||
|
||
def test_force(self): | ||
"""Test that sanity checks can be overridden.""" | ||
with TemporaryDirectory(prefix='rotate-backups-', suffix='-test-suite') as root: | ||
for date in '2019-03-05', '2019-03-06': | ||
os.mkdir(os.path.join(root, date)) | ||
with readonly_directory(root): | ||
program = RotateBackups(force=True, rotation_scheme=dict(monthly='always')) | ||
self.assertRaises(ExternalCommandFailed, program.rotate_backups, root) | ||
|
||
def test_ensure_writable(self): | ||
"""Test that ensure_writable() complains when the location isn't writable.""" | ||
with TemporaryDirectory(prefix='rotate-backups-', suffix='-test-suite') as root: | ||
|