detached 9209a14

refactor(app): split cleanupOrphanDomainResources into focused helpers

Extract removeOrphanVolumes, removeOrphanNetwork, removeOrphanRoute
to flatten nesting and improve readability. Use errors.Join to
collect failures.
commit
9209a14c3a5ffef86850e294b891d5331a0ae91c
author
brice · · 2026-03-25 08:06 UTC
parent
8b31c1c
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +38 -27
M internal/app/run.go +38 -27
@@ -673,44 +673,55 @@ func gcOrphanedPreviews(ctx context.Context, svc *services, previewConfig domain
673673 func cleanupOrphanDomainResources(ctx context.Context, svc *services, orphanDomain string) error {
674674 log := zerowrap.FromCtx(ctx)
675675 domainSanitized := strings.ReplaceAll(orphanDomain, ".", "-")
676- var cleanupErr error
676+ var errs []error
677677
678- // Remove volumes matching domain prefix (convention: {volPrefix}-{domain-sanitized}-).
678+ errs = append(errs, removeOrphanVolumes(ctx, svc, domainSanitized, log)...)
679+ errs = append(errs, removeOrphanNetwork(ctx, svc, domainSanitized, log))
680+ errs = append(errs, removeOrphanRoute(ctx, svc, orphanDomain, log))
681+ svc.proxySvc.InvalidateTarget(ctx, orphanDomain)
682+
683+ return errors.Join(errs...)
684+}
685+
686+func removeOrphanVolumes(ctx context.Context, svc *services, domainSanitized string, log zerowrap.Logger) []error {
679687 _, volPrefix, _ := svc.configSvc.GetVolumeConfig()
680- fullVolumePrefix := volPrefix + "-" + domainSanitized + "-"
688+ prefix := volPrefix + "-" + domainSanitized + "-"
689+
681690 volumes, err := svc.runtime.ListVolumes(ctx)
682691 if err != nil {
683692 log.Warn().Err(err).Msg("failed to list volumes for orphan cleanup")
684- cleanupErr = err
685- } else {
686- for _, v := range volumes {
687- if strings.HasPrefix(v.Name, fullVolumePrefix) {
688- if err := svc.runtime.RemoveVolume(ctx, v.Name, true); err != nil {
689- log.Warn().Err(err).Str("volume", v.Name).Msg("failed to remove orphan volume")
690- cleanupErr = err
691- }
692- }
693- }
693+ return []error{err}
694694 }
695695
696- // Remove network (convention: {networkPrefix}-{domain-sanitized}).
697- networkPrefix := svc.configSvc.GetNetworkPrefix()
698- networkName := networkPrefix + "-" + domainSanitized
699- if err := svc.runtime.RemoveNetwork(ctx, networkName); err != nil {
700- log.Warn().Err(err).Str("network", networkName).Msg("failed to remove orphan network")
701- cleanupErr = err
696+ var errs []error
697+ for _, v := range volumes {
698+ if !strings.HasPrefix(v.Name, prefix) {
699+ continue
700+ }
701+ if err := svc.runtime.RemoveVolume(ctx, v.Name, true); err != nil {
702+ log.Warn().Err(err).Str("volume", v.Name).Msg("failed to remove orphan volume")
703+ errs = append(errs, err)
704+ }
702705 }
706+ return errs
707+}
703708
704- // Remove route and invalidate proxy.
705- if err := svc.configSvc.RemoveRoute(ctx, orphanDomain); err != nil {
706- if !errors.Is(err, domain.ErrRouteNotFound) {
707- log.Warn().Err(err).Str("domain", orphanDomain).Msg("failed to remove orphan route")
708- cleanupErr = err
709- }
709+func removeOrphanNetwork(ctx context.Context, svc *services, domainSanitized string, log zerowrap.Logger) error {
710+ name := svc.configSvc.GetNetworkPrefix() + "-" + domainSanitized
711+ if err := svc.runtime.RemoveNetwork(ctx, name); err != nil {
712+ log.Warn().Err(err).Str("network", name).Msg("failed to remove orphan network")
713+ return err
710714 }
711- svc.proxySvc.InvalidateTarget(ctx, orphanDomain)
715+ return nil
716+}
712717
713- return cleanupErr
718+func removeOrphanRoute(ctx context.Context, svc *services, orphanDomain string, log zerowrap.Logger) error {
719+ err := svc.configSvc.RemoveRoute(ctx, orphanDomain)
720+ if err == nil || errors.Is(err, domain.ErrRouteNotFound) {
721+ return nil
722+ }
723+ log.Warn().Err(err).Str("domain", orphanDomain).Msg("failed to remove orphan route")
724+ return err
714725 }
715726
716727 // injectTelemetryMetrics creates and injects OTel metrics into services when
@@ -673,44 +673,55 @@ func gcOrphanedPreviews(ctx context.Context, svc *services, previewConfig domain
673 func cleanupOrphanDomainResources(ctx context.Context, svc *services, orphanDomain string) error {673 func cleanupOrphanDomainResources(ctx context.Context, svc *services, orphanDomain string) error {
674 log := zerowrap.FromCtx(ctx)674 log := zerowrap.FromCtx(ctx)
675 domainSanitized := strings.ReplaceAll(orphanDomain, ".", "-")675 domainSanitized := strings.ReplaceAll(orphanDomain, ".", "-")
676- var cleanupErr error676+ var errs []error
677 677
678- // Remove volumes matching domain prefix (convention: {volPrefix}-{domain-sanitized}-).678+ errs = append(errs, removeOrphanVolumes(ctx, svc, domainSanitized, log)...)
679+ errs = append(errs, removeOrphanNetwork(ctx, svc, domainSanitized, log))
680+ errs = append(errs, removeOrphanRoute(ctx, svc, orphanDomain, log))
681+ svc.proxySvc.InvalidateTarget(ctx, orphanDomain)
682+
683+ return errors.Join(errs...)
684+}
685+
686+func removeOrphanVolumes(ctx context.Context, svc *services, domainSanitized string, log zerowrap.Logger) []error {
679 _, volPrefix, _ := svc.configSvc.GetVolumeConfig()687 _, volPrefix, _ := svc.configSvc.GetVolumeConfig()
680- fullVolumePrefix := volPrefix + "-" + domainSanitized + "-"688+ prefix := volPrefix + "-" + domainSanitized + "-"
689+
681 volumes, err := svc.runtime.ListVolumes(ctx)690 volumes, err := svc.runtime.ListVolumes(ctx)
682 if err != nil {691 if err != nil {
683 log.Warn().Err(err).Msg("failed to list volumes for orphan cleanup")692 log.Warn().Err(err).Msg("failed to list volumes for orphan cleanup")
684- cleanupErr = err693+ return []error{err}
685- } else {
686- for _, v := range volumes {
687- if strings.HasPrefix(v.Name, fullVolumePrefix) {
688- if err := svc.runtime.RemoveVolume(ctx, v.Name, true); err != nil {
689- log.Warn().Err(err).Str("volume", v.Name).Msg("failed to remove orphan volume")
690- cleanupErr = err
691- }
692- }
693- }
694 }694 }
695 695
696- // Remove network (convention: {networkPrefix}-{domain-sanitized}).696+ var errs []error
697- networkPrefix := svc.configSvc.GetNetworkPrefix()697+ for _, v := range volumes {
698- networkName := networkPrefix + "-" + domainSanitized698+ if !strings.HasPrefix(v.Name, prefix) {
699- if err := svc.runtime.RemoveNetwork(ctx, networkName); err != nil {699+ continue
700- log.Warn().Err(err).Str("network", networkName).Msg("failed to remove orphan network")700+ }
701- cleanupErr = err701+ if err := svc.runtime.RemoveVolume(ctx, v.Name, true); err != nil {
702+ log.Warn().Err(err).Str("volume", v.Name).Msg("failed to remove orphan volume")
703+ errs = append(errs, err)
704+ }
702 }705 }
706+ return errs
707+}
703 708
704- // Remove route and invalidate proxy.709+func removeOrphanNetwork(ctx context.Context, svc *services, domainSanitized string, log zerowrap.Logger) error {
705- if err := svc.configSvc.RemoveRoute(ctx, orphanDomain); err != nil {710+ name := svc.configSvc.GetNetworkPrefix() + "-" + domainSanitized
706- if !errors.Is(err, domain.ErrRouteNotFound) {711+ if err := svc.runtime.RemoveNetwork(ctx, name); err != nil {
707- log.Warn().Err(err).Str("domain", orphanDomain).Msg("failed to remove orphan route")712+ log.Warn().Err(err).Str("network", name).Msg("failed to remove orphan network")
708- cleanupErr = err713+ return err
709- }
710 }714 }
711- svc.proxySvc.InvalidateTarget(ctx, orphanDomain)715+ return nil
716+}
712 717
713- return cleanupErr718+func removeOrphanRoute(ctx context.Context, svc *services, orphanDomain string, log zerowrap.Logger) error {
719+ err := svc.configSvc.RemoveRoute(ctx, orphanDomain)
720+ if err == nil || errors.Is(err, domain.ErrRouteNotFound) {
721+ return nil
722+ }
723+ log.Warn().Err(err).Str("domain", orphanDomain).Msg("failed to remove orphan route")
724+ return err
714 }725 }
715 726
716 // injectTelemetryMetrics creates and injects OTel metrics into services when727 // injectTelemetryMetrics creates and injects OTel metrics into services when

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