diff --git a/api/datastore/test_data/output_24_to_latest.json b/api/datastore/test_data/output_24_to_latest.json index 54107d616..9532d463e 100644 --- a/api/datastore/test_data/output_24_to_latest.json +++ b/api/datastore/test_data/output_24_to_latest.json @@ -769,6 +769,7 @@ "GpuUseList": null, "HealthyContainerCount": 0, "ImageCount": 9, + "IsPodman": false, "NodeCount": 0, "RunningContainerCount": 5, "ServiceCount": 0, diff --git a/api/docker/snapshot.go b/api/docker/snapshot.go index 812e8ba70..d380cc8ee 100644 --- a/api/docker/snapshot.go +++ b/api/docker/snapshot.go @@ -267,6 +267,17 @@ func snapshotVersion(snapshot *portainer.DockerSnapshot, cli *client.Client) err } snapshot.SnapshotRaw.Version = version - + snapshot.IsPodman = isPodman(version) return nil } + +// isPodman checks if the version is for Podman by checking if any of the components contain "podman". +// If it's podman, a component name should be "Podman Engine" +func isPodman(version types.Version) bool { + for _, component := range version.Components { + if strings.Contains(strings.ToLower(component.Name), "podman") { + return true + } + } + return false +} diff --git a/api/internal/snapshot/snapshot.go b/api/internal/snapshot/snapshot.go index 1d648d199..d51c5b440 100644 --- a/api/internal/snapshot/snapshot.go +++ b/api/internal/snapshot/snapshot.go @@ -219,6 +219,10 @@ func (service *Service) snapshotDockerEndpoint(endpoint *portainer.Endpoint) err return err } + if err := validateContainerEngineCompatibility(endpoint, dockerSnapshot); err != nil { + return err + } + if dockerSnapshot != nil { snapshot := &portainer.Snapshot{EndpointID: endpoint.ID, Docker: dockerSnapshot} @@ -228,6 +232,20 @@ func (service *Service) snapshotDockerEndpoint(endpoint *portainer.Endpoint) err return nil } +func validateContainerEngineCompatibility(endpoint *portainer.Endpoint, dockerSnapshot *portainer.DockerSnapshot) error { + if endpoint.ContainerEngine == portainer.ContainerEngineDocker && dockerSnapshot.IsPodman { + err := errors.New("the Docker environment option doesn't support Podman environments. Please select the Podman option instead.") + log.Error().Err(err).Str("endpoint", endpoint.Name).Msg(err.Error()) + return err + } + if endpoint.ContainerEngine == portainer.ContainerEnginePodman && !dockerSnapshot.IsPodman { + err := errors.New("the Podman environment option doesn't support Docker environments. Please select the Docker option instead.") + log.Error().Err(err).Str("endpoint", endpoint.Name).Msg(err.Error()) + return err + } + return nil +} + func (service *Service) startSnapshotLoop() { ticker := time.NewTicker(time.Duration(service.snapshotIntervalInSeconds) * time.Second) diff --git a/api/portainer.go b/api/portainer.go index b3677f3de..5bdf7ee61 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -214,6 +214,7 @@ type ( NodeCount int `json:"NodeCount"` GpuUseAll bool `json:"GpuUseAll"` GpuUseList []string `json:"GpuUseList"` + IsPodman bool `json:"IsPodman"` } // DockerContainerSnapshot is an extent of Docker's Container struct