summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJavier Sánchez Parra <jsanchez@soleta.eu>2022-04-06 17:29:44 +0200
committerJavier Sánchez Parra <jsanchez@soleta.eu>2022-04-08 08:03:32 +0200
commitfcbaf7d66d5e344b12b57d8d8c4c182c7497e764 (patch)
treef3a30c47d0ae91838495485e3a1c45c39e6c54d9
parentd2fef8e85dcd348201631911711cbb9b5db30ec3 (diff)
Add Update image to commands
Allows updating the image file for an existing image. This action is related to /image/create in ogServer API. If ogServer receives an POST /image/create without the parameter "description", it does not create a new image and only updates.
-rw-r--r--ogcp/forms/action_forms.py8
-rw-r--r--ogcp/templates/actions/image_update.html22
-rw-r--r--ogcp/templates/commands.html2
-rw-r--r--ogcp/views.py69
4 files changed, 100 insertions, 1 deletions
diff --git a/ogcp/forms/action_forms.py b/ogcp/forms/action_forms.py
index 5e8bce1..5cabd54 100644
--- a/ogcp/forms/action_forms.py
+++ b/ogcp/forms/action_forms.py
@@ -137,6 +137,14 @@ class ImageCreateForm(FlaskForm):
description = StringField(label=_l('Description'))
create = SubmitField(label=_l('Create'))
+
+class ImageUpdateForm(FlaskForm):
+ ip = HiddenField()
+ os = SelectField(label=_l('Partition'), choices=[])
+ image = SelectField(label=_l('Image'), choices=[])
+ update = SubmitField(label=_l('Update'))
+
+
class CenterForm(FlaskForm):
name = StringField(label=_l('Center name'),
validators=[InputRequired()])
diff --git a/ogcp/templates/actions/image_update.html b/ogcp/templates/actions/image_update.html
new file mode 100644
index 0000000..c008aa8
--- /dev/null
+++ b/ogcp/templates/actions/image_update.html
@@ -0,0 +1,22 @@
+{% 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_image_update %}active{% endblock %}
+{% block content %}
+
+<h1 class="m-5">{{_('Update partition image')}}</h1>
+
+{{ macros.cmd_selected_clients(selected_clients) }}
+
+{{ wtf.quick_form(form,
+ action=url_for('action_image_update'),
+ method='post',
+ button_map={'update': 'primary'},
+ extra_classes='mx-5') }}
+
+{% endblock %}
diff --git a/ogcp/templates/commands.html b/ogcp/templates/commands.html
index 65ab840..a819267 100644
--- a/ogcp/templates/commands.html
+++ b/ogcp/templates/commands.html
@@ -66,6 +66,8 @@
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<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_update %}{% endblock %}" type="submit" value="{{ _('Update image') }}"
+ form="scopesForm" formaction="{{ url_for('action_image_update') }}" formmethod="get">
<input class="btn btn-light dropdown-item{% block nav_image_create %}{% endblock %}" type="submit" value="{{ _('Create image') }}"
form="scopesForm" formaction="{{ url_for('action_image_create') }}" formmethod="get">
</div>
diff --git a/ogcp/views.py b/ogcp/views.py
index ef85f05..ffd5ebf 100644
--- a/ogcp/views.py
+++ b/ogcp/views.py
@@ -12,7 +12,7 @@ from ogcp.forms.action_forms import (
WOLForm, SetupForm, ClientDetailsForm, ImageDetailsForm, HardwareForm,
SessionForm, ImageRestoreForm, ImageCreateForm, SoftwareForm, BootModeForm,
RoomForm, DeleteRoomForm, CenterForm, DeleteCenterForm, OgliveForm,
- GenericForm, SelectClientForm
+ GenericForm, SelectClientForm, ImageUpdateForm
)
from flask_login import (
current_user, LoginManager,
@@ -906,6 +906,73 @@ def action_image_create():
return render_template('actions/image_create.html', form=form,
scopes=scopes)
+
+@app.route('/action/image/update', methods=['GET', 'POST'])
+@login_required
+def action_image_update():
+ form = ImageUpdateForm(request.form)
+ if request.method == 'POST':
+ ip = form.ip.data
+ disk, partition, code = form.os.data.split(' ')
+ image_id = form.image.data
+ r = g.server.get('/images')
+ images_list = r.json()['images']
+ image = search_image(images_list, int(image_id))
+ if not image:
+ flash(_('Image to restore was not found'), category='error')
+ return redirect(url_for('commands'))
+ payload = {'clients': [ip],
+ 'disk': disk,
+ 'partition': partition,
+ 'code': code,
+ 'name': image['name'],
+ 'repository': g.server.ip,
+ 'id': str(image['id']),
+ # Dummy parameters, not used by ogServer on image update.
+ 'group_id': 0,
+ 'center_id': 0}
+ r = g.server.post('/image/create', payload)
+ if r.status_code == requests.codes.ok:
+ flash(_('Image update command sent sucessfully'), category='info')
+ else:
+ flash(_('There was a problem sending the image update command'),
+ category='error')
+ return redirect(url_for('commands'))
+
+ ips = parse_elements(request.args.to_dict())
+ if not validate_elements(ips, max_len=1):
+ return redirect(url_for('commands'))
+ form.ip.data = ' '.join(ips)
+
+ r = g.server.get('/images')
+ for image in r.json()['images']:
+ form.image.choices.append((image['id'], image['name']))
+
+ r = g.server.get('/client/setup', payload={'client': list(ips)})
+ for partition in r.json()['partitions']:
+ disk_id = partition['disk']
+ part_id = partition['partition']
+ fs_id = partition['filesystem']
+ code = partition['code']
+
+ if part_id == 0:
+ # This is the disk data, not a partition.
+ continue
+
+ choice_value = f'{disk_id} {part_id} {code}'
+ choice_name = (f"{_('Disk')} {disk_id} | "
+ f"{_('Partition')} {part_id} | "
+ f"{_('FS')} {FS_CODES[fs_id]}")
+ form.os.choices.append((choice_value, choice_name))
+
+ scopes, _clients = get_scopes(set(ips))
+ selected_clients = list(get_selected_clients(scopes['scope']).items())
+
+ return render_template('actions/image_update.html', form=form,
+ selected_clients=selected_clients,
+ scopes=scopes)
+
+
@app.route('/action/reboot', methods=['GET', 'POST'])
@login_required
def action_reboot():