mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
snapshot: Fix snapshots filling up the disk
- Snapper's cleanup algorithms don't apply limits unless they are specified in the form of ranges. Changed all limit values in the configuration to ranges. - Also, all MIN_AGE values have been set to 0 to avoid the disk space filling up in case of a large number of snapshots generated in a very short amount of time. - FREE_LIMIT has been increased to 30% from the default 20% since backup archives also take up disk space on the root partition. Fixes #1435 Signed-off-by: Joseph Nuthalapati <njoseph@thoughtworks.com> Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
parent
8dbf73d3f5
commit
8ba0bda869
@ -39,6 +39,9 @@ def parse_arguments():
|
||||
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
|
||||
|
||||
subparsers.add_parser('setup', help='Configure snapper')
|
||||
subparsers.add_parser(
|
||||
'migrate',
|
||||
help='Migrate existing user configuration to the new format')
|
||||
subparsers.add_parser('list', help='List snapshots')
|
||||
subparsers.add_parser('create', help='Create snapshot')
|
||||
subparsers.add_parser('get-config', help='Configurations of snapshot')
|
||||
@ -85,11 +88,20 @@ def subcommand_setup(_):
|
||||
|
||||
def _set_default_config():
|
||||
command = [
|
||||
'snapper', 'set-config', 'TIMELINE_CREATE=yes',
|
||||
'TIMELINE_LIMIT_HOURLY=10', 'TIMELINE_LIMIT_MONTHLY=2',
|
||||
'TIMELINE_LIMIT_WEEKLY=2', 'TIMELINE_LIMIT_YEARLY=0',
|
||||
'TIMELINE_LIMIT_DAILY=3', 'NUMBER_MIN_AGE=1296000', 'NUMBER_LIMIT=0',
|
||||
'NUMBER_LIMIT_IMPORTANT=4-10'
|
||||
'snapper',
|
||||
'set-config',
|
||||
'TIMELINE_CREATE=yes',
|
||||
'TIMELINE_MIN_AGE=0',
|
||||
'TIMELINE_LIMIT_HOURLY=0-10',
|
||||
'TIMELINE_LIMIT_DAILY=0-3',
|
||||
'TIMELINE_LIMIT_WEEKLY=0-2',
|
||||
'TIMELINE_LIMIT_MONTHLY=0-2',
|
||||
'TIMELINE_LIMIT_YEARLY=0-0',
|
||||
'NUMBER_MIN_AGE=0',
|
||||
'NUMBER_LIMIT=0-100',
|
||||
'NUMBER_LIMIT_IMPORTANT=0-20',
|
||||
'EMPTY_PRE_POST_MIN_AGE=0',
|
||||
'FREE_LIMIT=0.3',
|
||||
]
|
||||
subprocess.run(command, check=True)
|
||||
|
||||
@ -223,7 +235,7 @@ def subcommand_set_config(arguments):
|
||||
subprocess.run(command, check=True)
|
||||
|
||||
|
||||
def subcommand_get_config(_):
|
||||
def _get_config():
|
||||
command = ['snapper', 'get-config']
|
||||
process = subprocess.run(command, stdout=subprocess.PIPE, check=True)
|
||||
lines = process.stdout.decode().splitlines()
|
||||
@ -231,9 +243,45 @@ def subcommand_get_config(_):
|
||||
for line in lines[2:]:
|
||||
parts = [part.strip() for part in line.split('|')]
|
||||
config[parts[0]] = parts[1]
|
||||
return config
|
||||
|
||||
|
||||
def subcommand_get_config(_):
|
||||
config = _get_config()
|
||||
print(json.dumps(config))
|
||||
|
||||
|
||||
def subcommand_migrate(_):
|
||||
"""Migrate existing user configuration for snapshots
|
||||
to the new configuration format.
|
||||
Add in version 4 of the snapshots module.
|
||||
This command will not check or perform first setup steps.
|
||||
"""
|
||||
config = _get_config()
|
||||
|
||||
def convert_to_range(key):
|
||||
value = config[key]
|
||||
value = value if '-' in value else '0-{}'.format(value)
|
||||
return '{}={}'.format(key, value)
|
||||
|
||||
command = [
|
||||
'snapper',
|
||||
'set-config',
|
||||
'TIMELINE_MIN_AGE=0',
|
||||
convert_to_range('TIMELINE_LIMIT_HOURLY'),
|
||||
convert_to_range('TIMELINE_LIMIT_DAILY'),
|
||||
convert_to_range('TIMELINE_LIMIT_WEEKLY'),
|
||||
convert_to_range('TIMELINE_LIMIT_MONTHLY'),
|
||||
convert_to_range('TIMELINE_LIMIT_YEARLY'),
|
||||
'NUMBER_MIN_AGE=0',
|
||||
'NUMBER_LIMIT=0-100',
|
||||
'NUMBER_LIMIT_IMPORTANT=0-20',
|
||||
'EMPTY_PRE_POST_MIN_AGE=0',
|
||||
'FREE_LIMIT=0.3',
|
||||
]
|
||||
subprocess.run(command, check=True)
|
||||
|
||||
|
||||
def subcommand_kill_daemon(_):
|
||||
"""Kill the snapper daemon.
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ from plinth.menu import main_menu
|
||||
|
||||
from .manifest import backup
|
||||
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
managed_packages = ['snapper']
|
||||
|
||||
@ -67,13 +67,16 @@ def init():
|
||||
def setup(helper, old_version=None):
|
||||
"""Install and configure the module."""
|
||||
helper.install(managed_packages)
|
||||
helper.call('post', actions.superuser_run, 'snapshot', ['setup'])
|
||||
if old_version:
|
||||
helper.call('post', actions.superuser_run, 'snapshot', ['migrate'])
|
||||
else:
|
||||
helper.call('post', actions.superuser_run, 'snapshot', ['setup'])
|
||||
|
||||
|
||||
def load_augeas():
|
||||
"""Initialize Augeas."""
|
||||
aug = augeas.Augeas(
|
||||
flags=augeas.Augeas.NO_LOAD + augeas.Augeas.NO_MODL_AUTOLOAD)
|
||||
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
||||
augeas.Augeas.NO_MODL_AUTOLOAD)
|
||||
|
||||
# shell-script config file lens
|
||||
aug.set('/augeas/load/Shellvars/lens', 'Shellvars.lns')
|
||||
@ -96,21 +99,24 @@ def get_configuration():
|
||||
def get_boolean_choice(status):
|
||||
return ('yes', 'Enabled') if status else ('no', 'Disabled')
|
||||
|
||||
def get_max_from_range(key):
|
||||
return output[key].split('-')[-1]
|
||||
|
||||
return {
|
||||
'enable_timeline_snapshots':
|
||||
get_boolean_choice(output['TIMELINE_CREATE'] == 'yes'),
|
||||
'enable_software_snapshots':
|
||||
get_boolean_choice(is_apt_snapshots_enabled(aug)),
|
||||
'hourly_limit':
|
||||
output['TIMELINE_LIMIT_HOURLY'],
|
||||
get_max_from_range('TIMELINE_LIMIT_HOURLY'),
|
||||
'daily_limit':
|
||||
output['TIMELINE_LIMIT_DAILY'],
|
||||
get_max_from_range('TIMELINE_LIMIT_DAILY'),
|
||||
'weekly_limit':
|
||||
output['TIMELINE_LIMIT_WEEKLY'],
|
||||
'yearly_limit':
|
||||
output['TIMELINE_LIMIT_YEARLY'],
|
||||
get_max_from_range('TIMELINE_LIMIT_WEEKLY'),
|
||||
'monthly_limit':
|
||||
output['TIMELINE_LIMIT_MONTHLY'],
|
||||
get_max_from_range('TIMELINE_LIMIT_MONTHLY'),
|
||||
'yearly_limit':
|
||||
get_max_from_range('TIMELINE_LIMIT_YEARLY'),
|
||||
'number_min_age':
|
||||
round(int(output['NUMBER_MIN_AGE']) / 86400),
|
||||
}
|
||||
|
||||
@ -98,25 +98,28 @@ def update_configuration(request, old_status, new_status):
|
||||
def make_config(args):
|
||||
key, stamp = args[0], args[1]
|
||||
if old_status[key] != new_status[key]:
|
||||
return stamp.format(new_status[key])
|
||||
if 'limit' in key:
|
||||
return stamp.format('0-{}'.format(new_status[key]))
|
||||
else:
|
||||
return stamp.format(new_status[key])
|
||||
else:
|
||||
return None
|
||||
|
||||
new_status['number_min_age'] = int(new_status['number_min_age']) * 86400
|
||||
|
||||
config = filter(None,
|
||||
map(make_config, [
|
||||
('enable_timeline_snapshots', 'TIMELINE_CREATE={}'),
|
||||
('hourly_limit', 'TIMELINE_LIMIT_HOURLY={}'),
|
||||
('daily_limit', 'TIMELINE_LIMIT_DAILY={}'),
|
||||
('weekly_limit', 'TIMELINE_LIMIT_WEEKLY={}'),
|
||||
('monthly_limit', 'TIMELINE_LIMIT_MONTHLY={}'),
|
||||
('yearly_limit', 'TIMELINE_LIMIT_YEARLY={}'),
|
||||
('number_min_age', 'NUMBER_MIN_AGE={}'),
|
||||
]))
|
||||
config = filter(
|
||||
None,
|
||||
map(make_config, [
|
||||
('enable_timeline_snapshots', 'TIMELINE_CREATE={}'),
|
||||
('hourly_limit', 'TIMELINE_LIMIT_HOURLY={}'),
|
||||
('daily_limit', 'TIMELINE_LIMIT_DAILY={}'),
|
||||
('weekly_limit', 'TIMELINE_LIMIT_WEEKLY={}'),
|
||||
('monthly_limit', 'TIMELINE_LIMIT_MONTHLY={}'),
|
||||
('yearly_limit', 'TIMELINE_LIMIT_YEARLY={}'),
|
||||
('number_min_age', 'NUMBER_MIN_AGE={}'),
|
||||
]))
|
||||
|
||||
if old_status['enable_software_snapshots'] != new_status[
|
||||
'enable_software_snapshots']:
|
||||
if old_status['enable_software_snapshots'] != new_status['enable_software_snapshots']:
|
||||
if new_status['enable_software_snapshots'] == 'yes':
|
||||
actions.superuser_run('snapshot', ['disable-apt-snapshot', 'no'])
|
||||
else:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user