mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
fix(container/network): recreate container changes static IP [EE-5448] (#8960)
Co-authored-by: Chaim Lev-Ari <chaim.levi-ari@portainer.io>
This commit is contained in:
parent
d340c4ea96
commit
96de026eba
35 changed files with 1651 additions and 491 deletions
97
api/http/handler/docker/containers/recreate.go
Normal file
97
api/http/handler/docker/containers/recreate.go
Normal file
|
@ -0,0 +1,97 @@
|
|||
package containers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/docker/consts"
|
||||
"github.com/portainer/portainer/api/docker/images"
|
||||
"github.com/portainer/portainer/api/http/middlewares"
|
||||
"github.com/portainer/portainer/api/internal/authorization"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type RecreatePayload struct {
|
||||
// PullImage if true will pull the image
|
||||
PullImage bool `json:"PullImage"`
|
||||
}
|
||||
|
||||
func (r RecreatePayload) Validate(request *http.Request) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (handler *Handler) recreate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
containerID, err := request.RetrieveRouteVariableValue(r, "containerId")
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid containerId", err)
|
||||
}
|
||||
|
||||
var payload RecreatePayload
|
||||
err = request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
if err != nil {
|
||||
return httperror.BadRequest("Invalid request payload", err)
|
||||
}
|
||||
|
||||
endpoint, err := middlewares.FetchEndpoint(r)
|
||||
if err != nil {
|
||||
return httperror.NotFound("Unable to find an environment on request context", err)
|
||||
}
|
||||
|
||||
err = handler.bouncer.AuthorizedEndpointOperation(r, endpoint)
|
||||
if err != nil {
|
||||
return httperror.Forbidden("Permission denied to force update service", err)
|
||||
}
|
||||
|
||||
agentTargetHeader := r.Header.Get(portainer.PortainerAgentTargetHeader)
|
||||
|
||||
newContainer, err := handler.containerService.Recreate(r.Context(), endpoint, containerID, payload.PullImage, "", agentTargetHeader)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Error recreating container", err)
|
||||
}
|
||||
|
||||
handler.updateWebhook(containerID, newContainer.ID)
|
||||
handler.createResourceControl(containerID, newContainer.ID)
|
||||
|
||||
go func() {
|
||||
images.EvictImageStatus(containerID)
|
||||
images.EvictImageStatus(newContainer.Config.Labels[consts.ComposeStackNameLabel])
|
||||
images.EvictImageStatus(newContainer.Config.Labels[consts.SwarmServiceIdLabel])
|
||||
}()
|
||||
return response.JSON(w, newContainer)
|
||||
}
|
||||
|
||||
func (handler *Handler) createResourceControl(oldContainerId string, newContainerId string) {
|
||||
resourceControls, err := handler.dataStore.ResourceControl().ResourceControls()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Exporting Resource Controls")
|
||||
return
|
||||
}
|
||||
|
||||
resourceControl := authorization.GetResourceControlByResourceIDAndType(oldContainerId, portainer.ContainerResourceControl, resourceControls)
|
||||
if resourceControl == nil {
|
||||
return
|
||||
}
|
||||
resourceControl.ResourceID = newContainerId
|
||||
err = handler.dataStore.ResourceControl().Create(resourceControl)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("containerId", newContainerId).Msg("Failed to create new resource control for container")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (handler *Handler) updateWebhook(oldContainerId string, newContainerId string) {
|
||||
webhook, err := handler.dataStore.Webhook().WebhookByResourceID(oldContainerId)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Str("containerId", oldContainerId).Msg("cannot find webhook by containerId")
|
||||
return
|
||||
}
|
||||
|
||||
webhook.ResourceID = newContainerId
|
||||
err = handler.dataStore.Webhook().UpdateWebhook(webhook.ID, webhook)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Int("webhookId", int(webhook.ID)).Msg("cannot update webhook")
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue