mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-11-05 08:05:06 +00:00
* feat: add MCP error metadata handling and improve source policy resolution * fix: adjust height-diff for improved table layout
87 lines
2.8 KiB
Go
87 lines
2.8 KiB
Go
package mcpruntime
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"regexp"
|
|
)
|
|
|
|
var dockerContainerIDPattern = regexp.MustCompile(`^[a-f0-9]{64}$`)
|
|
|
|
func validCleanupReference(reference *cleanupReference) bool {
|
|
return reference != nil && dockerContainerIDPattern.MatchString(reference.ContainerID) &&
|
|
dockerContainerIDPattern.MatchString(reference.PreviousContainerID) &&
|
|
reference.ContainerID != reference.PreviousContainerID && ValidDockerImageID(reference.PreviousImageID)
|
|
}
|
|
|
|
// Finalize is called only after the new runtime settings have been committed.
|
|
// It uses the exact containers returned by this installation, never a tag or a scan.
|
|
func (m *DockerManager) Finalize(ctx context.Context, deleteOldImage bool) error {
|
|
m.installMu.Lock()
|
|
if m.installCleanup == nil {
|
|
m.installMu.Unlock()
|
|
return nil
|
|
}
|
|
reference, imageID, enabled := *m.installCleanup, m.installImageID, m.installEnabled
|
|
m.installMu.Unlock()
|
|
if !validCleanupReference(&reference) || !ValidDockerImageID(imageID) {
|
|
return errors.New("MCP installation cleanup reference is unavailable")
|
|
}
|
|
ReportProgress(ctx, Progress{Status: "cleanup"})
|
|
response, err := m.send(ctx, dockerRequest{
|
|
Operation: "finalize", Image: m.image, Port: m.port, Enabled: enabled, ImageID: imageID,
|
|
Cleanup: &reference, DeleteOldImage: deleteOldImage,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !validCleanupResult(response.CleanupResult, deleteOldImage, reference.PreviousImageID == imageID) {
|
|
return errors.New("MCP Docker agent returned an invalid cleanup result")
|
|
}
|
|
result := response.CleanupResult
|
|
if result.ContainerRemoved {
|
|
ReportProgress(ctx, Progress{Status: "cleanup_complete"})
|
|
}
|
|
switch {
|
|
case result.ImageRemoved:
|
|
ReportProgress(ctx, Progress{Status: "old_image_removed"})
|
|
case result.ImageRetainedReason == "not_requested":
|
|
ReportProgress(ctx, Progress{Status: "old_image_kept"})
|
|
case result.ImageRetainedReason == "previous_missing":
|
|
ReportProgress(ctx, Progress{Status: "cleanup_skipped"})
|
|
default:
|
|
ReportProgress(ctx, Progress{Status: "old_image_retained"})
|
|
}
|
|
m.installMu.Lock()
|
|
if m.installCleanup != nil && *m.installCleanup == reference {
|
|
m.installCleanup = nil
|
|
}
|
|
m.installMu.Unlock()
|
|
return nil
|
|
}
|
|
|
|
func validCleanupResult(result *cleanupResult, deleteOldImage, sameImage bool) bool {
|
|
if result == nil {
|
|
return false
|
|
}
|
|
if result.ImageRetainedReason == "previous_missing" {
|
|
return !result.ContainerRemoved && !result.ImageRemoved
|
|
}
|
|
if !result.ContainerRemoved {
|
|
return false
|
|
}
|
|
if result.ImageRemoved {
|
|
return deleteOldImage && !sameImage && result.ImageRetainedReason == ""
|
|
}
|
|
switch result.ImageRetainedReason {
|
|
case "not_requested":
|
|
return !deleteOldImage
|
|
case "same_image":
|
|
return deleteOldImage && sameImage
|
|
case "in_use", "multiple_tags":
|
|
return deleteOldImage && !sameImage
|
|
default:
|
|
return false
|
|
}
|
|
}
|