ogcp: Add /action/cache/fetch endpoint

Add view to request the download of images into the client's cache.
master
Alejandro Sirgo Rica 2024-08-07 16:13:50 +02:00
parent ace0c5bb46
commit 844bc1e7c6
4 changed files with 127 additions and 1 deletions

View File

@ -110,6 +110,14 @@ class ImageRestoreForm(FlaskForm):
('UNICAST-DIRECT', 'UNICAST-DIRECT')])
restore = SubmitField(label=_l('Restore'))
class ImageFetchForm(FlaskForm):
ips = HiddenField()
image = SelectField(label=_l('Image'), choices=[])
method = SelectField(label=_l('Method'),
choices=[('TIPTORRENT', 'TIPTORRENT'),
('UNICAST', 'UNICAST')])
submit = SubmitField(label=_l('Submit'))
class RepoForm(FlaskForm):
server = HiddenField()
repo_id = HiddenField()

View File

@ -0,0 +1,27 @@
{% extends 'commands.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% import "macros.html" as macros %}
{% set sidebar_state = 'disabled' %}
{% set btn_back = true %}
{% block nav_image %} active {% endblock %}
{% block nav_cache_fetch %} active {% endblock %}
{% block content %}
{% set ip_list = form.ips.data.split(' ') %}
{% set ip_count = ip_list | length %}
<h2 class="mx-5 subhead-heading">
{{ _('Cache image in %(ip_count)d computer(s)', ip_count=ip_count) }}
</h2>
{{ macros.cmd_selected_clients(selected_clients) }}
{{ wtf.quick_form(form,
action=url_for('action_image_fetch'),
method='post',
button_map={'submit': 'primary'},
extra_classes='m-5') }}
{% endblock %}

View File

@ -76,6 +76,8 @@
{% endif %}
<input class="btn btn-light dropdown-item{% block nav_image_restore %}{% endblock %}" type="submit" value="{{ _('Restore Image') }}"
form="scopesForm" formaction="{{ url_for('action_image_restore') }}" formmethod="get">
<input class="btn btn-light dropdown-item{% block nav_image_fetch %}{% endblock %}" type="submit" value="{{ _('Cache image') }}"
form="scopesForm" formaction="{{ url_for('action_image_fetch') }}" formmethod="get">
</div>
</div>

View File

@ -14,7 +14,7 @@ from ogcp.forms.action_forms import (
RoomForm, DeleteRoomForm, CenterForm, DeleteCenterForm, OgliveForm,
GenericForm, SelectClientForm, ImageUpdateForm, ImportClientsForm,
ServerForm, DeleteRepositoryForm, RepoForm, FolderForm, CacheForm,
ClientMoveForm, RunScriptForm, ImageConfigForm
ClientMoveForm, RunScriptForm, ImageConfigForm, ImageFetchForm
)
from flask_login import (
current_user, LoginManager,
@ -1307,6 +1307,95 @@ def action_client_cache():
storage_data=storage_data,
client_images=client_images)
@app.route('/action/cache/fetch', methods=['GET', 'POST'])
@login_required
def action_image_fetch():
form = ImageFetchForm(request.form)
if request.method == 'POST':
ips = form.ips.data.split(' ')
server = get_server_from_clients(list(ips))
image_id = form.image.data
server = get_server_from_clients(ips)
r = server.get('/images')
if not r:
return ogserver_down('commands')
if r.status_code != requests.codes.ok:
return ogserver_error('commands')
images_list = r.json()['images']
image = search_image(images_list, int(image_id))
if not image:
flash(_(f'Image to fetch was not found'), category='error')
return redirect(url_for('commands'))
try:
repository = get_repository(image['repo_id'], server)
except ServerError:
return ogserver_down('commands')
except ServerErrorCode:
return ogserver_error('commands')
payload = {'clients': ips,
'repository': repository['ip'],
'type': form.method.data,
'image': image['name']}
r = server.post('/cache/fetch', payload=payload)
if not r:
return ogserver_down('commands')
if r.status_code == requests.codes.ok:
flash(_('Cache fetch request sent successfully'), category='info')
else:
flash(_(f'Invalid cache fetch form'), category='error')
return redirect(url_for('commands'))
else:
params = request.args.to_dict()
ips = parse_elements(params)
center_id = int(params.get('scope-center'))
if not validate_elements(ips):
return redirect(url_for('commands'))
ips_list = list(ips)
form.ips.data = ' '.join(ips_list)
server = get_server_from_clients(ips)
try:
repo_id = get_clients_repo(server, ips)
except ServerError:
return ogserver_down('commands')
except ServerErrorCode:
return ogserver_error('commands')
if repo_id is None:
flash(_(f'Computers have different repos assigned'), category='error')
return redirect(url_for('commands'))
try:
images = get_images_from_repo(server, repo_id)
if not images:
flash(_(f'Computer(s) assigned to a repo with no images'), category='error')
return redirect(url_for('commands'))
images = filter_images_allowed_in_center(server, images, center_id)
except ServerError:
return ogserver_down('commands')
except ServerErrorCode:
return ogserver_error('commands')
sort_images(images)
for image in images:
form.image.choices.append((image['id'], image['name']))
scopes, clients = get_scopes(set(ips))
selected_clients = list(get_selected_clients(scopes['scope']).items())
return render_template('actions/cache_fetch.html', form=form,
selected_clients=selected_clients,
scopes=scopes)
@app.route('/action/client/info', methods=['GET'])
@login_required
def action_client_info():