diff --git a/actions/snapshot b/actions/snapshot index 309ecec27..2b0bf3271 100755 --- a/actions/snapshot +++ b/actions/snapshot @@ -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. diff --git a/plinth/modules/snapshot/__init__.py b/plinth/modules/snapshot/__init__.py index 55b5ca926..6946a046c 100644 --- a/plinth/modules/snapshot/__init__.py +++ b/plinth/modules/snapshot/__init__.py @@ -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), } diff --git a/plinth/modules/snapshot/views.py b/plinth/modules/snapshot/views.py index 09edbad0d..75669a733 100644 --- a/plinth/modules/snapshot/views.py +++ b/plinth/modules/snapshot/views.py @@ -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: