389 lines
30 KiB
HTML
389 lines
30 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>SysCmd</title>
|
|
<style>
|
|
:root{--bg:#f8fafc;--fg:#0f172a;--sidebar:#fff;--brd:#e2e8f0;--brd2:#f1f5f9;--muted:#94a3b8;--txt:#475569;--title:#0f172a;--hover:#f1f5f9;--alt:#fafbfc;--actbg:#0f172a;--actfg:#fff;--boxbg:#fff}
|
|
.dark{--bg:#0b1120;--fg:#e2e8f0;--sidebar:#0f172a;--brd:#1e293b;--brd2:#1e293b;--muted:#64748b;--txt:#94a3b8;--title:#f1f5f9;--hover:#1e293b;--alt:#151e30;--actbg:#3b82f6;--actfg:#fff;--boxbg:#1e293b}
|
|
*{box-sizing:border-box;margin:0;padding:0}
|
|
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--bg);color:var(--fg);line-height:1.5;transition:background .2s,color .2s}
|
|
.sbar{width:12rem;border-right:1px solid var(--brd);background:var(--sidebar);display:flex;flex-direction:column;min-height:100vh;padding:10px 0;overflow-y:auto;flex-shrink:0}
|
|
.main{flex:1;padding:24px 32px;max-width:100%}
|
|
.tree{flex:1;overflow-y:auto}
|
|
.grp{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);padding:8px 12px 4px}
|
|
.slk{display:flex;align-items:center;gap:6px;padding:4px 10px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;color:var(--txt);transition:all .12s;user-select:none}
|
|
.slk:hover{background:var(--hover);color:var(--title)}
|
|
.slk.act{background:var(--actbg);color:var(--actfg)}
|
|
.slk3{padding-left:48px;font-size:12px}
|
|
.slk4{padding-left:64px;font-size:11px;font-weight:400}
|
|
.tgl{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;flex-shrink:0;transition:transform .15s;color:var(--muted)}
|
|
.tgl.o{transform:rotate(90deg)}
|
|
.chd{display:none}.chd.o{display:block}
|
|
.dg{width:6px;height:6px;border-radius:50%;background:#22c55e;flex-shrink:0}
|
|
.dgr{width:6px;height:6px;border-radius:50%;background:var(--muted);flex-shrink:0}
|
|
.do{width:6px;height:6px;border-radius:50%;background:#f59e0b;flex-shrink:0}
|
|
.bd{font-size:11px;color:var(--muted);display:flex;gap:6px;align-items:center;margin-bottom:2px}
|
|
.bd .c{color:var(--title);font-weight:500}
|
|
.scmd{display:grid;grid-template-columns:190px 1fr;align-items:start;padding:4px 12px;border-radius:5px;font-size:13px;gap:8px;transition:background .1s}
|
|
.scmd:hover{background:var(--hover)}
|
|
.scmd .d{color:var(--txt);font-weight:500;line-height:1.4}
|
|
.scmd .t{font-family:Consolas,'Courier New',monospace;font-size:12px;color:var(--title);cursor:pointer;display:inline-flex;align-items:center;gap:6px;line-height:1.4;word-break:break-all}
|
|
.scmd .t:hover .cp{opacity:1}
|
|
.cp{opacity:0;width:14px;height:14px;flex-shrink:0;color:var(--muted);transition:opacity .12s}
|
|
.alt{background:var(--alt)}
|
|
.stab{padding:4px 10px;border-radius:5px;font-size:11px;font-weight:500;cursor:pointer;border:1px solid var(--brd);color:var(--txt);white-space:nowrap;transition:all .12s}
|
|
.stab.a{background:var(--actbg);color:var(--actfg);border-color:var(--actbg)}
|
|
.stab:hover:not(.a){background:var(--hover)}
|
|
.si{width:100%;padding:7px 12px 7px 34px;border-radius:8px;font-size:13px;outline:none;border:1.5px solid var(--brd);background:var(--boxbg);color:var(--fg);transition:border-color .12s,.2s}
|
|
.si:focus{border-color:var(--actbg)}
|
|
.si::placeholder{color:var(--muted)}
|
|
.oc{border-radius:10px;border:1px solid var(--brd);background:var(--boxbg);cursor:pointer;transition:all .15s;padding:12px}
|
|
.oc:hover{border-color:var(--actbg);box-shadow:0 2px 8px rgba(0,0,0,.1)}
|
|
.oc .ic{width:32px;height:32px;border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
|
|
.oc .sl{font-size:11px;color:var(--muted)}
|
|
.oc.ph{opacity:.6}.oc.ph:hover{opacity:.8}
|
|
.emp{padding:40px 16px;max-width:360px;margin:0 auto;text-align:center}
|
|
.emp h3{font-weight:600;font-size:15px;margin-bottom:4px;color:var(--title)}
|
|
.emp p{font-size:13px;color:var(--muted)}
|
|
.sb{border:1px solid var(--brd);border-radius:10px;background:var(--boxbg);text-align:center;padding:12px}
|
|
.sb .n{font-size:20px;font-weight:700;color:var(--title)}
|
|
.sb .l{font-size:11px;color:var(--muted)}
|
|
.cl{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-top:8px;margin-bottom:4px;grid-column:1/-1}
|
|
.gp{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:12px}
|
|
.lr{display:flex;gap:12px;align-items:center;margin-bottom:12px;font-size:11px;color:var(--txt)}
|
|
.p8{padding:24px;font-size:13px;color:var(--muted)}
|
|
.cmdbox{background:var(--boxbg);border:1px solid var(--brd);border-radius:12px;overflow:hidden}
|
|
.cmdbox .s{font-size:11px;color:var(--muted);padding:8px 12px;border-bottom:1px solid var(--brd2)}
|
|
.dbtn{padding:3px;border-radius:5px;cursor:pointer;border:none;background:transparent;color:var(--muted);font-size:14px;line-height:1;transition:all .12s;display:flex;align-items:center;justify-content:center;width:28px;height:28px}
|
|
.dbtn:hover{background:var(--hover);color:var(--title)}
|
|
</style>
|
|
</head>
|
|
<body style="display:flex;min-height:100vh">
|
|
<div class="sbar">
|
|
<div style="display:flex;align-items:center;gap:10px;padding:8px 12px 12px;border-bottom:1px solid var(--brd2);flex-shrink:0">
|
|
<div style="width:28px;height:28px;background:var(--actbg);border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0" onclick="SH()">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2.5"><path d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/></svg>
|
|
</div>
|
|
<span style="font-weight:700;font-size:14px;flex:1;cursor:pointer" onclick="SH()">SysCmd</span>
|
|
</div>
|
|
<div class="tree" id="tree"></div>
|
|
<div style="padding-top:8px;border-top:1px solid var(--brd2);flex-shrink:0">
|
|
<div style="display:flex;align-items:center;gap:8px;padding:6px 12px">
|
|
<div style="width:28px;height:28px;background:var(--brd2);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--muted)">LK</div>
|
|
<div style="font-size:12px;flex:1"><div style="font-weight:500;color:var(--title)">Laurent</div><div style="color:var(--muted)">sysadmin</div></div>
|
|
<div class="dbtn" onclick="TD()" id="dm-btn" title="Dark mode">☾</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="main">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px">
|
|
<div>
|
|
<div class="bd" id="bd"></div>
|
|
<h1 style="font-size:18px;font-weight:700" id="os-title">SysCmd</h1>
|
|
<p style="font-size:11px;color:var(--txt);margin-top:2px" id="os-sub"></p>
|
|
</div>
|
|
<div style="position:relative">
|
|
<svg style="position:absolute;left:10px;top:50%;transform:translateY(-50%);width:14px;height:14px;color:var(--muted)" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
|
|
<input class="si" id="search" placeholder="Search a command..." oninput="onSearch(this.value)">
|
|
</div>
|
|
</div>
|
|
<div class="gp" id="tabs"></div>
|
|
<div class="lr" id="stats-bar">
|
|
<span id="shown">0</span> <span>commands</span>
|
|
<span class="sep">·</span>
|
|
<span id="fi">No filter</span>
|
|
</div>
|
|
<div class="cmdbox" id="cmd-box">
|
|
<div id="cmds"></div>
|
|
</div>
|
|
<div id="home">
|
|
<div style="display:grid;grid-template-columns:repeat(5,1fr);gap:6px" id="grid"></div>
|
|
<div id="gs" style="display:none;margin-bottom:24px"></div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
"use strict";
|
|
var DM=localStorage.getItem('dm')==='1',N=null,MS=null;
|
|
if(DM)document.documentElement.classList.add('dark');
|
|
|
|
function $(i){return document.getElementById(i)}
|
|
function FN(t,i){if(t.id===i)return t;for(var j=0;j<(t.children||[]).length;j++){var r=FN(t.children[j],i);if(r)return r}return null}
|
|
function CL(n,o){if(n.children){for(var i=0;i<n.children.length;i++)CL(n.children[i],o)}else o.push(n);return o}
|
|
function CC(n){
|
|
if(n.secs){var t=0;for(var i=0;i<n.secs.length;i++)if(SEC[n.secs[i]])t+=SEC[n.secs[i]].cmds.length;return t}
|
|
if(n.children){var t=0;for(var i=0;i<n.children.length;i++)t+=CC(n.children[i]);return t}
|
|
return 0}
|
|
function TD(){DM=!DM;document.documentElement.classList.toggle('dark',DM);localStorage.setItem('dm',DM?'1':'0')}
|
|
|
|
var TREE={id:'r',children:[
|
|
{id:'os',label:'OS',children:[
|
|
{id:'lnx',label:'Linux',children:[
|
|
{id:'ubu',label:'Ubuntu',children:[
|
|
{id:'u20',label:'20.04',secs:['sys','apt','users']},
|
|
{id:'u22',label:'22.04',secs:['sys','apt','users']},
|
|
{id:'u24',label:'24.04',secs:['sys','apt','users','systemd']}]},
|
|
{id:'deb',label:'Debian',secs:['sys','apt','users','systemd']},
|
|
{id:'ora',label:'Oracle Linux',secs:['odnf','ospec','osel','ofw','systemd']},
|
|
{id:'rhel',label:'RHEL/CentOS',secs:['r_dnf','r_fw','r_selinux','r_epel','systemd']},{id:'fed',label:'Fedora'}]},
|
|
{id:'win',label:'Windows',children:[
|
|
{id:'wcl',label:'Client',children:[
|
|
{id:'wxp',label:'XP'},{id:'w10',label:'10',secs:['wsys','wfiles','wproc','wnet']},
|
|
{id:'w11',label:'11',secs:['wsys','wfiles','wproc','wnet']}]},
|
|
{id:'wsrv',label:'Server',children:[
|
|
{id:'w16',label:'2016',secs:['wsys','wfiles','wproc','wnet']},
|
|
{id:'w19',label:'2019',secs:['wsys','wfiles','wproc','wnet']}]}]},
|
|
{id:'sol',label:'Solaris/illumos',secs:['sips','ssmf','szfs','szones']},
|
|
{id:'mac',label:'macOS',secs:['mac_brew','mac_defaults','mac_disk','mac_sys']},{id:'bsd',label:'BSD',children:[
|
|
{id:'freebsd',label:'FreeBSD',secs:['fbsd_sys','fbsd_pkg','fbsd_zfs','fbsd_jail','fbsd_net']},
|
|
{id:'openbsd',label:'OpenBSD'},{id:'netbsd',label:'NetBSD'}]}]},
|
|
{id:'dck',label:'Docker',children:[
|
|
{id:'dck-up',label:'Compose up/down',secs:['dc_up']},
|
|
{id:'dck-logs',label:'Compose logs',secs:['dc_logs']},
|
|
{id:'dck-exec',label:'Compose exec',secs:['dc_exec']},
|
|
{id:'dck-ps',label:'Compose ps',secs:['dc_ps']},
|
|
{id:'dck-build',label:'Compose build',secs:['dc_build']},
|
|
{id:'dck-df',label:'Dockerfile build',secs:['dck_build']},
|
|
{id:'dck-instr',label:'Dockerfile instr.',secs:['dck_directives']}]},
|
|
{id:'oth',label:'Other',children:[
|
|
{id:'net',label:'Network',children:[{id:'cis',label:'Cisco'},{id:'tpl',label:'TP-Link'}]},
|
|
{id:'sql',label:'SQL',children:[{id:'my',label:'MySQL/MariaDB',secs:['mysql']},{id:'pg',label:'PostgreSQL',secs:['pg']}]},
|
|
{id:'dev',label:'DevOps',children:[{id:'ans',label:'Ansible'},{id:'tf',label:'Terraform'},{id:'k8',label:'Kubernetes'}]}]}]};
|
|
|
|
var SEC={};
|
|
SEC.sys={label:'System',cmds:[
|
|
{d:'Kernel version',c:'uname -r'},{d:'OS version',c:'lsb_release -a'},{d:'Memory',c:'free -h'},
|
|
{d:'Hostname',c:'hostnamectl'},{d:'Uptime',c:'uptime'},{d:'CPU',c:'lscpu'},{d:'Date',c:'timedatectl'}]};
|
|
SEC.apt={label:'APT',cmds:[
|
|
{d:'Sync repos',c:'sudo apt update'},{d:'Upgrade',c:'sudo apt full-upgrade -y'},{d:'Install',c:'sudo apt install [pkg]'},
|
|
{d:'Purge',c:'sudo apt purge [pkg]'},{d:'Search',c:'apt search [kw]'},{d:'Installed',c:'apt list --installed'},
|
|
{d:'Package files',c:'dpkg -L [pkg]'}]};
|
|
SEC.users={label:'Users',cmds:[
|
|
{d:'Add user',c:'sudo adduser [n]'},{d:'Delete user',c:'sudo deluser --remove-home [n]'},
|
|
{d:'Sudo group',c:'sudo usermod -aG sudo [n]'},{d:'Permissions',c:'chmod 755 [f]'},{d:'Root shell',c:'sudo -i'}]};
|
|
SEC.systemd={label:'Systemd',cmds:[
|
|
{d:'Start/Stop',c:'sudo systemctl start|stop [s]'},{d:'Restart',c:'sudo systemctl restart [s]'},
|
|
{d:'Enable',c:'sudo systemctl enable [s]'},{d:'Status',c:'systemctl status [s]'},
|
|
{d:'Logs',c:'journalctl -u [s] -n 50'},{d:'Purge logs',c:'sudo journalctl --vacuum-time=7d'}]};
|
|
SEC.wsys={label:'System',cmds:[
|
|
{d:'(CMD) Version',c:'ver'},{d:'(CMD) systeminfo',c:'systeminfo'},{d:'(PS) Get-ComputerInfo',c:'Get-ComputerInfo'}]};
|
|
SEC.wfiles={label:'Files',cmds:[
|
|
{d:'(CMD) dir',c:'dir /s'},{d:'(CMD) rmdir',c:'rmdir /s [f]'},{d:'(PS) Get-ChildItem',c:'Get-ChildItem -Recurse -Filter *.txt'}]};
|
|
SEC.wproc={label:'Processes',cmds:[
|
|
{d:'(CMD) tasklist',c:'tasklist'},{d:'(CMD) taskkill',c:'taskkill /IM notepad.exe /F'},{d:'(PS) Get-Process',c:'Get-Process'}]};
|
|
SEC.wnet={label:'Network',cmds:[
|
|
{d:'(CMD) ipconfig',c:'ipconfig /all'},{d:'(CMD) netstat',c:'netstat -an | findstr LISTEN'},
|
|
{d:'(PS) Test-NetConn',c:'Test-NetConnection [ip] -Port [port]'}]};
|
|
SEC.odnf={label:'DNF',cmds:[
|
|
{d:'Sync',c:'sudo dnf check-update'},{d:'Upgrade',c:'sudo dnf upgrade -y'},{d:'Install',c:'sudo dnf install [p]'},{d:'Remove',c:'sudo dnf remove [p]'}]};
|
|
SEC.r_dnf={label:'DNF',cmds:[
|
|
{d:'Sync repos',c:'sudo dnf check-update'},{d:'Upgrade',c:'sudo dnf upgrade -y'},{d:'Install',c:'sudo dnf install [pkg]'},
|
|
{d:'Remove',c:'sudo dnf remove [pkg]'},{d:'Search',c:'dnf search [kw]'},{d:'History',c:'dnf history'},
|
|
{d:'Package info',c:'dnf info [pkg]'},{d:'Package files',c:'rpm -ql [pkg]'}]};
|
|
SEC.r_fw={label:'firewalld',cmds:[
|
|
{d:'Status',c:'sudo firewall-cmd --state'},{d:'Default zone',c:'sudo firewall-cmd --get-default-zone'},
|
|
{d:'Open port',c:'sudo firewall-cmd --permanent --add-port=22/tcp'},
|
|
{d:'Open service',c:'sudo firewall-cmd --permanent --add-service=http'},
|
|
{d:'Reload',c:'sudo firewall-cmd --reload'},{d:'List rules',c:'sudo firewall-cmd --list-all'}]};
|
|
SEC.r_selinux={label:'SELinux',cmds:[
|
|
{d:'Status',c:'getenforce'},{d:'Permissive',c:'sudo setenforce 0'},{d:'Enforcing',c:'sudo setenforce 1'},
|
|
{d:'AVC logs',c:'sudo ausearch -m avc -ts recent'},{d:'File contexts',c:'ls -Z [f]'},{d:'restorecon',c:'sudo restorecon -Rv [p]'},
|
|
{d:'Bool list',c:'getsebool -a'},{d:'Permanent config',c:'cat /etc/selinux/config'}]};
|
|
SEC.r_epel={label:'EPEL',cmds:[{d:'Install EPEL',c:'sudo dnf install epel-release'},{d:'Enable EPEL',c:'sudo dnf config-manager --set-enabled epel'}]};
|
|
SEC.ospec={label:'Oracle specifics',cmds:[
|
|
{d:'Ksplice status',c:'sudo uptrack-status'},{d:'Ksplice upgrade',c:'sudo uptrack-upgrade'},{d:'Switch kernel',c:'sudo grubby --set-default /boot/vmlinuz-[v]'}]};
|
|
SEC.osel={label:'SELinux',cmds:[{d:'Status',c:'getenforce'},{d:'Permissive',c:'sudo setenforce 0'},{d:'AVC logs',c:'sudo ausearch -m avc -ts recent'}]};
|
|
SEC.ofw={label:'firewalld',cmds:[{d:'Status',c:'sudo firewall-cmd --state'},{d:'Open port',c:'sudo firewall-cmd --permanent --add-port=22/tcp'}]};
|
|
SEC.sips={label:'IPS',cmds:[
|
|
{d:'Refresh',c:'sudo pkg refresh'},{d:'Update',c:'sudo pkg update'},{d:'Install',c:'sudo pkg install [p]'},{d:'Remove',c:'sudo pkg uninstall [p]'}]};
|
|
SEC.ssmf={label:'SMF',cmds:[{d:'List',c:'svcs -a'},{d:'Enable',c:'sudo svcadm enable [s]'},{d:'Disable',c:'sudo svcadm disable [s]'},{d:'Restart',c:'sudo svcadm restart [s]'}]};
|
|
SEC.szfs={label:'ZFS',cmds:[
|
|
{d:'Pool status',c:'zpool status'},{d:'Scrub',c:'sudo zpool scrub [p]'},{d:'Snapshot',c:'sudo zfs snapshot [p]/[ds]@[n]'},{d:'Send/Receive',c:'zfs send [p]/[ds]@snap | zfs receive [d]'}]};
|
|
SEC.szones={label:'Zones',cmds:[{d:'List',c:'zoneadm list -cv'},{d:'Boot',c:'sudo zoneadm -z [z] boot'},{d:'Halt',c:'sudo zoneadm -z [z] halt'},{d:'Console',c:'sudo zlogin -C [z]'}]};
|
|
SEC.fbsd_pkg={label:'pkg',cmds:[{d:'Update repos',c:'sudo pkg update'},{d:'Upgrade',c:'sudo pkg upgrade'},{d:'Install',c:'sudo pkg install [pkg]'},
|
|
{d:'Remove',c:'sudo pkg delete [pkg]'},{d:'Search',c:'pkg search [kw]'},{d:'Package info',c:'pkg info [pkg]'},{d:'Installed',c:'pkg info'}]};
|
|
SEC.fbsd_zfs={label:'ZFS',cmds:[{d:'Pool status',c:'zpool status'},{d:'Pool list',c:'zpool list'},{d:'Scrub',c:'sudo zpool scrub [pool]'},{d:'Datasets',c:'zfs list'},
|
|
{d:'Snapshot',c:'sudo zfs snapshot [pool]/[ds]@[n]'},{d:'Rollback',c:'sudo zfs rollback [pool]/[ds]@[n]'}]};
|
|
SEC.fbsd_jail={label:'jail',cmds:[{d:'List jails',c:'jls'},{d:'Console',c:'jexec [id] sh'},{d:'Start jail',c:'sudo service jail start [name]'},{d:'Stop jail',c:'sudo service jail stop [name]'}]};
|
|
SEC.fbsd_net={label:'Network',cmds:[{d:'Interfaces',c:'ifconfig'},{d:'Route',c:'netstat -rn'},{d:'DNS config',c:'cat /etc/resolv.conf'},{d:'pf status',c:'sudo pfctl -s info'}]};
|
|
SEC.fbsd_sys={label:'System',cmds:[{d:'Version',c:'uname -r -s'},{d:'Hostname',c:'hostname'},{d:'CPU info',c:'sysctl hw.model'},{d:'Memory',c:'sysctl hw.physmem'}]};
|
|
SEC.mac_brew={label:'Homebrew',cmds:[{d:'Install',c:'brew install [pkg]'},{d:'Uninstall',c:'brew uninstall [pkg]'},{d:'Update',c:'brew update'},{d:'Upgrade all',c:'brew upgrade'},
|
|
{d:'Search',c:'brew search [kw]'},{d:'Info',c:'brew info [pkg]'},{d:'List installed',c:'brew list'},{d:'Install cask',c:'brew install --cask [app]'}]};
|
|
SEC.mac_defaults={label:'defaults',cmds:[{d:'Read key',c:"defaults read [domain] [key]"},{d:'Write key',c:"defaults write [domain] [key] -type [val]"},
|
|
{d:'Show hidden files',c:"defaults write com.apple.Finder AppleShowAllFiles true && killall Finder"},
|
|
{d:'Screenshot path',c:"defaults write com.apple.screencapture location [path]; killall SystemUIServer"}]};
|
|
SEC.mac_disk={label:'disk',cmds:[{d:'List disks',c:'diskutil list'},{d:'Disk info',c:'diskutil info [disk]'},{d:'Mount',c:'diskutil mount [disk]'},{d:'Unmount',c:'diskutil unmount [disk]'}]};
|
|
SEC.mac_sys={label:'System',cmds:[{d:'macOS version',c:'sw_vers'},{d:'Hardware',c:'system_profiler SPHardwareDataType'},{d:'Memory',c:'system_profiler SPMemoryDataType'},{d:'Processes',c:'top -l 1 -n 10'},{d:'Disk space',c:'df -h'}]};
|
|
SEC.dc_up={label:'Up/Down',cmds:[{d:'Start',c:'docker compose up -d'},{d:'Stop',c:'docker compose down'},{d:'Rebuild+start',c:'docker compose up -d --build'},{d:'Force recreate',c:'docker compose up -d --force-recreate'},{d:'Stop (no rm)',c:'docker compose stop'},{d:'Remove all',c:'docker compose down -v'}]};
|
|
SEC.dc_logs={label:'Logs',cmds:[{d:'Follow',c:'docker compose logs -f'},{d:'Service logs',c:'docker compose logs [s] -f'},{d:'Last 50',c:'docker compose logs --tail=50'},{d:'Timestamps',c:'docker compose logs -t'}]};
|
|
SEC.dc_exec={label:'Exec',cmds:[{d:'Shell',c:'docker compose exec [s] bash'},{d:'Run command',c:'docker compose exec [s] [cmd]'},{d:'Shell root',c:'docker compose exec -u root [s] bash'}]};
|
|
SEC.dc_ps={label:'PS',cmds:[{d:'List services',c:'docker compose ps'},{d:'Validate config',c:'docker compose config'},{d:'Images',c:'docker compose images'}]};
|
|
SEC.dc_build={label:'Build',cmds:[{d:'Build all',c:'docker compose build'},{d:'Build service',c:'docker compose build [s]'},{d:'No cache',c:'docker compose build --no-cache'},{d:'Pull images',c:'docker compose pull'}]};
|
|
SEC.dck_build={label:'Build image',cmds:[{d:'Build',c:'docker build -t [name]:[tag] .'},{d:'No cache',c:'docker build --no-cache -t [name]:[tag] .'},{d:'Build args',c:'docker build --build-arg [k]=[v] -t [name]:[tag] .'},{d:'Multi-stage',c:'docker build --target [stage] -t [name]:[tag] .'}]};
|
|
SEC.dck_directives={label:'Dockerfile',cmds:[{d:'FROM',c:'FROM [image]:[tag]'},{d:'RUN',c:'RUN [command]'},{d:'COPY',c:'COPY [src] [dest]'},{d:'WORKDIR',c:'WORKDIR /app'},
|
|
{d:'EXPOSE',c:'EXPOSE [port]'},{d:'CMD',c:'CMD ["exec","args"]'},{d:'ENTRYPOINT',c:'ENTRYPOINT ["exec","args"]'},{d:'ENV',c:'ENV [key]=[value]'},
|
|
{d:'VOLUME',c:'VOLUME [path]'},{d:'USER',c:'USER [user]'},{d:'HEALTHCHECK',c:'HEALTHCHECK CMD [cmd]'},{d:'LABEL',c:'LABEL [key]=[value]'}]};
|
|
SEC.mysql={label:'MySQL/MariaDB',cmds:[{d:'Connect',c:'mysql -u [user] -p'},{d:'Show databases',c:'SHOW DATABASES;'},{d:'Show tables',c:'SHOW TABLES;'},
|
|
{d:'Users',c:'SELECT User,Host FROM mysql.user;'},{d:'Create DB',c:'CREATE DATABASE [db];'},{d:'Create user',c:"CREATE USER '[u]'@'localhost' IDENTIFIED BY '[p]';"},
|
|
{d:'Grant',c:"GRANT ALL ON [db].* TO '[u]'@'localhost';"},{d:'Dump DB',c:'mysqldump -u [u] -p [db] > backup.sql'},{d:'Restore DB',c:'mysql -u [u] -p [db] < backup.sql'},
|
|
{d:'Dump all',c:'mysqldump -u [u] -p --all-databases > all.sql'},{d:'Processlist',c:'SHOW FULL PROCESSLIST;'},{d:'Variables',c:"SHOW VARIABLES LIKE '%[kw]%';"}]};
|
|
SEC.pg={label:'PostgreSQL',cmds:[{d:'Connect',c:"psql -U [user] -d [db]"},{d:'List databases',c:'\\l+'},{d:'List tables',c:'\\dt+'},{d:'Describe',c:'\\d+ [table]'},
|
|
{d:'Create DB',c:'CREATE DATABASE [db];'},{d:'Create user',c:"CREATE USER [u] WITH PASSWORD '[p]';"},{d:'Grant',c:"GRANT ALL PRIVILEGES ON DATABASE [db] TO [u];"},
|
|
{d:'Dump DB',c:'pg_dump -U [u] [db] > backup.sql'},{d:'Restore DB',c:'psql -U [u] -d [db] < backup.sql'},{d:'Vacuum',c:"VACUUM FULL ANALYZE;"}]};
|
|
|
|
var ALL=[];(function(){var seen={};for(var k in SEC)SEC[k].cmds.forEach(function(x){if(!seen[x.c]){seen[x.c]=1;ALL.push(x)}})})();
|
|
|
|
// ── RENDER TREE ──
|
|
function RT(){
|
|
var el=$('tree');el.innerHTML='';
|
|
(function RN(c,n,d){
|
|
var br=n.children&&n.children.length>0,ver=!!n.secs;
|
|
var dv=document.createElement('div');
|
|
if(d===0){var lb=document.createElement('div');lb.className='grp';lb.textContent='Categories';dv.appendChild(lb)}
|
|
else{
|
|
var rw=document.createElement('div');
|
|
var c2='slk';if(d===2)c2+=' slk3';if(d===3)c2+=' slk4';if(n===N)c2+=' act';rw.className=c2;
|
|
if(br){var tg=document.createElement('span');tg.className='tgl o';
|
|
tg.innerHTML='<svg width="12" height="12" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 18l6-6-6-6"/></svg>';rw.appendChild(tg)}
|
|
else{rw.appendChild(document.createElement('span'))}
|
|
var dt=document.createElement('span');
|
|
if(ver||n._p)dt.className='dg';else if(br)dt.className='do';else dt.className='dgr';
|
|
rw.appendChild(dt);
|
|
var lb2=document.createElement('span');lb2.textContent=n.label;rw.appendChild(lb2);
|
|
var cnt=CC(n)||(n._p&&n._p.secs?SEC[n._sid]?SEC[n._sid].cmds.length:0:0);
|
|
if(cnt>0){var b2=document.createElement('span');b2.style.cssText='margin-left:auto;font-size:10px;color:var(--muted)';b2.textContent=''+cnt;rw.appendChild(b2)}
|
|
rw.onclick=function(e){
|
|
if(br&&(e.target.closest('.tgl')||e.target.closest('[data-toggle]'))){var tg=rw.querySelector('.tgl');if(tg){tg.classList.toggle('o');rw.nextElementSibling.classList.toggle('o');e.stopPropagation()}return}
|
|
if(br)return;S(n)
|
|
};
|
|
dv.appendChild(rw)}
|
|
function onPath(t){if(!t)return false;if(t===n)return true;var p=t._p;while(p){if(p===n)return true;p=p._p}return false}
|
|
if(br){var kd=document.createElement('div');kd.className='chd'+(onPath(N)?' o':'');
|
|
for(var i=0;i<n.children.length;i++){n.children[i]._p=n;RN(kd,n.children[i],d+1)}
|
|
dv.appendChild(kd)}
|
|
if(ver&&n.secs){var kd=document.createElement('div');kd.className='chd';
|
|
if(n===N||(N&&N._p===n))kd.className='chd o';
|
|
for(var j=0;j<n.secs.length;j++){var s=n.secs[j],sc=SEC[s];if(!sc)continue;
|
|
var sn={id:n.id+'-'+s,label:sc.label,_sid:s,_p:n};RN(kd,sn,d+1)}
|
|
dv.appendChild(kd)}
|
|
c.appendChild(dv)
|
|
})(el,TREE,0)
|
|
}
|
|
|
|
// ── SELECT ──
|
|
function S(n){
|
|
N=n;MS=null;RT();$('search').value='';HI();$('bd').innerHTML='';
|
|
if(n._sid){var sc=SEC[n._sid];if(sc){$('os-title').textContent=(n._p.label||'')+' > '+sc.label;$('os-sub').textContent=sc.cmds.length+' commands';SC(sc.cmds);return}}
|
|
if(n.secs&&n.secs.length>0){var s0=n.secs[0],sc0=SEC[s0];if(sc0){$('os-title').textContent=n.label;$('os-sub').textContent=n.secs.length+' sections . '+CC(n)+' commands';SC(sc0.cmds);return}}
|
|
$('os-title').textContent=n.label;$('os-sub').textContent='No data';$('cmds').innerHTML='<div class="emp"><h3>'+n.label+'</h3><p>'+'No commands yet for this OS.</p></div>'
|
|
}
|
|
|
|
function SH(){N=null;MS=null;RT();$('search').value='';
|
|
$('home').style.display='block';$('tabs').style.display='none';$('stats-bar').style.display='none';$('cmd-box').style.display='none';
|
|
$('bd').innerHTML='';$('os-title').textContent='SysCmd';$('os-sub').textContent='';RCS()}
|
|
function HI(){$('home').style.display='none';$('tabs').style.display='flex';$('stats-bar').style.display='flex';$('cmd-box').style.display='block'}
|
|
|
|
function RH(){RS();RCS()}
|
|
function RS(){
|
|
var tc=ALL.length,ts=0;for(var k in SEC)ts++;
|
|
var lv=CL(TREE,[]),tos=0;for(var i=0;i<lv.length;i++)if(lv[i].secs)tos++;
|
|
$('stats-row').innerHTML='<div class="sb"><div class="n">'+tc+'</div><div class="l">commands</div></div><div class="sb"><div class="n">'+ts+'</div><div class="l">sections</div></div><div class="sb"><div class="n">'+tos+'</div><div class="l">OS documented</div></div><div class="sb"><div class="n" style="color:var(--muted)">'+(lv.length-tos)+'</div><div class="l">pending</div></div>'
|
|
}
|
|
|
|
var CARDS=[
|
|
{id:'deb',l:'Debian',i:'D',c:'#0f172a',d:'Stable distribution',cat:'os'},
|
|
{id:'ubu',l:'Ubuntu',i:'U',c:'#dc2626',d:'Debian-based LTS',cat:'os',gr:true},
|
|
{id:'ora',l:'Oracle Linux',i:'O',c:'#b9141e',d:'Linux UEK+SELinux',cat:'os'},
|
|
{id:'win',l:'Windows',i:'W',c:'#0078d4',d:'CMD+PS client/server',cat:'os',gr:true},
|
|
{id:'sol',l:'Solaris',i:'S',c:'#b46400',d:'Solaris ZFS+DTrace',cat:'os'},
|
|
{id:'rhel',l:'RHEL/CentOS',i:'R',c:'#e63946',d:'Enterprise Linux',cat:'os'},
|
|
{id:'fed',l:'Fedora',i:'F',c:'#94a3b8',d:'RHEL-based (pending)',cat:'os',ph:1},
|
|
{id:'freebsd',l:'FreeBSD',i:'B',c:'#cc1111',d:'BSD with ZFS+jails',cat:'os'},
|
|
{id:'mac',l:'macOS',i:'M',c:'#a1a1a6',d:'Homebrew+defaults',cat:'os'},
|
|
{id:'dck',l:'Docker',i:'D',c:'#0ea5e9',d:'Compose + Dockerfile',cat:'dk',gr:true},
|
|
{id:'cis',l:'Cisco',i:'C',c:'#8b5cf6',d:'Cisco networking (pending)',cat:'oth',ph:1},
|
|
{id:'my',l:'MySQL/MariaDB',i:'S',c:'#8b5cf6',d:'SQL databases',cat:'oth'},
|
|
{id:'pg',l:'PostgreSQL',i:'P',c:'#8b5cf6',d:'Advanced database',cat:'oth'},
|
|
{id:'ans',l:'Ansible',i:'A',c:'#8b5cf6',d:'IT automation (pending)',cat:'oth',ph:1},
|
|
{id:'k8',l:'Kubernetes',i:'K',c:'#8b5cf6',d:'Container orchestration (pending)',cat:'oth',ph:1}];
|
|
|
|
function RCS(){
|
|
var ct0={os:{l:'Operating Systems',h:''},dk:{l:'Docker/Containers',h:''},oth:{l:'Network, DB, DevOps',h:''}};
|
|
CARDS.forEach(function(cd){
|
|
var nd=FN(TREE,cd.id),cnt=nd?CC(nd):0,ph=cd.ph&&cnt===0;
|
|
if(!ct0[cd.cat])ct0[cd.cat]={l:cd.cat,h:''};
|
|
var h='<div class="oc'+(ph?' ph':'')+'" data-card="'+cd.id+'">'+
|
|
'<div style="display:flex;gap:12px;margin-bottom:12px">'+
|
|
'<div class="ic" style="background:'+(ph?'var(--brd2)':cd.c)+';color:'+(ph?'var(--muted)':'#fff')+'"><span style="font-weight:700;font-size:13px">'+cd.i+'</span></div>'+
|
|
'<div style="flex:1;min-width:0"><div style="font-weight:600;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--title)">'+(cd.gr?cd.l+'>':cd.l)+'</div>'+
|
|
'<div style="font-size:11px;color:var(--muted)">'+cd.d+'</div></div></div>'+
|
|
'<div style="display:flex;gap:8px;font-size:11px">'+(cnt>0?'<span style="font-weight:600;color:var(--title)">'+cnt+'</span><span style="color:var(--muted)">commands</span>':'<span style="color:var(--muted)">Pending</span>')+'</div></div>';
|
|
ct0[cd.cat].h+=h});
|
|
var html='';Object.keys(ct0).forEach(function(k){html+='<div class="cl">'+ct0[k].l+'</div>'+ct0[k].h});
|
|
$('grid').innerHTML=html;
|
|
$('grid').querySelectorAll('[data-card]').forEach(function(el){
|
|
el.onclick=function(){
|
|
var id=el.dataset.card,cd=null;
|
|
for(var i=0;i<CARDS.length;i++)if(CARDS[i].id===id){cd=CARDS[i];break}
|
|
if(!cd)return;
|
|
var nd=FN(TREE,cd.id);
|
|
if(cd.gr&&nd&&nd.children&&nd.children.length>0)S(nd.children[0]);else if(nd)S(nd)}})
|
|
}
|
|
|
|
function SC(cmds){
|
|
var el=$('cmds'),sv=$('search').value.trim().toLowerCase();
|
|
var c2=sv?cmds.filter(function(x){return x.d.toLowerCase().indexOf(sv)!==-1||x.c.toLowerCase().indexOf(sv)!==-1}):cmds;
|
|
$('shown').textContent=''+c2.length;
|
|
if(c2.length===0){el.innerHTML='<div class="p8">No commands found</div>';return}
|
|
el.innerHTML='';
|
|
c2.forEach(function(x,i){
|
|
var r=document.createElement('div');r.className='scmd'+(i%2===0?' alt':'');
|
|
r.innerHTML='<div class="d">'+x.d+'</div><div class="t"><span class="cp"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg></span><span>'+x.c+'</span></div>';
|
|
r.querySelector('.t').onclick=function(){
|
|
navigator.clipboard.writeText(x.c).then(function(){
|
|
var ic=r.querySelector('.cp');
|
|
ic.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="#22c55e" stroke-width="2.5" width="14" height="14"><polyline points="20 6 9 17 4 12"/></svg>';
|
|
setTimeout(function(){ic.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg>'},1200)})};
|
|
el.appendChild(r)})
|
|
}
|
|
|
|
function onSearch(v){
|
|
$('fi').textContent=v.trim()?'Filter: "'+v+'"':'No filter';
|
|
if(N&&N._sid){SC(SEC[N._sid].cmds);return}
|
|
if(N&&N.secs&&N.secs.length>0){MSS(N,v);return}
|
|
if(!N&&v.trim()){
|
|
var r=ALL.filter(function(x){return x.d.toLowerCase().indexOf(v.trim().toLowerCase())!==-1||x.c.toLowerCase().indexOf(v.trim().toLowerCase())!==-1});
|
|
$('gs').style.display='block';
|
|
var h='<div class="cmdbox"><div class="s">'+r.length+' result(s)</div>';
|
|
if(r.length===0)h+='<div class="p8">No results</div>';
|
|
else{r.forEach(function(x,i){
|
|
h+='<div class="scmd'+(i%2===0?' alt':'')+'"><div class="d">'+x.d+'</div><div class="t"><span class="cp"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg></span><span>'+x.c+'</span></div></div>'})}
|
|
h+='</div>';$('gs').innerHTML=h;$('grid').style.display='none';$('stats-row').style.display='none'
|
|
}else if(!N){$('gs').style.display='none';$('grid').style.display='grid';$('stats-row').style.display='grid'}
|
|
}
|
|
|
|
function MSS(n,v){
|
|
var secs=n.secs;
|
|
if(!secs||secs.length===0){SC(SEC[secs[0]].cmds);return}
|
|
var allCmds=[];
|
|
secs.forEach(function(sid){var sc=SEC[sid];if(sc)sc.cmds.forEach(function(x){allCmds.push({cmd:x,sec:sc.label})})});
|
|
var sv=v.trim().toLowerCase();
|
|
if(sv)allCmds=allCmds.filter(function(x){return x.cmd.d.toLowerCase().indexOf(sv)!==-1||x.cmd.c.toLowerCase().indexOf(sv)!==-1});
|
|
$('shown').textContent=''+allCmds.length;
|
|
var el=$('cmds');
|
|
if(allCmds.length===0){el.innerHTML='<div class="p8">No commands found</div>';return}
|
|
el.innerHTML='';
|
|
allCmds.forEach(function(x,i){
|
|
var r=document.createElement('div');r.className='scmd'+(i%2===0?' alt':'');
|
|
r.innerHTML='<div class="d">'+x.cmd.d+' <span style="color:var(--muted);font-weight:400;font-size:10px">['+x.sec+']</span></div><div class="t"><span class="cp"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg></span><span>'+x.cmd.c+'</span></div>';
|
|
r.querySelector('.t').onclick=function(){navigator.clipboard.writeText(x.cmd.c)};
|
|
el.appendChild(r)})
|
|
}
|
|
|
|
RT();
|
|
SH();
|
|
</script>
|
|
</body>
|
|
</html>
|