diff --git a/ogcp/forms/action_forms.py b/ogcp/forms/action_forms.py index 94388c8..46081b5 100644 --- a/ogcp/forms/action_forms.py +++ b/ogcp/forms/action_forms.py @@ -86,7 +86,6 @@ class SoftwareForm(FlaskForm): class SessionForm(FlaskForm): ips = HiddenField() os = RadioField(label=_l('Session'), choices=[]) - run = SubmitField(label=_l('Run')) class ImageRestoreForm(FlaskForm): ips = HiddenField() diff --git a/ogcp/templates/actions/session.html b/ogcp/templates/actions/session.html index 1e16a03..56865fb 100644 --- a/ogcp/templates/actions/session.html +++ b/ogcp/templates/actions/session.html @@ -16,10 +16,37 @@ {{ macros.cmd_selected_clients(selected_clients) }} -{{ wtf.quick_form(form, - action=url_for('action_session'), - method='post', - button_map={'run': 'primary'}, - extra_classes='mx-5') }} +
+{% if os_groups|length > 1 %} +The selected clients have different installed OS: +{% endif %} +
+ + {% endblock %} diff --git a/ogcp/views.py b/ogcp/views.py index a5d5e2e..056c3e5 100644 --- a/ogcp/views.py +++ b/ogcp/views.py @@ -647,6 +647,7 @@ def action_setup_modify(): for partition in form.partitions: if partition.part_type.data == 'CACHE': cache_count += 1 + if cache_count == 0: flash(_(f'Missing cache partition'), category='error') return redirect(url_for('commands')) @@ -957,23 +958,10 @@ def action_session(): form = SessionForm(request.form) if request.method == 'POST': ips = form.ips.data.split(' ') - disk, partition = form.os.data.split(' ') - + disk, partition, os_name = form.os.data.split(' ', 2) server = get_server_from_clients(list(ips)) - r = server.post('/session', payload={'clients': ips, - 'disk': str(disk), - 'partition': str(partition)}) - if r.status_code == requests.codes.ok: - return redirect(url_for('commands')) - return make_response("400 Bad Request", 400) - else: - ips = parse_elements(request.args.to_dict()) - if not validate_elements(ips, max_len=1): - return redirect(url_for('commands')) - server = get_server_from_clients(list(ips)) - form.ips.data = ' '.join(ips) - r = server.get('/session', payload={'client': list(ips)}) + r = server.get('/session', payload={'clients': ips}) if not r: return ogserver_down('commands') if r.status_code != requests.codes.ok: @@ -982,18 +970,64 @@ def action_session(): sessions = r.json()['sessions'] if not sessions: flash(_('ogServer returned an empty session list'), - category='error') + category='error') return redirect(url_for('commands')) - for os in sessions: - choice = (f"{os['disk']} {os['partition']}", - f"OS: {os['name']} (Disk:{os['disk']}, Partition:{os['partition']})") - form.os.choices.append(choice) + valid_ips = [] + excluded_ips = [] + for os, ip in zip(sessions, ips): + if os['disk'] == int(disk) and os['partition'] == int(partition) and os['name'] == os_name: + valid_ips.append(ip) + else: + excluded_ips.append(ip) + + r = server.post('/session', payload={'clients': valid_ips, + 'disk': str(disk), + 'partition': str(partition)}) + if r.status_code == requests.codes.ok: + if excluded_ips: + flash('The following clients didn\'t match the boot configuration: ' + str(excluded_ips)) + return redirect(url_for('commands')) + return make_response("400 Bad Request", 400) + else: + ips = parse_elements(request.args.to_dict()) + ips_list = list(ips) + if not validate_elements(ips): + return redirect(url_for('commands')) + + server = get_server_from_clients(ips_list) + form.ips.data = ' '.join(ips_list) + + r = server.get('/session', payload={'clients': ips_list}) + if not r: + return ogserver_down('commands') + if r.status_code != requests.codes.ok: + return ogserver_error('commands') + + sessions = r.json()['sessions'] + if not sessions: + flash(_('ogServer returned an empty session list'), + category='error') + return redirect(url_for('commands')) + + os_groups = {} + for os, ip in zip(sessions, ips_list): + item_key = f"{os['disk']} {os['partition']} {os['name']}" + + if item_key in os_groups: + os_groups[item_key].append(ip) + else: + os_groups[item_key] = [ip] + + choice = (item_key, + f"{os['name']} (Disk:{os['disk']}, Partition:{os['partition']})") + form.os.choices.append(choice) + scopes, clients = get_scopes(set(ips)) selected_clients = list(get_selected_clients(scopes['scope']).items()) return render_template('actions/session.html', form=form, selected_clients=selected_clients, - scopes=scopes) + scopes=scopes, os_groups=os_groups) @app.route('/action/client/info', methods=['GET']) @login_required