v2.16.0 ebd2ab3

kernel.go RawHistoryFolder

1package app
2
3import (
4	"context"
5	"fmt"
6
7	"github.com/bnema/zerowrap"
8
9	"github.com/bnema/gordon/internal/boundaries/in"
10	configusecase "github.com/bnema/gordon/internal/usecase/config"
11	secretsusecase "github.com/bnema/gordon/internal/usecase/secrets"
12)
13
14// Kernel provides in-process service access for local CLI execution.
15//
16// It intentionally does not start HTTP servers or register signal handlers.
17type Kernel struct {
18	authEnabled  bool
19	configSvc    in.ConfigService
20	secretSvc    in.SecretService
21	containerSvc in.ContainerService
22	backupSvc    in.BackupService
23	registrySvc  in.RegistryService
24	healthSvc    in.HealthService
25	logSvc       in.LogService
26	cleanup      func()
27}
28
29// NewKernel initializes local services without starting server listeners.
30func NewKernel(configPath string) (*Kernel, error) {
31	ctx := context.Background()
32	v, cfg, err := initConfig(configPath)
33	if err != nil {
34		return nil, err
35	}
36
37	log, cleanup, err := initLogger(cfg)
38	if err != nil {
39		return nil, err
40	}
41	if cleanup == nil {
42		cleanup = func() {}
43	}
44
45	ctx = zerowrap.WithCtx(ctx, log)
46
47	// Prefer full service wiring so local CLI can execute the same operations
48	// as remote mode without going through HTTP admin endpoints.
49	if svc, fullErr := createServices(ctx, v, cfg, log); fullErr == nil {
50		return &Kernel{
51			authEnabled:  cfg.Auth.Enabled,
52			configSvc:    svc.configSvc,
53			secretSvc:    svc.secretSvc,
54			containerSvc: svc.containerSvc,
55			backupSvc:    svc.backupSvc,
56			registrySvc:  svc.registrySvc,
57			healthSvc:    svc.healthSvc,
58			logSvc:       svc.logSvc,
59			cleanup:      cleanup,
60		}, nil
61	} else {
62		log.Warn().Err(fullErr).Msg("local kernel running in minimal mode")
63	}
64
65	configSvc := configusecase.NewService(v, nil)
66	if err := configSvc.Load(ctx); err != nil {
67		cleanup()
68		return nil, fmt.Errorf("failed to load configuration: %w", err)
69	}
70
71	_, _, _, domainSecretStore, err := createDomainSecretStore(cfg, log)
72	if err != nil {
73		cleanup()
74		return nil, fmt.Errorf("failed to create local secret store: %w", err)
75	}
76
77	secretSvc := secretsusecase.NewService(domainSecretStore, log)
78
79	return &Kernel{
80		authEnabled: cfg.Auth.Enabled,
81		configSvc:   configSvc,
82		secretSvc:   secretSvc,
83		cleanup:     cleanup,
84	}, nil
85}
86
87func (k *Kernel) Close() error {
88	if k == nil || k.cleanup == nil {
89		return nil
90	}
91	k.cleanup()
92	return nil
93}
94
95func (k *Kernel) Config() in.ConfigService { return k.configSvc }
96
97func (k *Kernel) Secrets() in.SecretService { return k.secretSvc }
98
99func (k *Kernel) Container() in.ContainerService { return k.containerSvc }
100
101func (k *Kernel) Backup() in.BackupService { return k.backupSvc }
102
103func (k *Kernel) Registry() in.RegistryService { return k.registrySvc }
104
105func (k *Kernel) Health() in.HealthService { return k.healthSvc }
106
107func (k *Kernel) Logs() in.LogService { return k.logSvc }
108
109func (k *Kernel) AuthEnabled() bool { return k != nil && k.authEnabled }

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 7

Tags 106

↑↓ moveenter openesc close