MCPcopy Create free account
hub / github.com/github/gh-aw / validateDockerImage

Function validateDockerImage

pkg/workflow/docker_validation.go:107–226  ·  view source on GitHub ↗

validateDockerImage checks if a Docker image exists and is accessible. When Docker is not installed or the daemon is not running, validation is silently skipped (returns nil) so that compile-time validation does not depend on Docker availability. If requireDocker is true, returns an error instead of

(image string, verbose bool, requireDocker bool)

Source from the content-addressed store, hash-verified

105// Docker is available and the image cannot be found. The caller treats these
106// as warnings.
107func validateDockerImage(image string, verbose bool, requireDocker bool) error {
108 dockerValidationLog.Printf("Validating Docker image: %s", image)
109
110 // Reject names starting with '-' to prevent argument injection
111 if strings.HasPrefix(image, "-") {
112 return fmt.Errorf("container image name '%s' is invalid: names must not start with '-'", image)
113 }
114
115 // Check if docker CLI is available on PATH.
116 // If Docker is not installed, skip validation silently — compile is a source
117 // transformation step and should not require Docker at authoring time.
118 // When requireDocker is true, return an error instead of skipping.
119 _, err := exec.LookPath("docker")
120 if err != nil {
121 if requireDocker {
122 return fmt.Errorf("docker not installed - could not validate container image '%s'. Install Docker or omit the --validate-images flag to skip container image validation", image)
123 }
124 dockerValidationLog.Print("Docker not installed, skipping container image validation")
125 return nil
126 }
127
128 // Check if Docker daemon is actually running (cached check with short timeout).
129 // If the daemon is not running (common on CI runners like ubuntu-slim, or when
130 // Docker Desktop is stopped), skip validation silently instead of emitting a
131 // warning. Image accessibility is a runtime concern, not a compile-time one.
132 // When requireDocker is true, return an error instead of skipping.
133 if !isDockerDaemonRunning() {
134 if requireDocker {
135 return fmt.Errorf("docker daemon not running - could not validate container image '%s'. Start the Docker daemon or omit the --validate-images flag to skip container image validation", image)
136 }
137 dockerValidationLog.Print("Docker daemon not running, skipping container image validation")
138 return nil
139 }
140
141 // Try to inspect the image (will succeed if image exists locally)
142 cmd := exec.Command("docker", "image", "inspect", image)
143 _, err = cmd.CombinedOutput()
144
145 if err == nil {
146 // Image exists locally
147 dockerValidationLog.Printf("Docker image found locally: %s", image)
148 return nil
149 }
150
151 dockerValidationLog.Printf("Docker image not found locally, attempting to pull: %s", image)
152
153 // Image doesn't exist locally, try to pull it with retry logic
154 maxAttempts := 3
155 waitTime := 5 // seconds
156
157 var lastOutput string
158
159 for attempt := 1; attempt <= maxAttempts; attempt++ {
160 dockerValidationLog.Printf("Attempt %d of %d: Pulling image %s", attempt, maxAttempts, image)
161
162 pullCmd := exec.Command("docker", "pull", image)
163 pullOutput, pullErr := pullCmd.CombinedOutput()
164 outputStr := strings.TrimSpace(string(pullOutput))

Calls 6

PrintMethod · 0.80
ToLowerMethod · 0.80
isDockerDaemonRunningFunction · 0.70
PrintfMethod · 0.45
ErrorfMethod · 0.45