Compare commits

6 Commits

Author SHA1 Message Date
Sovran_Systems
84d76f0436 Merge pull request #66 from naturallaw777/copilot/update-installer-for-desktop-only
Desktop Only: enforce 128 GB boot disk minimum, skip data disk logic
2026-04-05 00:08:54 -05:00
copilot-swe-agent[bot]
9664c59523 feat: enforce 128 GB minimum, skip data disk for Desktop Only role
Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/2be6c138-feda-4c5d-9bd8-0e5f2f6416bc

Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
2026-04-05 05:07:55 +00:00
copilot-swe-agent[bot]
265f34b8aa Initial plan 2026-04-05 05:06:55 +00:00
Sovran_Systems
0d6e7e6381 Merge pull request #65 from naturallaw777/copilot/add-btcpay-web-feature
feat(node): add BTCPay Server web exposure as a toggleable feature
2026-04-04 23:59:15 -05:00
copilot-swe-agent[bot]
e5d3b9236c feat: add btcpay-web feature toggle for node role
Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/3881717f-97fc-4b8a-8f01-794a0699e7b3

Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
2026-04-05 04:55:25 +00:00
copilot-swe-agent[bot]
53c2371c45 Initial plan 2026-04-05 04:53:41 +00:00
2 changed files with 39 additions and 4 deletions

View File

@@ -192,6 +192,21 @@ FEATURE_REGISTRY = [
"conflicts_with": ["bip110"], "conflicts_with": ["bip110"],
"port_requirements": [], "port_requirements": [],
}, },
{
"id": "btcpay-web",
"name": "BTCPay Server Web Access",
"description": "Expose BTCPay Server to the internet via your domain. When disabled, BTCPay Server still runs locally but is not accessible from the web.",
"category": "bitcoin",
"needs_domain": True,
"domain_name": "btcpayserver",
"needs_ddns": True,
"extra_fields": [],
"conflicts_with": [],
"port_requirements": [
{"port": "80", "protocol": "TCP", "description": "HTTP (redirect to HTTPS)"},
{"port": "443", "protocol": "TCP", "description": "HTTPS"},
],
},
] ]
# Map feature IDs to their systemd units in config.json # Map feature IDs to their systemd units in config.json
@@ -202,6 +217,7 @@ FEATURE_SERVICE_MAP = {
"mempool": "mempool.service", "mempool": "mempool.service",
"bip110": None, "bip110": None,
"bitcoin-core": None, "bitcoin-core": None,
"btcpay-web": "btcpayserver.service",
} }
# Port requirements for service tiles (keyed by unit name or icon) # Port requirements for service tiles (keyed by unit name or icon)
@@ -270,7 +286,7 @@ ROLE_CATEGORIES: dict[str, set[str] | None] = {
ROLE_FEATURES: dict[str, set[str] | None] = { ROLE_FEATURES: dict[str, set[str] | None] = {
"server_plus_desktop": None, "server_plus_desktop": None,
"desktop": {"rdp"}, "desktop": {"rdp"},
"node": {"rdp", "bip110", "bitcoin-core", "mempool"}, "node": {"rdp", "bip110", "bitcoin-core", "mempool", "btcpay-web"},
} }
SERVICE_DESCRIPTIONS: dict[str, str] = { SERVICE_DESCRIPTIONS: dict[str, str] = {
@@ -932,6 +948,11 @@ def _read_hub_overrides() -> tuple[dict, str | None]:
section, section,
): ):
features[m.group(1)] = m.group(2) == "true" features[m.group(1)] = m.group(2) == "true"
for m in re.finditer(
r'sovran_systemsOS\.web\.btcpayserver\s*=\s*(?:lib\.mkForce\s+)?(true|false)\s*;',
section,
):
features["btcpay-web"] = m.group(1) == "true"
m2 = re.search( m2 = re.search(
r'sovran_systemsOS\.nostr_npub\s*=\s*(?:lib\.mkForce\s+)?"([^"]*)"', r'sovran_systemsOS\.nostr_npub\s*=\s*(?:lib\.mkForce\s+)?"([^"]*)"',
section, section,
@@ -948,6 +969,9 @@ def _write_hub_overrides(features: dict, nostr_npub: str | None) -> None:
lines = [] lines = []
for feat_id, enabled in features.items(): for feat_id, enabled in features.items():
val = "true" if enabled else "false" val = "true" if enabled else "false"
if feat_id == "btcpay-web":
lines.append(f" sovran_systemsOS.web.btcpayserver = lib.mkForce {val};")
else:
lines.append(f" sovran_systemsOS.features.{feat_id} = lib.mkForce {val};") lines.append(f" sovran_systemsOS.features.{feat_id} = lib.mkForce {val};")
if nostr_npub: if nostr_npub:
lines.append(f' sovran_systemsOS.nostr_npub = lib.mkForce "{nostr_npub}";') lines.append(f' sovran_systemsOS.nostr_npub = lib.mkForce "{nostr_npub}";')
@@ -990,6 +1014,8 @@ def _write_hub_overrides(features: dict, nostr_npub: str | None) -> None:
def _is_feature_enabled_in_config(feature_id: str) -> bool | None: def _is_feature_enabled_in_config(feature_id: str) -> bool | None:
"""Check if a feature's service appears as enabled in the running config.json. """Check if a feature's service appears as enabled in the running config.json.
Returns True/False if found, None if the feature has no mapped service.""" Returns True/False if found, None if the feature has no mapped service."""
if feature_id == "btcpay-web":
return False # Default off in Node role; only on via explicit hub toggle
unit = FEATURE_SERVICE_MAP.get(feature_id) unit = FEATURE_SERVICE_MAP.get(feature_id)
if unit is None: if unit is None:
return None # bip110, bitcoin-core — can't determine from config return None # bip110, bitcoin-core — can't determine from config

View File

@@ -501,8 +501,17 @@ class InstallerWindow(Adw.ApplicationWindow):
self.boot_disk, self.boot_size = disks[0] self.boot_disk, self.boot_size = disks[0]
self.data_disk, self.data_size = None, None self.data_disk, self.data_size = None, None
BYTES_128GB = 128 * 1024 ** 3
if self.role == "Desktop Only" and self.boot_size < BYTES_128GB:
self.show_error(
f"Boot disk /dev/{self.boot_disk} is only "
f"{human_size(self.boot_size)}. "
f"The Desktop Only role requires at least 128 GB."
)
return
BYTES_2TB = 2 * 1024 ** 4 BYTES_2TB = 2 * 1024 ** 4
if len(disks) >= 2: if self.role != "Desktop Only" and len(disks) >= 2:
d, s = disks[-1] d, s = disks[-1]
if s >= BYTES_2TB: if s >= BYTES_2TB:
self.data_disk, self.data_size = d, s self.data_disk, self.data_size = d, s
@@ -528,7 +537,7 @@ class InstallerWindow(Adw.ApplicationWindow):
data_row.set_subtitle(f"/dev/{self.data_disk}{human_size(self.data_size)}") data_row.set_subtitle(f"/dev/{self.data_disk}{human_size(self.data_size)}")
data_row.add_prefix(symbolic_icon("drive-harddisk-symbolic")) data_row.add_prefix(symbolic_icon("drive-harddisk-symbolic"))
disk_group.add(data_row) disk_group.add(data_row)
else: elif self.role != "Desktop Only":
no_row = Adw.ActionRow() no_row = Adw.ActionRow()
no_row.set_title("Data Disk") no_row.set_title("Data Disk")
no_row.set_subtitle("None detected (requires 2 TB or larger)") no_row.set_subtitle("None detected (requires 2 TB or larger)")