mirror of
https://github.com/portainer/portainer.git
synced 2025-07-23 15:29:42 +02:00
feat(system): upgrade portainer on kubernetes [EE-4625] (#8448)
This commit is contained in:
parent
0669ad77d3
commit
4c86be725d
8 changed files with 394 additions and 139 deletions
121
api/internal/upgrade/upgrade_docker.go
Normal file
121
api/internal/upgrade/upgrade_docker.go
Normal file
|
@ -0,0 +1,121 @@
|
|||
package upgrade
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
libstack "github.com/portainer/docker-compose-wrapper"
|
||||
"github.com/portainer/portainer/api/filesystem"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func (service *service) upgradeDocker(licenseKey, version, envType string) error {
|
||||
ctx := context.TODO()
|
||||
templateName := filesystem.JoinPaths(service.assetsPath, "mustache-templates", mustacheUpgradeDockerTemplateFile)
|
||||
|
||||
portainerImagePrefix := os.Getenv(portainerImagePrefixEnvVar)
|
||||
if portainerImagePrefix == "" {
|
||||
portainerImagePrefix = "portainer/portainer-ee"
|
||||
}
|
||||
|
||||
image := fmt.Sprintf("%s:%s", portainerImagePrefix, version)
|
||||
|
||||
skipPullImage := os.Getenv(skipPullImageEnvVar)
|
||||
|
||||
if err := service.checkImageForDocker(ctx, image, skipPullImage != ""); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
composeFile, err := mustache.RenderFile(templateName, map[string]string{
|
||||
"image": image,
|
||||
"skip_pull_image": skipPullImage,
|
||||
"updater_image": os.Getenv(updaterImageEnvVar),
|
||||
"license": licenseKey,
|
||||
"envType": envType,
|
||||
})
|
||||
|
||||
log.Debug().
|
||||
Str("composeFile", composeFile).
|
||||
Msg("Compose file for upgrade")
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to render upgrade template")
|
||||
}
|
||||
|
||||
tmpDir := os.TempDir()
|
||||
timeId := time.Now().Unix()
|
||||
filePath := filesystem.JoinPaths(tmpDir, fmt.Sprintf("upgrade-%d.yml", timeId))
|
||||
|
||||
r := bytes.NewReader([]byte(composeFile))
|
||||
|
||||
err = filesystem.CreateFile(filePath, r)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create upgrade compose file")
|
||||
}
|
||||
|
||||
projectName := fmt.Sprintf(
|
||||
"portainer-upgrade-%d-%s",
|
||||
timeId,
|
||||
strings.Replace(version, ".", "-", -1))
|
||||
|
||||
err = service.composeDeployer.Deploy(
|
||||
ctx,
|
||||
[]string{filePath},
|
||||
libstack.DeployOptions{
|
||||
ForceRecreate: true,
|
||||
AbortOnContainerExit: true,
|
||||
Options: libstack.Options{
|
||||
ProjectName: projectName,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
// optimally, server was restarted by the updater, so we should not reach this point
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to deploy upgrade stack")
|
||||
}
|
||||
|
||||
return errors.New("upgrade failed: server should have been restarted by the updater")
|
||||
}
|
||||
|
||||
func (service *service) checkImageForDocker(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…
Add table
Add a link
Reference in a new issue