ИШ обновляется через сервер лицензий вместе с bj; наглядный ход установки ИШ
- Дистрибутив ИШ — компонент выпуска igate-dist (версия = версия ИШ). В выпуск попадает только одобренный архив: deploy/release/igate-approved (версия и sha256), сборка сверяет контрольную сумму. Клиент получает его обновлением; bj-server после обновления (и при запуске) сам обновляет ИШ, если на сервере он старее; итог — событие в «Новостях». Настройки, каналы и база ИШ сохраняются, прежняя версия — в /var/backups. - Установка «с сервера» берёт самый новый проверенный дистрибутив: с образа или из обновления. С сайта НРД — только в режиме разработки. - Большие файлы: одна прежняя копия вместо пяти; предел скачивания — по размеру. - Ход установки ИШ — этапами: пройденные, текущий («идёт 0:41 · обычно до 1:30», дольше обычного — предупреждение), журнал под раскрытием; кнопка на время установки выключена. - Установщик: уникальные этапы; igate-cli и сессия ключницы с принудительным завершением (timeout -k); зависшая установка (ход не менялся 15 минут) снимается повторным запуском; служба установки — не дольше 40 минут. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
@@ -8,6 +8,19 @@
|
||||
#ig-ct td{vertical-align:top;padding:6px 8px 6px 0}
|
||||
#ig-box .btn.sm{padding:4px 10px;font-size:12.5px}
|
||||
#ig-box .btn.ghost{background:var(--card);color:var(--text);border:1px solid var(--border-strong,#c9cdd8)}
|
||||
/* ход установки ИШ: этапы по порядку, у текущего — сколько идёт и сколько обычно */
|
||||
.ig-steps{list-style:none;margin:10px 0 0;padding:10px 14px;border:1px solid var(--border);border-radius:10px;display:grid;gap:2px}
|
||||
.ig-steps li{display:flex;gap:10px;align-items:flex-start;padding:4px 0;font-size:13.5px;color:var(--muted)}
|
||||
.ig-steps li.done{color:var(--text-2)} .ig-steps li.cur{color:var(--text);font-weight:500} .ig-steps li.err{color:var(--err)}
|
||||
.ig-ic{flex:none;position:relative;width:16px;height:16px;border-radius:50%;margin-top:2px;box-sizing:border-box;border:1.5px solid var(--border-strong)}
|
||||
.ig-steps li.done .ig-ic{background:var(--ok);border-color:var(--ok)}
|
||||
.ig-steps li.done .ig-ic::after{content:"";position:absolute;left:50%;top:45%;width:3.5px;height:7px;border:solid #fff;border-width:0 1.6px 1.6px 0;transform:translate(-50%,-50%) rotate(45deg)}
|
||||
.ig-steps li.cur .ig-ic{border:2px solid var(--accent-weak);border-top-color:var(--accent);animation:ig-spin .8s linear infinite}
|
||||
.ig-steps li.err .ig-ic{background:var(--err);border-color:var(--err)}
|
||||
.ig-t small{display:block;font-weight:400;color:var(--muted);font-size:12px}
|
||||
.ig-t small.slow{color:var(--warn)}
|
||||
@keyframes ig-spin{to{transform:rotate(360deg)}}
|
||||
@media (prefers-reduced-motion:reduce){.ig-steps li.cur .ig-ic{animation:none;border-color:var(--accent)}}
|
||||
</style>
|
||||
<div id="ig-box">
|
||||
<div class="card" style="margin:10px 0">
|
||||
@@ -15,8 +28,10 @@
|
||||
<div id="ig-head" class="muted">Проверяю…</div>
|
||||
<p class="muted" style="font-size:13px;margin:6px 0 0">Версия ИШ — та, что проверена ZETIT вместе с bj; новые версии приходят с обновлением bj. bj ставит шлюз сам при подготовке.</p>
|
||||
<div id="ig-reinst" style="display:none;margin-top:10px"><button type="button" class="btn" id="ig-bnd">Установить ИШ</button> <span class="muted" id="ig-bnd-v" style="font-size:12.5px"></span></div>
|
||||
<ol class="ig-steps" id="ig-steps" hidden></ol>
|
||||
<div id="ig-out" style="margin-top:8px;font-size:13px"></div>
|
||||
<pre id="ig-log" style="display:none;max-height:180px;overflow:auto;font-size:11px;margin-top:6px"></pre>
|
||||
<details id="ig-logbox" hidden style="margin-top:6px;font-size:12.5px"><summary style="cursor:pointer;color:var(--accent)">Журнал установки</summary>
|
||||
<pre id="ig-log" style="max-height:220px;overflow:auto;font-size:11px;margin-top:6px"></pre></details>
|
||||
{{if devOn}}<details style="margin-top:8px"><summary style="cursor:pointer;color:var(--accent);font-size:13px">Для разработчиков: другая версия ИШ</summary>
|
||||
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:end;margin-top:8px">
|
||||
<label class="f">Версия на сайте НРД<input id="ig-ver" value="107.0.930" style="width:140px"></label>
|
||||
@@ -104,23 +119,51 @@
|
||||
post('/admin/setup/igate/switch',p).then(function(d){ cout.innerHTML=d.ok?ok(d.output):bad(d.error); if(d.ok) setTimeout(function(){location.reload()},15000); });
|
||||
};
|
||||
document.getElementById('ig-crypto').onchange=load;
|
||||
function poll(){ var t0=Date.now(), iv=setInterval(function(){
|
||||
// этапы установщика (bj-igate-admin) по порядку и сколько каждый обычно длится, секунд
|
||||
var STAGES=[['queued','Запуск установки',15],['deps','Системные пакеты для работы без графики',120],['dist','Дистрибутив ИШ',30],
|
||||
['user','Пользователь igate и хранилище паролей',15],['db','База ИШ в PostgreSQL',20],['install','Установка пакета ИШ',90],
|
||||
['config','Настройка для работы без графики',15],['schema','Создание схемы базы ИШ',90],['start','Запуск ИШ и движка',120]];
|
||||
var stepsEl=document.getElementById('ig-steps'), logbox=document.getElementById('ig-logbox'), cur={key:'',since:0,s:null}, tick=0;
|
||||
function stageKey(s){ // прежний установщик называл два этапа «package», а первый и последний — «start»
|
||||
if(s.stage==='package') return /дистрибутив/.test(s.msg||'')?'dist':'install';
|
||||
if(s.stage==='start' && /запущена/.test(s.msg||'')) return 'queued';
|
||||
return s.stage; }
|
||||
function mmss(n){ n=Math.max(0,Math.round(n)); return Math.floor(n/60)+':'+('0'+n%60).slice(-2); }
|
||||
function draw(){
|
||||
var s=cur.s; if(!s) return;
|
||||
var k=stageKey(s), idx=-1; STAGES.forEach(function(x,i){ if(x[0]===k) idx=i; });
|
||||
if(s.stage==='done') idx=STAGES.length;
|
||||
var el=(Date.now()-cur.since)/1000;
|
||||
stepsEl.hidden=false;
|
||||
stepsEl.innerHTML=STAGES.map(function(x,i){
|
||||
var cls=i<idx?'done':i===idx?(s.stage==='error'?'err':'cur'):'', note='';
|
||||
if(i===idx && s.stage!=='error'){ var slow=el>x[2]*2;
|
||||
note='<small'+(slow?' class="slow"':'')+'>идёт '+mmss(el)+' · обычно до '+mmss(x[2])+(slow?' — дольше обычного; установка работает, пока счётчик идёт; зависшая снимается сама через 40 минут':'')+'</small>'; }
|
||||
return '<li class="'+cls+'"><span class="ig-ic"></span><span class="ig-t">'+esc(x[1])+note+'</span></li>'; }).join('');
|
||||
}
|
||||
function poll(){ var t0=Date.now(), btn=document.getElementById('ig-bnd');
|
||||
btn.disabled=true; // пока идёт установка — второй раз не нажать
|
||||
clearInterval(tick); tick=setInterval(draw,1000);
|
||||
var iv=setInterval(function(){
|
||||
fetch('/admin/setup/igate/install-status',{cache:'no-store'}).then(function(r){return r.json()}).then(function(s){
|
||||
if(!s.stage) return; out.textContent='Установка: '+s.msg; if(s.log){ lg.style.display='block'; lg.textContent=s.log; lg.scrollTop=lg.scrollHeight; }
|
||||
if(s.stage==='done'){ clearInterval(iv); out.innerHTML=ok(s.msg); load(); }
|
||||
if(s.stage==='error'){ clearInterval(iv); out.innerHTML=bad(s.msg); }
|
||||
if(!s.stage) return;
|
||||
if(stageKey(s)!==cur.key){ cur.key=stageKey(s); cur.since=Date.now()-(s.elapsed||0)*1000; }
|
||||
cur.s=s; draw(); out.textContent='';
|
||||
if(s.log){ logbox.hidden=false; lg.textContent=s.log; lg.scrollTop=lg.scrollHeight; }
|
||||
if(s.stage==='done'){ clearInterval(iv); clearInterval(tick); btn.disabled=false; out.innerHTML=ok(s.msg); load(); }
|
||||
if(s.stage==='error'){ clearInterval(iv); clearInterval(tick); btn.disabled=false; out.innerHTML=bad(s.msg)+' — можно нажать «Установить ИШ заново»'; logbox.open=true; load(); }
|
||||
}).catch(function(){});
|
||||
if(Date.now()-t0>1200000) clearInterval(iv); },3000); }
|
||||
if(Date.now()-t0>2700000){ clearInterval(iv); clearInterval(tick); } },3000); }
|
||||
document.getElementById('ig-bnd').onclick=function(){ var p=new URLSearchParams(); p.set('bundled','1');
|
||||
out.textContent='Запускаю…'; post('/admin/setup/igate/install',p).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
out.textContent='Запускаю…'; cur={key:'',since:0,s:null}; post('/admin/setup/igate/install',p).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
if(document.getElementById('ig-dl')) document.getElementById('ig-dl').onclick=function(){ var p=new URLSearchParams(); p.set('version',document.getElementById('ig-ver').value.trim());
|
||||
out.textContent='Запускаю…'; post('/admin/setup/igate/install',p).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
out.textContent='Запускаю…'; cur={key:'',since:0,s:null}; post('/admin/setup/igate/install',p).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
if(document.getElementById('ig-up')) document.getElementById('ig-up').onclick=function(){ var f=document.getElementById('ig-file').files[0]; if(!f){ out.textContent='Выберите файл igate-…-amd64.zip'; return; }
|
||||
var fd=new FormData(); fd.append('file',f); out.textContent='Загружаю '+f.name+'…';
|
||||
fetch('/admin/setup/igate/install',{method:'POST',body:fd}).then(function(r){return r.json()}).then(function(d){ if(!d.ok){out.innerHTML=bad(d.error);return} out.textContent=d.output; poll(); }); };
|
||||
load();
|
||||
// установка уже идёт (например, её начала «Подготовка модулей») — показать ход
|
||||
fetch('/admin/setup/igate/install-status',{cache:'no-store'}).then(function(r){return r.json()}).then(function(s){ if(s.stage&&s.stage!=='done'&&s.stage!=='error'){ out.textContent='Установка: '+s.msg; poll(); } }).catch(function(){});
|
||||
fetch('/admin/setup/igate/install-status',{cache:'no-store'}).then(function(r){return r.json()}).then(function(s){ if(s.stage&&s.stage!=='done'&&s.stage!=='error') poll(); }).catch(function(){});
|
||||
})();
|
||||
</script>
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user