panel

package
v0.2.3 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: 48 Imported by: 0

Documentation

Overview

Package panel is the unprivileged half of Zelie: the web interface, its API and user accounts. It never listens on the network. The proxy hands it web traffic over a Unix socket, and it asks the core to do anything that needs root.

Index

Constants

This section is empty.

Variables

View Source
var ErrSetupDone = errors.New("an administrator exists already")

ErrSetupDone means an administrator exists, so there is no setup link.

Functions

This section is empty.

Types

type Client

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

Client talks to the panel's socket from the server itself.

func NewClient

func NewClient(socket string) *Client
func (c *Client) SetupLink(ctx context.Context) (string, error)

SetupLink asks the panel for a new setup token.

func (*Client) Version added in v0.2.0

func (c *Client) Version(ctx context.Context) (string, error)

Version asks the running panel which version it is.

type Core

type Core interface {
	List(ctx context.Context) ([]engine.Status, error)
	Run(ctx context.Context, s engine.Spec) error
	RunApp(ctx context.Context, s engine.Spec, sealedEnv []string, linked ...core.LinkedVar) error
	SetLinks(ctx context.Context, app string, links []engine.Link) error
	Build(ctx context.Context, app, version string, env, sealedEnv []string, source io.Reader, out io.Writer) (build.Result, error)
	Wait(ctx context.Context, id string) (int, error)
	SecretKey(ctx context.Context) (secret.PublicKey, error)
	Stop(ctx context.Context, id string, graceSeconds int) error
	Remove(ctx context.Context, id string) error
	Logs(ctx context.Context, id string, follow bool, tail int64, w io.Writer) error
	RemoveImage(ctx context.Context, name string) error
	SweepImages(ctx context.Context, keep []string) ([]string, error)
	RemoveBuildCache(ctx context.Context, app string) error
	SetExternal(ctx context.Context, app, engine, container string, port, target int, sealedPassword string) error
	RemoveExternal(ctx context.Context, app, engine, container string) error
	SyncExternal(ctx context.Context, list []core.ExternalListener) error
	UpdateStatus(ctx context.Context) (core.UpdateStatus, error)
	Update(ctx context.Context, version string) error
	Usage(ctx context.Context, id string) (engine.Usage, error)
	Host(ctx context.Context) (engine.Host, error)
	CreateVolume(ctx context.Context, name string) error
	RemoveVolume(ctx context.Context, name string) error
	VolumeSizes(ctx context.Context) (map[string]int64, error)
	CreateBackup(ctx context.Context, app, container, kind string) (core.Backup, error)
	DownloadBackup(ctx context.Context, app, name string, w io.Writer) error
	RemoveBackup(ctx context.Context, app, name string) error
	RestoreBackup(ctx context.Context, app, name, kind, container, volume string) error
	BackUpVolumes(ctx context.Context, app string, vols []core.VolumeRef, live bool) (core.Backup, error)
	RestoreVolumes(ctx context.Context, app, name string, vols []core.VolumeRef, size int64) error
	RecoveryKey(ctx context.Context, host string, w io.Writer) error
	Offsite(ctx context.Context) (core.OffsiteInfo, error)
	SetOffsite(ctx context.Context, cfg core.OffsiteConfig) (core.OffsiteInfo, error)
	RemoveOffsite(ctx context.Context) error
	UploadBackup(ctx context.Context, app, name string, meta core.BackupMeta) error
	OffsiteBackups(ctx context.Context) (core.OffsiteList, error)
	AddOldKey(ctx context.Context, recovery string) ([]string, error)
	RemoveOffsiteBackup(ctx context.Context, app, name string) error
	FetchBackup(ctx context.Context, app, name string) error
	StartUpload(ctx context.Context, app string, size int64) (core.Upload, error)
	Upload(ctx context.Context, id string) (core.Upload, error)
	AppendUpload(ctx context.Context, id string, offset int64, piece io.Reader) (core.Upload, error)
	RemoveUpload(ctx context.Context, id string) error
	ImportUpload(ctx context.Context, id, kind string) (core.Backup, error)
	DataTables(ctx context.Context, app, container, engine string) ([]dataview.Table, error)
	DataRows(ctx context.Context, app, container, engine string, q dataview.Query) (dataview.Page, error)
	DataExport(ctx context.Context, app, container, engine string, q dataview.Query, w io.Writer) error
	DataKeys(ctx context.Context, app, container, pattern, cursor string) (dataview.KeyPage, error)
	DataKey(ctx context.Context, app, container, key string) (dataview.Value, error)
}

Core is what the panel asks the privileged core to do. *core.Client implements it; tests use a fake.

type Proxy

type Proxy interface {
	Config(ctx context.Context) (proxy.Config, error)
	Apply(ctx context.Context, cfg proxy.Config) error
}

Proxy is how the panel tells the proxy where each domain goes.

type PublicGitHub

type PublicGitHub struct {
	Client   *http.Client
	API      string // https://api.github.com
	Codeload string // https://codeload.github.com
}

PublicGitHub reads public repositories without an account. Private ones need the GitHub connection.

func NewPublicGitHub

func NewPublicGitHub() *PublicGitHub

func (*PublicGitHub) Archive

func (g *PublicGitHub) Archive(ctx context.Context, repo, commit string) (io.ReadCloser, error)

func (*PublicGitHub) Resolve

func (g *PublicGitHub) Resolve(ctx context.Context, repo, branch string) (string, error)

type Release added in v0.2.0

type Release struct {
	Version   string    `json:"version"`
	Notes     string    `json:"notes"`
	Published time.Time `json:"published"`
	URL       string    `json:"url"`
}

Release is a published version of Zelie.

func GitHubRelease added in v0.2.0

func GitHubRelease(ctx context.Context) (Release, error)

GitHubRelease reads the latest release from GitHub.

type Sealer

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

Sealer encrypts the panel's own secrets, such as authenticator app keys, before they go into the database. A copy of the database alone, from a backup for example, then does not give them away.

func LoadSealer

func LoadSealer(path string) (*Sealer, error)

LoadSealer reads the key at path, creating it on first start.

func (*Sealer) Open

func (s *Sealer) Open(sealed []byte, purpose string) ([]byte, error)

func (*Sealer) Seal

func (s *Sealer) Seal(plain []byte, purpose string) []byte

Seal encrypts plain. purpose is bound to the result, so a value sealed for one use cannot be passed off as another.

type Server

type Server struct {
	Store  *store.Store
	Sealer *Sealer
	Core   Core
	Proxy  Proxy
	Source Source
	Log    *slog.Logger
	// DataDir holds files that do not belong in the database, such as
	// deployment logs.
	DataDir string
	// ProxyUID is the user the proxy runs as. Requests from it are web
	// traffic; requests from root come from the zelie command on the server.
	ProxyUID uint32
	Now      func() time.Time
	// Where GitHub is. Empty means the real one; tests set them.
	GitHubAPI  string
	GitHubWeb  string
	GitHubHTTP *http.Client
	// HealthCheck replaces the HTTP request of the health check in tests.
	HealthCheck func(ctx context.Context, url, host string) (int, error)
	// PortCheck replaces the connection a database's health check makes.
	PortCheck func(ctx context.Context, ip netip.Addr, port int) bool

	// Releases returns the latest release; tests replace GitHub.
	Releases func(ctx context.Context) (Release, error)
	// contains filtered or unexported fields
}

func (*Server) Handler

func (s *Server) Handler() http.Handler

func (*Server) Serve

func (s *Server) Serve(ctx context.Context, socket string) error

Serve listens on the socket until ctx is cancelled.

type Source

type Source interface {
	// Resolve returns the commit a branch points at.
	Resolve(ctx context.Context, repo, branch string) (string, error)
	// Archive returns the code at a commit as a gzipped tar.
	Archive(ctx context.Context, repo, commit string) (io.ReadCloser, error)
}

Source fetches an app's code.

Jump to

Keyboard shortcuts

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