aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/spfinal.go
blob: 7e444168ebed52174047bd8c9c3464e1bf1ad540 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package app

import (
	"encoding/gob"
	"fmt"
	"slices"
	"strings"
	"syscall"

	"hakurei.app/container/fhs"
	"hakurei.app/hst"
	"hakurei.app/system"
	"hakurei.app/system/acl"
)

func init() { gob.Register(spFinalOp{}) }

// spFinalOp is a transitional op destined for removal after #3, #8, #9 has been resolved.
// It exists to avoid reordering the expected entries in test cases.
type spFinalOp struct{}

func (s spFinalOp) toSystem(state *outcomeStateSys) error {
	// append ExtraPerms last
	for i := range state.extraPerms {
		p := &state.extraPerms[i]
		if p.Path == nil {
			continue
		}

		if p.Ensure {
			state.sys.Ensure(p.Path, 0700)
		}

		perms := make(acl.Perms, 0, 3)
		if p.Read {
			perms = append(perms, acl.Read)
		}
		if p.Write {
			perms = append(perms, acl.Write)
		}
		if p.Execute {
			perms = append(perms, acl.Execute)
		}
		state.sys.UpdatePermType(system.User, p.Path, perms...)
	}
	return nil
}

func (s spFinalOp) toContainer(state *outcomeStateParams) error {
	// TODO(ophestra): move this to spFilesystemOp after #8 and #9

	// mount root read-only as the final setup Op
	state.params.Remount(fhs.AbsRoot, syscall.MS_RDONLY)

	state.params.Env = make([]string, 0, len(state.env))
	for key, value := range state.env {
		if strings.IndexByte(key, '=') != -1 {
			return &hst.AppError{Step: "flatten environment", Err: syscall.EINVAL,
				Msg: fmt.Sprintf("invalid environment variable %s", key)}
		}
		state.params.Env = append(state.params.Env, key+"="+value)
	}
	// range over map has randomised order
	slices.Sort(state.params.Env)

	return nil
}