v0.66.0: userdata layout + shared-storage ownership convention
appbackup/userdata.go: EnsureUserdataDir (MkdirAll + explicit setgid Chmod 2775 +
chown gid 1000), UserdataSkeleton, EnsureUserdataSkeleton; linux chown/StatGID +
non-linux stubs. stackEnv injects USERDATA_PATH=<HDD_PATH>/userdata. Skeleton
pre-created on register + FileBrowser sync; deploy belt (composeExecCustomEnv on
'up') pre-creates every ${USERDATA_PATH} bind source. FileBrowser mounts userdata
(was appdata) — uid 1000 can now write into 2775 setgid. #8: migrate merge walk +
copyFile preserve source setgid+group so the convention survives MigrateAll.
Non-hollow tests incl. Linux setgid assertions + migration-preserve companion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,7 +21,7 @@ type Metadata struct {
|
||||
AppInfo AppInfo `yaml:"app_info" json:"app_info"`
|
||||
OptionalConfig []OptionalConfigGroup `yaml:"optional_config" json:"optional_config"`
|
||||
HealthCheck *HealthCheckConfig `yaml:"healthcheck,omitempty" json:"healthcheck,omitempty"`
|
||||
Integrations []IntegrationDef `yaml:"integrations,omitempty" json:"integrations,omitempty"`
|
||||
Integrations []IntegrationDef `yaml:"integrations,omitempty" json:"integrations,omitempty"`
|
||||
}
|
||||
|
||||
// AppInfo holds detailed app information for the info page.
|
||||
@@ -52,25 +52,25 @@ type OptionalConfigField struct {
|
||||
|
||||
// ResourceHints describe what the app needs.
|
||||
type ResourceHints struct {
|
||||
MemRequest string `yaml:"mem_request" json:"mem_request"`
|
||||
MemLimit string `yaml:"mem_limit" json:"mem_limit"`
|
||||
PiCompatible bool `yaml:"pi_compatible" json:"pi_compatible"`
|
||||
NeedsHDD bool `yaml:"needs_hdd" json:"needs_hdd"`
|
||||
HungarianUI bool `yaml:"hungarian_ui" json:"hungarian_ui"`
|
||||
MemRequest string `yaml:"mem_request" json:"mem_request"`
|
||||
MemLimit string `yaml:"mem_limit" json:"mem_limit"`
|
||||
PiCompatible bool `yaml:"pi_compatible" json:"pi_compatible"`
|
||||
NeedsHDD bool `yaml:"needs_hdd" json:"needs_hdd"`
|
||||
HungarianUI bool `yaml:"hungarian_ui" json:"hungarian_ui"`
|
||||
}
|
||||
|
||||
// DeployField defines one configuration field shown during first deployment.
|
||||
type DeployField struct {
|
||||
EnvVar string `yaml:"env_var" json:"env_var"`
|
||||
Label string `yaml:"label" json:"label"`
|
||||
Type string `yaml:"type" json:"type"` // domain, subdomain, secret, password, path, text, select, boolean
|
||||
Generate string `yaml:"generate" json:"generate"` // e.g., "password:24", "hex:32", "static:admin"
|
||||
Default string `yaml:"default" json:"default"`
|
||||
Required bool `yaml:"required" json:"required"`
|
||||
Placeholder string `yaml:"placeholder" json:"placeholder"`
|
||||
Description string `yaml:"description" json:"description"`
|
||||
EnvVar string `yaml:"env_var" json:"env_var"`
|
||||
Label string `yaml:"label" json:"label"`
|
||||
Type string `yaml:"type" json:"type"` // domain, subdomain, secret, password, path, text, select, boolean
|
||||
Generate string `yaml:"generate" json:"generate"` // e.g., "password:24", "hex:32", "static:admin"
|
||||
Default string `yaml:"default" json:"default"`
|
||||
Required bool `yaml:"required" json:"required"`
|
||||
Placeholder string `yaml:"placeholder" json:"placeholder"`
|
||||
Description string `yaml:"description" json:"description"`
|
||||
LockedAfterDeploy bool `yaml:"locked_after_deploy" json:"locked_after_deploy"`
|
||||
Options []SelectOption `yaml:"options" json:"options,omitempty"`
|
||||
Options []SelectOption `yaml:"options" json:"options,omitempty"`
|
||||
// DataKey marks a field as a DATA-ENCRYPTING key (e.g. AdventureLog's "Titkosítási kulcs"):
|
||||
// the app encrypts stored data with it, so regenerating it would render restored data
|
||||
// unreadable. It is a fail-closed annotation only — the recovery unit never stores secrets;
|
||||
@@ -113,7 +113,7 @@ type HealthCheckConfig struct {
|
||||
|
||||
// HealthCheckItem defines a single health check probe.
|
||||
type HealthCheckItem struct {
|
||||
Type string `yaml:"type" json:"type"` // "http", "api", "tcp"
|
||||
Type string `yaml:"type" json:"type"` // "http", "api", "tcp"
|
||||
Port int `yaml:"port" json:"port"`
|
||||
Path string `yaml:"path" json:"path"` // for http/api; default "/"
|
||||
Method string `yaml:"method" json:"method"` // for api; default "GET"
|
||||
|
||||
Reference in New Issue
Block a user