hst/config: move container fields from toplevel
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m7s
Test / Hpkg (push) Successful in 3m54s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Sandbox (race detector) (push) Successful in 2m10s
Test / Hakurei (push) Successful in 2m13s
Test / Flake checks (push) Successful in 1m33s
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m7s
Test / Hpkg (push) Successful in 3m54s
Test / Hakurei (race detector) (push) Successful in 5m18s
Test / Sandbox (race detector) (push) Successful in 2m10s
Test / Hakurei (push) Successful in 2m13s
Test / Flake checks (push) Successful in 1m33s
This change also moves pd behaviour to cmd/hakurei, as this does not belong in the hst API. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -2,10 +2,12 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -52,7 +54,9 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
|
||||
|
||||
// config extraArgs...
|
||||
config := tryPath(msg, args[0])
|
||||
config.Args = append(config.Args, args[1:]...)
|
||||
if config != nil && config.Container != nil {
|
||||
config.Container.Args = append(config.Container.Args, args[1:]...)
|
||||
}
|
||||
|
||||
app.Main(ctx, msg, config)
|
||||
panic("unreachable")
|
||||
@@ -75,12 +79,6 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
|
||||
)
|
||||
|
||||
c.NewCommand("run", "Configure and start a permissive container", func(args []string) error {
|
||||
// initialise config from flags
|
||||
config := &hst.Config{
|
||||
ID: flagID,
|
||||
Args: args,
|
||||
}
|
||||
|
||||
if flagIdentity < hst.IdentityMin || flagIdentity > hst.IdentityMax {
|
||||
log.Fatalf("identity %d out of range", flagIdentity)
|
||||
}
|
||||
@@ -106,41 +104,109 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
|
||||
}
|
||||
)
|
||||
|
||||
if flagHomeDir == "os" {
|
||||
passwdOnce.Do(passwdFunc)
|
||||
flagHomeDir = passwd.HomeDir
|
||||
// paths are identical, resolve inner shell and program path
|
||||
shell := container.AbsFHSRoot.Append("bin", "sh")
|
||||
if a, err := container.NewAbs(os.Getenv("SHELL")); err == nil {
|
||||
shell = a
|
||||
}
|
||||
progPath := shell
|
||||
if len(args) > 0 {
|
||||
if p, err := exec.LookPath(args[0]); err != nil {
|
||||
log.Fatal(errors.Unwrap(err))
|
||||
return err
|
||||
} else if progPath, err = container.NewAbs(p); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if flagUserName == "chronos" {
|
||||
passwdOnce.Do(passwdFunc)
|
||||
flagUserName = passwd.Username
|
||||
}
|
||||
|
||||
config.Identity = flagIdentity
|
||||
config.Groups = flagGroups
|
||||
config.Username = flagUserName
|
||||
|
||||
if a, err := container.NewAbs(flagHomeDir); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return err
|
||||
} else {
|
||||
config.Home = a
|
||||
}
|
||||
|
||||
var e hst.Enablement
|
||||
var et hst.Enablement
|
||||
if flagWayland {
|
||||
e |= hst.EWayland
|
||||
et |= hst.EWayland
|
||||
}
|
||||
if flagX11 {
|
||||
e |= hst.EX11
|
||||
et |= hst.EX11
|
||||
}
|
||||
if flagDBus {
|
||||
e |= hst.EDBus
|
||||
et |= hst.EDBus
|
||||
}
|
||||
if flagPulse {
|
||||
e |= hst.EPulse
|
||||
et |= hst.EPulse
|
||||
}
|
||||
|
||||
config := &hst.Config{
|
||||
ID: flagID,
|
||||
Identity: flagIdentity,
|
||||
Groups: flagGroups,
|
||||
Enablements: hst.NewEnablements(et),
|
||||
|
||||
Container: &hst.ContainerConfig{
|
||||
Userns: true,
|
||||
HostNet: true,
|
||||
Tty: true,
|
||||
HostAbstract: true,
|
||||
|
||||
Filesystem: []hst.FilesystemConfigJSON{
|
||||
// autoroot, includes the home directory
|
||||
{FilesystemConfig: &hst.FSBind{
|
||||
Target: container.AbsFHSRoot,
|
||||
Source: container.AbsFHSRoot,
|
||||
Write: true,
|
||||
Special: true,
|
||||
}},
|
||||
},
|
||||
|
||||
Username: flagUserName,
|
||||
Shell: shell,
|
||||
|
||||
Path: progPath,
|
||||
Args: args,
|
||||
},
|
||||
}
|
||||
|
||||
// bind GPU stuff
|
||||
if et&(hst.EX11|hst.EWayland) != 0 {
|
||||
config.Container.Filesystem = append(config.Container.Filesystem, hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{
|
||||
Source: container.AbsFHSDev.Append("dri"),
|
||||
Device: true,
|
||||
Optional: true,
|
||||
}})
|
||||
}
|
||||
|
||||
config.Container.Filesystem = append(config.Container.Filesystem,
|
||||
// opportunistically bind kvm
|
||||
hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{
|
||||
Source: container.AbsFHSDev.Append("kvm"),
|
||||
Device: true,
|
||||
Optional: true,
|
||||
}},
|
||||
|
||||
// do autoetc last
|
||||
hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{
|
||||
Target: container.AbsFHSEtc,
|
||||
Source: container.AbsFHSEtc,
|
||||
Special: true,
|
||||
}},
|
||||
)
|
||||
|
||||
if config.Container.Username == "chronos" {
|
||||
passwdOnce.Do(passwdFunc)
|
||||
config.Container.Username = passwd.Username
|
||||
}
|
||||
|
||||
{
|
||||
homeDir := flagHomeDir
|
||||
if homeDir == "os" {
|
||||
passwdOnce.Do(passwdFunc)
|
||||
homeDir = passwd.HomeDir
|
||||
}
|
||||
if a, err := container.NewAbs(homeDir); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
return err
|
||||
} else {
|
||||
config.Container.Home = a
|
||||
}
|
||||
}
|
||||
config.Enablements = hst.NewEnablements(e)
|
||||
|
||||
// parse D-Bus config file from flags if applicable
|
||||
if flagDBus {
|
||||
@@ -218,7 +284,9 @@ func buildCommand(ctx context.Context, msg container.Msg, early *earlyHardeningE
|
||||
if config == nil {
|
||||
config = tryPath(msg, name)
|
||||
}
|
||||
printShowInstance(os.Stdout, time.Now().UTC(), entry, config, flagShort, flagJSON)
|
||||
if !printShowInstance(os.Stdout, time.Now().UTC(), entry, config, flagShort, flagJSON) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
default:
|
||||
log.Fatal("show requires 1 argument")
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"hakurei.app/container"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/app"
|
||||
"hakurei.app/internal/app/state"
|
||||
@@ -39,7 +40,9 @@ func printShowSystem(output io.Writer, short, flagJSON bool) {
|
||||
func printShowInstance(
|
||||
output io.Writer, now time.Time,
|
||||
instance *state.State, config *hst.Config,
|
||||
short, flagJSON bool) {
|
||||
short, flagJSON bool) (valid bool) {
|
||||
valid = true
|
||||
|
||||
if flagJSON {
|
||||
if instance != nil {
|
||||
printJSON(output, short, instance)
|
||||
@@ -52,8 +55,11 @@ func printShowInstance(
|
||||
t := newPrinter(output)
|
||||
defer t.MustFlush()
|
||||
|
||||
if config.Container == nil {
|
||||
mustPrint(output, "Warning: this configuration uses permissive defaults!\n\n")
|
||||
if err := config.Validate(); err != nil {
|
||||
valid = false
|
||||
if m, ok := container.GetErrorMessage(err); ok {
|
||||
mustPrint(output, "Error: "+m+"!\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
if instance != nil {
|
||||
@@ -73,11 +79,11 @@ func printShowInstance(
|
||||
if len(config.Groups) > 0 {
|
||||
t.Printf(" Groups:\t%s\n", strings.Join(config.Groups, ", "))
|
||||
}
|
||||
if config.Home != nil {
|
||||
t.Printf(" Home:\t%s\n", config.Home)
|
||||
}
|
||||
if config.Container != nil {
|
||||
params := config.Container
|
||||
if params.Home != nil {
|
||||
t.Printf(" Home:\t%s\n", params.Home)
|
||||
}
|
||||
if params.Hostname != "" {
|
||||
t.Printf(" Hostname:\t%s\n", params.Hostname)
|
||||
}
|
||||
@@ -100,12 +106,12 @@ func printShowInstance(
|
||||
}
|
||||
t.Printf(" Flags:\t%s\n", strings.Join(flags, " "))
|
||||
|
||||
if config.Path != nil {
|
||||
t.Printf(" Path:\t%s\n", config.Path)
|
||||
if params.Path != nil {
|
||||
t.Printf(" Path:\t%s\n", params.Path)
|
||||
}
|
||||
if len(params.Args) > 0 {
|
||||
t.Printf(" Arguments:\t%s\n", strings.Join(params.Args, " "))
|
||||
}
|
||||
}
|
||||
if len(config.Args) > 0 {
|
||||
t.Printf(" Arguments:\t%s\n", strings.Join(config.Args, " "))
|
||||
}
|
||||
t.Printf("\n")
|
||||
|
||||
@@ -114,6 +120,7 @@ func printShowInstance(
|
||||
t.Printf("Filesystem\n")
|
||||
for _, f := range config.Container.Filesystem {
|
||||
if !f.Valid() {
|
||||
valid = false
|
||||
t.Println(" <invalid>")
|
||||
continue
|
||||
}
|
||||
@@ -161,6 +168,8 @@ func printShowInstance(
|
||||
printDBus(config.SystemBus)
|
||||
t.Printf("\n")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func printPs(output io.Writer, now time.Time, s state.Store, short, flagJSON bool) {
|
||||
|
||||
@@ -27,13 +27,14 @@ var (
|
||||
testAppTime = time.Unix(0, 9).UTC()
|
||||
)
|
||||
|
||||
func Test_printShowInstance(t *testing.T) {
|
||||
func TestPrintShowInstance(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
instance *state.State
|
||||
config *hst.Config
|
||||
short, json bool
|
||||
want string
|
||||
valid bool
|
||||
}{
|
||||
{"config", nil, hst.Template(), false, false, `App
|
||||
Identity: 9 (org.chromium.Chromium)
|
||||
@@ -71,21 +72,25 @@ System bus
|
||||
Filter: true
|
||||
Talk: ["org.bluez" "org.freedesktop.Avahi" "org.freedesktop.UPower"]
|
||||
|
||||
`},
|
||||
{"config pd", nil, new(hst.Config), false, false, `Warning: this configuration uses permissive defaults!
|
||||
`, true},
|
||||
{"config pd", nil, new(hst.Config), false, false, `Error: configuration missing container state!
|
||||
|
||||
App
|
||||
Identity: 0
|
||||
Enablements: (no enablements)
|
||||
|
||||
`},
|
||||
{"config flag none", nil, &hst.Config{Container: new(hst.ContainerConfig)}, false, false, `App
|
||||
`, false},
|
||||
{"config flag none", nil, &hst.Config{Container: new(hst.ContainerConfig)}, false, false, `Error: container configuration missing path to home directory!
|
||||
|
||||
App
|
||||
Identity: 0
|
||||
Enablements: (no enablements)
|
||||
Flags: none
|
||||
|
||||
`},
|
||||
{"config nil entries", nil, &hst.Config{Container: &hst.ContainerConfig{Filesystem: make([]hst.FilesystemConfigJSON, 1)}, ExtraPerms: make([]*hst.ExtraPermConfig, 1)}, false, false, `App
|
||||
`, false},
|
||||
{"config nil entries", nil, &hst.Config{Container: &hst.ContainerConfig{Filesystem: make([]hst.FilesystemConfigJSON, 1)}, ExtraPerms: make([]*hst.ExtraPermConfig, 1)}, false, false, `Error: container configuration missing path to home directory!
|
||||
|
||||
App
|
||||
Identity: 0
|
||||
Enablements: (no enablements)
|
||||
Flags: none
|
||||
@@ -95,8 +100,8 @@ Filesystem
|
||||
|
||||
Extra ACL
|
||||
|
||||
`},
|
||||
{"config pd dbus see", nil, &hst.Config{SessionBus: &dbus.Config{See: []string{"org.example.test"}}}, false, false, `Warning: this configuration uses permissive defaults!
|
||||
`, false},
|
||||
{"config pd dbus see", nil, &hst.Config{SessionBus: &dbus.Config{See: []string{"org.example.test"}}}, false, false, `Error: configuration missing container state!
|
||||
|
||||
App
|
||||
Identity: 0
|
||||
@@ -106,7 +111,7 @@ Session bus
|
||||
Filter: false
|
||||
See: ["org.example.test"]
|
||||
|
||||
`},
|
||||
`, false},
|
||||
|
||||
{"instance", testState, hst.Template(), false, false, `State
|
||||
Instance: 8e2c76b066dabe574cf073bdb46eb5c1 (3735928559)
|
||||
@@ -148,8 +153,8 @@ System bus
|
||||
Filter: true
|
||||
Talk: ["org.bluez" "org.freedesktop.Avahi" "org.freedesktop.UPower"]
|
||||
|
||||
`},
|
||||
{"instance pd", testState, new(hst.Config), false, false, `Warning: this configuration uses permissive defaults!
|
||||
`, true},
|
||||
{"instance pd", testState, new(hst.Config), false, false, `Error: configuration missing container state!
|
||||
|
||||
State
|
||||
Instance: 8e2c76b066dabe574cf073bdb46eb5c1 (3735928559)
|
||||
@@ -159,10 +164,10 @@ App
|
||||
Identity: 0
|
||||
Enablements: (no enablements)
|
||||
|
||||
`},
|
||||
`, false},
|
||||
|
||||
{"json nil", nil, nil, false, true, `null
|
||||
`},
|
||||
`, true},
|
||||
{"json instance", testState, nil, false, true, `{
|
||||
"instance": [
|
||||
142,
|
||||
@@ -185,14 +190,6 @@ App
|
||||
"pid": 3735928559,
|
||||
"config": {
|
||||
"id": "org.chromium.Chromium",
|
||||
"path": "/run/current-system/sw/bin/chromium",
|
||||
"args": [
|
||||
"chromium",
|
||||
"--ignore-gpu-blocklist",
|
||||
"--disable-smooth-scrolling",
|
||||
"--enable-features=UseOzonePlatform",
|
||||
"--ozone-platform=wayland"
|
||||
],
|
||||
"enablements": {
|
||||
"wayland": true,
|
||||
"dbus": true,
|
||||
@@ -234,9 +231,6 @@ App
|
||||
"broadcast": null,
|
||||
"filter": true
|
||||
},
|
||||
"username": "chronos",
|
||||
"shell": "/run/current-system/sw/bin/zsh",
|
||||
"home": "/data/data/org.chromium.Chromium",
|
||||
"extra_perms": [
|
||||
{
|
||||
"ensure": true,
|
||||
@@ -331,22 +325,25 @@ App
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
],
|
||||
"username": "chronos",
|
||||
"shell": "/run/current-system/sw/bin/zsh",
|
||||
"home": "/data/data/org.chromium.Chromium",
|
||||
"path": "/run/current-system/sw/bin/chromium",
|
||||
"args": [
|
||||
"chromium",
|
||||
"--ignore-gpu-blocklist",
|
||||
"--disable-smooth-scrolling",
|
||||
"--enable-features=UseOzonePlatform",
|
||||
"--ozone-platform=wayland"
|
||||
]
|
||||
}
|
||||
},
|
||||
"time": "1970-01-01T00:00:00.000000009Z"
|
||||
}
|
||||
`},
|
||||
`, true},
|
||||
{"json config", nil, hst.Template(), false, true, `{
|
||||
"id": "org.chromium.Chromium",
|
||||
"path": "/run/current-system/sw/bin/chromium",
|
||||
"args": [
|
||||
"chromium",
|
||||
"--ignore-gpu-blocklist",
|
||||
"--disable-smooth-scrolling",
|
||||
"--enable-features=UseOzonePlatform",
|
||||
"--ozone-platform=wayland"
|
||||
],
|
||||
"enablements": {
|
||||
"wayland": true,
|
||||
"dbus": true,
|
||||
@@ -388,9 +385,6 @@ App
|
||||
"broadcast": null,
|
||||
"filter": true
|
||||
},
|
||||
"username": "chronos",
|
||||
"shell": "/run/current-system/sw/bin/zsh",
|
||||
"home": "/data/data/org.chromium.Chromium",
|
||||
"extra_perms": [
|
||||
{
|
||||
"ensure": true,
|
||||
@@ -485,26 +479,39 @@ App
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
],
|
||||
"username": "chronos",
|
||||
"shell": "/run/current-system/sw/bin/zsh",
|
||||
"home": "/data/data/org.chromium.Chromium",
|
||||
"path": "/run/current-system/sw/bin/chromium",
|
||||
"args": [
|
||||
"chromium",
|
||||
"--ignore-gpu-blocklist",
|
||||
"--disable-smooth-scrolling",
|
||||
"--enable-features=UseOzonePlatform",
|
||||
"--ozone-platform=wayland"
|
||||
]
|
||||
}
|
||||
}
|
||||
`},
|
||||
`, true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
output := new(strings.Builder)
|
||||
printShowInstance(output, testTime, tc.instance, tc.config, tc.short, tc.json)
|
||||
gotValid := printShowInstance(output, testTime, tc.instance, tc.config, tc.short, tc.json)
|
||||
if got := output.String(); got != tc.want {
|
||||
t.Errorf("printShowInstance: got\n%s\nwant\n%s",
|
||||
got, tc.want)
|
||||
t.Errorf("printShowInstance: \n%s\nwant\n%s", got, tc.want)
|
||||
return
|
||||
}
|
||||
if gotValid != tc.valid {
|
||||
t.Errorf("printShowInstance: valid = %v, want %v", gotValid, tc.valid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_printPs(t *testing.T) {
|
||||
func TestPrintPs(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
entries state.Entries
|
||||
@@ -547,14 +554,6 @@ func Test_printPs(t *testing.T) {
|
||||
"pid": 3735928559,
|
||||
"config": {
|
||||
"id": "org.chromium.Chromium",
|
||||
"path": "/run/current-system/sw/bin/chromium",
|
||||
"args": [
|
||||
"chromium",
|
||||
"--ignore-gpu-blocklist",
|
||||
"--disable-smooth-scrolling",
|
||||
"--enable-features=UseOzonePlatform",
|
||||
"--ozone-platform=wayland"
|
||||
],
|
||||
"enablements": {
|
||||
"wayland": true,
|
||||
"dbus": true,
|
||||
@@ -596,9 +595,6 @@ func Test_printPs(t *testing.T) {
|
||||
"broadcast": null,
|
||||
"filter": true
|
||||
},
|
||||
"username": "chronos",
|
||||
"shell": "/run/current-system/sw/bin/zsh",
|
||||
"home": "/data/data/org.chromium.Chromium",
|
||||
"extra_perms": [
|
||||
{
|
||||
"ensure": true,
|
||||
@@ -693,6 +689,17 @@ func Test_printPs(t *testing.T) {
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
],
|
||||
"username": "chronos",
|
||||
"shell": "/run/current-system/sw/bin/zsh",
|
||||
"home": "/data/data/org.chromium.Chromium",
|
||||
"path": "/run/current-system/sw/bin/chromium",
|
||||
"args": [
|
||||
"chromium",
|
||||
"--ignore-gpu-blocklist",
|
||||
"--disable-smooth-scrolling",
|
||||
"--enable-features=UseOzonePlatform",
|
||||
"--ozone-platform=wayland"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user