daemon_start.go RawHistoryFolder

1package broker
2
3import (
4	"errors"
5	"fmt"
6
7	"github.com/bnema/vev/internal/ports"
8)
9
10// DaemonLaunchAuthority is the policy launch token that explicitly authorizes
11// starting a stopped target daemon. Ports carry it opaquely; the broker is the
12// component that interprets it. Any other token, including every
13// sandbox-private one, fails closed and never starts a daemon.
14const DaemonLaunchAuthority = "explicit"
15
16// RequireLocalDaemonTarget refuses a target that is not the broker-owned local
17// daemon. Only that authority names a daemon this process can start, so a
18// registered host is never started by mistake, even on a local carriage.
19func RequireLocalDaemonTarget(target ports.BrokerDialTarget) error {
20	if !target.Fence.Local {
21		return daemonStartRefused("the target is not the broker-owned local daemon")
22	}
23	return nil
24}
25
26// ClassifyDaemonDialFailure decides whether a failed carriage dial may lead to
27// a start at all. absent reports whether the transport proved the daemon is
28// simply not there; that classification belongs to the carriage adapter and
29// must fail closed.
30//
31// It returns nil only when the daemon is absent under a mode other than
32// ExistingOnly. Otherwise it returns the error to report, and no lock,
33// election, or process may be touched:
34//
35//   - ExistingOnly never starts: absence becomes BrokerErrorNoDaemon and every
36//     other failure is reported unchanged.
37//   - A failure that is not absence (cancellation, a rejected peer, a foreign
38//     path, a permission error) is never repaired by starting another daemon.
39func ClassifyDaemonDialFailure(target ports.BrokerDialTarget, dialErr error, absent bool) error {
40	if dialErr == nil {
41		return errors.New("broker: a running daemon is never started again")
42	}
43	if target.StartMode == ports.BrokerDaemonExistingOnly {
44		if absent {
45			return ports.BrokerError{Code: ports.BrokerErrorNoDaemon, Cause: dialErr}
46		}
47		return dialErr
48	}
49	if !absent {
50		return dialErr
51	}
52	return nil
53}
54
55// AuthorizeDaemonLaunch is the final start decision for an absent daemon. The
56// start mode is an authorization, never an obligation, and it can only narrow
57// the policy: the resolved policy must also name DaemonLaunchAuthority.
58func AuthorizeDaemonLaunch(target ports.BrokerDialTarget) error {
59	if target.StartMode != ports.BrokerDaemonStartIfNeeded {
60		return daemonStartRefused("the acquisition does not authorize starting a daemon")
61	}
62	if target.Policy.Launch != DaemonLaunchAuthority {
63		return daemonStartRefused("the resolved policy does not authorize launching")
64	}
65	return nil
66}
67
68// daemonStartRefused reports a refused start as a typed policy conflict. The
69// reason is local diagnostic text, never a message the daemon produced.
70func daemonStartRefused(reason string) error {
71	return ports.BrokerError{
72		Code:  ports.BrokerErrorConflictingPolicy,
73		Cause: fmt.Errorf("refusing to start the daemon: %s", reason),
74	}
75}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close