1
0
mirror of git://f0xx.org/android_cast synced 2026-07-29 03:57:50 +03:00
This commit is contained in:
Anton Afanasyeu
2026-06-10 16:55:21 +02:00
parent 9dfe9a6c1c
commit 603aaa0055
16 changed files with 619 additions and 27 deletions

View File

@@ -182,7 +182,7 @@ Mounted copy: `tmp/FE_gentoo/etc/nginx/nginx.conf`.
| `server_name` | `location /` | androidcast crashes | Hub `/app/androidcast_project/` |
|---------------|--------------|---------------------|--------------------------------|
| **`apps.f0xx.org`** | → `http://artc0:80` | Must **not**`https://artc0:443/...` (static download) | Hub/crashes blocks must use **`http://artc0:80`** — see `nginx.fe-apps.f0xx.org.snippet` |
| **`/v0/ota/`** on FE | → **`http://artc0:80`** | BE :80 serves static tree | Without this, public OTA is **HTTP 400** while BE localhost is 200 — run `install-fe-ota-nginx.sh` on FE |
| **`/v0/ota/`** on FE | → **`http://artc0:80`** | BE :80 serves static tree | In consolidated **`/etc/nginx/apps.conf`** — see `patches/fe-nginx-APPLY.md` |
| **`artc0.f0xx.org`** | → `http://artc0:80` | Legacy → **:8089** | Legacy → **:8089** — **remove** hub block; prefer apps.f0xx.org |
**Agent default:** fix **BE `listen 80`** first. Change FE only when user asks or to delete wrong **8089** hub overrides on `artc0.f0xx.org`.

View File

@@ -8,7 +8,9 @@
"nav.culture": "Culture",
"nav.pricing": "Pricing",
"nav.contact": "Contact us",
"nav.console": "Console",
"nav.git": "Git",
"nav.issues": "Issues",
"nav.tickets": "Tickets",
"nav.crashes": "Crashes",
"nav.graphs": "Graphs",

View File

@@ -8,7 +8,9 @@
"nav.culture": "Культура",
"nav.pricing": "Цены",
"nav.contact": "Контакты",
"nav.console": "Консоль",
"nav.git": "Git",
"nav.issues": "Проблемы",
"nav.tickets": "Тикеты",
"nav.crashes": "Крэши",
"nav.graphs": "Графики",

View File

@@ -137,11 +137,12 @@ function hub_h(string $s): string {
<span class="nav-icon nav-icon--menu" aria-hidden="true"></span>
</button>
<ul class="nav-list">
<li><a href="crashes/?view=home" class="nav-link"><span class="nav-icon nav-icon--home"></span><span class="nav-label" data-i18n="nav.console">Console</span></a></li>
<li><a href="git/" class="nav-link"><span class="nav-icon nav-icon--git"></span><span class="nav-label" data-i18n="nav.git">Git</span></a></li>
<li><a href="crashes/?view=reports" class="nav-link"><span class="nav-icon nav-icon--reports"></span><span class="nav-label" data-i18n="nav.issues">Issues</span></a></li>
<li><a href="crashes/?view=tickets" class="nav-link"><span class="nav-icon nav-icon--tickets"></span><span class="nav-label" data-i18n="nav.tickets">Tickets</span></a></li>
<li><a href="crashes/?view=reports" class="nav-link"><span class="nav-icon nav-icon--reports"></span><span class="nav-label" data-i18n="nav.crashes">Crashes</span></a></li>
<li><a href="graphs/" class="nav-link"><span class="nav-icon nav-icon--graphs"></span><span class="nav-label" data-i18n="nav.graphs">Graphs</span></a></li>
<li><a href="crashes/?view=remote_access" class="nav-link"><span class="nav-icon nav-icon--reports"></span><span class="nav-label" data-i18n="nav.remote">Remote access</span></a></li>
<li><a href="crashes/?view=remote_access" class="nav-link"><span class="nav-icon nav-icon--remote"></span><span class="nav-label" data-i18n="nav.remote">Remote access</span></a></li>
<li><a href="build/" class="nav-link"><span class="nav-icon nav-icon--builder"></span><span class="nav-label" data-i18n="nav.builder">Builder</span></a></li>
</ul>
<div class="nav-user">

View File

@@ -1,21 +1,3 @@
# FE apps.f0xx.org — include from nginx.conf server block.
# Build must use the same upstream style as hub/crashes (BE :443), not :80.
# Redirect without trailing slash
location = /app/androidcast_project/build {
return 301 $scheme://$host/app/androidcast_project/build/;
}
location /app/androidcast_project/build/ {
proxy_pass https://artc0.intra.raptor.org/app/androidcast_project/build/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
client_max_body_size 512m;
}
# DEPRECATED — use nginx/fe/apps.conf (full apps.f0xx.org vhost).
# nginx.conf should contain only: include /etc/nginx/apps.conf;
# See patches/fe-nginx-APPLY.md and scripts/generate-fe-nginx-patch.sh

View File

@@ -0,0 +1,137 @@
# apps.f0xx.org — Android Cast public vhost (FE Gentoo).
# Included from nginx.conf: include /etc/nginx/apps.conf;
#
# Upstream: BE nginx on artc0.intra.raptor.org:80 (hub PHP, crashes, graphs, build, OTA).
# Git browser: BE :3000 (Gitea). Do not proxy androidcast to BE :443 or :8089.
#
# Reload: nginx -t && rc-service nginx reload
server {
listen 80;
server_name apps.f0xx.org;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name apps.f0xx.org;
access_log /var/log/nginx/apps.intra.raptor.org.access_log main;
error_log /var/log/nginx/apps.intra.raptor.org.error_log info;
ssl_certificate /etc/letsencrypt/live/apps.f0xx.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/apps.f0xx.org/privkey.pem;
# --- OTA artifacts (BE static tree on listen 80) ---
location ^~ /v0/ota/ {
proxy_pass http://artc0.intra.raptor.org:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# --- APK builder (long-running Docker builds) ---
location = /app/androidcast_project/build {
return 301 $scheme://$host/app/androidcast_project/build/;
}
location ^~ /app/androidcast_project/build/ {
proxy_pass http://artc0.intra.raptor.org:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
client_max_body_size 512m;
}
# --- Crash / ticket console ---
location = /app/androidcast_project/crashes {
return 301 $scheme://$host/app/androidcast_project/crashes/;
}
location ^~ /app/androidcast_project/crashes/ {
proxy_pass http://artc0.intra.raptor.org:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 16m;
}
# --- Graphs dashboard ---
location = /app/androidcast_project/graphs {
return 301 $scheme://$host/app/androidcast_project/graphs/;
}
location ^~ /app/androidcast_project/graphs/ {
proxy_pass http://artc0.intra.raptor.org:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# --- Hub landing (PHP index) ---
location = /app/androidcast_project {
return 301 $scheme://$host/app/androidcast_project/;
}
location ^~ /app/androidcast_project/ {
proxy_pass http://artc0.intra.raptor.org:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# --- Gitea web UI ---
location = /app/androidcast_project/git {
return 301 $scheme://$host/app/androidcast_project/git/;
}
location ^~ /app/androidcast_project/git/ {
proxy_pass http://artc0.intra.raptor.org:3000/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
client_max_body_size 512m;
}
# --- Default: anything else on this vhost → BE :80 ---
location / {
proxy_pass http://artc0.intra.raptor.org:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 180s;
proxy_buffers 16 16m;
proxy_buffer_size 16m;
client_body_buffer_size 16m;
client_max_body_size 16m;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache_bypass $http_upgrade;
}
location ~ /\.ht {
deny all;
}
}

View File

@@ -0,0 +1,42 @@
# FE nginx consolidation — review & apply
## What changes
- **`/etc/nginx/apps.conf`** becomes the full `apps.f0xx.org` vhost (HTTP redirect + HTTPS server + all Android Cast locations).
- **`/etc/nginx/nginx.conf`** drops inline `apps.f0xx.org` server blocks; adds one `include /etc/nginx/apps.conf;` at `http` level.
## New / consolidated paths in apps.conf
| Path | Upstream |
|------|----------|
| `/v0/ota/` | BE :80 (OTA) |
| `/app/androidcast_project/build/` | BE :80 |
| `/app/androidcast_project/crashes/` | BE :80 |
| `/app/androidcast_project/graphs/` | BE :80 (explicit) |
| `/app/androidcast_project/` | BE :80 (hub) |
| `/app/androidcast_project/git/` | BE :3000 (Gitea) |
| `/` (default) | BE :80 |
Canonical template: `examples/crash_reporter/backend/nginx/fe/apps.conf`
## Apply (on f0xx-monstro)
```bash
cd /etc/nginx
cp -a apps.conf "apps.conf.bak.$(date +%Y%m%d)"
cp -a nginx.conf "nginx.conf.bak.$(date +%Y%m%d)"
# copy template from repo sync, or patch:
# patch -p1 < .../fe-nginx-apps-consolidation.patch
cp /path/to/android_cast/examples/crash_reporter/backend/nginx/fe/apps.conf apps.conf
# edit nginx.conf: replace apps.f0xx.org server {…} blocks with:
# include /etc/nginx/apps.conf;
nginx -t && rc-service nginx reload
```
## Verify
```bash
curl -sS -o /dev/null -w 'hub %{http_code}\n' https://apps.f0xx.org/app/androidcast_project/
curl -sS -o /dev/null -w 'ota %{http_code}\n' https://apps.f0xx.org/v0/ota/channel/stable.json
curl -sS -o /dev/null -w 'build %{http_code}\n' https://apps.f0xx.org/app/androidcast_project/build/
```

View File

@@ -0,0 +1,271 @@
--- a/etc/nginx/apps.conf 2026-06-10 14:42:23.706574376 +0200
+++ b/etc/nginx/apps.conf 2026-06-10 14:42:23.714746551 +0200
@@ -1,23 +1,137 @@
-# location /app/androidcast_project/build/ {
-# proxy_pass https://artc0.intra.raptor.org/app/androidcast_project/build/;
-# }
-
- # Redirect without trailing slash
- location = /app/androidcast_project/build {
- return 301 $scheme://$host/app/androidcast_project/build/;
- }
- location /app/androidcast_project/build/ {
- proxy_pass http://artc0.intra.raptor.org:80;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $connection_upgrade;
- proxy_read_timeout 1800s;
- proxy_send_timeout 1800s;
- client_max_body_size 512m;
- }
+# apps.f0xx.org — Android Cast public vhost (FE Gentoo).
+# Included from nginx.conf: include /etc/nginx/apps.conf;
+#
+# Upstream: BE nginx on artc0.intra.raptor.org:80 (hub PHP, crashes, graphs, build, OTA).
+# Git browser: BE :3000 (Gitea). Do not proxy androidcast to BE :443 or :8089.
+#
+# Reload: nginx -t && rc-service nginx reload
+server {
+ listen 80;
+ server_name apps.f0xx.org;
+ return 301 https://$host$request_uri;
+}
+
+server {
+ listen 443 ssl http2;
+ server_name apps.f0xx.org;
+
+ access_log /var/log/nginx/apps.intra.raptor.org.access_log main;
+ error_log /var/log/nginx/apps.intra.raptor.org.error_log info;
+
+ ssl_certificate /etc/letsencrypt/live/apps.f0xx.org/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/apps.f0xx.org/privkey.pem;
+
+ # --- OTA artifacts (BE static tree on listen 80) ---
+ location ^~ /v0/ota/ {
+ proxy_pass http://artc0.intra.raptor.org:80;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+ # --- APK builder (long-running Docker builds) ---
+ location = /app/androidcast_project/build {
+ return 301 $scheme://$host/app/androidcast_project/build/;
+ }
+ location ^~ /app/androidcast_project/build/ {
+ proxy_pass http://artc0.intra.raptor.org:80;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ proxy_read_timeout 1800s;
+ proxy_send_timeout 1800s;
+ client_max_body_size 512m;
+ }
+
+ # --- Crash / ticket console ---
+ location = /app/androidcast_project/crashes {
+ return 301 $scheme://$host/app/androidcast_project/crashes/;
+ }
+ location ^~ /app/androidcast_project/crashes/ {
+ proxy_pass http://artc0.intra.raptor.org:80;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ client_max_body_size 16m;
+ }
+
+ # --- Graphs dashboard ---
+ location = /app/androidcast_project/graphs {
+ return 301 $scheme://$host/app/androidcast_project/graphs/;
+ }
+ location ^~ /app/androidcast_project/graphs/ {
+ proxy_pass http://artc0.intra.raptor.org:80;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+ # --- Hub landing (PHP index) ---
+ location = /app/androidcast_project {
+ return 301 $scheme://$host/app/androidcast_project/;
+ }
+ location ^~ /app/androidcast_project/ {
+ proxy_pass http://artc0.intra.raptor.org:80;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+ # --- Gitea web UI ---
+ location = /app/androidcast_project/git {
+ return 301 $scheme://$host/app/androidcast_project/git/;
+ }
+ location ^~ /app/androidcast_project/git/ {
+ proxy_pass http://artc0.intra.raptor.org:3000/;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ proxy_read_timeout 1800s;
+ proxy_send_timeout 1800s;
+ client_max_body_size 512m;
+ }
+
+ # --- Default: anything else on this vhost → BE :80 ---
+ location / {
+ proxy_pass http://artc0.intra.raptor.org:80;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_connect_timeout 120s;
+ proxy_send_timeout 120s;
+ proxy_read_timeout 180s;
+ proxy_buffers 16 16m;
+ proxy_buffer_size 16m;
+ client_body_buffer_size 16m;
+ client_max_body_size 16m;
+ proxy_buffering off;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ proxy_cache_bypass $http_upgrade;
+ }
+
+ location ~ /\.ht {
+ deny all;
+ }
+}
--- a/etc/nginx/nginx.conf 2026-06-10 14:42:23.656573680 +0200
+++ b/etc/nginx/nginx.conf 2026-06-10 14:42:23.745801792 +0200
@@ -918,104 +918,8 @@
## -------------------------------------------------------------------------------
+## apps.f0xx.org — Android Cast (hub, crashes, graphs, build, OTA, git)
+ include /etc/nginx/apps.conf;
- server {
- listen 80;
- server_name apps.f0xx.org;
- location / {
- rewrite ^(.*)$ https://apps.f0xx.org$1 permanent;
- }
- # redirects both www and non-www to https
- return 301 https://apps.f0xx.org$request_uri;
- }
- server {
- listen 443 ssl http2;
- server_name apps.f0xx.org;
-
- access_log /var/log/nginx/apps.intra.raptor.org.access_log main;
- error_log /var/log/nginx/apps.intra.raptor.org.error_log info;
-
- ssl_certificate /etc/letsencrypt/live/apps.f0xx.org/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/apps.f0xx.org/privkey.pem;
-
- location / {
- proxy_pass http://artc0.intra.raptor.org:80;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_connect_timeout 120;
- proxy_send_timeout 120;
- proxy_read_timeout 180;
- proxy_buffers 16 16M;
- proxy_buffer_size 16M;
- client_body_buffer_size 16M;
- client_max_body_size 16M;
- proxy_buffering off;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection keep-alive;
- proxy_set_header Host $host;
- proxy_cache_bypass $http_upgrade;
- proxy_set_header Connection "upgrade";
- }
-
- #location /app/androidcast_project/ {
- # proxy_pass https://artc0.intra.raptor.org/app/androidcast_project/;
- #}
-#
-# location /app/androidcast_project/crashes/ {
-# proxy_pass https://artc0.intra.raptor.org/app/androidcast_project/crashes/;
-# }
-#
-
- location /app/androidcast_project/ {
- proxy_pass http://artc0.intra.raptor.org:80;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
-
- location /app/androidcast_project/crashes/ {
- proxy_pass http://artc0.intra.raptor.org:80;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
-
- include /etc/nginx/apps.conf;
-
- location ~ /\.ht {
- deny all;
- }
-
- root /var/www/localhost/htdocs/android_cast/project/android_cast/examples/crash_reporter/backend/public/;
- index index.php;
-
-
-## gitea redirection
-# Redirect without trailing slash
- location = /app/androidcast_project/git {
- return 301 $scheme://$host/app/androidcast_project/git/;
- }
- location /app/androidcast_project/git/ {
- proxy_pass http://artc0.intra.raptor.org:3000/;
- proxy_http_version 1.1;
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-Host $host;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $connection_upgrade;
- proxy_read_timeout 1800s;
- proxy_send_timeout 1800s;
- client_max_body_size 512m;
- }
-
- }
}

View File

@@ -1762,6 +1762,19 @@ button.report-tag--filter:hover {
align-items: center;
gap: 8px;
}
.graphs-session-notice {
margin: 0 0 12px;
padding: 10px 14px;
border-radius: 8px;
border: 1px solid rgba(245, 158, 11, 0.45);
background: rgba(245, 158, 11, 0.12);
color: var(--text);
font-size: 0.9rem;
line-height: 1.45;
}
.graphs-session-notice[hidden] {
display: none;
}
.graph-brick-drag-handle {
flex-shrink: 0;
display: inline-flex;

View File

@@ -16,6 +16,7 @@
"home.card_issues": "Issues",
"home.card_issues_desc": "Browse and triage crash reports, tags, and fingerprints.",
"home.card_new_issue_desc": "Log a new issue or task in one step.",
"home.card_new_ticket_desc": "Create a roadmap or QA ticket in one step.",
"home.card_tickets_desc": "Roadmap tasks, QA items, and workflow tags.",
"home.card_graphs": "Graphs",
"home.card_graphs_desc": "Sessions, crashes, and device activity over time.",
@@ -63,6 +64,7 @@
"col.drag": "Drag column",
"col.drag_reorder": "Drag column to reorder",
"graphs.brick_drag": "Drag chart to reorder",
"graphs.session_deficit": "Session charts are empty. On the device: Developer settings → enable “Grab session stats”, cast a session, then wait for upload to graph_upload.php.",
"row.show_summary": "Show summary",
"row.open_report": "Click to open full report",
"row.edit_tags": "Edit tags",

View File

@@ -26,6 +26,7 @@
"home.card_issues": "Проблемы",
"home.card_issues_desc": "Просмотр и разбор отчётов о сбоях, тегов и отпечатков.",
"home.card_new_issue_desc": "Создать новую проблему или задачу.",
"home.card_new_ticket_desc": "Создать тикет roadmap или QA за один шаг.",
"home.card_tickets_desc": "Задачи, QA и теги workflow.",
"home.card_graphs": "Графики",
"home.card_graphs_desc": "Сессии, сбои и активность устройств.",
@@ -73,6 +74,7 @@
"col.drag": "Перетащить столбец",
"col.drag_reorder": "Перетащите для смены порядка столбцов",
"graphs.brick_drag": "Перетащите график для смены порядка",
"graphs.session_deficit": "Графики сессий пусты. На устройстве: Настройки разработчика → «Grab session stats», проведите сессию трансляции и дождитесь загрузки в graph_upload.php.",
"row.show_summary": "Показать сводку",
"row.open_report": "Нажмите, чтобы открыть полный отчёт",
"row.edit_tags": "Редактировать метки",

View File

@@ -1025,9 +1025,10 @@
let statusText = 'Loaded · viewer=' + viewer + ' · window=' + days + 'd · columns=' + cols;
const visibleScope =
viewer === 'platform_admin' ? graphScopes.platform : viewer === 'slug_admin' ? graphScopes.slug : graphScopes.user;
if (sessionMetricsDeficit(visibleScope)) {
statusText +=
' · Session metrics empty — cast with Developer “Grab session stats” on; app uploads graph_session to graph_upload.php';
const deficitNotice = el('graphs-session-notice');
const deficit = sessionMetricsDeficit(visibleScope);
if (deficitNotice) {
deficitNotice.hidden = !deficit;
}
status.textContent = statusText;
openGraphFromPermalink();

View File

@@ -0,0 +1,128 @@
#!/usr/bin/env bash
# Build fe-nginx-apps-consolidation.patch from repo template vs tmp/FE_gentoo mirror.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/../../../.." && pwd)"
FE_MIRROR="${FE_MIRROR:-$REPO_ROOT/tmp/FE_gentoo/etc/nginx}"
TEMPLATE="$REPO_ROOT/examples/crash_reporter/backend/nginx/fe/apps.conf"
PATCH_OUT="$REPO_ROOT/examples/crash_reporter/backend/patches/fe-nginx-apps-consolidation.patch"
if [[ ! -f "$FE_MIRROR/nginx.conf" || ! -f "$FE_MIRROR/apps.conf" ]]; then
echo "Missing FE mirror at $FE_MIRROR (sshfs tmp/FE_gentoo)" >&2
exit 1
fi
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
cp "$FE_MIRROR/nginx.conf" "$WORK/nginx.conf.orig"
cp "$FE_MIRROR/apps.conf" "$WORK/apps.conf.orig"
cp "$TEMPLATE" "$WORK/apps.conf.new"
python3 - "$WORK/nginx.conf.orig" "$WORK/nginx.conf.new" << 'PY'
import sys
from pathlib import Path
src, dst = map(Path, sys.argv[1:3])
lines = src.read_text().splitlines(keepends=True)
start = None
for i, line in enumerate(lines):
if line.strip() == "## -------------------------------------------------------------------------------":
# Next non-empty should be server { listen 80 apps.f0xx.org
for j in range(i + 1, min(i + 5, len(lines))):
if "server_name apps.f0xx.org" in lines[j] or (
j + 1 < len(lines) and "server_name apps.f0xx.org" in lines[j + 1]
):
start = i
break
if start is not None:
break
if start is None:
raise SystemExit("Could not find apps.f0xx.org section start in nginx.conf")
# End at closing brace of 443 server: line that is only `\t}` or ` }` before blank line and http `}`
end = None
for i in range(len(lines) - 1, start, -1):
if lines[i].strip() == "}":
# http block ends with `}\n` then EOF; 443 server closes with `}\n` then `\n` then `}`
if i + 1 < len(lines) and lines[i + 1].strip() == "":
if i + 2 < len(lines) and lines[i + 2].strip() == "}":
end = i
break
if end is None:
raise SystemExit("Could not find apps.f0xx.org section end in nginx.conf")
replacement = (
"## -------------------------------------------------------------------------------\n"
"## apps.f0xx.org — Android Cast (hub, crashes, graphs, build, OTA, git)\n"
"\tinclude /etc/nginx/apps.conf;\n"
"\n"
)
new_lines = lines[:start] + [replacement] + lines[end + 1 :]
dst.write_text("".join(new_lines))
print(f"nginx.conf: replaced lines {start + 1}{end + 1} with include")
PY
mkdir -p "$(dirname "$PATCH_OUT")"
(
cd "$WORK"
diff -u apps.conf.orig apps.conf.new || true
diff -u nginx.conf.orig nginx.conf.new || true
) > "$PATCH_OUT" || true
# Fix patch headers to use etc/nginx/ paths for clarity
sed -i 's|--- .*apps.conf.orig|--- a/etc/nginx/apps.conf|' "$PATCH_OUT"
sed -i 's|+++ .*apps.conf.new|+++ b/etc/nginx/apps.conf|' "$PATCH_OUT"
sed -i 's|--- .*nginx.conf.orig|--- a/etc/nginx/nginx.conf|' "$PATCH_OUT"
sed -i 's|+++ .*nginx.conf.new|+++ b/etc/nginx/nginx.conf|' "$PATCH_OUT"
cat > "$REPO_ROOT/examples/crash_reporter/backend/patches/fe-nginx-APPLY.md" << EOF
# FE nginx consolidation — review & apply
## What changes
- **\`/etc/nginx/apps.conf\`** becomes the full \`apps.f0xx.org\` vhost (HTTP redirect + HTTPS server + all Android Cast locations).
- **\`/etc/nginx/nginx.conf\`** drops inline \`apps.f0xx.org\` server blocks; adds one \`include /etc/nginx/apps.conf;\` at \`http\` level.
## New / consolidated paths in apps.conf
| Path | Upstream |
|------|----------|
| \`/v0/ota/\` | BE :80 (OTA) |
| \`/app/androidcast_project/build/\` | BE :80 |
| \`/app/androidcast_project/crashes/\` | BE :80 |
| \`/app/androidcast_project/graphs/\` | BE :80 (explicit) |
| \`/app/androidcast_project/\` | BE :80 (hub) |
| \`/app/androidcast_project/git/\` | BE :3000 (Gitea) |
| \`/\` (default) | BE :80 |
Canonical template: \`examples/crash_reporter/backend/nginx/fe/apps.conf\`
## Apply (on f0xx-monstro)
\`\`\`bash
cd /etc/nginx
cp -a apps.conf "apps.conf.bak.\$(date +%Y%m%d)"
cp -a nginx.conf "nginx.conf.bak.\$(date +%Y%m%d)"
# copy template from repo sync, or patch:
# patch -p1 < .../fe-nginx-apps-consolidation.patch
cp /path/to/android_cast/examples/crash_reporter/backend/nginx/fe/apps.conf apps.conf
# edit nginx.conf: replace apps.f0xx.org server {…} blocks with:
# include /etc/nginx/apps.conf;
nginx -t && rc-service nginx reload
\`\`\`
## Verify
\`\`\`bash
curl -sS -o /dev/null -w 'hub %{http_code}\\n' https://apps.f0xx.org/app/androidcast_project/
curl -sS -o /dev/null -w 'ota %{http_code}\\n' https://apps.f0xx.org/v0/ota/channel/stable.json
curl -sS -o /dev/null -w 'build %{http_code}\\n' https://apps.f0xx.org/app/androidcast_project/build/
\`\`\`
EOF
echo "Wrote $PATCH_OUT"
echo "Wrote $REPO_ROOT/examples/crash_reporter/backend/patches/fe-nginx-APPLY.md"

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env bash
# Run on Gentoo FE as root — proxy /v0/ota/ to BE listen 80 (static OTA tree).
# Superseded by consolidated apps.conf (nginx/fe/apps.conf + fe-nginx-apps-consolidation.patch).
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "$0")/../../../.." && pwd)"

View File

@@ -313,6 +313,9 @@
</div>
</div>
<?php require __DIR__ . '/partials/console_quick_links.php'; ?>
<p id="graphs-session-notice" class="graphs-session-notice" role="status" hidden data-i18n="graphs.session_deficit">
Session charts are empty. On the device: Developer settings → enable “Grab session stats”, cast a session, then wait for upload to graph_upload.php.
</p>
<p id="graphs-status" class="reports-status muted" aria-live="polite">Loading…</p>
<section class="graphs-scope" data-graph-scope="user">

View File

@@ -34,6 +34,11 @@ $proj = '/app/androidcast_project';
<h2 data-i18n="nav.tickets">Tickets</h2>
<p class="muted" data-i18n="home.card_tickets_desc">Roadmap tasks, QA items, and workflow tags.</p>
</a>
<button type="button" class="card card--lift console-home-card console-home-card--btn js-new-ticket-btn">
<span class="nav-icon nav-icon--tickets" aria-hidden="true"></span>
<h2 data-i18n="tickets.new">New ticket</h2>
<p class="muted" data-i18n="home.card_new_ticket_desc">Create a roadmap or QA ticket in one step.</p>
</button>
<a href="<?= h($proj) ?>/graphs/" class="card card--lift console-home-card">
<span class="nav-icon nav-icon--graphs" aria-hidden="true"></span>
<h2 data-i18n="home.card_graphs">Graphs</h2>