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

Method validateContainerImages

pkg/workflow/runtime_validation.go:182–249  ·  view source on GitHub ↗

validateContainerImages validates that container images specified in MCP configs exist and are accessible

(workflowData *WorkflowData)

Source from the content-addressed store, hash-verified

180
181// validateContainerImages validates that container images specified in MCP configs exist and are accessible
182func (c *Compiler) validateContainerImages(workflowData *WorkflowData) error {
183 if workflowData.Tools == nil {
184 runtimeValidationLog.Print("No tools configured, skipping container validation")
185 return nil
186 }
187
188 runtimeValidationLog.Printf("Validating container images for %d tools", len(workflowData.Tools))
189
190 // Snapshot daemon availability before iterating so we can detect a
191 // mid-loop transition (available → unavailable) and emit exactly one
192 // warning for it, correctly counted in the compiler's warning total.
193 daemonWasAvailable := isDockerDaemonRunning()
194
195 var errors []string
196 for toolName, toolConfig := range workflowData.Tools {
197 if config, ok := toolConfig.(map[string]any); ok {
198 // Get the MCP configuration to extract container info
199 mcpConfig, err := getMCPConfig(config, toolName)
200 if err != nil {
201 // If we can't parse the MCP config, skip validation (will be caught elsewhere)
202 continue
203 }
204
205 // Check if this tool originally had a container field (before transformation)
206 if containerName, hasContainer := config["container"]; hasContainer && mcpConfig.Type == "stdio" {
207 // Build the full container image name with version
208 containerStr, ok := containerName.(string)
209 if !ok {
210 continue
211 }
212
213 containerImage := containerStr
214 if version, hasVersion := config["version"]; hasVersion {
215 if versionStr, ok := version.(string); ok && versionStr != "" {
216 containerImage = containerImage + ":" + versionStr
217 }
218 }
219
220 // Validate the container image exists using docker
221 if err := validateDockerImage(containerImage, c.verbose, c.requireDocker); err != nil {
222 errors = append(errors, fmt.Sprintf("tool '%s': %v", toolName, err))
223 }
224 }
225 }
226 }
227
228 // If the daemon appeared available at the start of the loop but became
229 // unreachable during a pull (requireDocker=false path only), emit a single
230 // visible warning here where we can also increment the warning count.
231 // For requireDocker=true, the per-image errors are already returned below
232 // and surfaced as a warning by the caller — no extra warning is needed.
233 if daemonWasAvailable && !isDockerDaemonRunning() && !c.requireDocker {
234 fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Docker daemon is not running — skipping container image validation"))
235 c.IncrementWarningCount()
236 }
237
238 if len(errors) > 0 {
239 return NewValidationError(

Calls 8

IncrementWarningCountMethod · 0.95
FormatWarningMessageFunction · 0.92
getMCPConfigFunction · 0.85
PrintMethod · 0.80
isDockerDaemonRunningFunction · 0.70
validateDockerImageFunction · 0.70
NewValidationErrorFunction · 0.70
PrintfMethod · 0.45