feat(update): mode container -> menu Update tampil dgn pesan rebuild image (bukan disembunyikan)

This commit is contained in:
oxpoe committed 2026-10-13 04:00:25 +07:00
1 parent fed81ed5f9
commit d02c9baf7b
3 files changed
+21 -6

No files matched your search

+1 -5
View File
@@ -546,9 +546,7 @@ function forceUnlockCoreMenus() {
let states = rowStates ? JSON.parse(rowStates.value) : {}; let states = rowStates ? JSON.parse(rowStates.value) : {};
let keys = rowKeys ? JSON.parse(rowKeys.value) : {}; let keys = rowKeys ? JSON.parse(rowKeys.value) : {};
const hasGit = fs.existsSync(path.join(__dirname, '..', '.git')); const coreMenus = ['mikrotik', 'radius_server', 'whatsapp', 'broadcast', 'update', 'settings', 'backup', 'monitoring', 'audit_logs'];
const coreMenus = ['mikrotik', 'radius_server', 'whatsapp', 'broadcast', 'settings', 'backup', 'monitoring', 'audit_logs'];
if (hasGit) coreMenus.push('update');
const passwordHash = 'af03458614be223016c5bc1c0788eaefc6a6bfd0c11cdcd4bc520f49d0cb474a'; // hash kode aktivasi default — plaintext hanya di settings.json (activation_code) const passwordHash = 'af03458614be223016c5bc1c0788eaefc6a6bfd0c11cdcd4bc520f49d0cb474a'; // hash kode aktivasi default — plaintext hanya di settings.json (activation_code)
const crypto = require('crypto'); const crypto = require('crypto');
@@ -571,8 +569,6 @@ function forceUnlockCoreMenus() {
} }
} }
if (!hasGit && states['update'] !== 'hidden') { states['update'] = 'hidden'; changed = true; }
if (changed) { if (changed) {
const now = new Date().toISOString(); const now = new Date().toISOString();
db.prepare('INSERT OR REPLACE INTO app_settings (key, value, updated_at) VALUES (?, ?, ?)').run(SETTINGS_KEY, JSON.stringify(states), now); db.prepare('INSERT OR REPLACE INTO app_settings (key, value, updated_at) VALUES (?, ?, ?)').run(SETTINGS_KEY, JSON.stringify(states), now);
+7 -1
View File
@@ -384,7 +384,9 @@ function getUpdateInfo(repoRoot) {
const inside = runCmd('git', ['rev-parse', '--is-inside-work-tree'], repoRoot); const inside = runCmd('git', ['rev-parse', '--is-inside-work-tree'], repoRoot);
if (!inside.ok) { if (!inside.ok) {
info.error = 'Folder ini belum menjadi git repository.'; // Tanpa .git (Docker/container): update dilakukan via rebuild image (bukan git)
info.container = true;
info.containerMessage = 'Instalasi ini berjalan sebagai kontainer/gambar (tanpa .git). Pembaruan dilakukan dengan membangun ulang image dari repo terbaru.';
return info; return info;
} }
@@ -4554,6 +4556,10 @@ router.get('/update', requireAdminSession, requireSidebarMenuAccess('update'), r
router.post('/update/run', requireAdminSession, restrictToAdmin, (req, res) => { router.post('/update/run', requireAdminSession, restrictToAdmin, (req, res) => {
const repoRoot = path.resolve(__dirname, '..'); const repoRoot = path.resolve(__dirname, '..');
if (!runCmd('git', ['rev-parse', '--is-inside-work-tree'], repoRoot).ok) {
req.session._msg = { type: 'error', text: 'Instalasi kontainer (tanpa .git): pembaruan dilakukan dengan rebuild image, bukan lewat git.' };
return res.redirect('/admin/update');
}
const log = []; const log = [];
const pushCmd = (label, r) => { const pushCmd = (label, r) => {
log.push(`$ ${label}`.trim()); log.push(`$ ${label}`.trim());
+13
View File
@@ -29,6 +29,17 @@
<% if (info && info.error) { %> <% if (info && info.error) { %>
<div class="alert alert-d"><i class="bi bi-exclamation-circle"></i> <%= info.error %></div> <div class="alert alert-d"><i class="bi bi-exclamation-circle"></i> <%= info.error %></div>
<% } %> <% } %>
<% if (info && info.container) { %>
<div class="alert" style="background:rgba(59,130,246,.08);border:1px solid rgba(59,130,246,.3);border-radius:10px;padding:12px 14px;font-size:13px;line-height:1.55">
<b><i class="bi bi-box-seam"></i> <%= t('admin.update.container_title', 'Instalasi Container (tanpa .git)') %></b><br>
<%= t('admin.update.container_msg', 'Pembaruan TIDAK lewat git. Bangun ulang image dari repo terbaru lalu ganti container:') %>
<div style="margin-top:8px;font-family:monospace;font-size:12px;background:rgba(0,0,0,.25);padding:8px 10px;border-radius:8px">
docker compose build &amp;&amp; docker compose up -d<br>
# atau: build image baru, lalu ganti tag/container
</div>
<%= t('admin.update.container_safe', 'Data (settings.json, database, uploads) tetap aman bila disimpan di volume/mount.') %>
</div>
<% } %>
<div class="form-row" style="align-items:flex-start"> <div class="form-row" style="align-items:flex-start">
<div class="fg"> <div class="fg">
<label class="fl"><%= t('admin.update.server_version', 'Versi Server (version.txt)') %></label> <label class="fl"><%= t('admin.update.server_version', 'Versi Server (version.txt)') %></label>
@@ -51,6 +62,7 @@
</div> </div>
</div> </div>
<% if (!(info && info.container)) { %>
<div style="display:flex;gap:10px;flex-wrap:wrap;margin-top:12px"> <div style="display:flex;gap:10px;flex-wrap:wrap;margin-top:12px">
<form method="GET" action="/admin/update"> <form method="GET" action="/admin/update">
<button type="submit" class="btn btn-g"><i class="bi bi-arrow-repeat"></i> <%= t('admin.update.check', 'Cek Versi') %></button> <button type="submit" class="btn btn-g"><i class="bi bi-arrow-repeat"></i> <%= t('admin.update.check', 'Cek Versi') %></button>
@@ -63,6 +75,7 @@
<div style="margin-top:12px;color:var(--muted);font-size:12px;line-height:1.5"> <div style="margin-top:12px;color:var(--muted);font-size:12px;line-height:1.5">
<%= t('admin.update.keep_files', 'File yang tidak ditimpa saat update: settings.json dan folder database. Setelah update selesai, restart aplikasi agar versi baru aktif.') %> <%= t('admin.update.keep_files', 'File yang tidak ditimpa saat update: settings.json dan folder database. Setelah update selesai, restart aplikasi agar versi baru aktif.') %>
</div> </div>
<% } %>
</div> </div>
</div> </div>