carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux
2
3package activator
4
5import (
6 "context"
7 "crypto/sha256"
8 "encoding/hex"
9 "os"
10 "os/exec"
11 "path"
12
13 "github.com/carlosframework/platform/internal/cgroup"
14 "github.com/carlosframework/platform/internal/hostbox"
15 "github.com/carlosframework/platform/internal/hostclaim"
16 "github.com/carlosframework/platform/internal/hostwrite"
17 "golang.org/x/sys/unix"
18)
19
20// prepareRoleReservation preserves the recoverable reservation primitive for
21// the future root integration. It grants no execution capability and Start
22// never calls it while the isolated root protocol is unavailable.
23func (l RoleLaunch) prepareRoleReservation(ctx context.Context, role string, attempt hostclaim.WakeRetryAttempt, build func() *exec.Cmd) (*exec.Cmd, *cgroup.Prepared, hostbox.LaunchReservation, error) {
24 if l.Journal.Remote() || l.Parent == nil || l.ParentPath == "" || l.Work == nil || l.Journal == nil || l.Executable == nil || build == nil || attempt.ID == "" || attempt.InvocationID == "" || attempt.LaunchInputs == "" || attempt.Session != l.Target.Session || attempt.Box != l.Target.Box || attempt.Enrollment != l.Target.Enrollment || attempt.BootID != l.Target.BootID || attempt.ControllerID != l.Target.ControllerID {
25 return nil, nil, hostbox.LaunchReservation{}, hostwrite.ErrUnavailable
26 }
27 var cmd *exec.Cmd
28 var executable *os.File
29 defer func() {
30 if executable != nil {
31 executable.Close()
32 }
33 }()
34 var child *cgroup.Prepared
35 var reservation hostbox.LaunchReservation
36 err := l.Work.With(ctx, l.Identity, func() error {
37 if l.Initialize != nil {
38 if err := l.Initialize(ctx); err != nil {
39 return err
40 }
41 }
42 var err error
43 cmd = build()
44 if cmd == nil {
45 return hostwrite.ErrUnavailable
46 }
47 executable, err = l.Executable(ctx, cmd)
48 if err != nil {
49 return err
50 }
51 if executable == nil {
52 return hostwrite.ErrUnavailable
53 }
54 var stat unix.Stat_t
55 if err = unix.Fstat(int(executable.Fd()), &stat); err != nil {
56 return err
57 }
58 if stat.Mode&unix.S_IFMT != unix.S_IFREG || stat.Mode&0111 == 0 {
59 return hostwrite.ErrUnavailable
60 }
61 digest := sha256.Sum256([]byte(role + "\x00" + attempt.ID))
62 name := hex.EncodeToString(digest[:16])
63 reservation = hostbox.LaunchReservation{ID: attempt.ID + ":" + role, Role: role, InvocationID: attempt.InvocationID, Inputs: attempt.LaunchInputs, Target: l.Target, Group: hostbox.LaunchGroup{RelativePath: path.Join(l.ParentPath, "role-"+name), InvocationID: attempt.InvocationID}, Executable: hostbox.LaunchFile{Device: uint64(stat.Dev), Inode: stat.Ino}}
64 child, err = l.Parent.PrepareRoleChildWithIntent(name, func(parent cgroup.ContainmentIdentity) error {
65 reservation.Parent = hostbox.LaunchGroup{RelativePath: l.ParentPath, Device: parent.Device, Inode: parent.Inode}
66 return l.Journal.IntendRole(ctx, reservation)
67 })
68 if err != nil {
69 return err
70 }
71 id, err := child.Identity()
72 if err != nil {
73 return err
74 }
75 reservation.Group.Device, reservation.Group.Inode = id.Device, id.Inode
76 if err = l.Journal.Reserve(ctx, reservation); err != nil {
77 return err
78 }
79 return nil
80 })
81 return cmd, child, reservation, err
82}
83