hakurei/hst/hst.go
Ophestra 81430987e7
All checks were successful
Test / Create distribution (push) Successful in 6m57s
Test / Sandbox (push) Successful in 8m53s
Test / Hpkg (push) Successful in 10m40s
Test / Sandbox (race detector) (push) Successful in 10m50s
Test / Create distribution (pull_request) Successful in 10m12s
Test / Hakurei (race detector) (push) Successful in 11m27s
Test / Hakurei (race detector) (pull_request) Successful in 11m24s
Test / Sandbox (pull_request) Successful in 40s
Test / Sandbox (race detector) (pull_request) Successful in 40s
Test / Hpkg (pull_request) Successful in 41s
Test / Hakurei (push) Successful in 2m39s
Test / Hakurei (pull_request) Successful in 2m33s
Test / Flake checks (pull_request) Successful in 1m44s
Test / Flake checks (push) Successful in 1m46s
internal/pipewire: integrate pw_security_context
This is required for securely providing access to PipeWire.

This change has already been manually tested and confirmed to work correctly.

This unfortunately cannot be upstreamed in its current state as libpipewire-0.3 breaks static linking.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-11-19 06:37:30 +09:00

152 lines
5.4 KiB
Go

// Package hst exports stable shared types for interacting with hakurei.
package hst
import (
"errors"
"math"
"net"
"os"
"hakurei.app/container/check"
"hakurei.app/container/fhs"
)
// An AppError is returned while starting an app according to [hst.Config].
type AppError struct {
// A user-facing description of where the error occurred.
Step string `json:"step"`
// The underlying error value.
Err error `json:"err"`
// An arbitrary error message, overriding the return value of Message if not empty.
Msg string `json:"message,omitempty"`
}
func (e *AppError) Error() string { return e.Err.Error() }
func (e *AppError) Unwrap() error { return e.Err }
func (e *AppError) Message() string {
if e.Msg != "" {
return e.Msg
}
switch {
case errors.As(e.Err, new(*os.PathError)),
errors.As(e.Err, new(*os.LinkError)),
errors.As(e.Err, new(*os.SyscallError)),
errors.As(e.Err, new(*net.OpError)):
return "cannot " + e.Error()
default:
return "cannot " + e.Step + ": " + e.Error()
}
}
// Paths contains environment-dependent paths used by hakurei.
type Paths struct {
// Temporary directory returned by [os.TempDir], usually equivalent to [fhs.AbsTmp].
TempDir *check.Absolute `json:"temp_dir"`
// Shared directory specific to the hsu userid, usually (`/tmp/hakurei.%d`, [Info.User]).
SharePath *check.Absolute `json:"share_path"`
// Checked XDG_RUNTIME_DIR value, usually (`/run/user/%d`, uid).
RuntimePath *check.Absolute `json:"runtime_path"`
// Shared directory specific to the hsu userid located in RuntimePath, usually (`/run/user/%d/hakurei`, uid).
RunDirPath *check.Absolute `json:"run_dir_path"`
}
// Info holds basic system information collected from the implementation.
type Info struct {
// WaylandVersion is the libwayland value of WAYLAND_VERSION.
WaylandVersion string `json:"WAYLAND_VERSION"`
// PipeWireVersion is the pipewire value of pw_get_headers_version().
PipeWireVersion string `json:"pw_get_headers_version"`
// Version is a hardcoded version string.
Version string `json:"version"`
// User is the userid according to hsu.
User int `json:"user"`
Paths
}
// Template returns a fully populated instance of Config.
func Template() *Config {
return &Config{
ID: "org.chromium.Chromium",
Enablements: NewEnablements(EWayland | EDBus | EPulse),
SessionBus: &BusConfig{
See: nil,
Talk: []string{"org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver",
"org.freedesktop.secrets", "org.kde.kwalletd5", "org.kde.kwalletd6", "org.gnome.SessionManager"},
Own: []string{"org.chromium.Chromium.*", "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
"org.mpris.MediaPlayer2.chromium.*"},
Call: map[string]string{"org.freedesktop.portal.*": "*"},
Broadcast: map[string]string{"org.freedesktop.portal.*": "@/org/freedesktop/portal/*"},
Log: false,
Filter: true,
},
SystemBus: &BusConfig{
See: nil,
Talk: []string{"org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"},
Own: nil,
Call: nil,
Broadcast: nil,
Log: false,
Filter: true,
},
DirectWayland: false,
ExtraPerms: []ExtraPermConfig{
{Path: fhs.AbsVarLib.Append("hakurei/u0"), Ensure: true, Execute: true},
{Path: fhs.AbsVarLib.Append("hakurei/u0/org.chromium.Chromium"), Read: true, Write: true, Execute: true},
},
Identity: 9,
Groups: []string{"video", "dialout", "plugdev"},
Container: &ContainerConfig{
Hostname: "localhost",
WaitDelay: -1,
// example API credentials pulled from Google Chrome
// DO NOT USE THESE IN A REAL BROWSER
Env: map[string]string{
"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY",
"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com",
"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT",
},
Filesystem: []FilesystemConfigJSON{
{&FSBind{Target: fhs.AbsRoot, Source: fhs.AbsVarLib.Append("hakurei/base/org.debian"), Write: true, Special: true}},
{&FSBind{Target: fhs.AbsEtc, Source: fhs.AbsEtc, Special: true}},
{&FSEphemeral{Target: fhs.AbsTmp, Write: true, Perm: 0755}},
{&FSOverlay{
Target: check.MustAbs("/nix/store"),
Lower: []*check.Absolute{fhs.AbsVarLib.Append("hakurei/base/org.nixos/ro-store")},
Upper: fhs.AbsVarLib.Append("hakurei/nix/u0/org.chromium.Chromium/rw-store/upper"),
Work: fhs.AbsVarLib.Append("hakurei/nix/u0/org.chromium.Chromium/rw-store/work"),
}},
{&FSLink{Target: fhs.AbsRun.Append("current-system"), Linkname: "/run/current-system", Dereference: true}},
{&FSLink{Target: fhs.AbsRun.Append("opengl-driver"), Linkname: "/run/opengl-driver", Dereference: true}},
{&FSBind{Source: fhs.AbsVarLib.Append("hakurei/u0/org.chromium.Chromium"),
Target: check.MustAbs("/data/data/org.chromium.Chromium"), Write: true, Ensure: true}},
{&FSBind{Source: fhs.AbsDev.Append("dri"), Device: true, Optional: true}},
},
Username: "chronos",
Shell: fhs.AbsRun.Append("current-system/sw/bin/zsh"),
Home: check.MustAbs("/data/data/org.chromium.Chromium"),
Path: fhs.AbsRun.Append("current-system/sw/bin/chromium"),
Args: []string{
"chromium",
"--ignore-gpu-blocklist",
"--disable-smooth-scrolling",
"--enable-features=UseOzonePlatform",
"--ozone-platform=wayland",
},
// Set all bits here so new flags trip the template test.
Flags: math.MaxUint,
},
}
}