detached 69d0d4b

chore: Update .gitignore and Makefile for development release

- Add 'dist/' directory to .gitignore to prevent build artifacts from being tracked.
- Introduce a new 'dev-release' target in the Makefile to automate the creation of development GitHub releases with timestamped tags.
- Update README installation instructions to reflect the correct GitHub release URL.
commit
69d0d4bf05a074843198bfe309bf097c8e673bb7
author
bamen · · 2025-06-07 08:15 UTC
parent
27b4107
signature
unsigned
4 files · +65 -41
M .gitignore +1 -0
@@ -1,2 +1,3 @@
11 gordon
22 .env
3+dist/⏎̸
@@ -1,2 +1,3 @@
1 gordon1 gordon
2 .env2 .env
3+dist/⏎̸
M Makefile +25 -1
@@ -2,6 +2,7 @@
22 # Variables
33 REPO := ghcr.io/bnema/gordon
44 TAG := v2-dev
5+DEV_TAG := v2-dev-$(shell date +%Y%m%d-%H%M%S)
56 DIST_DIR := ./dist
67 ENGINE := podman
78
@@ -20,7 +21,7 @@ LDFLAGS := -s -w \
2021 ARCHS := amd64 arm64
2122
2223 # Phony targets
23-.PHONY: all build build-push clean
24+.PHONY: all build build-push clean dev-release
2425
2526 # Default target
2627 all: build
@@ -68,6 +69,29 @@ build-push: build
6869
6970 @echo "Script completed successfully."
7071
72+# Create dev GitHub release (separate from GoReleaser)
73+dev-release: build
74+ @echo "Creating dev GitHub release..."
75+ @if [ -z "$(shell which gh)" ]; then \
76+ echo "Error: GitHub CLI (gh) is not installed. Please install it first."; \
77+ exit 1; \
78+ fi
79+ @echo "Creating dev release $(DEV_TAG)..."
80+ @gh release create $(DEV_TAG) \
81+ --title "Gordon Dev Build $(DEV_TAG)" \
82+ --notes "🚧 **Development Build** 🚧\n\nThis is an automated development build for testing purposes.\n\n**Commit:** $(COMMIT)\n**Build Date:** $(BUILD_DATE)\n\n⚠️ This is not a stable release. Use at your own risk." \
83+ --prerelease \
84+ --draft=false \
85+ $(DIST_DIR)/gordon-linux-amd64 \
86+ $(DIST_DIR)/gordon-linux-arm64
87+ @echo "Dev release created successfully!"
88+ @echo ""
89+ @echo "📦 Download URLs:"
90+ @echo " AMD64: wget https://github.com/bnema/gordon/releases/download/$(DEV_TAG)/gordon-linux-amd64"
91+ @echo " ARM64: wget https://github.com/bnema/gordon/releases/download/$(DEV_TAG)/gordon-linux-arm64"
92+ @echo ""
93+ @echo "🔗 Release page: https://github.com/bnema/gordon/releases/tag/$(DEV_TAG)"
94+
7195 # Clean up
7296 clean:
7397 @echo "Cleaning up..."
@@ -2,6 +2,7 @@
2 # Variables2 # Variables
3 REPO := ghcr.io/bnema/gordon3 REPO := ghcr.io/bnema/gordon
4 TAG := v2-dev4 TAG := v2-dev
5+DEV_TAG := v2-dev-$(shell date +%Y%m%d-%H%M%S)
5 DIST_DIR := ./dist6 DIST_DIR := ./dist
6 ENGINE := podman7 ENGINE := podman
7 8
@@ -20,7 +21,7 @@ LDFLAGS := -s -w \
20 ARCHS := amd64 arm6421 ARCHS := amd64 arm64
21 22
22 # Phony targets23 # Phony targets
23-.PHONY: all build build-push clean24+.PHONY: all build build-push clean dev-release
24 25
25 # Default target26 # Default target
26 all: build27 all: build
@@ -68,6 +69,29 @@ build-push: build
68 69
69 @echo "Script completed successfully."70 @echo "Script completed successfully."
70 71
72+# Create dev GitHub release (separate from GoReleaser)
73+dev-release: build
74+ @echo "Creating dev GitHub release..."
75+ @if [ -z "$(shell which gh)" ]; then \
76+ echo "Error: GitHub CLI (gh) is not installed. Please install it first."; \
77+ exit 1; \
78+ fi
79+ @echo "Creating dev release $(DEV_TAG)..."
80+ @gh release create $(DEV_TAG) \
81+ --title "Gordon Dev Build $(DEV_TAG)" \
82+ --notes "🚧 **Development Build** 🚧\n\nThis is an automated development build for testing purposes.\n\n**Commit:** $(COMMIT)\n**Build Date:** $(BUILD_DATE)\n\n⚠️ This is not a stable release. Use at your own risk." \
83+ --prerelease \
84+ --draft=false \
85+ $(DIST_DIR)/gordon-linux-amd64 \
86+ $(DIST_DIR)/gordon-linux-arm64
87+ @echo "Dev release created successfully!"
88+ @echo ""
89+ @echo "📦 Download URLs:"
90+ @echo " AMD64: wget https://github.com/bnema/gordon/releases/download/$(DEV_TAG)/gordon-linux-amd64"
91+ @echo " ARM64: wget https://github.com/bnema/gordon/releases/download/$(DEV_TAG)/gordon-linux-arm64"
92+ @echo ""
93+ @echo "🔗 Release page: https://github.com/bnema/gordon/releases/tag/$(DEV_TAG)"
94+
71 # Clean up95 # Clean up
72 clean:96 clean:
73 @echo "Cleaning up..."97 @echo "Cleaning up..."
M README.md +1 -1
@@ -119,7 +119,7 @@ EOF
119119
120120 ### 2. Install Gordon
121121 ```bash
122-wget https://github.com/yourusername/gordon/releases/latest/download/gordon-linux-amd64
122+wget https://github.com/bnema/gordon/releases/latest/download/gordon-linux-amd64
123123 chmod +x gordon-linux-amd64
124124 sudo mv gordon-linux-amd64 /usr/local/bin/gordon
125125 ```
@@ -119,7 +119,7 @@ EOF
119 119
120 ### 2. Install Gordon120 ### 2. Install Gordon
121 ```bash121 ```bash
122-wget https://github.com/yourusername/gordon/releases/latest/download/gordon-linux-amd64122+wget https://github.com/bnema/gordon/releases/latest/download/gordon-linux-amd64
123 chmod +x gordon-linux-amd64123 chmod +x gordon-linux-amd64
124 sudo mv gordon-linux-amd64 /usr/local/bin/gordon124 sudo mv gordon-linux-amd64 /usr/local/bin/gordon
125 ```125 ```
M internal/container/factory.go +38 -39
@@ -5,7 +5,6 @@ import (
55 "fmt"
66 "os"
77 "os/user"
8- "path/filepath"
98 "strings"
109
1110 "github.com/docker/docker/client"
@@ -19,9 +18,9 @@ import (
1918 type RuntimeType string
2019
2120 const (
22- RuntimeAuto RuntimeType = "auto"
23- RuntimeDocker RuntimeType = "docker"
24- RuntimePodman RuntimeType = "podman"
21+ RuntimeAuto RuntimeType = "auto"
22+ RuntimeDocker RuntimeType = "docker"
23+ RuntimePodman RuntimeType = "podman"
2524 RuntimePodmanRootless RuntimeType = "podman-rootless"
2625 )
2726
@@ -35,10 +34,10 @@ type RuntimeInfo struct {
3534 // CreateRuntime creates a container runtime based on configuration
3635 func CreateRuntime(cfg *config.Config) (runtime.Runtime, error) {
3736 runtimeType := RuntimeType(cfg.Server.Runtime)
38-
37+
3938 // Get socket path from config or environment
4039 socketPath := getSocketPath(cfg.Server.SocketPath)
41-
40+
4241 switch runtimeType {
4342 case RuntimeAuto:
4443 return createAutoRuntime(socketPath)
@@ -58,13 +57,13 @@ func getSocketPath(configPath string) string {
5857 log.Debug().Str("path", configPath).Msg("Using socket path from config")
5958 return configPath
6059 }
61-
60+
6261 // 2. Check CONTAINER_HOST environment variable
6362 if envPath := os.Getenv("CONTAINER_HOST"); envPath != "" {
6463 log.Debug().Str("path", envPath).Msg("Using socket path from CONTAINER_HOST")
6564 return envPath
6665 }
67-
66+
6867 // 3. Return empty string for auto-detection
6968 return ""
7069 }
@@ -72,7 +71,7 @@ func getSocketPath(configPath string) string {
7271 // createAutoRuntime automatically detects and creates the best available runtime
7372 func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
7473 var candidatePaths []string
75-
74+
7675 if customSocketPath != "" {
7776 // If custom path provided, try it first
7877 candidatePaths = []string{customSocketPath}
@@ -80,7 +79,7 @@ func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
8079 // Auto-detect socket paths
8180 candidatePaths = getDefaultSocketPaths()
8281 }
83-
82+
8483 // Try each socket path
8584 for _, socketPath := range candidatePaths {
8685 if rt, info, err := tryCreateRuntime(socketPath); err == nil {
@@ -92,7 +91,7 @@ func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
9291 return rt, nil
9392 }
9493 }
95-
94+
9695 return nil, fmt.Errorf("no container runtime found. Tried paths: %v", candidatePaths)
9796 }
9897
@@ -100,22 +99,22 @@ func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
10099 func createDockerRuntime(socketPath string) (runtime.Runtime, error) {
101100 var opts []client.Opt
102101 opts = append(opts, client.FromEnv, client.WithAPIVersionNegotiation())
103-
102+
104103 if socketPath != "" {
105104 opts = append(opts, client.WithHost(socketPath))
106105 }
107-
106+
108107 cli, err := client.NewClientWithOpts(opts...)
109108 if err != nil {
110109 return nil, fmt.Errorf("failed to create Docker client: %w", err)
111110 }
112-
111+
113112 // Test connectivity
114113 ctx := context.Background()
115114 if _, err := cli.Ping(ctx); err != nil {
116115 return nil, fmt.Errorf("Docker ping failed: %w", err)
117116 }
118-
117+
119118 return &DockerRuntime{client: cli}, nil
120119 }
121120
@@ -124,7 +123,7 @@ func createPodmanRuntime(socketPath string, rootless bool) (runtime.Runtime, err
124123 if socketPath == "" {
125124 socketPath = getDefaultPodmanSocket(rootless)
126125 }
127-
126+
128127 return createPodmanRuntimeWithSocket(socketPath)
129128 }
130129
@@ -135,35 +134,35 @@ func tryCreateRuntime(socketPath string) (runtime.Runtime, *RuntimeInfo, error)
135134 client.WithHost(socketPath),
136135 client.WithAPIVersionNegotiation(),
137136 }
138-
137+
139138 cli, err := client.NewClientWithOpts(opts...)
140139 if err != nil {
141140 return nil, nil, fmt.Errorf("failed to create client: %w", err)
142141 }
143-
142+
144143 // Test connectivity and get version
145144 ctx := context.Background()
146145 ping, err := cli.Ping(ctx)
147146 if err != nil {
148147 return nil, nil, fmt.Errorf("ping failed: %w", err)
149148 }
150-
149+
151150 // Determine runtime type based on socket path and server info
152151 runtimeType := detectRuntimeType(socketPath, ping.APIVersion)
153-
152+
154153 var rt runtime.Runtime
155154 if runtimeType == RuntimeDocker {
156155 rt = &DockerRuntime{client: cli}
157156 } else {
158157 rt = &PodmanRuntime{client: cli}
159158 }
160-
159+
161160 info := &RuntimeInfo{
162161 Type: runtimeType,
163162 SocketPath: socketPath,
164163 Version: ping.APIVersion,
165164 }
166-
165+
167166 return rt, info, nil
168167 }
169168
@@ -176,11 +175,11 @@ func detectRuntimeType(socketPath, apiVersion string) RuntimeType {
176175 }
177176 return RuntimePodman
178177 }
179-
178+
180179 if strings.Contains(socketPath, "docker") {
181180 return RuntimeDocker
182181 }
183-
182+
184183 // Default socket paths
185184 switch socketPath {
186185 case "/var/run/docker.sock", "unix:///var/run/docker.sock":
@@ -188,12 +187,12 @@ func detectRuntimeType(socketPath, apiVersion string) RuntimeType {
188187 case "/run/podman/podman.sock", "unix:///run/podman/podman.sock":
189188 return RuntimePodman
190189 }
191-
190+
192191 // Check if it's in user runtime directory (rootless)
193192 if strings.Contains(socketPath, "/run/user/") {
194193 return RuntimePodmanRootless
195194 }
196-
195+
197196 // Default to Docker for unknown paths
198197 return RuntimeDocker
199198 }
@@ -201,15 +200,15 @@ func detectRuntimeType(socketPath, apiVersion string) RuntimeType {
201200 // getDefaultSocketPaths returns the default socket paths to try
202201 func getDefaultSocketPaths() []string {
203202 paths := []string{
204- "unix:///var/run/docker.sock", // Docker
205- "unix:///run/podman/podman.sock", // Podman root
203+ "unix:///var/run/docker.sock", // Docker
204+ "unix:///run/podman/podman.sock", // Podman root
206205 }
207-
206+
208207 // Add Podman rootless socket
209208 if rootlessSocket := getDefaultPodmanSocket(true); rootlessSocket != "" {
210209 paths = append(paths, rootlessSocket)
211210 }
212-
211+
213212 return paths
214213 }
215214
@@ -218,17 +217,17 @@ func getDefaultPodmanSocket(rootless bool) string {
218217 if !rootless {
219218 return "unix:///run/podman/podman.sock"
220219 }
221-
220+
222221 // Get user runtime directory for rootless Podman
223222 if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {
224223 return fmt.Sprintf("unix://%s/podman/podman.sock", xdgRuntimeDir)
225224 }
226-
225+
227226 // Fallback: construct from user ID
228227 if currentUser, err := user.Current(); err == nil {
229228 return fmt.Sprintf("unix:///run/user/%s/podman/podman.sock", currentUser.Uid)
230229 }
231-
230+
232231 log.Warn().Msg("Could not determine rootless Podman socket path")
233232 return ""
234233 }
@@ -239,30 +238,30 @@ func createPodmanRuntimeWithSocket(socketPath string) (runtime.Runtime, error) {
239238 client.WithHost(socketPath),
240239 client.WithAPIVersionNegotiation(),
241240 }
242-
241+
243242 cli, err := client.NewClientWithOpts(opts...)
244243 if err != nil {
245244 return nil, fmt.Errorf("failed to create Podman client: %w", err)
246245 }
247-
246+
248247 // Test connectivity
249248 ctx := context.Background()
250249 if _, err := cli.Ping(ctx); err != nil {
251250 return nil, fmt.Errorf("Podman ping failed: %w", err)
252251 }
253-
252+
254253 return &PodmanRuntime{client: cli}, nil
255254 }
256255
257256 // GetAvailableRuntimes returns information about all available runtimes
258257 func GetAvailableRuntimes() []RuntimeInfo {
259258 var runtimes []RuntimeInfo
260-
259+
261260 for _, socketPath := range getDefaultSocketPaths() {
262261 if _, info, err := tryCreateRuntime(socketPath); err == nil {
263262 runtimes = append(runtimes, *info)
264263 }
265264 }
266-
265+
267266 return runtimes
268-}⏎̸
267+}
@@ -5,7 +5,6 @@ import (
5 "fmt"5 "fmt"
6 "os"6 "os"
7 "os/user"7 "os/user"
8- "path/filepath"
9 "strings"8 "strings"
10 9
11 "github.com/docker/docker/client"10 "github.com/docker/docker/client"
@@ -19,9 +18,9 @@ import (
19 type RuntimeType string18 type RuntimeType string
20 19
21 const (20 const (
22- RuntimeAuto RuntimeType = "auto"21+ RuntimeAuto RuntimeType = "auto"
23- RuntimeDocker RuntimeType = "docker"22+ RuntimeDocker RuntimeType = "docker"
24- RuntimePodman RuntimeType = "podman"23+ RuntimePodman RuntimeType = "podman"
25 RuntimePodmanRootless RuntimeType = "podman-rootless"24 RuntimePodmanRootless RuntimeType = "podman-rootless"
26 )25 )
27 26
@@ -35,10 +34,10 @@ type RuntimeInfo struct {
35 // CreateRuntime creates a container runtime based on configuration34 // CreateRuntime creates a container runtime based on configuration
36 func CreateRuntime(cfg *config.Config) (runtime.Runtime, error) {35 func CreateRuntime(cfg *config.Config) (runtime.Runtime, error) {
37 runtimeType := RuntimeType(cfg.Server.Runtime)36 runtimeType := RuntimeType(cfg.Server.Runtime)
38- 37+
39 // Get socket path from config or environment38 // Get socket path from config or environment
40 socketPath := getSocketPath(cfg.Server.SocketPath)39 socketPath := getSocketPath(cfg.Server.SocketPath)
41- 40+
42 switch runtimeType {41 switch runtimeType {
43 case RuntimeAuto:42 case RuntimeAuto:
44 return createAutoRuntime(socketPath)43 return createAutoRuntime(socketPath)
@@ -58,13 +57,13 @@ func getSocketPath(configPath string) string {
58 log.Debug().Str("path", configPath).Msg("Using socket path from config")57 log.Debug().Str("path", configPath).Msg("Using socket path from config")
59 return configPath58 return configPath
60 }59 }
61- 60+
62 // 2. Check CONTAINER_HOST environment variable61 // 2. Check CONTAINER_HOST environment variable
63 if envPath := os.Getenv("CONTAINER_HOST"); envPath != "" {62 if envPath := os.Getenv("CONTAINER_HOST"); envPath != "" {
64 log.Debug().Str("path", envPath).Msg("Using socket path from CONTAINER_HOST")63 log.Debug().Str("path", envPath).Msg("Using socket path from CONTAINER_HOST")
65 return envPath64 return envPath
66 }65 }
67- 66+
68 // 3. Return empty string for auto-detection67 // 3. Return empty string for auto-detection
69 return ""68 return ""
70 }69 }
@@ -72,7 +71,7 @@ func getSocketPath(configPath string) string {
72 // createAutoRuntime automatically detects and creates the best available runtime71 // createAutoRuntime automatically detects and creates the best available runtime
73 func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {72 func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
74 var candidatePaths []string73 var candidatePaths []string
75- 74+
76 if customSocketPath != "" {75 if customSocketPath != "" {
77 // If custom path provided, try it first76 // If custom path provided, try it first
78 candidatePaths = []string{customSocketPath}77 candidatePaths = []string{customSocketPath}
@@ -80,7 +79,7 @@ func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
80 // Auto-detect socket paths79 // Auto-detect socket paths
81 candidatePaths = getDefaultSocketPaths()80 candidatePaths = getDefaultSocketPaths()
82 }81 }
83- 82+
84 // Try each socket path83 // Try each socket path
85 for _, socketPath := range candidatePaths {84 for _, socketPath := range candidatePaths {
86 if rt, info, err := tryCreateRuntime(socketPath); err == nil {85 if rt, info, err := tryCreateRuntime(socketPath); err == nil {
@@ -92,7 +91,7 @@ func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
92 return rt, nil91 return rt, nil
93 }92 }
94 }93 }
95- 94+
96 return nil, fmt.Errorf("no container runtime found. Tried paths: %v", candidatePaths)95 return nil, fmt.Errorf("no container runtime found. Tried paths: %v", candidatePaths)
97 }96 }
98 97
@@ -100,22 +99,22 @@ func createAutoRuntime(customSocketPath string) (runtime.Runtime, error) {
100 func createDockerRuntime(socketPath string) (runtime.Runtime, error) {99 func createDockerRuntime(socketPath string) (runtime.Runtime, error) {
101 var opts []client.Opt100 var opts []client.Opt
102 opts = append(opts, client.FromEnv, client.WithAPIVersionNegotiation())101 opts = append(opts, client.FromEnv, client.WithAPIVersionNegotiation())
103- 102+
104 if socketPath != "" {103 if socketPath != "" {
105 opts = append(opts, client.WithHost(socketPath))104 opts = append(opts, client.WithHost(socketPath))
106 }105 }
107- 106+
108 cli, err := client.NewClientWithOpts(opts...)107 cli, err := client.NewClientWithOpts(opts...)
109 if err != nil {108 if err != nil {
110 return nil, fmt.Errorf("failed to create Docker client: %w", err)109 return nil, fmt.Errorf("failed to create Docker client: %w", err)
111 }110 }
112- 111+
113 // Test connectivity112 // Test connectivity
114 ctx := context.Background()113 ctx := context.Background()
115 if _, err := cli.Ping(ctx); err != nil {114 if _, err := cli.Ping(ctx); err != nil {
116 return nil, fmt.Errorf("Docker ping failed: %w", err)115 return nil, fmt.Errorf("Docker ping failed: %w", err)
117 }116 }
118- 117+
119 return &DockerRuntime{client: cli}, nil118 return &DockerRuntime{client: cli}, nil
120 }119 }
121 120
@@ -124,7 +123,7 @@ func createPodmanRuntime(socketPath string, rootless bool) (runtime.Runtime, err
124 if socketPath == "" {123 if socketPath == "" {
125 socketPath = getDefaultPodmanSocket(rootless)124 socketPath = getDefaultPodmanSocket(rootless)
126 }125 }
127- 126+
128 return createPodmanRuntimeWithSocket(socketPath)127 return createPodmanRuntimeWithSocket(socketPath)
129 }128 }
130 129
@@ -135,35 +134,35 @@ func tryCreateRuntime(socketPath string) (runtime.Runtime, *RuntimeInfo, error)
135 client.WithHost(socketPath),134 client.WithHost(socketPath),
136 client.WithAPIVersionNegotiation(),135 client.WithAPIVersionNegotiation(),
137 }136 }
138- 137+
139 cli, err := client.NewClientWithOpts(opts...)138 cli, err := client.NewClientWithOpts(opts...)
140 if err != nil {139 if err != nil {
141 return nil, nil, fmt.Errorf("failed to create client: %w", err)140 return nil, nil, fmt.Errorf("failed to create client: %w", err)
142 }141 }
143- 142+
144 // Test connectivity and get version143 // Test connectivity and get version
145 ctx := context.Background()144 ctx := context.Background()
146 ping, err := cli.Ping(ctx)145 ping, err := cli.Ping(ctx)
147 if err != nil {146 if err != nil {
148 return nil, nil, fmt.Errorf("ping failed: %w", err)147 return nil, nil, fmt.Errorf("ping failed: %w", err)
149 }148 }
150- 149+
151 // Determine runtime type based on socket path and server info150 // Determine runtime type based on socket path and server info
152 runtimeType := detectRuntimeType(socketPath, ping.APIVersion)151 runtimeType := detectRuntimeType(socketPath, ping.APIVersion)
153- 152+
154 var rt runtime.Runtime153 var rt runtime.Runtime
155 if runtimeType == RuntimeDocker {154 if runtimeType == RuntimeDocker {
156 rt = &DockerRuntime{client: cli}155 rt = &DockerRuntime{client: cli}
157 } else {156 } else {
158 rt = &PodmanRuntime{client: cli}157 rt = &PodmanRuntime{client: cli}
159 }158 }
160- 159+
161 info := &RuntimeInfo{160 info := &RuntimeInfo{
162 Type: runtimeType,161 Type: runtimeType,
163 SocketPath: socketPath,162 SocketPath: socketPath,
164 Version: ping.APIVersion,163 Version: ping.APIVersion,
165 }164 }
166- 165+
167 return rt, info, nil166 return rt, info, nil
168 }167 }
169 168
@@ -176,11 +175,11 @@ func detectRuntimeType(socketPath, apiVersion string) RuntimeType {
176 }175 }
177 return RuntimePodman176 return RuntimePodman
178 }177 }
179- 178+
180 if strings.Contains(socketPath, "docker") {179 if strings.Contains(socketPath, "docker") {
181 return RuntimeDocker180 return RuntimeDocker
182 }181 }
183- 182+
184 // Default socket paths183 // Default socket paths
185 switch socketPath {184 switch socketPath {
186 case "/var/run/docker.sock", "unix:///var/run/docker.sock":185 case "/var/run/docker.sock", "unix:///var/run/docker.sock":
@@ -188,12 +187,12 @@ func detectRuntimeType(socketPath, apiVersion string) RuntimeType {
188 case "/run/podman/podman.sock", "unix:///run/podman/podman.sock":187 case "/run/podman/podman.sock", "unix:///run/podman/podman.sock":
189 return RuntimePodman188 return RuntimePodman
190 }189 }
191- 190+
192 // Check if it's in user runtime directory (rootless)191 // Check if it's in user runtime directory (rootless)
193 if strings.Contains(socketPath, "/run/user/") {192 if strings.Contains(socketPath, "/run/user/") {
194 return RuntimePodmanRootless193 return RuntimePodmanRootless
195 }194 }
196- 195+
197 // Default to Docker for unknown paths196 // Default to Docker for unknown paths
198 return RuntimeDocker197 return RuntimeDocker
199 }198 }
@@ -201,15 +200,15 @@ func detectRuntimeType(socketPath, apiVersion string) RuntimeType {
201 // getDefaultSocketPaths returns the default socket paths to try200 // getDefaultSocketPaths returns the default socket paths to try
202 func getDefaultSocketPaths() []string {201 func getDefaultSocketPaths() []string {
203 paths := []string{202 paths := []string{
204- "unix:///var/run/docker.sock", // Docker203+ "unix:///var/run/docker.sock", // Docker
205- "unix:///run/podman/podman.sock", // Podman root204+ "unix:///run/podman/podman.sock", // Podman root
206 }205 }
207- 206+
208 // Add Podman rootless socket207 // Add Podman rootless socket
209 if rootlessSocket := getDefaultPodmanSocket(true); rootlessSocket != "" {208 if rootlessSocket := getDefaultPodmanSocket(true); rootlessSocket != "" {
210 paths = append(paths, rootlessSocket)209 paths = append(paths, rootlessSocket)
211 }210 }
212- 211+
213 return paths212 return paths
214 }213 }
215 214
@@ -218,17 +217,17 @@ func getDefaultPodmanSocket(rootless bool) string {
218 if !rootless {217 if !rootless {
219 return "unix:///run/podman/podman.sock"218 return "unix:///run/podman/podman.sock"
220 }219 }
221- 220+
222 // Get user runtime directory for rootless Podman221 // Get user runtime directory for rootless Podman
223 if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {222 if xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR"); xdgRuntimeDir != "" {
224 return fmt.Sprintf("unix://%s/podman/podman.sock", xdgRuntimeDir)223 return fmt.Sprintf("unix://%s/podman/podman.sock", xdgRuntimeDir)
225 }224 }
226- 225+
227 // Fallback: construct from user ID226 // Fallback: construct from user ID
228 if currentUser, err := user.Current(); err == nil {227 if currentUser, err := user.Current(); err == nil {
229 return fmt.Sprintf("unix:///run/user/%s/podman/podman.sock", currentUser.Uid)228 return fmt.Sprintf("unix:///run/user/%s/podman/podman.sock", currentUser.Uid)
230 }229 }
231- 230+
232 log.Warn().Msg("Could not determine rootless Podman socket path")231 log.Warn().Msg("Could not determine rootless Podman socket path")
233 return ""232 return ""
234 }233 }
@@ -239,30 +238,30 @@ func createPodmanRuntimeWithSocket(socketPath string) (runtime.Runtime, error) {
239 client.WithHost(socketPath),238 client.WithHost(socketPath),
240 client.WithAPIVersionNegotiation(),239 client.WithAPIVersionNegotiation(),
241 }240 }
242- 241+
243 cli, err := client.NewClientWithOpts(opts...)242 cli, err := client.NewClientWithOpts(opts...)
244 if err != nil {243 if err != nil {
245 return nil, fmt.Errorf("failed to create Podman client: %w", err)244 return nil, fmt.Errorf("failed to create Podman client: %w", err)
246 }245 }
247- 246+
248 // Test connectivity247 // Test connectivity
249 ctx := context.Background()248 ctx := context.Background()
250 if _, err := cli.Ping(ctx); err != nil {249 if _, err := cli.Ping(ctx); err != nil {
251 return nil, fmt.Errorf("Podman ping failed: %w", err)250 return nil, fmt.Errorf("Podman ping failed: %w", err)
252 }251 }
253- 252+
254 return &PodmanRuntime{client: cli}, nil253 return &PodmanRuntime{client: cli}, nil
255 }254 }
256 255
257 // GetAvailableRuntimes returns information about all available runtimes256 // GetAvailableRuntimes returns information about all available runtimes
258 func GetAvailableRuntimes() []RuntimeInfo {257 func GetAvailableRuntimes() []RuntimeInfo {
259 var runtimes []RuntimeInfo258 var runtimes []RuntimeInfo
260- 259+
261 for _, socketPath := range getDefaultSocketPaths() {260 for _, socketPath := range getDefaultSocketPaths() {
262 if _, info, err := tryCreateRuntime(socketPath); err == nil {261 if _, info, err := tryCreateRuntime(socketPath); err == nil {
263 runtimes = append(runtimes, *info)262 runtimes = append(runtimes, *info)
264 }263 }
265 }264 }
266- 265+
267 return runtimes266 return runtimes
268-}⏎̸267+}

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