siteops

package
v1.26.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	StopRuntimeWorkers func(site *config.Site) []string
	RecreateFPMWorkers func(site *config.Site, workers []string)
)

StopRuntimeWorkers and RecreateFPMWorkers let the cli package (which owns worker lifecycle) tear down a FrankenPHP site's workers before its per-site container is removed and rebuild them against the shared FPM container once the registry has been flipped to FPM. They mirror switchToFPM, wired at init the same way as StopSiteWorkers. Without them a demote leaves the workers' units still pointed at (and BindsTo) the removed FrankenPHP container, where heal can't recover them. StopRuntimeWorkers returns the names it stopped.

View Source
var (
	NginxTestFn   = nginx.Test
	NginxReloadFn = nginx.Reload
)

NginxTestFn / NginxReloadFn are indirections so tests can stub the podman-bound `nginx -t` and reload. The global-nginx editor reuses these so site and global saves share one validator/reload pair. Defaults are real.

View Source
var StopSiteWorkers func(site *config.Site)

StopSiteWorkers, when set, stops all running workers for a site as part of UnlinkSiteCore. It is wired up by the cli package (which owns worker lifecycle) at init time, mirroring podman.AfterUnitChange. Without it, the MCP and parked-watcher unlink paths — which call UnlinkSiteCore directly — would leave a host-proxy site's always-restart dev-server worker (and any framework workers) running after the site is gone.

Functions

func CleanupRelink(path, newName string) bool

CleanupRelink handles the re-link scenario: when a site is being linked at a path that already has registrations, it carries over the secured state and removes stale entries (e.g. name changed). Returns the carried-over secured flag.

func CustomNginxPath added in v1.23.0

func CustomNginxPath(domain string) string

CustomNginxPath is the on-disk path of a domain's custom override.

func DemoteFrankenPHPToFPM added in v1.25.0

func DemoteFrankenPHPToFPM(site *config.Site) error

DemoteFrankenPHPToFPM drops a FrankenPHP site back to the FPM runtime: it stops and tears down the per-site FrankenPHP container, clears the runtime in the registry and the project's .lerd.yaml, regenerates the normal fastcgi vhost, and recreates any running workers against the shared FPM container. It is the fallback the CLI takes (via runLink) when a site's PHP version is changed below the FrankenPHP minimum, mirrored here so the UI and MCP never silently upgrade PHP behind the user's back. The passed site is mutated to FPM.

func FinishCustomFPMLink(site config.Site, containerCfg *config.ContainerConfig) error

FinishCustomFPMLink performs post-registration steps for a PHP site whose runtime is "fpm-custom": build the per-site image from the project's Containerfile (FROM the lerd base, so it keeps php-fpm and the extensions), write a per-site FPM quadlet that reuses every lerd mount, start the container, and generate a normal fastcgi vhost pointing at it.

func FinishCustomLink(site config.Site, containerCfg *config.ContainerConfig) error

FinishCustomLink performs the post-registration steps for a custom container site: build the image, write a dedicated quadlet, generate a proxy vhost, update container hosts, and reload nginx.

func FinishFrankenPHPLink(site config.Site) error

FinishFrankenPHPLink performs the post-registration steps for a site whose runtime is "frankenphp": ensure the image is pulled, write a per-site quadlet that runs the framework's entrypoint, generate an nginx proxy vhost, update container hosts, and reload nginx.

func FinishHostProxyLink(site config.Site) error

FinishHostProxyLink performs the post-registration steps for a host-proxy site: no container is built or started. It refreshes the host.containers.internal mapping (so nginx can reach the host), generates the proxy vhost, and reloads nginx. The dev-server process is started separately by the caller (in the cli package) because siteops must not import cli.

func FinishLink(site config.Site, phpVersion string) error

FinishLink performs the post-registration steps shared by link, park, and MCP: vhost generation, FPM quadlet setup, container hosts update, and nginx reload.

func InheritCustomNginxConfig added in v1.23.0

func InheritCustomNginxConfig(parentDomain, worktreeDomain string) error

InheritCustomNginxConfig seeds a new worktree's override from its parent's: it copies custom.d/{parent}.conf to custom.d/{worktree}.conf only when the parent exists and the worktree override does not. Callers must invoke it only on genuine worktree creation — running it on every resync would resurrect an override the user deliberately reset (it can't tell "new" from "reset").

func IsParkedSite

func IsParkedSite(sitePath string, parkedDirs []string) bool

IsParkedSite checks whether a site's path is inside one of the parked directories.

func ListCustomNginxBackups added in v1.23.0

func ListCustomNginxBackups(domain string) ([]cfgedit.Backup, error)

ListCustomNginxBackups returns a domain's override backups, newest first.

func MoveCustomNginxConfig added in v1.23.0

func MoveCustomNginxConfig(oldPrimary, newPrimary string) error

MoveCustomNginxConfig follows a site's hand-authored nginx overrides across a primary-domain rename. The main snippet lives at custom.d/{primary}.conf and each worktree's at custom.d/{branch}.{primary}.conf; the generated vhosts include them by name, so without this they are orphaned and the renamed site (and its worktrees) silently lose their custom config. Timestamped backups in custom.d.bkp/ are keyed the same way and moved too so the UI restore dropdown keeps working. Missing files are not an error; renames far outnumber edits.

func ReadCustomNginx added in v1.23.0

func ReadCustomNginx(domain string) (cfgedit.Content, error)

ReadCustomNginx returns the saved override, or the seeded template (Exists=false) when nothing is on disk yet.

func ReadCustomNginxBackup added in v1.23.0

func ReadCustomNginxBackup(domain, name string) ([]byte, error)

ReadCustomNginxBackup returns the raw bytes of one backup (os.ErrNotExist when the name is invalid or the file is gone).

func RegenerateSiteVhost

func RegenerateSiteVhost(site *config.Site, oldPrimary string) error

RegenerateSiteVhost regenerates the nginx vhost for a site after domain changes. If the primary domain changed, the old vhost file is removed. For secured sites the SSL vhost is generated and renamed to the main .conf path.

func RemoveCustomNginxConfig added in v1.23.0

func RemoveCustomNginxConfig(domain string) error

RemoveCustomNginxConfig deletes a worktree's live override and every timestamped backup for that domain. Used when a worktree is removed.

func ResetCustomNginx added in v1.23.0

func ResetCustomNginx(domain string) error

ResetCustomNginx deletes the override and reloads nginx. Backups are kept.

func ResolveSecured added in v1.25.0

func ResolveSecured(relinkSecured bool, proj *config.ProjectConfig, cfg *config.GlobalConfig) bool

ResolveSecured decides whether a freshly linked site is secured. Both the re-link path (relinkSecured, from CleanupRelink) and .lerd.yaml's secured flag are honoured only when lerd manages DNS, so a site secured before DNS was switched off, or a project authored with secured: true, degrades to http on a localhost install rather than being registered as a non-functional HTTPS site that the cert layer would refuse with ErrDNSDisabled.

func RestoreCustomNginx added in v1.23.0

func RestoreCustomNginx(domain, name string) (cfgedit.RestoreResult, error)

RestoreCustomNginx swaps a backup over the live override and reloads nginx.

func SaveCustomNginx added in v1.23.0

func SaveCustomNginx(domain, content string, backup bool) (cfgedit.SaveResult, error)

SaveCustomNginx writes, validates with `nginx -t`, rolls back on a failure that names our file, and reloads nginx.

func SetSecured added in v1.20.2

func SetSecured(site *config.Site, secured bool) error

SetSecured toggles the site's TLS state and runs every step the toggle depends on. It is the single source of truth for "what happens when a site is secured/unsecured"; CLI, UI, and MCP all call this with no per-caller variation so a new step added here applies everywhere.

Steps:

  1. Issue or remove the certificate (also regenerates the nginx vhost on disk).
  2. Persist site.Secured to the registry.
  3. Sync APP_URL and VITE_REVERB_HOST/SCHEME/PORT in the project's .env.
  4. Update the per-project .lerd.yaml secured flag.
  5. Reload nginx so the new vhost takes effect.
  6. Notify the daemon to refresh dependent listeners (Stripe webhook URL, LAN share proxy backend port). The daemon owns the in-process state for these, so even callers running inside the daemon hit the same HTTP endpoints; a tiny loopback roundtrip is the cost of having one identical post-toggle path.

func SiteForDomain added in v1.23.0

func SiteForDomain(domain string) (*config.Site, error)

SiteForDomain resolves a domain to the site that owns it, accepting both a registered domain (primary/alias) and a worktree's subdomain. Worktree overrides are keyed by the worktree's full domain (custom.d/{wt}.conf), so the per-site nginx endpoints must recognise those too; the worktree is confirmed against live git detection so an arbitrary subdomain can't be used to reach outside custom.d.

func SiteNameAndDomain

func SiteNameAndDomain(dirName, tld string) (string, string)

SiteNameAndDomain derives a clean site name and domain from a directory name. It strips one trailing TLD (either a gTLD from the curated list or any 2-letter ccTLD), then replaces remaining dots with dashes so the result is a valid DNS label. Examples:

"myapp"              -> "myapp",          "myapp.test"
"myapp.com"          -> "myapp",          "myapp.test"
"astrolov.ro"        -> "astrolov",       "astrolov.test"
"admin.astrolov.com" -> "admin-astrolov", "admin-astrolov.test"

func SyncEnvIfPrimaryChanged added in v1.23.0

func SyncEnvIfPrimaryChanged(site *config.Site, oldPrimary string) error

SyncEnvIfPrimaryChanged updates APP_URL and the VITE_REVERB_* keys in the site's project .env and rewrites APP_URL in each worktree .env to the new <branch>.<newPrimary> subdomain, but only when the primary domain has actually changed since oldPrimary. Returns the first non-nil error so callers can warn; a worktree-detection failure is treated as no worktrees rather than as a fatal error because the parent sync has already landed.

func UnlinkSiteCore

func UnlinkSiteCore(site *config.Site, parkedDirs []string) error

UnlinkSiteCore performs the shared unlink steps: stop workers, remove vhost, remove certs, update registry (ignore if parked, remove otherwise), update container hosts, and reload nginx.

func ValidNginxBackupName added in v1.23.0

func ValidNginxBackupName(domain, name string) bool

ValidNginxBackupName reports whether name is a well-formed backup for domain.

func WorktreeDomain added in v1.23.0

func WorktreeDomain(site *config.Site, branch string) (string, error)

WorktreeDomain resolves a site plus an optional branch to the domain whose custom nginx override applies: the site's primary domain when branch is empty, or the worktree's subdomain otherwise. It is the single source of truth for "branch -> {branch}.{primary}", shared by the CLI and MCP so they can't drift from how the daemon derives worktree domains.

Types

type VersionResult

type VersionResult struct {
	PHP            string // best installed PHP version (clamped to framework range)
	Node           string // detected Node version
	PHPMin         string // framework minimum PHP version (empty if no framework or guessed)
	PHPMax         string // framework maximum PHP version (empty if no framework or guessed)
	SuggestedPHP   string // better PHP version to install (empty if current is optimal)
	FrameworkLabel string // human-readable framework name for messages
	// FrameworkGuessed is true when the framework version was clamped to a
	// borrowed definition; its PHP range is not enforced (PHPMin/PHPMax stay
	// empty) since it describes a different version than the project.
	FrameworkGuessed bool
}

VersionResult holds the detected and suggested versions for a site.

func DetectSiteVersions

func DetectSiteVersions(dir, framework, defaultPHP, defaultNode string) VersionResult

DetectSiteVersions resolves the framework, PHP version (clamped to framework range), and Node version for a project directory. When the best installed PHP version is below the framework's max, SuggestedPHP is set to the max version.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL