Web system administration and monitoring module for ShariX Open and ShariX Platform: component health, logs, backups, module configuration and support requests.
Веб-модуль системного администрирования и мониторинга ShariX Open и ShariX Platform: состояние компонентов, логи, резервные копии, подключение модулей и заявки в техподдержку.
|
|
1 hour ago | |
|---|---|---|
| bin | 2 weeks ago | |
| handlers | 1 month ago | |
| integration | 2 months ago | |
| license_corpus | 1 month ago | |
| locale | 1 hour ago | |
| management | 2 weeks ago | |
| migrations | 1 month ago | |
| services | 1 hour ago | |
| templates | 2 weeks ago | |
| tests | 2 weeks ago | |
| .gitignore | 1 month ago | |
| CODING_POLICY.md | 1 hour ago | |
| LICENSE | 1 month ago | |
| README.md | 1 hour ago | |
| RELEASE_POLICY.md | 1 month ago | |
| __init__.py | 4 months ago | |
| admin.py | 4 months ago | |
| apps.py | 1 month ago | |
| check_stage15_9.py | 1 month ago | |
| check_stage16_1.py | 1 month ago | |
| forms.py | 4 weeks ago | |
| handler_contributions.py | 1 month ago | |
| models.py | 1 month ago | |
| page_help.py | 1 hour ago | |
| platform_module.py | 2 months ago | |
| requirements.txt | 4 months ago | |
| sharix_access.py | 2 weeks ago | |
| sharix_health.py | 1 month ago | |
| sharix_management.py | 2 months ago | |
| sharix_menu.py | 2 months ago | |
| sharix_pages.py | 1 month ago | |
| urls.py | 2 weeks ago | |
| views.py | 2 weeks ago |
Подключаемый модуль ShariX для платформы и сервиса: веб-интерфейс системного администрирования для Django admin/staff, METASERVICE-TECHSUPPORT и PLATFORM-TECHSUPPORT.
slapd, ejabberd, postgresql, подключение Django к БД, SMTP/mail-сервер из .env, процессы обработчиков webservice_running/platform_running;journalctl, systemd unit, файлы из logs/, /var/log/sharix, /var/log/messages, /var/log/syslog;pg_dump -Fc в папку backups/;bin/install.cfg с синтаксической проверкой и сравнением с bin/install.cfg.example;bin/install.cfg, INSTALLED_APPS_LOCAL и универсальный installer;Ticket в модуле tickets, если модель tickets доступна.sharix_sysadmin в корень платформы или сервиса.sharix_sysadmin в INSTALLED_APPS_LOCAL в .env.Добавить URL в core/urls.py:
if sv.is_local_app_enabled("sharix_sysadmin"):
localized_urlpatterns.append(
path(
f"{sv.SHARIX_ADMIN_PATH}sysadmin/",
include("sharix_sysadmin.urls", namespace="sharix_sysadmin"),
name="sharix_sysadmin",
)
)
Для платформы добавить пункты меню в sharix_admin/context_processors.py:
is_sysadmin = (
user.is_staff
or user.is_superuser
or "PLATFORM-TECHSUPPORT" in user_groups
or "METASERVICE-TECHSUPPORT" in user_groups
)
if sv.is_local_app_enabled("sharix_sysadmin"):
_add_menu_item(
items,
"Заявка в техподдержку",
url_name="sharix_sysadmin:support_request",
icon="sharix_admin/img/menu/tickets.svg",
active_pages=["sysadmin_support_request"],
)
if is_sysadmin:
_add_menu_item(
items,
"Системная панель",
url_name="sharix_sysadmin:dashboard",
icon="sharix_admin/img/menu/settings.svg",
active_pages=[
"sysadmin_dashboard",
"sysadmin_logs",
"sysadmin_backup",
"sysadmin_install_cfg",
"sysadmin_modules",
"sysadmin_actions",
"sysadmin_audit",
],
)
Для сервиса ShariX Open добавить в sharix_admin/lib/menu.py:
if sv.is_local_app_enabled("sharix_sysadmin"):
_append_once(MENU_GLOBAL, "sysadmin_support_request")
_append_once(MENU_GLOBAL_CUSTOMIZABLE, "sysadmin_support_request")
MENU_SCHEME_LIST_OPEN["sysadmin_support_request"] = [
"sharix_sysadmin",
"tickets",
"Заявка в техподдержку",
]
_append_once(STAFF_METASERVICE_MENU_GLOBAL, "sysadmin_dashboard")
_append_once(STAFF_METASERVICE_MENU_CUSTOMIZABLE, "sysadmin_dashboard")
MENU_SCHEME_LIST_OPEN["sysadmin_dashboard"] = [
"sharix_sysadmin",
"hdd-network",
"Системная панель",
]
И в sharix_admin/lib/access_matrix.py:
VIEW_ACCESS_RULES.update({
"sysadmin_support_request": {"auth": True},
"sysadmin_dashboard": {"roles": ("METASERVICE-TECHSUPPORT",)},
})
Применить миграции:
python manage.py makemigrations sharix_sysadmin
python manage.py migrate sharix_sysadmin
Модуль вызывает systemctl, journalctl, pg_dump, pkill. В зависимости от того, от какого пользователя запущен Django, могут потребоваться sudo/systemd-права. Для production лучше выдавать точечные sudoers-правила только на разрешённые команды.
Модуль ориентирован на systemd-окружение ALT Linux P10. Для PostgreSQL проверяются типовые unit names postgresql, postgresql-15, postgresql-14, postgresql-13; подключение к БД дополнительно проверяется через Django connection.
bin/install.cfg.example is the tracked catalogue of repository/branch keys.
The root installer copies missing keys into the installation-local
bin/install.cfg before repository processing; existing local values are never
overwritten.
Public ShariX_Open/sharix-open-* modules may be selected from the public
catalogue. Private modules are intentionally absent from that catalogue and are
installed by an explicit repository URL. Both variants are stored in the same
install.cfg and INSTALLED_APPS_LOCAL model.
The same configuration lifecycle is available non-interactively through Django:
./venv/bin/python manage.py sysadmin_module add sharix_onboarding
./bin/install.sh
sysadmin_module add and Системная панель -> Модули use the same lifecycle service.
For an enabled module, initial add invokes the root-owned targeted materializer for
that module; broad assembly installation/update remains owned by the root installer.
For a private repository pass --repo-url explicitly; enable, disable,
remove, materialize and status use the same service layer as the web UI.
Git credentials, when required by the root repository policy, are process-local only
(SHARIX_GIT_USERNAME plus SHARIX_GIT_TOKEN/SHARIX_GIT_PASSWORD) and are never
stored by Sysadmin. An interactive sysadmin_module add may ask for these one-shot
credentials at the management-command boundary; JSON/non-interactive execution must
provide them through the environment. If initial materialization fails, Sysadmin restores .env and
bin/install.cfg to their exact pre-add contents so a missing checkout cannot remain
in INSTALLED_APPS_LOCAL; any source files created before a later failure are left
in place for inspection/retry.
The installer must not create Django migrations. If model state differs from the canonical migration files, installation stops and the migration must be created and committed in the repository that owns the model.
Stage 3 adds derived module health without an InstalledModule database table.
services.module_health combines source presence, assembly configuration,
per-module enable flags, Django runtime state and optional <app>.sharix_health
probes. Structural health is side-effect free; external connectivity is checked
only with check_sharix_modules --live.
Canonical derived states are absent, disabled, not_configured,
not_authorized, ready, degraded and error. A missing optional capability
must not break core. A broken enabled integration is recorded as error rather
than silently presented as absent.
Stage 15.7.2 keeps descriptive/source metadata in services.module_metadata and combines it with the existing install.cfg and module-health lifecycle through services.modules_catalog.canonical_module_metadata(). Consumers such as Onboarding must use this projection instead of maintaining their own module catalogue.
Repository visibility (ShariX_Open/... public vs ShariX/... private), runtime availability and software-license identity are separate facts. License identity comes only from the explicit Stage 16.1 repository binding plus the actual canonical LICENSE bytes/hash (or, for an unregistered materialized source, from an exact corpus-byte match). Namespace visibility never invents a license. Onboarding and other consumers must use the same Sysadmin metadata projection rather than maintaining their own license catalogue.
Sysadmin owns one tracked license corpus for GPL-3.0-only, AGPL-3.0-only and sharix-proprietary-v1. Every registered managed module repository is explicitly bound to a license_id, canonical license_file, SHA-256 and presentation mode. The repository LICENSE is authoritative evidence: if its bytes do not match the registered hash, Sysadmin reports an inconsistent identity instead of substituting a short notice or inferring a license from the repository namespace.
The Web module-install flow always opens a separate server-side license step before changing install.cfg. GPL/AGPL use an informational view with a Continue action and no synthetic acceptance checkbox. sharix-proprietary-v1 additionally requires explicit acceptance of the exact displayed license_id and SHA-256. Pending state stores a sanitized canonical repository URL and license snapshot; credentials and license bodies are never written to the session or audit log. If an already materialized proprietary checkout has a missing or different LICENSE, a new Web configuration fails closed.
Repository access entitlement remains independent from software-license presentation. A private ShariX/... repository can require Platform/Gogs access even though its license identity is determined only by explicit canonical metadata and verified license bytes. License acceptance never expands rights granted by a separate agreement and never creates repository entitlement.
On a Service assembly, accepting the proprietary license is necessary but no
longer sufficient to configure a private ShariX/... repository. Sysadmin asks
the registered Platform for the current entitlement and fails closed unless the
module status is active. The same check is used by the web UI and
manage.py sysadmin_module add through the existing module_lifecycle service.
The Modules page can submit an entitlement request to Platform. It displays the
Platform state independently from local source/configuration state:
not_requested, requested, awaiting_gogs_account, active, revoked or
error. Public ShariX_Open/... modules are unaffected if Platform is
unreachable. The Service never receives or stores the Platform Gogs admin token.
Platform assemblies skip this Service-side entitlement gate: Platform is the owner of the private repository access policy and must not call its own Service API.
A single owner-service exception exists for installations whose canonical
METASERVICE_INN is 7801685119. If a private https://git.sharix-app.org/ShariX/...
module does not have an active Platform entitlement, the interactive
manage.py sysadmin_module add command may verify direct repository read access
instead of fabricating an entitlement. The command asks for a Gogs login and
password/access token, runs one git ls-remote check for the exact repository and
branch through an ephemeral GIT_ASKPASS helper, and only then changes
install.cfg/.env.
The fallback does not write or change Platform entitlement state. Git credentials
are not stored in Django, .env, install.cfg, the Sysadmin audit payload or
command arguments. They live only in the process environment used for the one
verification command. Non-interactive automation may supply temporary
SHARIX_GIT_USERNAME plus SHARIX_GIT_TOKEN or SHARIX_GIT_PASSWORD; --json
never opens an interactive password prompt. Because credentials are deliberately
not retained, a subsequent ./bin/install.sh clone/update may request them again.
All other Service INNs remain fail-closed behind the normal Platform entitlement.
services.repository_status is the common read-only Git inspector for the Open
AGPL root and independent private module checkouts. It never crosses repository
ownership and never stores credentials. The Open root may refresh its public
origin and reports the existing AGPL publication proof. Private repositories use
local/cached Git metadata only; Platform compares the reported installed commit
with the current Gogs branch using its own service token.
The Modules page and manage.py report_module_statuses send the versioned Stage-11 report to Platform. Stage 16.7 extends that same channel to schema v2: all managed-source components are projected from the existing Stage-16.4/16.6 owners with license identity, deployment/canonical-upstream refs, running commit/tree, publication evidence and update/divergence states. Building the report does not create a second Service inventory and does not perform hidden Git network I/O. The explicit Modules-page send action may first refresh anonymous public repository evidence; automatic commercial delivery only reuses the last safe local snapshot. Git credentials, Platform API keys, offline grants and signing material are never report fields.
The module owns operation-aware help for the module-management page through sharix_sysadmin.page_help:PAGE_HELP_CONTRIBUTIONS. Open and Platform resolve this contribution dynamically when the module is installed. Stable operation/empty-state IDs are used for coverage; user-facing text is translated in this module's ru/en catalogs. Help visibility does not grant lifecycle permissions.
The Modules page consumes one Sysadmin-owned metadata projection for module identity, configured repository, repository visibility, actual software-license identity, source availability, runtime health and Stage-11 Git/version evidence. Onboarding uses the same projection and must not maintain a second license/repository catalogue.
Repository visibility and installation access remain separate from software license.
In particular sharix_translations is identified as GPL-3.0-only only when its
canonical root LICENSE matches the registered corpus hash, while
sharix_russian_post is identified as sharix-proprietary-v1 only through its
explicit repository binding and matching canonical root LICENSE. A private namespace
alone is never used to invent a license name.
For configured modules the repository hyperlink is the repository recorded in the active installation configuration. The local checkout remote is inspected separately; a mismatch is shown explicitly instead of silently replacing the configured URL. Version and dirty state come from the existing Stage-11 repository inspector. Private checkouts never perform an authenticated background fetch merely to render the page.
Sysadmin owns source/provenance inspection and verification metadata; the public
HTTP page itself belongs to webapp-base at /source/. Canonical upstream is
the normal AGPL source, but a divergent running tree is never represented by an
unrelated upstream link. A matching public fork/ref can be verified and recorded
in conf-real/source-provenance.json with:
python manage.py source_publication status
python manage.py source_publication set-override COMPONENT https://public.example/repo.git REF
python manage.py source_publication clear-override COMPONENT
python manage.py source_publication switch-source COMPONENT https://public.example/repo.git BRANCH
set-override and switch-source require anonymous public HTTPS Git access and
prove source-tree equivalence before mutation. The override file never stores
credentials and is not a replacement for bin/install.cfg; repository movement
remains owned by bin/repositories.sh.
Sysadmin recognizes sharix_service_projects / sharix-service-projects as a canonical private module with sharix-proprietary-v1 license identity. The repository may be advertised by Platform bin/install.cfg.example, but normal Open assemblies do not expose it as an install candidate unless their own install configuration contains SHARIX_SERVICE_PROJECTS. Platform capability resolution treats the canonical repository as Platform-owned and does not call the Service entitlement endpoint.
Private-module installation/repository authorization is centralized in services/proprietary_capabilities.py. UI and lifecycle code use the same resolver; signed offline evidence is accepted only during Platform unavailability, reachable online non-active state remains authoritative, and the owner-Service Git fallback remains an explicit narrow exception. The resolver does not mutate installation configuration or business data when authorization is denied.
services.repository_updates provides the Stage 16.6 update view for all repositories listed by the existing managed-source/install configuration. It does not replace bin/install.cfg, bin/repositories.sh or Stage 16.4 source-publication evidence.
Each row keeps two independent remote targets:
bin/install.cfg.example.The resulting state for each target is one of CURRENT, UPDATE_AVAILABLE, LOCAL_AHEAD, DIVERGED, SOURCE_UNAVAILABLE, PRIVATE_AUTH_REQUIRED or UNKNOWN. Local commit/tree/dirty state and Stage 16.4 publication evidence are shown alongside them.
The Modules page itself does not perform Git network I/O to calculate update state. Use the explicit refresh public Git status action, or the optional repository_update_watch handler. The watcher is a normal handler contribution, is disabled by default and performs anonymous public Git checks only.
CLI equivalents:
./venv/bin/python manage.py repository_updates
./venv/bin/python manage.py repository_updates --refresh-public
./venv/bin/python manage.py repository_updates --json
A private repository that cannot be checked anonymously remains PRIVATE_AUTH_REQUIRED. An administrator may run an explicit one-shot refresh:
./venv/bin/python manage.py repository_updates \
--refresh-private SHARIX_APPOINTMENTS \
--username <gogs-login>
The command requests the password/access token with getpass; the secret is not accepted as a command-line argument and is not persisted. Web Sysadmin uses the same process-local GIT_ASKPASS boundary. Safe results are stored in conf-real/repository-update-status.json; changing the local commit/tree or configured repository/ref invalidates stale remote evidence automatically.
Before changing configuration/admin/first-run/runtime behaviour for the 0.9.1 stabilization track, run the read-only S.1 audit from the assembly root:
./venv/bin/python sharix_sysadmin/bin/audit_stabilization_0_9_1_baseline.py \
--format markdown \
--output /tmp/stabilization-0.9.1-s1.md
The same command is used on Open and Platform. It records exact local Git
commit/branch/tag facts for the root and materialized child repositories, the
existing Stage-19 release/update files, current configuration owners, the
current admin/first-run/profile/module boundaries and a key-only configuration
classification for S.2. It never emits .env values or credentials.
The audit distinguishes four configuration classes instead of treating every
.env.example assignment as a Web setting:
INSTALLED_APPS_LOCAL;SYSTEMD_SERVICE_NAME.A source bundle can establish a historical code baseline, but S.1 factual installation evidence must be produced on the actual target installation so its current SHA/tag/branch/config-symlink facts are not guessed.
bin/check_stabilization_0_9_1_config.py --project-root <assembly-root> is the DB-independent configuration convergence guard. First-run edits Service identity and the same atomic Testing/Production profile used by the post-first-run administrative surface; it does not own a second configuration store.
services.config.read_install_cfg_values() returns only active installation-local assignments. read_install_cfg_example_values() also understands commented # KEY=... declarations so proprietary optional repositories remain discoverable without becoming enabled. Reconciliation preserves that comment state and must never auto-activate such modules.
R92.0 reuses the Sysadmin/source-lifecycle ownership established by the 0.9.1 baseline audit. Run the read-only 0.9.2 audit from each factual 0.9.1 assembly root before product changes:
./venv/bin/python sharix_sysadmin/bin/audit_release_0_9_2_baseline.py \
--format markdown \
--strict \
--output /tmp/release-0.9.2-baseline.md
Add --with-runtime on a running installation when local systemd/module-health
evidence is required. Runtime mode does not pass --live to module providers
and therefore does not intentionally perform external connectivity checks.
The report records only non-secret facts:
The audit never treats another release-builder/rehearsal host as the source of
truth for an installation's optional-module profile. Missing or untagged
historical release evidence is reported as observed and is never fabricated.
Credentials from Git URLs are stripped before report output; .env secret
values are not emitted.
support/request/ remains available to an authenticated user when the module is available, but its upper tab navigation is permission-aware. Each administrative tab is emitted only when the same authorization predicate used by the destination view accepts the current user; the destination view remains the authoritative backend guard. Ordinary support users therefore do not receive links to logs, handlers, backup, module, operations or audit pages they cannot open.
sharix_shortlinks is a public GPLv3 optional shared module discovered through the canonical SHARIX_SHORTLINKS install.cfg key. Sysadmin owns installation/source/license metadata only; redirect, QR and aggregate analytics remain module-owned.
python manage.py installation_diagnostics inventories local/cached source evidence, requirements declarations, env-key ownership/read-sites, CKEditor/rich-field uses and handler Blockly/provenance state. Use --section <name> to narrow the report and --json for machine-readable output.
The command does not refresh Git remotes, read deployment secret values, mutate configuration/business rows or start handlers. Dirty-path classes are diagnostic annotations only; they do not change source/publication compliance state.
python sharix_sysadmin/bin/s92_6_dependency_evidence.py --root . --assembly open|platform validates the assembly constraints, runs pip check and writes credential-blind dependency evidence. The shared validator also ensures constrained versions satisfy every direct declaration found in the assembled source tree and keeps pycares as an assembly-owned transitive resolver constraint.
The handlers page exposes canonical functional states DISABLED, STOPPED,
STARTING, HEALTHY, DEGRADED and FAILED. Classification combines local
runtime configuration, systemd state/restart count and the current handler
runtime-health evidence. XMPP handlers additionally receive one bounded DNS/TCP
probe of their configured endpoint; non-XMPP handlers do not gain an arbitrary
network dependency.
Activate all disabled is an enable-only administration operation. It changes
eligible disabled entries to runtime mode handler and runs systemctl enable,
but never starts or restarts a process. Start/restart remains a separate explicit
operation.
OPERATIONAL_BRANCH remains the canonical branch selector. Commented repository-specific # *_BRANCH=... examples in bin/install.cfg.example are not missing installation-local keys; active overrides are still tracked. This is narrower than the ordinary optional repository-key rule: commented repository URL declarations keep their existing schema/discovery semantics.
Handler health keeps runtime evidence and XMPP session evidence separate from systemd active. The live S92.8/S92.10 diagnostics distinguish an unreachable/unconfigured XMPP endpoint from a reachable DNS/TCP endpoint whose handler did not establish an authenticated session, without printing credential values. Systemd namespace repair is an explicit root-installer action, not a Sysadmin render-time side effect.
NRestarts is a cumulative systemd counter, not a count for the last heartbeat
interval. It stays visible in the existing handlers table and is never reset by
Sysadmin. The restart_loop_evidence threshold remains 3; recovery is a
separate, conservative classifier branch, not a raised threshold.
After at least 600 seconds (10 minutes) in the same error-free process,
previous systemd restarts alone need not force DEGRADED. The classifier requires
all of the following in addition to the usual fresh-heartbeat/bootstrap checks:
active/running, and its nonzero MainPID matches the health JSON;ExecMainStartTimestampMonotonic proves at least 600 seconds of process age;started_at agrees with that process age within the existing 120-second
heartbeat freshness limit; both clocks show at least 600 seconds;last_success_at may mean authenticated XMPP connection; it is
not proof of completed domain/report work.The returned state is then HEALTHY with reason
functional_evidence_current_with_restart_history and the untouched count in
historical_systemd_restarts. The table continues to show the real NRestarts.
A new process restarts the recovery interval automatically. Missing/invalid
monotonic time or ambiguous process evidence keeps the old conservative result;
there is no fallback to PID-only health. Current-process internal restart/error
history is intentionally not aged out by this change.
Inspection never calls reset-failed, restarts a process, removes a health file,
creates a DB/table, or writes a diagnostic checkpoint. Old restart causes still
require their own historical journal investigation. The normal classifier is
pure Python and can be exercised without Django or a test database:
python3 -m unittest sharix_sysadmin.tests.test_handler_health -v
Publish this shared repository on Open first; other installations receive it
through repositories.sh pull --shared --repo sharix_sysadmin. Fresh CLI checks
load the new classifier immediately, without restarting any handler. A normal
web-worker reload/restart is needed only to update an already running Sysadmin
web process. No migration, runtime schema change or collectstatic is required;
compile the changed module RU/EN catalogs before publication.