software packages and deploying

This commit is contained in:
2026-09-10 21:54:55 +02:00
parent 0fb18ae4f7
commit 4567df7ebb
73 changed files with 3088 additions and 6 deletions
+134
View File
@@ -0,0 +1,134 @@
{% extends 'base.html' %}
{% block content %}
<div class="toolbar">
<div>
<h1>{{ package.name }}</h1>
<p class="muted">{{ t('software_packages.detail_subtitle') }}</p>
</div>
<div class="setup-analyzer-actions">
<a class="button button-secondary" href="/software/packages">{{ t('software_packages.back') }}</a>
<a class="button button-secondary" href="/software">{{ t('setup_analyzer.back_to_software') }}</a>
</div>
</div>
{% if request.query_params.get('created') %}
<div class="notice success">{{ t('software_packages.created') }}</div>
{% endif %}
<div class="setup-analyzer-grid">
<section class="panel setup-analyzer-card">
<h2>{{ t('software_packages.package_info') }}</h2>
<dl class="setup-analyzer-details">
<dt>{{ t('software.package') }}</dt><dd>{{ package.name }}</dd>
<dt>{{ t('setup_analyzer.product_name') }}</dt><dd>{{ manifest.name or '—' }}</dd>
<dt>{{ t('setup_analyzer.version') }}</dt><dd>{{ manifest.version or '—' }}</dd>
<dt>{{ t('setup_analyzer.manufacturer') }}</dt><dd>{{ manifest.vendor or '—' }}</dd>
<dt>{{ t('setup_analyzer.architecture') }}</dt><dd>{{ manifest.architecture or '—' }}</dd>
<dt>{{ t('software_packages.installer_type') }}</dt><dd>{{ manifest.installer_type or '—' }}</dd>
<dt>{{ t('software_packages.installer_file') }}</dt><dd><code>{{ manifest.installer_file or '—' }}</code></dd>
<dt>{{ t('software_packages.storage') }}</dt><dd>{{ human_size(storage_size) }}</dd>
</dl>
</section>
<section class="panel setup-analyzer-card">
<h2>{{ t('software_packages.deployment_info') }}</h2>
<dl class="setup-analyzer-details">
<dt>{{ t('setup_analyzer.arguments') }}</dt><dd><code>{{ manifest.install.arguments or '—' }}</code></dd>
<dt>{{ t('setup_analyzer.timeout') }}</dt><dd>{{ manifest.install.timeout_seconds }} s</dd>
<dt>{{ t('setup_analyzer.success_codes') }}</dt><dd>{{ manifest.install.success_codes|join(', ') }}</dd>
<dt>{{ t('setup_analyzer.reboot_codes') }}</dt><dd>{{ manifest.install.reboot_codes|join(', ') }}</dd>
<dt>{{ t('setup_analyzer.suppress_browser') }}</dt><dd>{{ t('common.yes') if manifest.install.suppress_browser else t('common.no') }}</dd>
<dt>{{ t('software_packages.process_names') }}</dt><dd>{% if manifest.process_control.process_names %}<code>{{ manifest.process_control.process_names|join(', ') }}</code>{% else %}—{% endif %}</dd>
<dt>{{ t('setup_analyzer.detection_method') }}</dt><dd><code>{{ manifest.detection.method }}</code></dd>
</dl>
</section>
</div>
<section class="panel software-package-process-panel">
<h2>{{ t('software_packages.process_control') }}</h2>
<p class="muted">{{ t('software_packages.process_control_help') }}</p>
<form method="post" action="/software/packages/{{ package.id }}/process-control" class="software-package-process-form">
<label for="package_process_names">{{ t('software_packages.process_names') }}
<input id="package_process_names" name="process_names" value="{{ manifest.process_control.process_names|join(', ') }}" placeholder="Greenshot.exe">
</label>
<small class="muted">{{ t('software_packages.process_names_help') }}</small>
<label for="package_process_grace_seconds">{{ t('software_packages.process_grace_seconds') }}
<input id="package_process_grace_seconds" name="grace_seconds" type="number" min="0" max="30" value="{{ manifest.process_control.grace_seconds }}">
</label>
<label class="checkbox-label software-package-force-close" for="package_force_close">
<input id="package_force_close" name="force_close" type="checkbox" value="true" {% if manifest.process_control.force_close %}checked{% endif %}>
<span>{{ t('software_packages.force_close') }}</span>
</label>
<button class="button button-secondary" type="submit">{{ t('common.save') }}</button>
</form>
</section>
<section class="panel">
<h2>{{ t('software_packages.create_jobs') }}</h2>
<p class="muted">{{ t('software_packages.create_jobs_help') }}</p>
<form method="post" action="/software/packages/{{ package.id }}/run" class="software-package-job-form">
<fieldset class="software-package-action-fieldset">
<legend>{{ t('software_packages.action') }}</legend>
<div class="software-package-action-options">
<label class="checkbox-label"><input type="radio" name="action" value="install" checked><span>{{ t('jobs.action.install') }}</span></label>
<label class="checkbox-label"><input type="radio" name="action" value="uninstall"><span>{{ t('jobs.action.uninstall') }}</span></label>
<label class="checkbox-label"><input type="radio" name="action" value="reinstall"><span>{{ t('jobs.action.reinstall') }}</span></label>
</div>
</fieldset>
<div class="table-scroll management-table-scroll">
<table class="data-table" data-storage-key="software-package-assets">
<thead>
<tr>
<th class="selection-column" data-no-sort="1" data-no-filter="1"><input id="software-package-select-all" type="checkbox" aria-label="{{ t('software_packages.select_all') }}"></th>
<th>{{ t('common.assets') }}</th>
<th>{{ t('field.hostname') }}</th>
<th>{{ t('software.platform') }}</th>
<th>{{ t('field.department') }}</th>
<th>{{ t('field.location') }}</th>
</tr>
</thead>
<tbody>
{% for asset in assets %}
<tr>
<td class="selection-column"><input class="software-package-asset" type="checkbox" name="asset_ids" value="{{ asset.id }}"></td>
<td><a href="/assets/{{ asset.id }}">{{ asset.name }}</a></td>
<td>{{ asset.hostname or '—' }}</td>
<td>{{ detect_platform(asset) }}</td>
<td>{{ asset.department or '—' }}</td>
<td>{{ asset.location or '—' }}</td>
</tr>
{% else %}
<tr><td colspan="6">{{ t('software_packages.no_compatible_assets') }}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="form-actions">
<button class="button" type="submit">{{ t('software_packages.start_jobs') }}</button>
</div>
</form>
</section>
<section class="panel software-package-delete-panel">
<h2>{{ t('software_packages.delete_title') }}</h2>
<p class="muted">{{ t('software_packages.delete_help') }}</p>
<form method="post" action="/software/packages/{{ package.id }}/delete" class="software-package-delete-form" onsubmit="return confirm({{ t('software_packages.delete_confirm', package=package.name)|tojson }});">
{% if job_count %}
<label class="checkbox-label software-package-delete-jobs">
<input type="checkbox" name="delete_jobs" value="1">
<span>{{ t('software_packages.delete_jobs', count=job_count) }}</span>
</label>
{% endif %}
<button class="button button-danger" type="submit">{{ t('software_packages.delete_button') }}</button>
</form>
</section>
<script>
(function(){
const master=document.getElementById('software-package-select-all');
if(!master){return;}
const items=Array.from(document.querySelectorAll('.software-package-asset'));
master.addEventListener('change',()=>{items.forEach(item=>{item.checked=master.checked;});});
})();
</script>
{% endblock %}