Config: Update visibility/order of cluster options and flags #98

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer
2025-09-22 05:37:54 +02:00
parent 578fbe4d10
commit bfd26c55e3
5 changed files with 50 additions and 53 deletions

View File

@@ -13,39 +13,7 @@ import (
"github.com/photoprism/photoprism/pkg/rnd"
)
// ClusterDomain returns the cluster DOMAIN (lowercase DNS name; 163 chars).
func (c *Config) ClusterDomain() string {
return c.options.ClusterDomain
}
// ClusterUUID returns a stable UUIDv4 that uniquely identifies the Portal.
// Precedence: env PHOTOPRISM_CLUSTER_UUID -> options.yml (ClusterUUID) -> auto-generate and persist.
func (c *Config) ClusterUUID() string {
// Use value loaded into options only if it is persisted in the current options.yml.
// This avoids tests (or defaults) loading a UUID from an unrelated file path.
if c.options.ClusterUUID != "" {
// Respect explicit CLI value if provided.
if c.cliCtx != nil && c.cliCtx.IsSet("cluster-uuid") {
return c.options.ClusterUUID
}
// Otherwise, only trust a persisted value from the current options.yml.
if fs.FileExists(c.OptionsYaml()) {
return c.options.ClusterUUID
}
}
// Generate, persist, and cache in memory if still empty.
id := rnd.UUID()
c.options.ClusterUUID = id
if err := c.saveClusterUUID(id); err != nil {
log.Warnf("config: failed to persist ClusterUUID to %s (%s)", c.OptionsYaml(), err)
}
return id
}
// PortalUrl returns the URL of the cluster portal server, if configured.
// PortalUrl returns the URL of the cluster management portal server, if configured.
func (c *Config) PortalUrl() string {
return c.options.PortalUrl
}
@@ -85,6 +53,38 @@ func (c *Config) JoinToken() string {
}
}
// ClusterUUID returns a stable UUIDv4 that uniquely identifies the Portal.
// Precedence: env PHOTOPRISM_CLUSTER_UUID -> options.yml (ClusterUUID) -> auto-generate and persist.
func (c *Config) ClusterUUID() string {
// Use value loaded into options only if it is persisted in the current options.yml.
// This avoids tests (or defaults) loading a UUID from an unrelated file path.
if c.options.ClusterUUID != "" {
// Respect explicit CLI value if provided.
if c.cliCtx != nil && c.cliCtx.IsSet("cluster-uuid") {
return c.options.ClusterUUID
}
// Otherwise, only trust a persisted value from the current options.yml.
if fs.FileExists(c.OptionsYaml()) {
return c.options.ClusterUUID
}
}
// Generate, persist, and cache in memory if still empty.
id := rnd.UUID()
c.options.ClusterUUID = id
if err := c.saveClusterUUID(id); err != nil {
log.Warnf("config: failed to persist ClusterUUID to %s (%s)", c.OptionsYaml(), err)
}
return id
}
// ClusterDomain returns the cluster DOMAIN (lowercase DNS name; 163 chars).
func (c *Config) ClusterDomain() string {
return c.options.ClusterDomain
}
// NodeName returns the cluster node NAME (unique in cluster domain; [a-z0-9-]{1,32}).
func (c *Config) NodeName() string {
return clean.TypeLowerDash(c.options.NodeName)

View File

@@ -664,28 +664,25 @@ var Flags = CliFlags{
EnvVars: EnvVars("CORS_METHODS"),
Value: header.DefaultAccessControlAllowMethods,
}}, {
Flag: &cli.StringFlag{
Name: "cluster-domain",
Usage: "cluster `DOMAIN` (lowercase DNS name; 163 chars)",
EnvVars: EnvVars("CLUSTER_DOMAIN"),
}}, {
Flag: &cli.StringFlag{
Name: "cluster-uuid",
Usage: "cluster `UUID` (v4) to scope per-node credentials",
EnvVars: EnvVars("CLUSTER_UUID"),
Hidden: true,
}}, {
Flag: &cli.StringFlag{
Name: "portal-url",
Usage: "base `URL` of the cluster portal (e.g. https://portal.example.com)",
Usage: "base `URL` of the cluster management portal (e.g. https://portal.example.com)",
EnvVars: EnvVars("PORTAL_URL"),
Hidden: true,
}}, {
Flag: &cli.StringFlag{
Name: "join-token",
Usage: "secret `TOKEN` required to join the cluster",
EnvVars: EnvVars("JOIN_TOKEN"),
Hidden: true,
}}, {
Flag: &cli.StringFlag{
Name: "cluster-uuid",
Usage: "cluster `UUID` (v4) to scope node credentials",
EnvVars: EnvVars("CLUSTER_UUID"),
}}, {
Flag: &cli.StringFlag{
Name: "cluster-domain",
Usage: "cluster `DOMAIN` (lowercase DNS name; 163 chars)",
EnvVars: EnvVars("CLUSTER_DOMAIN"),
}}, {
Flag: &cli.StringFlag{
Name: "node-name",

View File

@@ -142,10 +142,10 @@ type Options struct {
CORSOrigin string `yaml:"CORSOrigin" json:"-" flag:"cors-origin"`
CORSHeaders string `yaml:"CORSHeaders" json:"-" flag:"cors-headers"`
CORSMethods string `yaml:"CORSMethods" json:"-" flag:"cors-methods"`
ClusterDomain string `yaml:"ClusterDomain" json:"-" flag:"cluster-domain"`
ClusterUUID string `yaml:"ClusterUUID" json:"-" flag:"cluster-uuid"`
PortalUrl string `yaml:"PortalUrl" json:"-" flag:"portal-url"`
JoinToken string `yaml:"JoinToken" json:"-" flag:"join-token"`
ClusterUUID string `yaml:"ClusterUUID" json:"-" flag:"cluster-uuid"`
ClusterDomain string `yaml:"ClusterDomain" json:"-" flag:"cluster-domain"`
NodeName string `yaml:"NodeName" json:"-" flag:"node-name"`
NodeRole string `yaml:"NodeRole" json:"-" flag:"node-role"`
NodeID string `yaml:"NodeID" json:"-" flag:"node-id"`

View File

@@ -162,12 +162,12 @@ func (c *Config) Report() (rows [][]string, cols []string) {
{"site-preview", c.SitePreview()},
// Cluster Configuration.
{"cluster-domain", c.ClusterDomain()},
{"cluster-uuid", c.ClusterUUID()},
{"portal-url", c.PortalUrl()},
{"portal-config-path", c.PortalConfigPath()},
{"portal-theme-path", c.PortalThemePath()},
{"join-token", fmt.Sprintf("%s", strings.Repeat("*", utf8.RuneCountInString(c.JoinToken())))},
{"cluster-uuid", c.ClusterUUID()},
{"cluster-domain", c.ClusterDomain()},
{"node-name", c.NodeName()},
{"node-role", c.NodeRole()},
{"node-id", c.NodeID()},

View File

@@ -25,7 +25,7 @@ var OptionsReportSections = []ReportSection{
{Start: "PHOTOPRISM_READONLY", Title: "Feature Flags"},
{Start: "PHOTOPRISM_DEFAULT_LOCALE", Title: "Customization"},
{Start: "PHOTOPRISM_SITE_URL", Title: "Site Information"},
{Start: "PHOTOPRISM_CLUSTER_DOMAIN", Title: "Cluster Configuration"},
{Start: "PHOTOPRISM_PORTAL_URL", Title: "Cluster Configuration"},
{Start: "PHOTOPRISM_HTTPS_PROXY", Title: "Proxy Server"},
{Start: "PHOTOPRISM_DISABLE_TLS", Title: "Web Server"},
{Start: "PHOTOPRISM_DATABASE_DRIVER", Title: "Database Connection"},
@@ -52,7 +52,7 @@ var YamlReportSections = []ReportSection{
{Start: "ReadOnly", Title: "Feature Flags"},
{Start: "DefaultLocale", Title: "Customization"},
{Start: "SiteUrl", Title: "Site Information"},
{Start: "ClusterDomain", Title: "Cluster Configuration"},
{Start: "PortalUrl", Title: "Cluster Configuration"},
{Start: "HttpsProxy", Title: "Proxy Server"},
{Start: "DisableTLS", Title: "Web Server"},
{Start: "DatabaseDriver", Title: "Database Connection"},