Show domains in pool status

This commit is contained in:
2026-08-18 02:53:40 +03:00
parent a1fa90c66a
commit eb5f4cbf5a
12 changed files with 517 additions and 141 deletions
+18 -5
View File
@@ -3,6 +3,7 @@ import { i18n } from '../i18n'
import { sdk } from '../sdk'
import {
defaultStratumPort,
defaultStratumPublicTlsPort,
defaultStratumTlsPort,
logLevels,
validatePorts,
@@ -12,9 +13,9 @@ const { InputSpec, Value } = sdk
export const inputSpec = InputSpec.of({
stratumPort: Value.number({
name: i18n('Stratum Port'),
name: i18n('Preferred Stratum Port'),
description: i18n(
'Network port your miners connect to for plaintext stratum. StartOS publishes the pool on this port; if it is already claimed by another service the OS assigns a different one, so check the Stratum interface after saving. Changing this does not interrupt connected miners.',
'Network port to publish plaintext stratum on. This is a request, not a guarantee: if the port is already claimed the OS assigns a different one and warns you. Run the Pool Status action to see the ports actually in use. Changing this does not interrupt connected miners.',
),
required: true,
default: defaultStratumPort,
@@ -23,9 +24,9 @@ export const inputSpec = InputSpec.of({
max: 65535,
}),
stratumTlsPort: Value.number({
name: i18n('Stratum TLS Port'),
name: i18n('Preferred Stratum TLS Port (Local Network)'),
description: i18n(
'Network port your miners connect to for TLS stratum — both for the local self-signed certificate and for any public domain attached to the Stratum (TLS) interface.',
'Network port to publish local-network TLS stratum on, using the self-signed certificate. A request, not a guarantee — see Pool Status for the port actually in use.',
),
required: true,
default: defaultStratumTlsPort,
@@ -33,6 +34,17 @@ export const inputSpec = InputSpec.of({
min: 1,
max: 65535,
}),
stratumPublicTlsPort: Value.number({
name: i18n('Preferred Stratum TLS Port (Public Domain)'),
description: i18n(
'Network port to publish public-domain TLS stratum on. A domain attached to the Stratum (TLS, Public Domain) interface is published on THIS port, which can differ from the one the OS assigns for IP access, and StartOS issues a Lets Encrypt certificate for it — miners validate it with nothing pasted in. See Pool Status for the ports and domains actually in use.',
),
required: true,
default: defaultStratumPublicTlsPort,
integer: true,
min: 1,
max: 65535,
}),
coinbaseTag: Value.text({
name: i18n('Coinbase Tag'),
description: i18n(
@@ -56,7 +68,7 @@ export const inputSpec = InputSpec.of({
tlsEnabled: Value.toggle({
name: i18n('Stratum TLS (Local Network)'),
description: i18n(
'Serve the self-signed certificate on the TLS stratum port, for miners on your local network. Miners have to trust it (see the Stratum TLS Certificate action) or connect with verification disabled. You do NOT need this for miners connecting over a public domain: attach the domain to the Stratum (TLS) interface and StartOS issues a publicly trusted certificate automatically.',
'Serve the self-signed certificate on the local-network TLS port. Miners have to trust it (see the Stratum TLS Certificate action) or connect with verification disabled. You do NOT need this for miners connecting over a public domain: attach the domain to the Stratum (TLS, Public Domain) interface instead, and StartOS issues a publicly trusted certificate for it automatically.',
),
default: false,
}),
@@ -151,6 +163,7 @@ export const config = sdk.Action.withInput(
const conflict = validatePorts({
stratumPort: input.stratumPort,
stratumTlsPort: input.stratumTlsPort,
stratumPublicTlsPort: input.stratumPublicTlsPort,
})
if (conflict) throw new Error(conflict)
+42 -3
View File
@@ -1,7 +1,14 @@
import { storeJson } from '../fileModels/store.json'
import { i18n } from '../i18n'
import { sdk } from '../sdk'
import { curlJson, defaultStratumPort, uiPort } from '../utils'
import {
curlJson,
defaultStratumPort,
defaultStratumPublicTlsPort,
defaultStratumTlsPort,
endpointPorts,
uiPort,
} from '../utils'
const API_BASE = `http://127.0.0.1:${uiPort}`
@@ -158,8 +165,22 @@ export const poolStatus = sdk.Action.withoutInput(
// the execution function
async ({ effects }) => {
const stratumPort =
(await storeJson.read((s) => s.stratumPort).once()) ?? defaultStratumPort
// Effective external ports, straight from the OS. The Configure form holds
// a *request*; if the port was taken the OS granted a different one, and
// this is where the user finds out what miners must actually connect to.
const requests = (await storeJson
.read((s) => ({
stratum: s.stratumPort,
tls: s.stratumTlsPort,
publicTls: s.stratumPublicTlsPort,
}))
.once()) ?? {
stratum: defaultStratumPort,
tls: defaultStratumTlsPort,
publicTls: defaultStratumPublicTlsPort,
}
const ports = await endpointPorts(effects, requests, 'once')
const stratumPort = ports[0].assigned ?? ports[0].requested
// Fetch from inside the service's network namespace: temp subcontainers
// share it, so curl reaches kamado-api on 127.0.0.1.
@@ -354,6 +375,24 @@ export const poolStatus = sdk.Action.withoutInput(
// ── 2. Stratum ───────────────────────────────────────────────────────────
log('')
sep()
log('● Endpoints (the ports miners connect to)')
for (const p of ports) {
const assigned = p.assigned ?? p.requested
const note =
p.assigned === null
? ' (not assigned yet)'
: p.assigned !== p.requested
? ` <- REQUESTED ${p.requested}, reassigned by StartOS`
: ''
log(` ${pad(p.label, 30)} ${assigned}${note}`)
// Domains publish on the requested port rather than the assigned one, so
// list them explicitly instead of letting the reader assume the number
// above applies to them too.
for (const d of p.domains) {
log(` ${pad(' domain:', 30)} ${d.fqdn}:${d.port}`)
}
}
log('')
log(`● Stratum (port ${stratumPort})`)
if (snap?.ckpool_ok) {
log(
+2 -2
View File
@@ -51,7 +51,7 @@ export const showTlsCert = sdk.Action.withoutInput(
version: '1',
title: i18n('Stratum TLS Certificate'),
message: i18n(
'Connect miners with stratum+ssl:// to the Stratum (TLS) interface. The certificate is self-signed: paste the PEM into firmware that accepts a custom root, pin the fingerprint, or disable verification.',
'Connect miners with stratum+ssl:// to the Stratum (TLS, Local Network) interface. The certificate is self-signed: paste the PEM into firmware that accepts a custom root, pin the fingerprint, or disable verification. Miners connecting over a public domain do not need any of this — they use the Stratum (TLS, Public Domain) interface and its CA-issued certificate.',
),
result: {
type: 'group',
@@ -59,7 +59,7 @@ export const showTlsCert = sdk.Action.withoutInput(
{
name: i18n('TLS Port (internal)'),
description: i18n(
'Container-side TLS stratum port. The externally reachable port is shown on the Stratum (TLS) interface.',
'Container-side TLS stratum port. The externally reachable port is shown on the Stratum (TLS, Local Network) interface.',
),
type: 'single',
value: String(tlsPort),