mirror of https://github.com/portainer/portainer
feat(system): check BE image existence before upgrade [EE-4071] (#8230)
parent
919a854d93
commit
649c1c9cee
|
@ -9,6 +9,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cbroglie/mustache"
|
"github.com/cbroglie/mustache"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
|
"github.com/docker/docker/api/types/filters"
|
||||||
|
"github.com/docker/docker/client"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
libstack "github.com/portainer/docker-compose-wrapper"
|
libstack "github.com/portainer/docker-compose-wrapper"
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
|
@ -43,7 +46,10 @@ type service struct {
|
||||||
assetsPath string
|
assetsPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewService(assetsPath string, composeDeployer libstack.Deployer) (Service, error) {
|
func NewService(
|
||||||
|
assetsPath string,
|
||||||
|
composeDeployer libstack.Deployer,
|
||||||
|
) (Service, error) {
|
||||||
platform, err := platform.DetermineContainerPlatform()
|
platform, err := platform.DetermineContainerPlatform()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to determine container platform")
|
return nil, errors.Wrap(err, "failed to determine container platform")
|
||||||
|
@ -74,6 +80,7 @@ func (service *service) Upgrade(licenseKey string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *service) upgradeDocker(licenseKey, version, envType string) error {
|
func (service *service) upgradeDocker(licenseKey, version, envType string) error {
|
||||||
|
ctx := context.TODO()
|
||||||
templateName := filesystem.JoinPaths(service.assetsPath, "mustache-templates", mustacheUpgradeDockerTemplateFile)
|
templateName := filesystem.JoinPaths(service.assetsPath, "mustache-templates", mustacheUpgradeDockerTemplateFile)
|
||||||
|
|
||||||
portainerImagePrefix := os.Getenv(portainerImagePrefixEnvVar)
|
portainerImagePrefix := os.Getenv(portainerImagePrefixEnvVar)
|
||||||
|
@ -85,6 +92,10 @@ func (service *service) upgradeDocker(licenseKey, version, envType string) error
|
||||||
|
|
||||||
skipPullImage := os.Getenv(skipPullImageEnvVar)
|
skipPullImage := os.Getenv(skipPullImageEnvVar)
|
||||||
|
|
||||||
|
if err := service.checkImage(ctx, image, skipPullImage != ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
composeFile, err := mustache.RenderFile(templateName, map[string]string{
|
composeFile, err := mustache.RenderFile(templateName, map[string]string{
|
||||||
"image": image,
|
"image": image,
|
||||||
"skip_pull_image": skipPullImage,
|
"skip_pull_image": skipPullImage,
|
||||||
|
@ -118,7 +129,7 @@ func (service *service) upgradeDocker(licenseKey, version, envType string) error
|
||||||
strings.Replace(version, ".", "-", -1))
|
strings.Replace(version, ".", "-", -1))
|
||||||
|
|
||||||
err = service.composeDeployer.Deploy(
|
err = service.composeDeployer.Deploy(
|
||||||
context.Background(),
|
ctx,
|
||||||
[]string{filePath},
|
[]string{filePath},
|
||||||
libstack.DeployOptions{
|
libstack.DeployOptions{
|
||||||
ForceRecreate: true,
|
ForceRecreate: true,
|
||||||
|
@ -137,3 +148,35 @@ func (service *service) upgradeDocker(licenseKey, version, envType string) error
|
||||||
|
|
||||||
return errors.New("upgrade failed: server should have been restarted by the updater")
|
return errors.New("upgrade failed: server should have been restarted by the updater")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (service *service) checkImage(ctx context.Context, image string, skipPullImage bool) error {
|
||||||
|
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to create docker client")
|
||||||
|
}
|
||||||
|
|
||||||
|
if skipPullImage {
|
||||||
|
filters := filters.NewArgs()
|
||||||
|
filters.Add("reference", image)
|
||||||
|
images, err := cli.ImageList(ctx, types.ImageListOptions{
|
||||||
|
Filters: filters,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to list images")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(images) == 0 {
|
||||||
|
return errors.Errorf("image %s not found locally", image)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
// check if available on registry
|
||||||
|
_, err := cli.DistributionInspect(ctx, image, "")
|
||||||
|
if err != nil {
|
||||||
|
return errors.Errorf("image %s not found on registry", image)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue