diff options
author | Javier Sánchez Parra <jsanchez@soleta.eu> | 2022-04-06 17:29:44 +0200 |
---|---|---|
committer | Javier Sánchez Parra <jsanchez@soleta.eu> | 2022-04-08 08:03:32 +0200 |
commit | fcbaf7d66d5e344b12b57d8d8c4c182c7497e764 (patch) | |
tree | f3a30c47d0ae91838495485e3a1c45c39e6c54d9 | |
parent | d2fef8e85dcd348201631911711cbb9b5db30ec3 (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.py | 8 | ||||
-rw-r--r-- | ogcp/templates/actions/image_update.html | 22 | ||||
-rw-r--r-- | ogcp/templates/commands.html | 2 | ||||
-rw-r--r-- | ogcp/views.py | 69 |
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(): |