mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-20 10:34:30 +00:00
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:
parent
5e18a648e1
commit
d615709b8a
@ -85,17 +85,27 @@ def subcommand_list(_):
|
|||||||
parts = [part.strip() for part in line.split('|')]
|
parts = [part.strip() for part in line.split('|')]
|
||||||
snapshots.append(dict(zip(keys, parts)))
|
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', '/']
|
command = ['btrfs', 'subvolume', 'get-default', '/']
|
||||||
process = subprocess.run(command, stdout=subprocess.PIPE, check=True)
|
process = subprocess.run(command, stdout=subprocess.PIPE, check=True)
|
||||||
output = process.stdout.decode()
|
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(_):
|
def subcommand_create(_):
|
||||||
|
|||||||
@ -35,7 +35,16 @@ title = _('Snapshots')
|
|||||||
|
|
||||||
description = [
|
description = [
|
||||||
_('Snapshots allows creating and managing filesystem snapshots. These can '
|
_('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
|
service = None
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "simple_service.html" %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
#
|
#
|
||||||
# This file is part of Plinth.
|
# This file is part of Plinth.
|
||||||
@ -21,55 +21,58 @@
|
|||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block content %}
|
{% block configuration %}
|
||||||
<h2>{{ title }}</h2>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<table class="table table-bordered table-condensed table-striped">
|
<table class="table table-bordered table-condensed table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<th>{% trans "Number" %}</th>
|
<th>{% trans "Number" %}</th>
|
||||||
<th>{% trans "Date" %}</th>
|
<th>{% trans "Date" %}</th>
|
||||||
<th>{% trans "Description" %}</th>
|
<th>{% trans "Description" %}</th>
|
||||||
<th>{% trans "Rollback" %}</th>
|
<th>{% trans "Rollback" %}</th>
|
||||||
<th>{% trans "Delete" %}</th>
|
<th>{% trans "Delete" %}</th>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for snapshot in snapshots %}
|
{% for snapshot in snapshots %}
|
||||||
{% if snapshot.description != "current" %}
|
{% if snapshot.description != "current" %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ snapshot.number }}</td>
|
<td>
|
||||||
<td>{{ snapshot.date }}</td>
|
{{ snapshot.number }}
|
||||||
<td>
|
{% if snapshot.is_default %}
|
||||||
{% if snapshot.is_default %}
|
<span class="label label-primary">
|
||||||
{% trans "[default subvolume]" %}<br />
|
{% trans "active" %}
|
||||||
{% endif %}
|
</span>
|
||||||
{{ snapshot.description }}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>{{ snapshot.date }}</td>
|
||||||
<a href="{% url 'snapshot:rollback' snapshot.number %}"
|
<td>{{ snapshot.description }}</td>
|
||||||
class="btn btn-default btn-sm"
|
<td>
|
||||||
role="button"
|
<a href="{% url 'snapshot:rollback' snapshot.number %}"
|
||||||
title="{% blocktrans with number=snapshot.number %}Rollback to snapshot #{{ number }}{% endblocktrans %}">
|
class="btn btn-default btn-sm" role="button"
|
||||||
<span class="glyphicon glyphicon-repeat"
|
title="{% blocktrans trimmed with number=snapshot.number %}
|
||||||
aria-hidden="true"></span>
|
Rollback to snapshot #{{ number }}
|
||||||
</a>
|
{% endblocktrans %}">
|
||||||
</td>
|
<span class="glyphicon glyphicon-repeat"
|
||||||
<td>
|
aria-hidden="true"></span>
|
||||||
{% if not snapshot.is_default %}
|
</a>
|
||||||
<a href="{% url 'snapshot:delete' snapshot.number %}"
|
</td>
|
||||||
class="btn btn-default btn-sm"
|
<td>
|
||||||
role="button"
|
{% if not snapshot.is_default %}
|
||||||
title="{% blocktrans with number=snapshot.number %}Delete snapshot #{{ number }}{% endblocktrans %}">
|
<a href="{% url 'snapshot:delete' snapshot.number %}"
|
||||||
<span class="glyphicon glyphicon-trash"
|
class="btn btn-default btn-sm" role="button"
|
||||||
aria-hidden="true"></span>
|
title="{% blocktrans trimmed with number=snapshot.number %}
|
||||||
</a>
|
Delete snapshot #{{ number }}
|
||||||
{% endif %}
|
{% endblocktrans %}">
|
||||||
</td>
|
<span class="glyphicon glyphicon-trash"
|
||||||
</tr>
|
aria-hidden="true"></span>
|
||||||
{% endif %}
|
</a>
|
||||||
{% endfor %}
|
{% endif %}
|
||||||
</tbody>
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -79,7 +82,8 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<input type="submit" class="btn btn-primary"
|
<input type="submit" class="btn btn-primary"
|
||||||
value="{% trans "Create Snapshot" %}"/>
|
value="{% trans "Create Snapshot" %}"/>
|
||||||
</form>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -24,11 +24,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
|
|
||||||
<p>
|
<p>{% trans "Delete this snapshot permanently?" %}</p>
|
||||||
{% blocktrans trimmed %}
|
|
||||||
The snapshot will be permanently deleted. Please confirm.
|
|
||||||
{% endblocktrans %}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
@ -54,7 +50,9 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<input type="submit" class="btn btn-primary"
|
<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>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
@ -24,9 +24,13 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>{{ title }}</h2>
|
<h2>{{ title }}</h2>
|
||||||
|
|
||||||
|
<p>{% trans "Roll back the system to this snapshot?" %}</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{% blocktrans trimmed %}
|
{% 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 %}
|
{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -54,7 +58,9 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<input type="submit" class="btn btn-primary"
|
<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>
|
</form>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
@ -41,6 +41,7 @@ def index(request):
|
|||||||
|
|
||||||
return TemplateResponse(request, 'snapshot.html',
|
return TemplateResponse(request, 'snapshot.html',
|
||||||
{'title': snapshot_module.title,
|
{'title': snapshot_module.title,
|
||||||
|
'description': snapshot_module.description,
|
||||||
'snapshots': snapshots})
|
'snapshots': snapshots})
|
||||||
|
|
||||||
|
|
||||||
@ -48,16 +49,17 @@ def delete(request, number):
|
|||||||
"""Show confirmation to delete a snapshot."""
|
"""Show confirmation to delete a snapshot."""
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
actions.superuser_run('snapshot', ['delete', number])
|
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'))
|
return redirect(reverse('snapshot:index'))
|
||||||
|
|
||||||
output = actions.superuser_run('snapshot', ['list'])
|
output = actions.superuser_run('snapshot', ['list'])
|
||||||
snapshots = json.loads(output)
|
snapshots = json.loads(output)
|
||||||
|
|
||||||
snapshot = None
|
snapshot = None
|
||||||
for s in snapshots:
|
for current_snapshot in snapshots:
|
||||||
if s['number'] == number:
|
if current_snapshot['number'] == number:
|
||||||
snapshot = s
|
snapshot = current_snapshot
|
||||||
|
|
||||||
return TemplateResponse(request, 'snapshot_delete.html',
|
return TemplateResponse(request, 'snapshot_delete.html',
|
||||||
{'title': _('Delete Snapshot'),
|
{'title': _('Delete Snapshot'),
|
||||||
@ -68,7 +70,9 @@ def rollback(request, number):
|
|||||||
"""Show confirmation to rollback to a snapshot."""
|
"""Show confirmation to rollback to a snapshot."""
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
actions.superuser_run('snapshot', ['rollback', number])
|
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(
|
messages.warning(
|
||||||
request,
|
request,
|
||||||
_('The system must be restarted to complete the rollback.'))
|
_('The system must be restarted to complete the rollback.'))
|
||||||
@ -78,9 +82,9 @@ def rollback(request, number):
|
|||||||
snapshots = json.loads(output)
|
snapshots = json.loads(output)
|
||||||
|
|
||||||
snapshot = None
|
snapshot = None
|
||||||
for s in snapshots:
|
for current_snapshot in snapshots:
|
||||||
if s['number'] == number:
|
if current_snapshot['number'] == number:
|
||||||
snapshot = s
|
snapshot = current_snapshot
|
||||||
|
|
||||||
return TemplateResponse(request, 'snapshot_rollback.html',
|
return TemplateResponse(request, 'snapshot_rollback.html',
|
||||||
{'title': _('Rollback to Snapshot'),
|
{'title': _('Rollback to Snapshot'),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user