Help us shape the future of Go! Take the 2026 Go Developer Survey

server

package
v0.56.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 112 Imported by: 0

Documentation

Overview

Package server contains the HTTP server lifecycle, the first-run detector that bootstraps an admin user, and the boot banner.

Thumbnail backfill and repair — walks the file nodes in scope and draws the ones a selection asks for (thumb.Pipeline.Wanted).

⚠⚠ ONE walk, three front ends:

  • `filex thumb backfill` (synchronous, prints progress);
  • FILEX_THUMB_BACKFILL_ON_BOOT=once (background, fired from Start());
  • Admin → Tools → Thumbnail repair, an ops job (thumb_repair.go) with progress, cancellation and a result.

Nothing else walks nodes to draw thumbnails: a second copy of this walk is how the CLI and the admin tool would come to disagree about which files "need repair".

Index

Constants

View Source
const (
	AuditActionEntryUnavailable = "storage.entry_unavailable"
	AuditActionEntryAvailable   = "storage.entry_available"
)

Audit actions for an entry the storage could not answer for (issue #104), written when the entry's state CHANGES - not on every pass that gets the same answer.

View Source
const (
	GapSyncRunning = "sync_running"
	GapSyncAborted = "sync_aborted"
	GapNeverSynced = "never_synced"
)

Why a storage's catalogue cannot be trusted to hold its files (catalogueGap).

Variables

View Source
var ErrNotIndexed = errors.New("thumb backfill: storage catalogue not ready")

ErrNotIndexed is returned (wrapped, after every other storage has been processed) when at least one targeted storage's catalogue cannot be trusted to hold its files.

⚠⚠ Why a backfill refuses instead of doing what it can. A backfill renders thumbnails for NODES — rows in the catalogue — because that is what a thumbnail is keyed on. Files written straight onto a storage's backend have no node until a sync writes one, and a sync answers 202 and writes them in the background. So this command, run against a storage nobody had synced, or one whose sync was still going, walked an empty (or half-written) catalogue and printed `{processed: 0, ok: 0, failed: 0, skipped: 0}` with exit 0. Measured 2026-09-14, and it is how a screenshot run produced a grid with no thumbnails while every step it took said "ok". A command that does nothing and reports success is worse than one that fails: nobody goes looking.

It cannot simply sync first: the CLI runs beside a live server, and two processes syncing one storage into one database is its own bug. So it says what is missing and what to do, and exits non-zero.

View Source
var ErrPathNeedsOneStorage = errors.New("thumb backfill: a path needs exactly one storage")

ErrPathNeedsOneStorage: a Path was given without exactly one storage.

View Source
var ErrPathNotFound = errors.New("thumb backfill: no file or folder at that path")

ErrPathNotFound: BackfillOptions.Path names nothing in the catalogue.

Functions

func PrintBanner

func PrintBanner(w io.Writer, cfg config.Config, fr FirstRunCredentials, caps map[string]model.ExternalServiceState, storages []*model.Storage)

PrintBanner writes the first-run banner to w (typically os.Stdout).

fr is the FirstRun result — when non-empty it adds the "first run detected" credentials section.

func RandomHex

func RandomHex(n int) (string, error)

RandomHex returns 2*n hex characters of cryptographically random data.

Types

type BackfillOptions

type BackfillOptions struct {
	// StorageIDs, when non-empty, restricts the run to specific storages.
	// Empty means "every enabled storage".
	StorageIDs []int64
	// Limit caps the number of files processed across all storages
	// combined. 0 = unlimited.
	Limit int
	// RetryFailed includes nodes whose existing thumbnails row is in
	// state="failed". Without this, failed rows are skipped (so a flaky
	// office doc doesn't block every subsequent run).
	RetryFailed bool
	// RetrySkipped includes nodes whose existing thumbnails row is in
	// state="skipped". Use when the pipeline has gained coverage for
	// kinds that previously skipped (e.g. v0.1.7 generic fallback /
	// audio waveform) — without this, old rows freeze the pipeline.
	RetrySkipped bool
	// Stale includes ready thumbnails drawn from other content (the file
	// changed after its render), and failures or skips recorded on other
	// content. `filex thumb backfill` turns it on unless --no-stale.
	Stale bool
	// All draws every file in scope, whatever its row says ("Rebuild").
	All bool
	// Path narrows the run to one file, or one folder with everything in it:
	// storage-relative ("/Photos/2024"). "" or "/" is the whole storage. Only
	// with exactly one storage in StorageIDs; a path that has no row answers
	// ErrPathNotFound.
	Path string
	// Concurrency controls the worker pool size. <=0 → 4.
	Concurrency int
	// ProgressEvery determines how many processed nodes between an
	// OnProgress callback. <=0 disables intermediate notifications.
	ProgressEvery int
	// OnProgress, if non-nil, is invoked with the running counters every
	// ProgressEvery files. CLI uses this to print to stdout; the boot
	// goroutine leaves it nil and lets the slog summary do the work.
	OnProgress func(BackfillStats)
}

BackfillOptions tunes a backfill run.

type BackfillStats

type BackfillStats struct {
	Processed int
	OK        int
	Failed    int
	Skipped   int
	// NotIndexed names the storages this run REFUSED, and why. See
	// ErrNotIndexed.
	NotIndexed []NotIndexedStorage
}

BackfillStats is the counter snapshot emitted via OnProgress and returned from BackfillThumbs.

type FirstRunCredentials

type FirstRunCredentials struct {
	AdminEmail    string
	AdminPassword string // plaintext — only ever shown ONCE (blank when preset)
	WroteFile     string // path of ~/.filex/.first-run.txt (blank when preset)
	// Preset is true when the admin was created from FILEX_ADMIN_EMAIL /
	// FILEX_ADMIN_PASSWORD — the operator already knows the password, so it is
	// neither written to disk nor echoed in the banner.
	Preset bool
}

FirstRunCredentials is what FirstRun returns when bootstrapping. Empty AdminEmail means no first-run was needed (a user already exists).

func FirstRun

func FirstRun(ctx context.Context, store db.Store, dataDir, adminEmail, adminPassword string) (FirstRunCredentials, error)

FirstRun checks whether the users table is empty. If so it creates an admin user and records the timestamp in the settings table.

When adminEmail/adminPassword are supplied (from FILEX_ADMIN_* env) they are used as-is and nothing is written to disk. Otherwise it falls back to admin@local with a fresh random password written to a 0600 file at {dataDir}/.first-run.txt.

Returns zero-value FirstRunCredentials when no bootstrap was performed.

type NotIndexedStorage

type NotIndexedStorage struct {
	ID     int64
	Name   string
	Reason string
	// Code is Reason for a client to say in its own language: one of the
	// Gap* constants.
	Code string
}

NotIndexedStorage is one storage a backfill would have reported success on while rendering nothing for it.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the high-level wrapper around HTTP + workers.

func New

func New(ctx context.Context, cfg config.Config, embedFS embed.FS) (*Server, error)

func (*Server) BackfillThumbs

func (s *Server) BackfillThumbs(ctx context.Context, opts BackfillOptions) (BackfillStats, error)

BackfillThumbs walks the file nodes in scope and draws the ones opts selects (thumb.Pipeline.Wanted). Safe to call concurrently with normal operation — the pipeline itself is idempotent and uses UpsertThumbnail.

func (*Server) CountBackfill added in v0.50.0

func (s *Server) CountBackfill(ctx context.Context, opts BackfillOptions) (int, error)

CountBackfill is the number of files BackfillThumbs(opts) would draw right now: the same walk, drawing nothing. The repair tool shows it as the total.

func (*Server) Start

func (s *Server) Start(ctx context.Context) error

Start runs first-run, prints the banner, starts the worker, and serves HTTP. Blocks until ctx is cancelled.

func (*Server) Store

func (s *Server) Store() db.Store

Store exposes the DB store — used by the CLI subcommands (filex admin reset-password, etc.).

Jump to

Keyboard shortcuts

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