diff options
Diffstat (limited to 'internal/layout/layout.go')
| -rw-r--r-- | internal/layout/layout.go | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/internal/layout/layout.go b/internal/layout/layout.go new file mode 100644 index 0000000..89e6848 --- /dev/null +++ b/internal/layout/layout.go @@ -0,0 +1,107 @@ +// Package layout defines Skiff's directory and dataset conventions in one +// place. Nothing else in the codebase should hardcode a path. +package layout + +import ( + "fmt" + "path/filepath" +) + +const ( + DefaultHealthPort = 8080 + DefaultHealthPath = "/healthz" + HealthTimeoutSecs = 10 +) + +// Config is Skiff's host-wide configuration. Every field has a sane FreeBSD +// default; override via flags on the skiff binary if a host differs. +type Config struct { + ZFSPool string // e.g. "zroot" + BaseDataset string // template jail root, cloned per app + ReposDir string // bare git repos live here + JailsMount string // parent mountpoint for per-app datasets + JailConfDir string // /etc/jail.conf.d + NginxConfDir string // nginx include dir regenerated on every deploy +} + +func Default() Config { + return Config{ + ZFSPool: "zroot/skiff", + BaseDataset: "zroot/skiff/base", + ReposDir: "/skiff/repos", + JailsMount: "/skiff/apps", + JailConfDir: "/etc/jail.conf.d", + NginxConfDir: "/usr/local/etc/nginx/skiff.d", + } +} + +func (c Config) AppDataset(app string) string { + return fmt.Sprintf("%s/apps/%s", c.ZFSPool, app) +} + +func (c Config) JailRoot(app string) string { + return filepath.Join(c.JailsMount, app) +} + +func (c Config) RepoPath(app string) string { + return filepath.Join(c.ReposDir, app+".git") +} + +func (c Config) JailConfPath(app string) string { + return filepath.Join(c.JailConfDir, app+".conf") +} + +func (c Config) NginxConfPath(app string) string { + return filepath.Join(c.NginxConfDir, app+".conf") +} + +// Everything below is Capistrano-style: each deploy gets its own immutable +// releases/<sha> checkout (built in place, inside the jail's own dataset), +// `current` is a symlink to whichever release is live, and data.db/env are +// persistent siblings that outlive any single release. +func (c Config) AppDir(app string) string { + return filepath.Join(c.JailRoot(app), "app") +} + +func (c Config) ReleaseDir(app, sha string) string { + return filepath.Join(c.AppDir(app), "releases", sha) +} + +func (c Config) CurrentRelease(app string) string { + return filepath.Join(c.AppDir(app), "current") +} + +// ReleaseDirInJail is releases/<sha> as seen from inside the jail's own +// chroot, not the host. The `current` symlink must be written with this +// form as its target: it's dereferenced by the jail's rc.d script (execing +// CurrentBin), where a host-absolute path like ReleaseDir's resolves +// relative to the jail root instead and never exists. +func (c Config) ReleaseDirInJail(sha string) string { + return filepath.Join("/app", "releases", sha) +} + +// CurrentBin is the path the jail's rc.d script execs - must match +// internal/tmpl/rc.d.tmpl's command_args. +func (c Config) CurrentBin(app string) string { + return filepath.Join(c.CurrentRelease(app), "app") +} + +func (c Config) MakefilePath(app, sha string) string { + return filepath.Join(c.ReleaseDir(app, sha), "Makefile") +} + +func (c Config) DataDB(app string) string { + return filepath.Join(c.AppDir(app), "data.db") +} + +func (c Config) EnvFile(app string) string { + return filepath.Join(c.AppDir(app), "env") +} + +func (c Config) MetaPath(app string) string { + return filepath.Join(c.AppDir(app), "meta.json") +} + +func (c Config) SnapshotName(app, sha string) string { + return fmt.Sprintf("%s@pre-%s", c.AppDataset(app), sha) +} |
