1package container
2
3import (
4 "crypto/sha256"
5 "fmt"
6 "regexp"
7 "strings"
8)
9
10// generateVolumeName creates a deterministic volume name for a domain and path
11func generateVolumeName(prefix, domain, path string) string {
12 // Sanitize domain name for use in volume name
13 sanitizedDomain := sanitizeDomainForVolume(domain)
14
15 // Create a short hash of the path to handle long paths and special characters
16 hasher := sha256.New()
17 hasher.Write([]byte(path))
18 pathHash := fmt.Sprintf("%x", hasher.Sum(nil))[:8]
19
20 return fmt.Sprintf("%s-%s-%s", prefix, sanitizedDomain, pathHash)
21}
22
23// sanitizeDomainForVolume converts domain to volume-safe format
24func sanitizeDomainForVolume(domain string) string {
25 // Replace dots and other special characters with hyphens
26 reg := regexp.MustCompile(`[^a-zA-Z0-9\-]`)
27 sanitized := reg.ReplaceAllString(domain, "-")
28
29 // Remove leading/trailing hyphens and convert to lowercase
30 sanitized = strings.Trim(sanitized, "-")
31 sanitized = strings.ToLower(sanitized)
32
33 return sanitized
34}
35
36// normalizeImageRef normalizes image references for comparison
37func normalizeImageRef(imageRef string) string {
38 // Split image and tag
39 parts := strings.Split(imageRef, ":")
40 image := parts[0]
41 tag := "latest"
42 if len(parts) > 1 {
43 tag = parts[1]
44 }
45
46 // Normalize Docker Hub references
47 if !strings.Contains(image, "/") {
48 // Official library image (e.g., "nginx" -> "docker.io/library/nginx")
49 image = "docker.io/library/" + image
50 } else if strings.Count(image, "/") == 1 && !strings.Contains(strings.Split(image, "/")[0], ".") {
51 // User repository (e.g., "user/repo" -> "docker.io/user/repo")
52 image = "docker.io/" + image
53 }
54
55 return image + ":" + tag
56}
57
58// mergeEnvironmentVariables merges Dockerfile ENV directives with user-provided env vars
59// User-provided env vars take precedence over Dockerfile ENV directives
60func mergeEnvironmentVariables(dockerfileEnv, userEnv []string) []string {
61 // Create a map to store environment variables by key
62 envMap := make(map[string]string)
63
64 // First, add Dockerfile ENV directives
65 for _, env := range dockerfileEnv {
66 parts := strings.SplitN(env, "=", 2)
67 if len(parts) == 2 {
68 envMap[parts[0]] = parts[1]
69 }
70 }
71
72 // Then, add user-provided env vars (these override Dockerfile ENV)
73 for _, env := range userEnv {
74 parts := strings.SplitN(env, "=", 2)
75 if len(parts) == 2 {
76 envMap[parts[0]] = parts[1]
77 }
78 }
79
80 // Convert back to slice format
81 var result []string
82 for key, value := range envMap {
83 result = append(result, fmt.Sprintf("%s=%s", key, value))
84 }
85
86 return result
87}