views: check if the image fits in cache before image/restore

Check if the image to be restored fits in the client's cache to
provide a better feedback for a failed restore operation.
Report the needed free space in clients where it does not fit.
Only check if the reported image size is not 0, older images
may not define the "size" attribute.
Ignore the check if the restore type is UNICAST-DIRECT.
master
Alejandro Sirgo Rica 2024-06-18 15:08:07 +02:00
parent 3c4b917280
commit 521b7c81ac
1 changed files with 33 additions and 0 deletions

View File

@ -746,6 +746,35 @@ def get_clients_repo(server, ips):
return None
return repo_id
def image_fits_in_cache(server, ips, image_size):
err_report = ""
r = server.get('/cache/list', payload={'clients': ips})
if not r:
return ogserver_down('commands')
if r.status_code != requests.codes.ok:
return ogserver_error('commands')
clients_info = r.json()['clients']
for client_info in clients_info:
ip = client_info['ip']
cache_size = int(client_info['cache_size'])
used_cache = 0
for image_info in client_info['images']:
used_cache += int(image_info['size'])
free_cache = cache_size - used_cache
if free_cache < image_size:
missing_cache = image_size - free_cache
err_report += f'{ip}: needs {(missing_cache / (1024 ** 3)):.3f} free GiB<br>'
if err_report:
flash(f'Client cache error:<br>{err_report}', category='error')
return False
return True
@app.route('/action/image/restore', methods=['GET', 'POST'])
@login_required
def action_image_restore():
@ -785,6 +814,10 @@ def action_image_restore():
flash(_(f'The image size is bigger than the target partition'), category='error')
return redirect(url_for('commands'))
image_size = int(image['size'])
if requires_cache and image_size and not image_fits_in_cache(server, ips, image_size):
return redirect(url_for('commands'))
try:
repository = get_repository(image['repo_id'], server)
except ServerError: