store

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2026 License: AGPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package store keeps the panel's state in a single SQLite file.

Index

Constants

View Source
const (
	SourceImage  = "image"
	SourceGitHub = "github"
)

App sources.

View Source
const (
	DeployQueued   = "queued"
	DeployBuilding = "building"
	DeployTesting  = "testing"
	DeployStarting = "starting"
	DeployLive     = "live"
	DeployFailed   = "failed"
	DeployReplaced = "replaced" // was live until a newer one took over
	DeploySkipped  = "skipped"  // a newer one came before it started
)

Deployment states. A deployment moves forward through them and ends in one of the last four.

View Source
const (
	CauseManual   = "manual"
	CausePush     = "push"
	CauseRestart  = "restart"  // the live image again, without a build
	CauseRollback = "rollback" // an earlier deployment's image
	CauseRecover  = "recover"  // the live image again, after it stopped by itself
	CauseRestore  = "restore"  // the live image again, after a backup was put back
	CauseBackup   = "backup"   // the live image again, after the app was stopped for its backup
)

What started a deployment.

View Source
const (
	BackupScheduled = "scheduled"
	BackupManual    = "manual"
	// BackupRestore is the safety backup taken just before a restore.
	BackupRestore = "restore"
	// BackupFound was made elsewhere and found in off-site storage.
	BackupFound = "found"
	// BackupUploaded is a dump from another server that someone uploaded.
	BackupUploaded = "uploaded"
)

Why a backup was made.

View Source
const (
	BackupRunning = "running"
	BackupDone    = "done"
	BackupFailed  = "failed"
)

Backup states.

View Source
const (
	OffsitePending = "pending"
	OffsiteDone    = "done"
	OffsiteFailed  = "failed"
)

Where a backup's off-site copy is. A backup that is not sent has none.

Variables

View Source
var (
	// ErrSetupDone means an administrator exists and setup is closed for good.
	ErrSetupDone = errors.New("setup is already complete")
	// ErrBadSetupToken means the setup link is wrong, used or expired.
	ErrBadSetupToken = errors.New("this setup link is not valid; run 'zelie setup-link' on the server for a new one")
)
View Source
var (
	// ErrNotFound means the thing asked for does not exist.
	ErrNotFound = errors.New("not found")
	// ErrLastFactor stops an account from removing its only second factor.
	ErrLastFactor = errors.New("this is the only second step left on the account; add another before removing it")
)
View Source
var ErrExists = errors.New("already exists")

ErrExists is returned when a name or domain is already taken.

Functions

This section is empty.

Types

type Account

type Account struct {
	User
	Password   string
	TOTPSecret []byte // encrypted; nil until an authenticator app is set up
	Passkeys   int
}

Account is a user with what is needed to log them in.

func (Account) HasSecondFactor

func (a Account) HasSecondFactor() bool

HasSecondFactor reports whether the account has an authenticator app or a passkey. Until it does, the panel only lets it set one up.

type App

type App struct {
	ID       string
	Source   string
	Image    string // for SourceImage
	Repo     string // owner/name, for SourceGitHub
	Branch   string
	Port     int
	Domain   string
	MemoryMB int64
	CPUs     float64
	// AutoDeploy deploys each push to the branch, for SourceGitHub.
	AutoDeploy bool
	// HealthPath is what the health check asks for, when the app has a
	// domain.
	HealthPath string
	// TestCommand runs the app's tests; empty means none. TestSet is false
	// until it has been decided, by a build's suggestion or by the user.
	TestCommand string
	TestSet     bool
	// Stopped is set when the user stopped the app.
	Stopped bool
	// The user's own commands; empty means what the build chose.
	BuildCommand string
	StartCommand string
	// Detected is what the last build chose.
	Detected Detected
	// RestartPulls makes a restart build the branch's newest commit.
	RestartPulls bool
	// Engine is set for a database: postgres, mariadb or redis, in the
	// major version EngineVersion.
	Engine        string
	EngineVersion string
	CreatedAt     time.Time
}

App is something Zelie keeps running.

func (App) IsDatabase

func (a App) IsDatabase() bool

IsDatabase reports whether the app is one of Zelie's databases.

type Backup

type Backup struct {
	ID     int64
	AppID  string
	Engine string // what the app was when it was made; empty for volumes
	Reason string
	State  string
	File   string // the core's name for it, once made
	Bytes  int64
	Error  *msg.Msg // why it failed
	// For a backup of volumes: the folders in it, how much its files take
	// and how many changed while they were copied.
	Volumes []string
	Size    int64
	Changed int
	// For an uploaded dump: what was changed so it loads here, by kind.
	Adapted map[string]int

	CreatedAt  time.Time
	FinishedAt time.Time // zero while running
	KeepUntil  time.Time
	RestoredAt time.Time // zero if it was never put back

	// The off-site copy: its state (empty when there is none), why it
	// failed, how often it was tried, when it was sent or is tried
	// again, and until when it is kept.
	Offsite      string
	OffsiteError *msg.Msg
	OffsiteTries int
	OffsiteAt    time.Time
	OffsiteUntil time.Time
	// Local is false once only the off-site copy is left.
	Local bool
}

Backup is one backup, made or tried.

type BackupPlan

type BackupPlan struct {
	AppID    string
	Enabled  bool
	Minute   int // of the day, in the server's time zone
	KeepDays int
	// Stop stops an app for its volume backup instead of copying the
	// files while it runs.
	Stop bool
	// Offsite sends each backup to the off-site storage, when there is
	// one, where it is kept for OffsiteDays.
	Offsite     bool
	OffsiteDays int
}

BackupPlan says when an app is backed up and for how long its backups are kept.

func AppBackupPlan

func AppBackupPlan(app string) BackupPlan

AppBackupPlan is what an app has until its plan is changed: the same hours, but off, since volumes such as game worlds can be large.

func DefaultBackupPlan

func DefaultBackupPlan(app string) BackupPlan

DefaultBackupPlan is what a new database gets: every night at three, kept for a week.

type Deployment

type Deployment struct {
	ID         int64
	AppID      string
	Version    string // a branch until the commit is known
	Image      string
	Cause      string
	Message    string // first line of the pushed commit's message
	Pruned     bool   // its image was deleted
	State      string
	Error      *msg.Msg // why it failed
	CreatedAt  time.Time
	FinishedAt time.Time // zero while in progress
}

Deployment is one attempt to put a version of an app live.

type Detected

type Detected struct {
	Builder string `json:"builder,omitempty"` // dockerfile or railpack
	Build   string `json:"build,omitempty"`
	Start   string `json:"start,omitempty"`
}

Detected is how the last build built an app.

type EnvVar

type EnvVar struct {
	Name   string
	Value  string
	Secret bool
}

EnvVar is one environment variable of an app. For a secret one, Value is sealed for the core and the panel cannot read it.

type ExternalAccess

type ExternalAccess struct {
	AppID     string
	Port      int
	CreatedAt time.Time
}

ExternalAccess is a database open to desktop tools on a loopback port.

type GitHubApp

type GitHubApp struct {
	AppID         int64
	Slug          string
	Owner         string
	HTMLURL       string
	BaseURL       string
	Key           []byte
	WebhookSecret []byte
	CreatedAt     time.Time
}

GitHubApp is the panel's own GitHub App. Key and WebhookSecret are encrypted with the panel key; the store never sees them in the clear.

type Link struct {
	AppID, DBID string
	// Prefix starts the names of the variables the app gets, so one app
	// can have several databases.
	Prefix    string
	CreatedAt time.Time
}

Link connects an app to a database.

type Passkey

type Passkey struct {
	ID         []byte
	UserID     int64
	Name       string
	Credential []byte // JSON, owned by the WebAuthn code
	CreatedAt  time.Time
	UsedAt     time.Time // zero if never used to log in
}

Passkey is a WebAuthn credential registered to an account.

type Session

type Session struct {
	Hash        []byte
	UserID      int64
	Verified    bool // the second factor has been checked
	CreatedAt   time.Time
	SeenAt      time.Time
	ExpiresAt   time.Time
	ConfirmedAt time.Time // last time the user proved it was them
	IP          string
	Agent       string
}

Session is a logged-in browser. Hash is the SHA-256 of the cookie value.

type Store

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

Store is the panel's database.

func Open

func Open(ctx context.Context, path string) (*Store, error)

Open opens or creates the database at path and brings its schema up to date.

func (*Store) AccountByEmail

func (s *Store) AccountByEmail(ctx context.Context, email string) (Account, error)

func (*Store) AccountByID

func (s *Store) AccountByID(ctx context.Context, id int64) (Account, error)

func (*Store) AddFoundBackup

func (s *Store) AddFoundBackup(ctx context.Context, b Backup) (int64, error)

AddFoundBackup records a backup found in off-site storage, kept there until offsite_until and not here.

func (*Store) AddPasskey

func (s *Store) AddPasskey(ctx context.Context, p Passkey) error

func (*Store) App

func (s *Store) App(ctx context.Context, id string) (App, error)

func (*Store) Apps

func (s *Store) Apps(ctx context.Context) ([]App, error)

func (*Store) Backup

func (s *Store) Backup(ctx context.Context, id int64) (Backup, error)

func (*Store) BackupFiles

func (s *Store) BackupFiles(ctx context.Context) (map[string]bool, error)

BackupFiles returns every backup file on record, as app/file.

func (*Store) BackupPlan

func (s *Store) BackupPlan(ctx context.Context, app string) (BackupPlan, error)

BackupPlan returns an app's plan, or ErrNotFound when it has none.

func (*Store) BackupPlans

func (s *Store) BackupPlans(ctx context.Context) ([]BackupPlan, error)

BackupPlans returns every plan.

func (*Store) Backups

func (s *Store) Backups(ctx context.Context, app string) ([]Backup, error)

Backups returns an app's backups, newest first. With app empty, it returns every backup whose app no longer exists.

func (*Store) Close

func (s *Store) Close() error

func (*Store) ConfirmSession

func (s *Store) ConfirmSession(ctx context.Context, hash []byte, now time.Time) error

ConfirmSession records that the user proved it was them again.

func (*Store) CreateApp

func (s *Store) CreateApp(ctx context.Context, a App) error

func (*Store) CreateDeployment

func (s *Store) CreateDeployment(ctx context.Context, d Deployment, now time.Time) (int64, error)

CreateDeployment adds d as a queued deployment and returns its id.

func (*Store) CreateFirstAdmin

func (s *Store) CreateFirstAdmin(ctx context.Context, tokenHash []byte, email, password string, now time.Time) (User, error)

CreateFirstAdmin spends the setup token and creates the first administrator. Once it succeeds, setup is closed.

func (s *Store) CreateLink(ctx context.Context, l Link) error

func (*Store) CreateSession

func (s *Store) CreateSession(ctx context.Context, x Session) error

func (*Store) CreateVolume

func (s *Store) CreateVolume(ctx context.Context, v Volume) (Volume, error)

CreateVolume saves a new volume under a new name for the core.

func (*Store) DeleteApp

func (s *Store) DeleteApp(ctx context.Context, id string) error

DeleteApp removes an app with its variables and deployments.

func (*Store) DeleteBackup

func (s *Store) DeleteBackup(ctx context.Context, id int64) error

func (*Store) DeleteExpiredSessions

func (s *Store) DeleteExpiredSessions(ctx context.Context, now time.Time) error

DeleteExpiredSessions keeps the table from growing forever.

func (*Store) DeleteGitHubApp

func (s *Store) DeleteGitHubApp(ctx context.Context) error
func (s *Store) DeleteLink(ctx context.Context, appID, dbID string) error

func (*Store) DeleteOtherSessions

func (s *Store) DeleteOtherSessions(ctx context.Context, userID int64, keep []byte) error

DeleteOtherSessions ends every session of the account except keep.

func (*Store) DeletePasskey

func (s *Store) DeletePasskey(ctx context.Context, userID int64, id []byte) error

DeletePasskey removes a passkey, unless it is the account's last second factor.

func (*Store) DeleteSession

func (s *Store) DeleteSession(ctx context.Context, hash []byte) error

func (*Store) DeleteUserSession

func (s *Store) DeleteUserSession(ctx context.Context, userID int64, hash []byte) error

DeleteUserSession ends one of an account's sessions. The account is part of the query so no one can end another account's session.

func (*Store) DeleteVolume

func (s *Store) DeleteVolume(ctx context.Context, appID string, id int64) error

func (*Store) Deployment

func (s *Store) Deployment(ctx context.Context, appID string, id int64) (Deployment, error)

func (*Store) Deployments

func (s *Store) Deployments(ctx context.Context, appID string, limit int) ([]Deployment, error)

Deployments lists an app's most recent deployments, newest first.

func (*Store) DropOffsiteQueue

func (s *Store) DropOffsiteQueue(ctx context.Context) error

DropOffsiteQueue forgets the backups still waiting to be sent, when there is no longer anywhere to send them.

func (*Store) Env

func (s *Store) Env(ctx context.Context, appID string) ([]EnvVar, error)

func (*Store) ExpiredBackups

func (s *Store) ExpiredBackups(ctx context.Context, now time.Time) ([]Backup, error)

ExpiredBackups returns the backups whose file here is due to go. The newest backup made of an app that still exists is never among them: if backups stop working, the last good one stays.

func (*Store) ExpiredOffsite

func (s *Store) ExpiredOffsite(ctx context.Context, now time.Time) ([]Backup, error)

ExpiredOffsite returns the backups left only off-site whose time is up there too.

func (*Store) ExternalAccess

func (s *Store) ExternalAccess(ctx context.Context, appID string) (ExternalAccess, error)

ExternalAccess returns the database's, or ErrNotFound.

func (*Store) ExternalAccesses

func (s *Store) ExternalAccesses(ctx context.Context) ([]ExternalAccess, error)

ExternalAccesses lists every database open to desktop tools.

func (*Store) FailUnfinished

func (s *Store) FailUnfinished(ctx context.Context, now time.Time) error

FailUnfinished marks deployments that were in progress when the panel stopped as failed. The panel calls it on start.

func (*Store) FailUnfinishedBackups

func (s *Store) FailUnfinishedBackups(ctx context.Context, now time.Time) error

FailUnfinishedBackups marks backups that were running when the panel stopped as failed. The panel calls it on start.

func (*Store) FinishBackup

func (s *Store) FinishBackup(ctx context.Context, id int64, file string, bytes int64, failure *msg.Msg, at time.Time) error

FinishBackup records how a backup ended: with a file, or with why not.

func (*Store) FirstDelivery

func (s *Store) FirstDelivery(ctx context.Context, id string, now time.Time) (bool, error)

FirstDelivery records a webhook delivery id and reports whether it is new.

func (*Store) GitHubApp

func (s *Store) GitHubApp(ctx context.Context) (GitHubApp, error)

func (*Store) GoLive

func (s *Store) GoLive(ctx context.Context, d Deployment, now time.Time) error

GoLive makes d the app's live deployment and marks the one before it replaced, in one step.

func (*Store) HasNewer

func (s *Store) HasNewer(ctx context.Context, d Deployment) (bool, error)

HasNewer reports whether the app has a deployment created after d.

func (*Store) Images

func (s *Store) Images(ctx context.Context) ([]string, error)

Images lists every image an app or a kept deployment refers to.

func (s *Store) Links(ctx context.Context, appID, dbID string) ([]Link, error)

Links returns the databases an app is linked to, or with appID empty, the apps linked to the database dbID.

func (*Store) LiveDeployment

func (s *Store) LiveDeployment(ctx context.Context, appID string) (Deployment, error)

LiveDeployment returns the deployment serving an app, if any.

func (*Store) OffsiteDue

func (s *Store) OffsiteDue(ctx context.Context, now time.Time) ([]Backup, error)

OffsiteDue returns the backups to send now, oldest first.

func (*Store) OffsiteFailedAt

func (s *Store) OffsiteFailedAt(ctx context.Context, id int64, failure msg.Msg, tries int, next time.Time) error

OffsiteFailedAt records a failed send, to be tried again at next.

func (*Store) OffsiteSent

func (s *Store) OffsiteSent(ctx context.Context, id int64, at time.Time) error

OffsiteSent records that a backup's copy is off-site.

func (*Store) Passkeys

func (s *Store) Passkeys(ctx context.Context, userID int64) ([]Passkey, error)

func (*Store) PushTargets

func (s *Store) PushTargets(ctx context.Context, repo, branch string) ([]App, error)

PushTargets lists the apps that deploy pushes to a repository's branch. GitHub names are case-insensitive.

func (*Store) RecoveryCodesLeft

func (s *Store) RecoveryCodesLeft(ctx context.Context, userID int64) (int, error)

RecoveryCodesLeft counts the account's unused recovery codes.

func (*Store) RecoverySavedAt

func (s *Store) RecoverySavedAt(ctx context.Context) (time.Time, error)

RecoverySavedAt returns when the backup recovery file was last saved, or the zero time.

func (*Store) RemoveExternalAccess

func (s *Store) RemoveExternalAccess(ctx context.Context, appID string) error

func (*Store) RemoveTOTP

func (s *Store) RemoveTOTP(ctx context.Context, userID int64) error

RemoveTOTP turns off the authenticator app, unless the account has no passkey to fall back on.

func (*Store) SendOffsite

func (s *Store) SendOffsite(ctx context.Context, id int64, until time.Time) error

SendOffsite marks a backup to be sent now, and kept off-site until.

func (*Store) Session

func (s *Store) Session(ctx context.Context, hash []byte, now time.Time) (Session, error)

Session returns the session with this hash if it has not expired.

func (*Store) Sessions

func (s *Store) Sessions(ctx context.Context, userID int64, now time.Time) ([]Session, error)

Sessions lists an account's unexpired sessions, most recently used first.

func (*Store) SetAdapted

func (s *Store) SetAdapted(ctx context.Context, id int64, adapted map[string]int) error

SetAdapted records what an uploaded dump needed changed to load here.

func (*Store) SetBackupContents

func (s *Store) SetBackupContents(ctx context.Context, id int64, volumes []string, size int64, changed int) error

SetBackupContents records what a volume backup holds.

func (*Store) SetBackupPlan

func (s *Store) SetBackupPlan(ctx context.Context, p BackupPlan) error

SetBackupPlan saves a plan. Backups already made are kept for the new numbers of days, counted from when each was made.

func (*Store) SetDeployment

func (s *Store) SetDeployment(ctx context.Context, d Deployment, now time.Time) error

SetDeployment records progress. Ending states also set the finish time.

func (*Store) SetDetected

func (s *Store) SetDetected(ctx context.Context, appID string, d Detected) error

SetDetected records how the last build built the app.

func (*Store) SetEnv

func (s *Store) SetEnv(ctx context.Context, appID string, vars []EnvVar) error

SetEnv replaces all of an app's variables.

func (*Store) SetExternalAccess

func (s *Store) SetExternalAccess(ctx context.Context, x ExternalAccess) error

SetExternalAccess saves the database's port. ErrExists means another database has it.

func (*Store) SetGitHubApp

func (s *Store) SetGitHubApp(ctx context.Context, g GitHubApp) error

SetGitHubApp saves the App, replacing the one before, if any.

func (*Store) SetLocal

func (s *Store) SetLocal(ctx context.Context, id int64, local bool, keep time.Time) error

SetLocal records whether a backup's file is here. One brought back from off-site is kept here until keep.

func (*Store) SetPassword

func (s *Store) SetPassword(ctx context.Context, userID int64, hash string) error

SetPassword replaces the account's password hash.

func (*Store) SetPruned

func (s *Store) SetPruned(ctx context.Context, appID, image string) error

SetPruned records that an image was deleted, for every deployment that used it.

func (*Store) SetRecoveryCodes

func (s *Store) SetRecoveryCodes(ctx context.Context, userID int64, hashes [][]byte) error

SetRecoveryCodes replaces the account's recovery codes.

func (*Store) SetRecoverySaved

func (s *Store) SetRecoverySaved(ctx context.Context, at time.Time) error

func (*Store) SetRestored

func (s *Store) SetRestored(ctx context.Context, id int64, at time.Time) error

SetRestored records that a backup was put back.

func (*Store) SetSetupToken

func (s *Store) SetSetupToken(ctx context.Context, hash []byte, expires time.Time) error

SetSetupToken replaces the setup token. Only the hash of the token is kept.

func (*Store) SetStopped

func (s *Store) SetStopped(ctx context.Context, appID string, stopped bool) error

SetStopped records whether the user stopped the app.

func (*Store) SetTOTP

func (s *Store) SetTOTP(ctx context.Context, userID int64, secret []byte, step int64) error

SetTOTP stores an encrypted authenticator secret. step is the time step of the code that confirmed it, which may not be used again.

func (*Store) SetupOpen

func (s *Store) SetupOpen(ctx context.Context) (bool, error)

SetupOpen reports whether the panel still has no users.

func (*Store) StartBackup

func (s *Store) StartBackup(ctx context.Context, b Backup) (int64, error)

StartBackup records a backup that is about to be made and returns its id.

func (*Store) SuggestTest

func (s *Store) SuggestTest(ctx context.Context, appID, command string) (bool, error)

SuggestTest stores a build's suggested test command, unless one was decided already. It reports whether it was stored.

func (*Store) TouchSession

func (s *Store) TouchSession(ctx context.Context, hash []byte, seen, expires time.Time) error

TouchSession records activity and moves the expiry.

func (*Store) Unpruned

func (s *Store) Unpruned(ctx context.Context, appID string) ([]Deployment, error)

Unpruned lists the app's deployments that still have an image, newest first.

func (*Store) UpdateApp

func (s *Store) UpdateApp(ctx context.Context, a App) error

UpdateApp saves everything about an app except its id, source and creation time.

func (s *Store) UpdateLink(ctx context.Context, l Link) error

func (*Store) UpdatePasskey

func (s *Store) UpdatePasskey(ctx context.Context, id, credential []byte, used time.Time) error

UpdatePasskey saves the credential after a login, which carries the authenticator's new signature counter.

func (*Store) UpdateVolume

func (s *Store) UpdateVolume(ctx context.Context, v Volume) error

UpdateVolume changes where the app sees a volume and how large it may grow.

func (*Store) UseRecoveryCode

func (s *Store) UseRecoveryCode(ctx context.Context, userID int64, hash []byte) (bool, error)

UseRecoveryCode spends a recovery code. It reports false if the code is wrong or already used.

func (*Store) UseTOTPStep

func (s *Store) UseTOTPStep(ctx context.Context, userID, step int64) (bool, error)

UseTOTPStep records that a code from this time step was used. It fails if a code from the same or a later step was used before, which stops a code that was seen over someone's shoulder from being replayed.

func (*Store) VerifySession

func (s *Store) VerifySession(ctx context.Context, hash []byte, now, expires time.Time) error

VerifySession marks the second factor as checked. Finishing a login also counts as confirming.

func (*Store) Volumes

func (s *Store) Volumes(ctx context.Context, appID string) ([]Volume, error)

Volumes returns an app's volumes, oldest first. An empty appID returns every app's.

type User

type User struct {
	ID    int64
	Email string
	Admin bool
}

User is a panel account.

type Volume

type Volume struct {
	ID        int64
	Name      string // the core's name for it, set when it is created
	AppID     string
	Path      string // where the app sees it
	LimitMB   int64
	CreatedAt time.Time
}

Volume is a directory an app keeps between deployments.

Jump to

Keyboard shortcuts

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