mirror of https://git.48k.eu/ogcp
ogcp: add view to identify clients setup diferences before restore
Add view to provide information before a restore operation where the selected clients have a not uniform partition setup. Show the view if only clients with not partition valid for a restore operation are selected.master
parent
d6a896628f
commit
6af4330016
|
@ -0,0 +1,46 @@
|
|||
{% extends 'commands.html' %}
|
||||
{% import "bootstrap/wtf.html" as wtf %}
|
||||
{% import "macros.html" as macros %}
|
||||
|
||||
{% set sidebar_state = 'disabled' %}
|
||||
{% set btn_back = true %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h2 class="mx-5 subhead-heading">
|
||||
{{ _('Partition scheme mismatch') }}
|
||||
</h2>
|
||||
|
||||
{{ macros.cmd_selected_clients(selected_clients) }}
|
||||
</br>
|
||||
|
||||
<div class="container mx-5">
|
||||
<b>{{ _('Cannot proceed with this command, selected clients have non-uniform or valid partition scheme') }}</b>
|
||||
</div>
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead class="text-center">
|
||||
<tr>
|
||||
<th style="min-width: 15em;">{{ _('Partitions') }}</th>
|
||||
<th>{{ _('Clients') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for idx in range(part_data | length) %}
|
||||
<tr>
|
||||
<td>
|
||||
{% for disk_id, part_id, part_type, fs_type, part_size in part_data.get_partition_setup(idx) %}
|
||||
<div>Part {{ part_id }} | {{ fs_type }} | {{ (part_size / 1024) | int}} MiB</div>
|
||||
{% else %}
|
||||
{{ _('Empty') }}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% for ip in part_data.get_clients(idx) %}<div class="card d-inline-block" style="padding: 5px; margin: 3px;">{{ ip }}</div>{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
|
@ -982,13 +982,47 @@ def image_fits_in_cache(server, clients_info, image):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
class PartitionCollection:
|
||||
def __init__(self):
|
||||
self.partition_list = []
|
||||
self.clients = []
|
||||
self.empty_scheme = False
|
||||
|
||||
def __len__(self):
|
||||
return len(self.partition_list)
|
||||
|
||||
def has_empty_scheme(self):
|
||||
return self.empty_scheme
|
||||
|
||||
def register_partition_setup(self, partitions, client):
|
||||
idx = None
|
||||
self.empty_scheme = self.empty_scheme or not partitions
|
||||
for index, p in enumerate(self.partition_list):
|
||||
if p == partitions:
|
||||
idx = index
|
||||
self.clients[idx].append(client)
|
||||
break
|
||||
else:
|
||||
idx = len(self.partition_list)
|
||||
self.partition_list.append(partitions)
|
||||
self.clients.append([client])
|
||||
|
||||
return idx
|
||||
|
||||
def get_partition_setup(self, idx):
|
||||
return self.partition_list[idx]
|
||||
|
||||
def get_clients(self, idx):
|
||||
return self.clients[idx]
|
||||
|
||||
@app.route('/action/image/restore', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def action_image_restore():
|
||||
form = ImageRestoreForm(request.form)
|
||||
if request.method == 'POST':
|
||||
ips = form.ips.data.split(' ')
|
||||
disk, partition, part_code, part_size, has_cache = form.partition.data.split(' ')
|
||||
disk, partition, part_size, has_cache = form.partition.data.split(' ')
|
||||
|
||||
requires_cache = form.method.data == 'TIPTORRENT' or form.method.data == 'UNICAST'
|
||||
if has_cache == 'False' and requires_cache:
|
||||
|
@ -1080,11 +1114,10 @@ def action_image_restore():
|
|||
for image in images:
|
||||
form.image.choices.append((image['id'], image['name']))
|
||||
|
||||
reference_patitioning = []
|
||||
empty_clients = []
|
||||
|
||||
invalid_part_types = get_invalid_image_partition_types()
|
||||
|
||||
part_collection = PartitionCollection()
|
||||
|
||||
for ip in ips:
|
||||
r = server.get('/client/setup', payload={'client': [ip]})
|
||||
if not r:
|
||||
|
@ -1113,37 +1146,36 @@ def action_image_restore():
|
|||
continue
|
||||
|
||||
filesystem = partition['filesystem']
|
||||
fs_type = FS_CODES.get(filesystem, 'UNKNOWN')
|
||||
part_size = partition['size']
|
||||
|
||||
choice_value = (disk_id, part_id, part_code, filesystem, part_size)
|
||||
parts.append(choice_value)
|
||||
parts.append((disk_id, part_id, part_type, fs_type, part_size))
|
||||
|
||||
if not parts:
|
||||
empty_clients.append(ip)
|
||||
part_collection.register_partition_setup(parts, ip)
|
||||
|
||||
if empty_clients:
|
||||
continue
|
||||
|
||||
if not reference_patitioning: # Use first computer as reference part setup conf
|
||||
reference_patitioning = [part for part in parts]
|
||||
elif reference_patitioning != parts:
|
||||
flash(_(f'Computers have different partition setup'), category='error')
|
||||
return redirect(url_for('commands'))
|
||||
|
||||
if empty_clients:
|
||||
flash(_(f'The following clients have not partitions: {" ".join(empty_clients)}'), category='error')
|
||||
return redirect(url_for('commands'))
|
||||
|
||||
for disk_id, part_id, part_code, filesystem, part_size in reference_patitioning:
|
||||
form.partition.choices.append(
|
||||
(f"{disk_id} {part_id} {part_code} {part_size} {has_cache}",
|
||||
f"Disk {disk_id} | Partition {part_id} "
|
||||
f"| {PART_TYPE_CODES.get(part_code, 'UNKNOWN')} "
|
||||
f"{FS_CODES.get(filesystem, 'UNKNOWN')}")
|
||||
)
|
||||
scopes, clients = get_scopes(set(ips))
|
||||
selected_clients = list(get_selected_clients(scopes['scope']).items())
|
||||
|
||||
if len(part_collection) > 1 or part_collection.has_empty_scheme():
|
||||
return render_template('actions/partition_report.html',
|
||||
selected_clients=selected_clients,
|
||||
part_data=part_collection,
|
||||
scopes=scopes)
|
||||
|
||||
reference_patitioning = part_collection.get_partition_setup(0)
|
||||
|
||||
if not reference_patitioning:
|
||||
flash(_(f'No valid partition found'), category='error')
|
||||
return redirect(url_for('commands'))
|
||||
|
||||
for disk_id, part_id, part_type, fs_type, part_size in reference_patitioning:
|
||||
form.partition.choices.append(
|
||||
(f"{disk_id} {part_id} {part_size} {has_cache}",
|
||||
f"Disk {disk_id} | Partition {part_id} "
|
||||
f"| {part_type} "
|
||||
f"{fs_type}")
|
||||
)
|
||||
|
||||
return render_template('actions/image_restore.html', form=form,
|
||||
selected_clients=selected_clients,
|
||||
scopes=scopes)
|
||||
|
|
Loading…
Reference in New Issue