snapshot: Improved messages and minor refactoring

- Make the default snapshot detection slightly more robust and refactor.

- Expand description to explain automatic snapshotting, etc.

- Show description even after setup.

- Show default snapshot as a bootstrap label.

- Message explaing how rollback can be undone.

- Minor updates to delete/rollback confirmation messages.

- Minor style refactoring
This commit is contained in:
Sunil Mohan Adapa 2016-08-08 14:20:35 +05:30
parent 5e18a648e1
commit d615709b8a
No known key found for this signature in database
GPG Key ID: 36C361440C9BC971
6 changed files with 102 additions and 71 deletions

View File

@ -85,17 +85,27 @@ def subcommand_list(_):
parts = [part.strip() for part in line.split('|')]
snapshots.append(dict(zip(keys, parts)))
# Mark default subvolume.
default = _get_default_snapshot()
for snapshot in snapshots:
snapshot['is_default'] = (snapshot['number'] == default)
print(json.dumps(snapshots))
def _get_default_snapshot():
"""Return the default snapshot by looking at default subvolume."""
command = ['btrfs', 'subvolume', 'get-default', '/']
process = subprocess.run(command, stdout=subprocess.PIPE, check=True)
output = process.stdout.decode()
default = None
if '.snapshots' in output:
default = output.split('/')[1]
for snapshot in snapshots:
snapshot['is_default'] = snapshot['number'] == default
print(json.dumps(snapshots))
output_parts = output.split()
if len(output_parts) >= 9:
path = output.split()[8]
path_parts = path.split('/')
if len(path_parts) == 3 and path_parts[0] == '.snapshots':
return path_parts[1]
return None
def subcommand_create(_):

View File

@ -35,7 +35,16 @@ title = _('Snapshots')
description = [
_('Snapshots allows creating and managing filesystem snapshots. These can '
'be used to roll back the system to a previous state.')
'be used to roll back the system to a previously known good state in '
'case of unwanted changes to the system.'),
_('Automatic snapshots are taken every hour, day, month and year. Older '
'snapshots are automatically deleted keeping 10 of each kind and 50 in '
'total. Although snapshots are efficient and only store the '
'differences, they may be deleted to reclaim free space. Individual '
'files from older snapshots can be accessed by visiting ".snapshots" '
'directory in the filesystem. Snapshots are not a replacement for '
'backups.')
]
service = None

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "simple_service.html" %}
{% comment %}
#
# This file is part of Plinth.
@ -21,55 +21,58 @@
{% load bootstrap %}
{% load i18n %}
{% block content %}
<h2>{{ title }}</h2>
{% block configuration %}
<div class="row">
<div class="col-lg-8">
<table class="table table-bordered table-condensed table-striped">
<thead>
<th>{% trans "Number" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "Description" %}</th>
<th>{% trans "Rollback" %}</th>
<th>{% trans "Delete" %}</th>
</thead>
<tbody>
{% for snapshot in snapshots %}
{% if snapshot.description != "current" %}
<tr>
<td>{{ snapshot.number }}</td>
<td>{{ snapshot.date }}</td>
<td>
{% if snapshot.is_default %}
{% trans "[default subvolume]" %}<br />
{% endif %}
{{ snapshot.description }}
</td>
<td>
<a href="{% url 'snapshot:rollback' snapshot.number %}"
class="btn btn-default btn-sm"
role="button"
title="{% blocktrans with number=snapshot.number %}Rollback to snapshot #{{ number }}{% endblocktrans %}">
<span class="glyphicon glyphicon-repeat"
aria-hidden="true"></span>
</a>
</td>
<td>
{% if not snapshot.is_default %}
<a href="{% url 'snapshot:delete' snapshot.number %}"
class="btn btn-default btn-sm"
role="button"
title="{% blocktrans with number=snapshot.number %}Delete snapshot #{{ number }}{% endblocktrans %}">
<span class="glyphicon glyphicon-trash"
aria-hidden="true"></span>
</a>
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
<thead>
<th>{% trans "Number" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "Description" %}</th>
<th>{% trans "Rollback" %}</th>
<th>{% trans "Delete" %}</th>
</thead>
<tbody>
{% for snapshot in snapshots %}
{% if snapshot.description != "current" %}
<tr>
<td>
{{ snapshot.number }}
{% if snapshot.is_default %}
<span class="label label-primary">
{% trans "active" %}
</span>
{% endif %}
</td>
<td>{{ snapshot.date }}</td>
<td>{{ snapshot.description }}</td>
<td>
<a href="{% url 'snapshot:rollback' snapshot.number %}"
class="btn btn-default btn-sm" role="button"
title="{% blocktrans trimmed with number=snapshot.number %}
Rollback to snapshot #{{ number }}
{% endblocktrans %}">
<span class="glyphicon glyphicon-repeat"
aria-hidden="true"></span>
</a>
</td>
<td>
{% if not snapshot.is_default %}
<a href="{% url 'snapshot:delete' snapshot.number %}"
class="btn btn-default btn-sm" role="button"
title="{% blocktrans trimmed with number=snapshot.number %}
Delete snapshot #{{ number }}
{% endblocktrans %}">
<span class="glyphicon glyphicon-trash"
aria-hidden="true"></span>
</a>
{% endif %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
@ -79,7 +82,8 @@
{% csrf_token %}
<input type="submit" class="btn btn-primary"
value="{% trans "Create Snapshot" %}"/>
value="{% trans "Create Snapshot" %}"/>
</form>
</p>
{% endblock %}

View File

@ -24,11 +24,7 @@
{% block content %}
<h2>{{ title }}</h2>
<p>
{% blocktrans trimmed %}
The snapshot will be permanently deleted. Please confirm.
{% endblocktrans %}
</p>
<p>{% trans "Delete this snapshot permanently?" %}</p>
<div class="row">
<div class="col-lg-8">
@ -54,7 +50,9 @@
{% csrf_token %}
<input type="submit" class="btn btn-primary"
value="{% blocktrans with number=snapshot.number %}Delete Snapshot #{{ number }}{% endblocktrans %}"/>
value="{% blocktrans trimmed with number=snapshot.number %}
Delete Snapshot #{{ number }}
{% endblocktrans %}"/>
</form>
</p>

View File

@ -24,9 +24,13 @@
{% block content %}
<h2>{{ title }}</h2>
<p>{% trans "Roll back the system to this snapshot?" %}</p>
<p>
{% blocktrans trimmed %}
The system will be rolled back to the selected snapshot. Please confirm.
A new snapshot with the current state of the file system will be
automatically created. You will be able to undo a rollback by
reverting to the newly created snapshot.
{% endblocktrans %}
</p>
@ -54,7 +58,9 @@
{% csrf_token %}
<input type="submit" class="btn btn-primary"
value="{% blocktrans with number=snapshot.number %}Rollback to Snapshot #{{ number }}{% endblocktrans %}"/>
value="{% blocktrans trimmed with number=snapshot.number %}
Rollback to Snapshot #{{ number }}
{% endblocktrans %}"/>
</form>
</p>

View File

@ -41,6 +41,7 @@ def index(request):
return TemplateResponse(request, 'snapshot.html',
{'title': snapshot_module.title,
'description': snapshot_module.description,
'snapshots': snapshots})
@ -48,16 +49,17 @@ def delete(request, number):
"""Show confirmation to delete a snapshot."""
if request.method == 'POST':
actions.superuser_run('snapshot', ['delete', number])
messages.success(request, _('Deleted snapshot.'))
messages.success(
request, _('Deleted snapshot #{number}.').format(number=number))
return redirect(reverse('snapshot:index'))
output = actions.superuser_run('snapshot', ['list'])
snapshots = json.loads(output)
snapshot = None
for s in snapshots:
if s['number'] == number:
snapshot = s
for current_snapshot in snapshots:
if current_snapshot['number'] == number:
snapshot = current_snapshot
return TemplateResponse(request, 'snapshot_delete.html',
{'title': _('Delete Snapshot'),
@ -68,7 +70,9 @@ def rollback(request, number):
"""Show confirmation to rollback to a snapshot."""
if request.method == 'POST':
actions.superuser_run('snapshot', ['rollback', number])
messages.success(request, _('Set default subvolume for rollback.'))
messages.success(
request,
_('Rolled back to snapshot #{number}.').format(number=number))
messages.warning(
request,
_('The system must be restarted to complete the rollback.'))
@ -78,9 +82,9 @@ def rollback(request, number):
snapshots = json.loads(output)
snapshot = None
for s in snapshots:
if s['number'] == number:
snapshot = s
for current_snapshot in snapshots:
if current_snapshot['number'] == number:
snapshot = current_snapshot
return TemplateResponse(request, 'snapshot_rollback.html',
{'title': _('Rollback to Snapshot'),