hst: separate container config
All checks were successful
Test / Create distribution (push) Successful in 34s
Test / Sandbox (push) Successful in 2m11s
Test / Hakurei (push) Successful in 3m7s
Test / Sandbox (race detector) (push) Successful in 4m7s
Test / Hpkg (push) Successful in 4m9s
Test / Hakurei (race detector) (push) Successful in 4m47s
Test / Flake checks (push) Successful in 1m31s

The booleans are getting packed into a single field. This requires non-insignificant amount of code for JSON serialisation to stay compatible.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-10-14 04:22:26 +09:00
parent e4ee8df83c
commit a341466942
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
2 changed files with 111 additions and 107 deletions

View File

@ -3,122 +3,40 @@ package hst
import (
"errors"
"strconv"
"time"
"hakurei.app/container/check"
)
// PrivateTmp is a private writable path in a hakurei container.
const PrivateTmp = "/.hakurei"
// Config configures an application container, implemented in internal/app.
type Config struct {
// Reverse-DNS style configured arbitrary identifier string.
// Passed to wayland security-context-v1 and used as part of defaults in dbus session proxy.
ID string `json:"id"`
// AbsPrivateTmp is a [check.Absolute] representation of [PrivateTmp].
var AbsPrivateTmp = check.MustAbs(PrivateTmp)
// System services to make available in the container.
Enablements *Enablements `json:"enablements,omitempty"`
const (
// WaitDelayDefault is used when WaitDelay has its zero value.
WaitDelayDefault = 5 * time.Second
// WaitDelayMax is used if WaitDelay exceeds its value.
WaitDelayMax = 30 * time.Second
// Session D-Bus proxy configuration.
// If set to nil, session bus proxy assume built-in defaults.
SessionBus *BusConfig `json:"session_bus,omitempty"`
// System D-Bus proxy configuration.
// If set to nil, system bus proxy is disabled.
SystemBus *BusConfig `json:"system_bus,omitempty"`
// Direct access to wayland socket, no attempt is made to attach security-context-v1
// and the bare socket is made available to the container.
DirectWayland bool `json:"direct_wayland,omitempty"`
// IdentityMin is the minimum value of [Config.Identity]. This is enforced by cmd/hsu.
IdentityMin = 0
// IdentityMax is the maximum value of [Config.Identity]. This is enforced by cmd/hsu.
IdentityMax = 9999
// Extra acl update ops to perform before setuid.
ExtraPerms []*ExtraPermConfig `json:"extra_perms,omitempty"`
// ShimExitRequest is returned when the priv side process requests shim exit.
ShimExitRequest = 254
// ShimExitOrphan is returned when the shim is orphaned before priv side delivers a signal.
ShimExitOrphan = 3
)
// Numerical application id, passed to hsu, used to derive init user namespace credentials.
Identity int `json:"identity"`
// Init user namespace supplementary groups inherited by all container processes.
Groups []string `json:"groups"`
type (
// Config configures an application container, implemented in internal/app.
Config struct {
// Reverse-DNS style configured arbitrary identifier string.
// Passed to wayland security-context-v1 and used as part of defaults in dbus session proxy.
ID string `json:"id"`
// System services to make available in the container.
Enablements *Enablements `json:"enablements,omitempty"`
// Session D-Bus proxy configuration.
// If set to nil, session bus proxy assume built-in defaults.
SessionBus *BusConfig `json:"session_bus,omitempty"`
// System D-Bus proxy configuration.
// If set to nil, system bus proxy is disabled.
SystemBus *BusConfig `json:"system_bus,omitempty"`
// Direct access to wayland socket, no attempt is made to attach security-context-v1
// and the bare socket is made available to the container.
DirectWayland bool `json:"direct_wayland,omitempty"`
// Extra acl update ops to perform before setuid.
ExtraPerms []*ExtraPermConfig `json:"extra_perms,omitempty"`
// Numerical application id, passed to hsu, used to derive init user namespace credentials.
Identity int `json:"identity"`
// Init user namespace supplementary groups inherited by all container processes.
Groups []string `json:"groups"`
// High level configuration applied to the underlying [container].
Container *ContainerConfig `json:"container"`
}
// ContainerConfig describes the container configuration to be applied to an underlying [container].
ContainerConfig struct {
// Container UTS namespace hostname.
Hostname string `json:"hostname,omitempty"`
// Duration in nanoseconds to wait for after interrupting the initial process.
// Defaults to [WaitDelayDefault] if zero, or [WaitDelayMax] if greater than [WaitDelayMax].
// Values lesser than zero is equivalent to zero, bypassing [WaitDelayDefault].
WaitDelay time.Duration `json:"wait_delay,omitempty"`
// Emit Flatpak-compatible seccomp filter programs.
SeccompCompat bool `json:"seccomp_compat,omitempty"`
// Allow ptrace and friends.
Devel bool `json:"devel,omitempty"`
// Allow userns creation and container setup syscalls.
Userns bool `json:"userns,omitempty"`
// Share host net namespace.
HostNet bool `json:"host_net,omitempty"`
// Share abstract unix socket scope.
HostAbstract bool `json:"host_abstract,omitempty"`
// Allow dangerous terminal I/O (faking input).
Tty bool `json:"tty,omitempty"`
// Allow multiarch.
Multiarch bool `json:"multiarch,omitempty"`
// Initial process environment variables.
Env map[string]string `json:"env"`
/* Map target user uid to privileged user uid in the container user namespace.
Some programs fail to connect to dbus session running as a different uid,
this option works around it by mapping priv-side caller uid in container. */
MapRealUID bool `json:"map_real_uid"`
// Mount /dev/ from the init mount namespace as-is in the container mount namespace.
Device bool `json:"device,omitempty"`
/* Container mount points.
If the first element targets /, it is inserted early and excluded from path hiding. */
Filesystem []FilesystemConfigJSON `json:"filesystem"`
// String used as the username of the emulated user, validated against the default NAME_REGEX from adduser.
// Defaults to passwd name of target uid or chronos.
Username string `json:"username,omitempty"`
// Pathname of shell in the container filesystem to use for the emulated user.
Shell *check.Absolute `json:"shell"`
// Directory in the container filesystem to enter and use as the home directory of the emulated user.
Home *check.Absolute `json:"home"`
// Pathname to executable file in the container filesystem.
Path *check.Absolute `json:"path,omitempty"`
// Final args passed to the initial program.
Args []string `json:"args"`
}
)
// High level configuration applied to the underlying [container].
Container *ContainerConfig `json:"container"`
}
var (
// ErrConfigNull is returned by [Config.Validate] for an invalid configuration that contains a null value for any

86
hst/container.go Normal file
View File

@ -0,0 +1,86 @@
package hst
import (
"time"
"hakurei.app/container/check"
)
// PrivateTmp is a private writable path in a hakurei container.
const PrivateTmp = "/.hakurei"
// AbsPrivateTmp is a [check.Absolute] representation of [PrivateTmp].
var AbsPrivateTmp = check.MustAbs(PrivateTmp)
const (
// WaitDelayDefault is used when WaitDelay has its zero value.
WaitDelayDefault = 5 * time.Second
// WaitDelayMax is used if WaitDelay exceeds its value.
WaitDelayMax = 30 * time.Second
// IdentityMin is the minimum value of [Config.Identity]. This is enforced by cmd/hsu.
IdentityMin = 0
// IdentityMax is the maximum value of [Config.Identity]. This is enforced by cmd/hsu.
IdentityMax = 9999
// ShimExitRequest is returned when the priv side process requests shim exit.
ShimExitRequest = 254
// ShimExitOrphan is returned when the shim is orphaned before priv side delivers a signal.
ShimExitOrphan = 3
)
// ContainerConfig describes the container configuration to be applied to an underlying [container].
type ContainerConfig struct {
// Container UTS namespace hostname.
Hostname string `json:"hostname,omitempty"`
// Duration in nanoseconds to wait for after interrupting the initial process.
// Defaults to [WaitDelayDefault] if zero, or [WaitDelayMax] if greater than [WaitDelayMax].
// Values lesser than zero is equivalent to zero, bypassing [WaitDelayDefault].
WaitDelay time.Duration `json:"wait_delay,omitempty"`
// Emit Flatpak-compatible seccomp filter programs.
SeccompCompat bool `json:"seccomp_compat,omitempty"`
// Allow ptrace and friends.
Devel bool `json:"devel,omitempty"`
// Allow userns creation and container setup syscalls.
Userns bool `json:"userns,omitempty"`
// Share host net namespace.
HostNet bool `json:"host_net,omitempty"`
// Share abstract unix socket scope.
HostAbstract bool `json:"host_abstract,omitempty"`
// Allow dangerous terminal I/O (faking input).
Tty bool `json:"tty,omitempty"`
// Allow multiarch.
Multiarch bool `json:"multiarch,omitempty"`
// Initial process environment variables.
Env map[string]string `json:"env"`
/* Map target user uid to privileged user uid in the container user namespace.
Some programs fail to connect to dbus session running as a different uid,
this option works around it by mapping priv-side caller uid in container. */
MapRealUID bool `json:"map_real_uid"`
// Mount /dev/ from the init mount namespace as-is in the container mount namespace.
Device bool `json:"device,omitempty"`
/* Container mount points.
If the first element targets /, it is inserted early and excluded from path hiding. */
Filesystem []FilesystemConfigJSON `json:"filesystem"`
// String used as the username of the emulated user, validated against the default NAME_REGEX from adduser.
// Defaults to passwd name of target uid or chronos.
Username string `json:"username,omitempty"`
// Pathname of shell in the container filesystem to use for the emulated user.
Shell *check.Absolute `json:"shell"`
// Directory in the container filesystem to enter and use as the home directory of the emulated user.
Home *check.Absolute `json:"home"`
// Pathname to executable file in the container filesystem.
Path *check.Absolute `json:"path,omitempty"`
// Final args passed to the initial program.
Args []string `json:"args"`
}