v2.31.0-dev17 bd898f0

target_metadata.go RawHistoryFolder

1package proxy
2
3import (
4	"context"
5	"fmt"
6	"strconv"
7
8	"github.com/bnema/zerowrap"
9
10	"github.com/bnema/gordon/internal/domain"
11)
12
13// TargetMetadata holds resolved backend connection metadata for a container image.
14type TargetMetadata struct {
15	Port     int    // The port to proxy traffic to
16	Protocol string // "" for HTTP/1.1, "h2c" for cleartext HTTP/2
17}
18
19// resolveTargetMetadata determines the port and protocol for an image by reading
20// image labels. It checks gordon.proxy.port first, then the deprecated gordon.port
21// alias, then falls back to the first exposed port. Protocol is read from
22// gordon.proxy.protocol (only "h2c" is recognized; unknown values are ignored).
23func (s *Service) resolveTargetMetadata(ctx context.Context, imageRef string) (TargetMetadata, error) {
24	log := zerowrap.FromCtx(ctx)
25	log.Debug().Str("image_ref", imageRef).Msg("resolving target metadata for image")
26
27	labels, err := s.runtime.GetImageLabels(ctx, imageRef)
28	if err != nil {
29		log.Debug().Err(err).Msg("failed to get image labels, falling back to exposed ports")
30		labels = nil
31	}
32
33	port := 0
34	if labels != nil {
35		for _, key := range []string{domain.LabelProxyPort, domain.LabelPort} {
36			if portStr, ok := labels[key]; ok && portStr != "" {
37				p, convErr := strconv.Atoi(portStr)
38				if convErr == nil && p > 0 && p <= 65535 {
39					log.Debug().Int("port", p).Str("label", key).Msg("using proxy port from image label")
40					port = p
41					break
42				}
43				log.Warn().Str("label", key).Str("port_value", portStr).Msg("invalid port label value")
44			}
45		}
46	}
47
48	if port == 0 {
49		exposedPorts, portsErr := s.runtime.GetImageExposedPorts(ctx, imageRef)
50		if portsErr != nil {
51			return TargetMetadata{}, fmt.Errorf("failed to get exposed ports for image %s: %w", imageRef, portsErr)
52		}
53		if len(exposedPorts) == 0 {
54			return TargetMetadata{}, fmt.Errorf("no exposed ports found for image %s", imageRef)
55		}
56		port = exposedPorts[0]
57		log.Debug().Int("port", port).Msg("using first exposed port")
58	}
59
60	protocol := ""
61	if labels != nil {
62		proto := labels[domain.LabelProxyProtocol]
63		switch proto {
64		case "h2c":
65			protocol = "h2c"
66			log.Debug().Str("protocol", proto).Msg("container opts into h2c")
67		case "":
68		default:
69			log.Warn().Str("protocol", proto).Msg("unknown proxy protocol label value, ignoring")
70		}
71	}
72
73	return TargetMetadata{Port: port, Protocol: protocol}, nil
74}

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