feat: WMT client versioning, release management and force-update playbook
- api/wmt.py: add GET /api/wmt/client/version and GET /api/wmt/client/download endpoints; rewrite submit_update_request with dedup logic - web/wmt.py: add releases, releases_upload, releases_delete, releases_build routes; build-from-folder excludes hidden/data/venv/pyc files - web/main.py: admin per-device delete route; clear-device-logs route; pass devices list to admin template - templates/wmt/releases.html: new release management page (current release info, upload form, build-from-folder card) - templates/admin.html: replace nuclear clear-devices with clear-logs + per-device delete table - templates/base.html: add Client Releases nav link in WMT sidebar section - templates/ansible/execute.html: add Update WMT Code playbook card - ansible/playbooks/update_wmt_code.yml: rsync WMT_project to clients excluding data/; backs up app.py; restarts wmt service - ansible_service.py: register update_wmt_code description - .gitignore: whitelist update_wmt_code.yml
This commit is contained in:
+47
-2
@@ -516,7 +516,18 @@ def admin():
|
||||
logging.error(f'Admin inventory stats error: {e}')
|
||||
stats['inventory_hosts'] = '?'
|
||||
stats['inventory_groups_yaml'] = '?'
|
||||
return render_template('admin.html', stats=stats)
|
||||
# Pass registered devices for per-device delete UI
|
||||
devices = []
|
||||
try:
|
||||
with get_db().get_session() as session:
|
||||
devices = [
|
||||
{'id': d.id, 'hostname': d.hostname, 'nume_masa': d.nume_masa,
|
||||
'mac_address': d.mac_address, 'device_ip': d.device_ip}
|
||||
for d in session.query(Device).order_by(Device.nume_masa).all()
|
||||
]
|
||||
except Exception as e:
|
||||
logging.error(f'Admin device list error: {e}')
|
||||
return render_template('admin.html', stats=stats, devices=devices)
|
||||
|
||||
|
||||
@main_bp.route('/admin/clear/logs', methods=['POST'])
|
||||
@@ -532,9 +543,43 @@ def admin_clear_logs():
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@main_bp.route('/admin/clear/device-logs', methods=['POST'])
|
||||
def admin_clear_device_logs():
|
||||
"""Delete all log entries from the database (devices stay intact)."""
|
||||
try:
|
||||
with get_db().get_session() as session:
|
||||
count = session.query(LogEntry).delete()
|
||||
session.commit()
|
||||
return jsonify({'success': True, 'deleted': count})
|
||||
except Exception as e:
|
||||
logging.error(f'Admin clear device logs error: {e}')
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@main_bp.route('/admin/delete/device/<int:device_id>', methods=['POST'])
|
||||
def admin_delete_device(device_id):
|
||||
"""Delete a single registered device and its log entries."""
|
||||
try:
|
||||
with get_db().get_session() as session:
|
||||
device = session.query(Device).filter_by(id=device_id).first()
|
||||
if not device:
|
||||
return jsonify({'success': False, 'error': 'Device not found'}), 404
|
||||
name = device.nume_masa or device.hostname
|
||||
session.execute(text('DELETE FROM device_inventory_groups WHERE device_id = :id'), {'id': device_id})
|
||||
session.query(LogEntry).filter_by(device_id=device_id).delete()
|
||||
session.query(WMTUpdateRequest).filter_by(device_id=device_id).delete()
|
||||
session.delete(device)
|
||||
session.commit()
|
||||
logging.info(f'Admin deleted device {device_id} ({name})')
|
||||
return jsonify({'success': True, 'name': name})
|
||||
except Exception as e:
|
||||
logging.error(f'Admin delete device {device_id} error: {e}')
|
||||
return jsonify({'success': False, 'error': str(e)}), 500
|
||||
|
||||
|
||||
@main_bp.route('/admin/clear/devices', methods=['POST'])
|
||||
def admin_clear_devices():
|
||||
"""Delete all devices (and their log entries) from the database."""
|
||||
"""Delete ALL devices (and their log entries) from the database."""
|
||||
try:
|
||||
with get_db().get_session() as session:
|
||||
session.execute(text('DELETE FROM device_inventory_groups'))
|
||||
|
||||
Reference in New Issue
Block a user