Compare commits
10
Commits
v1.0.1
...
81e34a4adb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81e34a4adb | ||
|
|
302eb43233 | ||
|
|
949391ed44 | ||
|
|
5041e5202f | ||
|
|
8baefe1bfd | ||
|
|
d8108dae0f | ||
|
|
3eb347da06 | ||
|
|
8d15b71c06 | ||
|
|
a28ad04b55 | ||
|
|
6720b602ba |
@@ -73,22 +73,47 @@ function openDomainSetupModal(feat, onSaved) {
|
|||||||
npubField = '<div class="domain-field-group"><label class="domain-field-label" for="domain-npub-input">Nostr Public Key (npub1...):</label><input class="domain-field-input" type="text" id="domain-npub-input" placeholder="npub1..." value="' + escHtml(currentNpub) + '" /></div>';
|
npubField = '<div class="domain-field-group"><label class="domain-field-label" for="domain-npub-input">Nostr Public Key (npub1...):</label><input class="domain-field-input" type="text" id="domain-npub-input" placeholder="npub1..." value="' + escHtml(currentNpub) + '" /></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
var externalIp = _cachedExternalIp || "your external IP";
|
var introHtml;
|
||||||
|
if (_currentRole === "node") {
|
||||||
|
introHtml =
|
||||||
|
'<p>To enable <strong>' + escHtml(feat.name) + '</strong>, it needs its own domain from Njal.la.</p>' +
|
||||||
|
'<ol style="margin:8px 0 0 16px;padding:0;line-height:1.7;">' +
|
||||||
|
'<li>Create an account at <a href="https://njal.la" target="_blank" rel="noopener noreferrer" style="color:var(--accent-color);">njal.la</a>.</li>' +
|
||||||
|
'<li>Set up a domain for it — either a free subdomain or a separate domain. Pick one option:</li>' +
|
||||||
|
'</ol>';
|
||||||
|
} else {
|
||||||
|
introHtml =
|
||||||
|
'<p>To enable <strong>' + escHtml(feat.name) + '</strong>, it needs its own domain from Njal.la. ' +
|
||||||
|
'In your Njal.la account, set up a domain for it — either a free subdomain or a separate domain. Pick one option:</p>';
|
||||||
|
}
|
||||||
|
|
||||||
$domainSetupBody.innerHTML =
|
$domainSetupBody.innerHTML =
|
||||||
'<div class="domain-setup-intro">' +
|
'<div class="domain-setup-intro">' +
|
||||||
'<p><strong>Before continuing:</strong></p>' +
|
introHtml +
|
||||||
'<ol>' +
|
'<details style="margin-top:10px;">' +
|
||||||
'<li>Create an account at <a href="https://njal.la" target="_blank" rel="noopener noreferrer" style="color:var(--accent-color);">https://njal.la</a></li>' +
|
'<summary style="cursor:pointer;font-weight:600;">Option A — Free subdomain (recommended)</summary>' +
|
||||||
'<li>Purchase a new domain on Njal.la, or create a subdomain from a domain you already own. Tip: Subdomains are free to create — you only need to purchase one domain, and you can add as many subdomains as you need at no extra cost.</li>' +
|
'<ol style="margin:8px 0 0 16px;padding:0;line-height:1.7;">' +
|
||||||
'<li>In the Njal.la web interface, create a <strong>Dynamic</strong> record pointing to this machine\'s external IP address:<br>' +
|
'<li>In Njal.la, open a domain you own and click "Add record".</li>' +
|
||||||
'<span style="display:inline-block;margin-top:4px;padding:4px 10px;background:var(--card-color);border:1px solid var(--border-color);border-radius:6px;font-family:monospace;font-size:1em;font-weight:700;">' + escHtml(externalIp) + '</span></li>' +
|
'<li>Set record type to <strong>Dynamic</strong>.</li>' +
|
||||||
'<li>Njal.la will give you a curl command like:<br>' +
|
'<li>In the <strong>Name</strong> field, type ONLY the host part — the word before your domain.<br>' +
|
||||||
'<code style="font-size:0.8em;">curl "https://njal.la/update/?h=sub.domain.com&k=abc123&auto"</code></li>' +
|
'(Example only, your choice — for "call.yourdomain.com" you'd type just: <code>call</code>)<br>' +
|
||||||
'<li>Enter the subdomain and paste that curl command below</li>' +
|
'⚠ Do NOT type the full domain here — Njal.la adds it automatically.</li>' +
|
||||||
|
'<li>A Dynamic record has NO IP field — the IP auto-fills after the rebuild/reboot.</li>' +
|
||||||
|
'<li>Copy the curl command Njal.la gives you, e.g.:<br>' +
|
||||||
|
'<code style="font-size:0.8em;">curl "https://njal.la/update/?h=call.yourdomain.com&k=abc123&auto"</code></li>' +
|
||||||
'</ol>' +
|
'</ol>' +
|
||||||
|
'</details>' +
|
||||||
|
'<details style="margin-top:6px;">' +
|
||||||
|
'<summary style="cursor:pointer;font-weight:600;">Option B — Separate / new domain</summary>' +
|
||||||
|
'<ol style="margin:8px 0 0 16px;padding:0;line-height:1.7;">' +
|
||||||
|
'<li>In Njal.la, buy the domain you want.</li>' +
|
||||||
|
'<li>Add a Dynamic record as in Option A. If this domain is dedicated to the service, leave the Name field blank or use <code>@</code>.</li>' +
|
||||||
|
'<li>Copy the curl command Njal.la gives you.</li>' +
|
||||||
|
'</ol>' +
|
||||||
|
'</details>' +
|
||||||
|
'<p style="margin-top:10px;">Below, enter the full domain for this service — a subdomain (e.g. call.yourdomain.com) or a separate domain (e.g. call.com) — and paste its curl command.</p>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="domain-field-group"><label class="domain-field-label" for="domain-subdomain-input">Subdomain (e.g. myservice.example.com):</label><input class="domain-field-input" type="text" id="domain-subdomain-input" placeholder="myservice.example.com" /></div>' +
|
'<div class="domain-field-group"><label class="domain-field-label" for="domain-subdomain-input">Service domain (e.g. call.yourdomain.com):</label><input class="domain-field-input" type="text" id="domain-subdomain-input" placeholder="myservice.example.com" /></div>' +
|
||||||
'<div class="domain-field-group"><label class="domain-field-label" for="domain-ddns-input">Njal.la Dynamic DNS Update Command:</label><input class="domain-field-input" type="text" id="domain-ddns-input" placeholder="curl "https://njal.la/update/?h=myservice.example.com&k=abc123&auto"" /><p class="domain-field-hint">ℹ Paste the full curl command from your Njal.la dashboard\'s Dynamic record</p></div>' +
|
'<div class="domain-field-group"><label class="domain-field-label" for="domain-ddns-input">Njal.la Dynamic DNS Update Command:</label><input class="domain-field-input" type="text" id="domain-ddns-input" placeholder="curl "https://njal.la/update/?h=myservice.example.com&k=abc123&auto"" /><p class="domain-field-hint">ℹ Paste the full curl command from your Njal.la dashboard\'s Dynamic record</p></div>' +
|
||||||
npubField +
|
npubField +
|
||||||
'<div class="domain-field-actions"><button class="btn btn-close-modal" id="domain-setup-cancel-btn">Cancel</button><button class="btn btn-primary" id="domain-setup-save-btn">Save & Enable</button></div>';
|
'<div class="domain-field-actions"><button class="btn btn-close-modal" id="domain-setup-cancel-btn">Cancel</button><button class="btn btn-primary" id="domain-setup-save-btn">Save & Enable</button></div>';
|
||||||
@@ -103,7 +128,7 @@ function openDomainSetupModal(feat, onSaved) {
|
|||||||
ddnsUrl = ddnsUrl.trim();
|
ddnsUrl = ddnsUrl.trim();
|
||||||
npub = npub.trim();
|
npub = npub.trim();
|
||||||
|
|
||||||
if (!subdomain) { alert("Please enter a subdomain."); return; }
|
if (!subdomain) { alert("Please enter a domain."); return; }
|
||||||
if (feat.id === "haven" && !npub) { alert("Please enter your Nostr public key."); return; }
|
if (feat.id === "haven" && !npub) { alert("Please enter your Nostr public key."); return; }
|
||||||
|
|
||||||
var saveBtn = document.getElementById("domain-setup-save-btn");
|
var saveBtn = document.getElementById("domain-setup-save-btn");
|
||||||
@@ -159,14 +184,14 @@ function openDomainReconfigureModal(feat, existingDomain, onSaved) {
|
|||||||
'<p><strong>Troubleshooting steps:</strong></p>' +
|
'<p><strong>Troubleshooting steps:</strong></p>' +
|
||||||
'<ol>' +
|
'<ol>' +
|
||||||
'<li>Log into your Njal.la dashboard at <a href="https://njal.la" target="_blank" rel="noopener noreferrer" style="color:var(--accent-color);">https://njal.la</a></li>' +
|
'<li>Log into your Njal.la dashboard at <a href="https://njal.la" target="_blank" rel="noopener noreferrer" style="color:var(--accent-color);">https://njal.la</a></li>' +
|
||||||
'<li>Find the DNS record for <strong>' + escHtml(currentDomain || "your domain") + '</strong></li>' +
|
'<li>Find the DNS record for <strong>' + escHtml(currentDomain || "your domain") + '</strong>. In Njal.la\'s Name field, note that only the host part is stored (the word before the domain) — not the full domain.</li>' +
|
||||||
'<li>Verify it has a <strong>Dynamic</strong> record pointing to your current external IP:<br>' +
|
'<li>Verify it has a <strong>Dynamic</strong> record pointing to your current external IP:<br>' +
|
||||||
'<span style="display:inline-block;margin-top:4px;padding:4px 10px;background:var(--card-color);border:1px solid var(--border-color);border-radius:6px;font-family:monospace;font-size:1em;font-weight:700;">' + escHtml(externalIp) + '</span></li>' +
|
'<span style="display:inline-block;margin-top:4px;padding:4px 10px;background:var(--card-color);border:1px solid var(--border-color);border-radius:6px;font-family:monospace;font-size:1em;font-weight:700;">' + escHtml(externalIp) + '</span></li>' +
|
||||||
'<li>If the IP is wrong or the record is missing, update it</li>' +
|
'<li>If the IP is wrong or the record is missing, update it</li>' +
|
||||||
'<li>If you changed the DDNS curl command, paste the updated one below</li>' +
|
'<li>If you changed the DDNS curl command, paste the updated one below</li>' +
|
||||||
'</ol>' +
|
'</ol>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="domain-field-group"><label class="domain-field-label" for="domain-subdomain-input">Subdomain (e.g. myservice.example.com):</label><input class="domain-field-input" type="text" id="domain-subdomain-input" placeholder="myservice.example.com" value="' + escHtml(currentDomain) + '" /></div>' +
|
'<div class="domain-field-group"><label class="domain-field-label" for="domain-subdomain-input">Service domain (e.g. call.yourdomain.com):</label><input class="domain-field-input" type="text" id="domain-subdomain-input" placeholder="myservice.example.com" value="' + escHtml(currentDomain) + '" /></div>' +
|
||||||
'<div class="domain-field-group"><label class="domain-field-label" for="domain-ddns-input">Njal.la Dynamic DNS Update Command:</label><input class="domain-field-input" type="text" id="domain-ddns-input" placeholder="curl "https://njal.la/update/?h=myservice.example.com&k=abc123&auto"" /><p class="domain-field-hint">ℹ Paste the full curl command from your Njal.la dashboard\'s Dynamic record</p></div>' +
|
'<div class="domain-field-group"><label class="domain-field-label" for="domain-ddns-input">Njal.la Dynamic DNS Update Command:</label><input class="domain-field-input" type="text" id="domain-ddns-input" placeholder="curl "https://njal.la/update/?h=myservice.example.com&k=abc123&auto"" /><p class="domain-field-hint">ℹ Paste the full curl command from your Njal.la dashboard\'s Dynamic record</p></div>' +
|
||||||
npubField +
|
npubField +
|
||||||
'<div class="domain-field-actions"><button class="btn btn-close-modal" id="domain-setup-cancel-btn">Cancel</button><button class="btn btn-primary" id="domain-setup-save-btn">Save & Update</button></div>';
|
'<div class="domain-field-actions"><button class="btn btn-close-modal" id="domain-setup-cancel-btn">Cancel</button><button class="btn btn-primary" id="domain-setup-save-btn">Save & Update</button></div>';
|
||||||
|
|||||||
@@ -333,8 +333,6 @@ async function loadStep3() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var externalIp = (networkData && networkData.external_ip) || "Unknown (could not retrieve)";
|
|
||||||
|
|
||||||
// Build set of enabled service units
|
// Build set of enabled service units
|
||||||
var enabledUnits = new Set();
|
var enabledUnits = new Set();
|
||||||
(_servicesData || []).forEach(function(svc) {
|
(_servicesData || []).forEach(function(svc) {
|
||||||
@@ -352,18 +350,24 @@ async function loadStep3() {
|
|||||||
html += '<p class="onboarding-body-text">No domain-based services are enabled for your role. You can skip this step.</p>';
|
html += '<p class="onboarding-body-text">No domain-based services are enabled for your role. You can skip this step.</p>';
|
||||||
} else {
|
} else {
|
||||||
html += '<div class="onboarding-port-warn" style="margin-bottom:16px;">'
|
html += '<div class="onboarding-port-warn" style="margin-bottom:16px;">'
|
||||||
+ '<strong>Before you continue:</strong>'
|
+ '<p style="margin:0 0 8px;"><strong>Sovran_SystemsOS uses Njal.la for domains and Dynamic DNS.</strong></p>'
|
||||||
+ '<ol style="margin:8px 0 0 16px; padding:0; line-height:1.7;">'
|
+ '<ol style="margin:8px 0 0 16px; padding:0; line-height:1.7;">'
|
||||||
+ '<li>Create an account at <a href="https://njal.la" target="_blank" style="color:var(--accent-color);">https://njal.la</a></li>'
|
+ '<li>Create an account at <a href="https://njal.la" target="_blank" style="color:var(--accent-color);">https://njal.la</a>.</li>'
|
||||||
+ '<li>Purchase a new domain on Njal.la, or create a subdomain from a domain you already own. Tip: Subdomains are free to create — you only need to purchase one domain, and you can add as many subdomains as you like.</li>'
|
+ '<li>Buy at least one domain. Each service below needs its own domain — you can either give each service its own subdomain of a single domain you buy (subdomains are free, and one domain can have many), OR use a separate domain for each. Your choice.</li>'
|
||||||
+ '<li>In the Njal.la web interface, create a <strong>Dynamic</strong> record pointing to this machine\'s external IP address:<br>'
|
+ '<li>For each service, add a <strong>Dynamic</strong> record in Njal.la:'
|
||||||
+ '<span style="display:inline-block;margin-top:4px;padding:4px 12px;background:var(--card-color);border:1px solid var(--border-color);border-radius:6px;font-family:monospace;font-size:1.1em;font-weight:700;">' + escHtml(externalIp) + '</span></li>'
|
+ '<ul style="margin:4px 0 0 16px;padding:0;line-height:1.7;">'
|
||||||
+ '<li>Njal.la will give you a curl command like:<br>'
|
+ '<li>In the Njal.la <strong>Name</strong> field, type ONLY the host part — the word before your domain.<br>'
|
||||||
+ '<code style="font-size:0.8em;">curl "https://njal.la/update/?h=sub.domain.com&k=abc123&auto"</code></li>'
|
+ '(Example only, your choice — for "call.yourdomain.com" you'd type just: <code>call</code>.)<br>'
|
||||||
+ '<li>Enter the subdomain and paste that curl command below for each service</li>'
|
+ 'If you bought a whole separate domain just for this service, leave Name blank or use <code>@</code>.<br>'
|
||||||
|
+ '⚠ Do NOT type the full domain in the Name field — Njal.la adds it automatically.</li>'
|
||||||
|
+ '<li>A Dynamic record has NO IP field. You don't enter an IP anywhere — it auto-fills once Sovran_SystemsOS updates it (on save, and again after reboot).</li>'
|
||||||
|
+ '</ul>'
|
||||||
|
+ '</li>'
|
||||||
|
+ '<li>Njal.la gives you a curl command like:<br>'
|
||||||
|
+ '<code style="font-size:0.8em;">curl "https://njal.la/update/?h=call.yourdomain.com&k=abc123&auto"</code></li>'
|
||||||
+ '</ol>'
|
+ '</ol>'
|
||||||
+ '</div>';
|
+ '</div>';
|
||||||
html += '<p class="onboarding-hint">Enter each fully-qualified subdomain (e.g. <code>matrix.yourdomain.com</code>) and its Njal.la DDNS curl command.</p>';
|
html += '<p class="onboarding-hint">Enter each service\'s full domain — a subdomain (e.g. <code>call.yourdomain.com</code>) or a separate domain (e.g. <code>call.com</code>) — and its Njal.la DDNS curl command.</p>';
|
||||||
relevantDomains.forEach(function(d) {
|
relevantDomains.forEach(function(d) {
|
||||||
var currentVal = (_domainsData && _domainsData[d.name]) || "";
|
var currentVal = (_domainsData && _domainsData[d.name]) || "";
|
||||||
html += '<div class="onboarding-domain-group">';
|
html += '<div class="onboarding-domain-group">';
|
||||||
|
|||||||
@@ -128,9 +128,8 @@
|
|||||||
<h2 class="onboarding-step-title">Domain Configuration</h2>
|
<h2 class="onboarding-step-title">Domain Configuration</h2>
|
||||||
<p class="onboarding-step-desc">
|
<p class="onboarding-step-desc">
|
||||||
Sovran_SystemsOS uses <strong><a href="https://njal.la" target="_blank" style="color: var(--accent-color);">Njal.la</a></strong> for domains and Dynamic DNS.
|
Sovran_SystemsOS uses <strong><a href="https://njal.la" target="_blank" style="color: var(--accent-color);">Njal.la</a></strong> for domains and Dynamic DNS.
|
||||||
First, create an account at <strong>Njal.la</strong> and purchase a new domain, or create a subdomain from a domain you already own. Tip: Subdomains are free to create — you only need to purchase one domain, and you can add as many subdomains as you need at no extra cost.
|
Create an account at Njal.la, then for each service below, add a <strong>Dynamic</strong> record — no IP needed, it auto-populates once the DDNS curl command runs.
|
||||||
Then, in the Njal.la web interface, create a <strong>Dynamic</strong> record pointing to this machine's external IP address (shown below).
|
Paste the curl command from your Njal.la dashboard for each service.
|
||||||
Finally, paste the DDNS curl command from your Njal.la dashboard for each service below.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="onboarding-card" id="step-3-body">
|
<div class="onboarding-card" id="step-3-body">
|
||||||
|
|||||||
+1
-1
@@ -149,7 +149,7 @@
|
|||||||
gparted pv unzip parted screen zenity
|
gparted pv unzip parted screen zenity
|
||||||
libargon2 gnome-terminal libreoffice-fresh
|
libargon2 gnome-terminal libreoffice-fresh
|
||||||
dig firefox wp-cli axel
|
dig firefox wp-cli axel
|
||||||
lk-jwt-service livekit-libwebrtc livekit-cli livekit
|
lk-jwt-service livekit-libwebrtc livekit
|
||||||
matrix-synapse age
|
matrix-synapse age
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
Generated
+15
-15
@@ -5,11 +5,11 @@
|
|||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781013869,
|
"lastModified": 1781789880,
|
||||||
"narHash": "sha256-XlEUtL+8M6kbPdmIh4sQQ7G02/1CwHQEk1RPvIMEWOs=",
|
"narHash": "sha256-HU/J4pFFkC2XXsYO8B3QFneTV2NWEXFuNi4QmV/4ZA8=",
|
||||||
"owner": "emmanuelrosa",
|
"owner": "emmanuelrosa",
|
||||||
"repo": "btc-clients-nix",
|
"repo": "btc-clients-nix",
|
||||||
"rev": "9a6c78204dc8961840375b110bca595b1f6f084c",
|
"rev": "10f0300231075e6c7417030fbcbf9f056d0a7c21",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -139,11 +139,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs-stable": {
|
"nixpkgs-stable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1780902259,
|
"lastModified": 1781216227,
|
||||||
"narHash": "sha256-q8yYEC5f1mFlQO9RGna4LTc9QrcvWunX6FYp83munkQ=",
|
"narHash": "sha256-9mUW6gNwoN2SWc/l0fW4svPNOulXLl8ijqKyeSOGgJE=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "bd0ff2d3eac24699c3664d5966b9ef36f388e2ca",
|
"rev": "a0374025a863d007d98e3297f6aa46cc3141c2f0",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -187,11 +187,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_3": {
|
"nixpkgs_3": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1780749050,
|
"lastModified": 1781577229,
|
||||||
"narHash": "sha256-3av0pIjlOWQ6rDbNOmpUSvbNnJkGORQKKjb4LtCZsIY=",
|
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a799d3e3886da994fa307f817a6bc705ae538eeb",
|
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -203,11 +203,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_4": {
|
"nixpkgs_4": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1780336545,
|
"lastModified": 1781607440,
|
||||||
"narHash": "sha256-vhVhuXzFrIOfcssC/9hDHx7MHzDKjF3keHuREOQqQiQ=",
|
"narHash": "sha256-rxO+uc/KFbSJp+pgyXRuAX6QlG9hJdnt0BXpEQRXY+U=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "4df1b885d76a54e1aa1a318f8d16fd6005b6401f",
|
"rev": "3e41b24abd260e8f71dbe2f5737d24122f972158",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -224,11 +224,11 @@
|
|||||||
"systems": "systems_2"
|
"systems": "systems_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1780995253,
|
"lastModified": 1781713417,
|
||||||
"narHash": "sha256-6Lsoyw2XPvY8YNMCtPnsyw0JVVtHsXP2xtrFJBBTAOQ=",
|
"narHash": "sha256-Kaj44jTNmnaFhKrcADx8nXmUYPa7l2HYfb7m6lEPy7Q=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixvim",
|
"repo": "nixvim",
|
||||||
"rev": "43a7e6f82978ac975c3bba6728869b231e7a1ba0",
|
"rev": "caee4e5d4161778815f522d9ea1c9e3dc42462b7",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
+59
-18
@@ -34,8 +34,8 @@ lib.mkIf config.sovran_systemsOS.features.element-calling {
|
|||||||
};
|
};
|
||||||
|
|
||||||
####### ENSURE SERVICES START AFTER KEY EXISTS #######
|
####### ENSURE SERVICES START AFTER KEY EXISTS #######
|
||||||
systemd.services.livekit.after = [ "livekit-key-setup.service" ];
|
systemd.services.livekit.after = [ "livekit-key-setup.service" "livekit-turn-setup.service" ];
|
||||||
systemd.services.livekit.wants = [ "livekit-key-setup.service" ];
|
systemd.services.livekit.wants = [ "livekit-key-setup.service" "livekit-turn-setup.service" ];
|
||||||
systemd.services.lk-jwt-service.after = [ "livekit-key-setup.service" ];
|
systemd.services.lk-jwt-service.after = [ "livekit-key-setup.service" ];
|
||||||
systemd.services.lk-jwt-service.wants = [ "livekit-key-setup.service" ];
|
systemd.services.lk-jwt-service.wants = [ "livekit-key-setup.service" ];
|
||||||
|
|
||||||
@@ -89,11 +89,17 @@ EOF
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
####### LIVEKIT RUNTIME CONFIG #######
|
####### LIVEKIT TURN SETUP (runtime cert + config) #######
|
||||||
systemd.services.livekit-runtime-config = {
|
# Replaces the old dead livekit-runtime-config.service. At runtime this:
|
||||||
description = "Generate LiveKit runtime config from domain files";
|
# * reads the matrix domain from /var/lib/domains/matrix (never hardcoded)
|
||||||
|
# * copies Caddy's already-issued matrix cert/key into /var/lib/livekit
|
||||||
|
# so LoadCredential can stage them for the (DynamicUser) livekit unit
|
||||||
|
# * writes a complete LiveKit config (with turn.domain substituted) that the
|
||||||
|
# overridden ExecStart loads.
|
||||||
|
systemd.services.livekit-turn-setup = {
|
||||||
|
description = "Stage TURN cert and generate LiveKit runtime config from domain files";
|
||||||
|
after = [ "caddy.service" "livekit-key-setup.service" ];
|
||||||
before = [ "livekit.service" ];
|
before = [ "livekit.service" ];
|
||||||
after = [ "livekit-key-setup.service" ];
|
|
||||||
requiredBy = [ "livekit.service" ];
|
requiredBy = [ "livekit.service" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
@@ -103,20 +109,42 @@ EOF
|
|||||||
unitConfig = {
|
unitConfig = {
|
||||||
ConditionPathExists = "/var/lib/domains/element-calling";
|
ConditionPathExists = "/var/lib/domains/element-calling";
|
||||||
};
|
};
|
||||||
path = [ pkgs.coreutils ];
|
path = [ pkgs.coreutils pkgs.findutils ];
|
||||||
script = ''
|
script = ''
|
||||||
MATRIX=$(cat /var/lib/domains/matrix)
|
MATRIX=$(cat /var/lib/domains/matrix)
|
||||||
|
|
||||||
mkdir -p /run/livekit
|
mkdir -p /run/livekit
|
||||||
|
|
||||||
cat > /run/livekit/runtime-config.yaml <<EOF
|
# Copy Caddy's already-issued matrix cert/key into LiveKit's state dir.
|
||||||
|
# The ACME CA hostname directory can vary, so glob for the domain dir.
|
||||||
|
CRT=$(find /var/lib/caddy -path "*/$MATRIX/$MATRIX.crt" | head -n1)
|
||||||
|
KEY=$(find /var/lib/caddy -path "*/$MATRIX/$MATRIX.key" | head -n1)
|
||||||
|
cp "$CRT" /var/lib/livekit/turn.crt
|
||||||
|
cp "$KEY" /var/lib/livekit/turn.key
|
||||||
|
chmod 640 /var/lib/livekit/turn.crt /var/lib/livekit/turn.key
|
||||||
|
|
||||||
|
# Generate the full LiveKit config the daemon will load. turn.domain is
|
||||||
|
# only known at runtime, so it is substituted here. The cert/key paths
|
||||||
|
# point at the LoadCredential-staged copies under /run/credentials.
|
||||||
|
cat > /run/livekit/livekit.yaml <<EOF
|
||||||
|
port: 7880
|
||||||
|
rtc:
|
||||||
|
use_external_ip: true
|
||||||
|
udp_port: 7882
|
||||||
|
port_range_start: 30000
|
||||||
|
port_range_end: 40000
|
||||||
|
room:
|
||||||
|
auto_create: false
|
||||||
turn:
|
turn:
|
||||||
|
enabled: true
|
||||||
domain: $MATRIX
|
domain: $MATRIX
|
||||||
cert_file: /var/lib/livekit/$MATRIX.crt
|
tls_port: 5349
|
||||||
key_file: /var/lib/livekit/$MATRIX.key
|
udp_port: 3478
|
||||||
|
cert_file: /run/credentials/livekit.service/turn-cert
|
||||||
|
key_file: /run/credentials/livekit.service/turn-key
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
chmod 640 /run/livekit/runtime-config.yaml
|
chmod 644 /run/livekit/livekit.yaml
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -128,6 +156,8 @@ EOF
|
|||||||
settings = {
|
settings = {
|
||||||
rtc.use_external_ip = true;
|
rtc.use_external_ip = true;
|
||||||
rtc.udp_port = 7882;
|
rtc.udp_port = 7882;
|
||||||
|
rtc.port_range_start = 30000;
|
||||||
|
rtc.port_range_end = 40000;
|
||||||
room.auto_create = false;
|
room.auto_create = false;
|
||||||
turn = {
|
turn = {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
@@ -137,15 +167,26 @@ EOF
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Override ExecStart to load the runtime-generated config (which carries the
|
||||||
|
# runtime-only turn.domain), mirroring the Caddy ExecStart override pattern in
|
||||||
|
# modules/core/caddy.nix. Deliver the TURN cert/key via LoadCredential so they
|
||||||
|
# are readable under the upstream unit's DynamicUser=true sandbox without
|
||||||
|
# weakening it. Everything else about the standard unit is left intact.
|
||||||
|
systemd.services.livekit.serviceConfig.ExecStart = lib.mkForce [
|
||||||
|
""
|
||||||
|
"${pkgs.livekit}/bin/livekit-server --config /run/credentials/livekit.service/livekit-config --key-file /run/credentials/livekit.service/livekit-secrets"
|
||||||
|
];
|
||||||
|
|
||||||
|
systemd.services.livekit.serviceConfig.LoadCredential = [
|
||||||
|
"livekit-config:/run/livekit/livekit.yaml"
|
||||||
|
"livekit-secrets:${livekitKeyFile}"
|
||||||
|
"turn-cert:/var/lib/livekit/turn.crt"
|
||||||
|
"turn-key:/var/lib/livekit/turn.key"
|
||||||
|
];
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 5349 7881 ];
|
networking.firewall.allowedTCPPorts = [ 5349 7881 ];
|
||||||
networking.firewall.allowedUDPPorts = [ 3478 7882 ];
|
networking.firewall.allowedUDPPorts = [ 3478 7882 ];
|
||||||
networking.firewall.allowedUDPPortRanges = [
|
|
||||||
{ from = 30000; to = 40000; }
|
|
||||||
];
|
|
||||||
networking.firewall.allowedTCPPortRanges = [
|
|
||||||
{ from = 30000; to = 40000; }
|
|
||||||
];
|
|
||||||
|
|
||||||
####### JWT SERVICE RUNTIME CONFIG #######
|
####### JWT SERVICE RUNTIME CONFIG #######
|
||||||
systemd.services.lk-jwt-service-runtime-config = {
|
systemd.services.lk-jwt-service-runtime-config = {
|
||||||
description = "Generate lk-jwt-service runtime config from domain files";
|
description = "Generate lk-jwt-service runtime config from domain files";
|
||||||
|
|||||||
Reference in New Issue
Block a user