Adding Upgrade to Enterprise version feature (#14539)
* Adding Upgrade to Enterprise version feature * Addressing PR review comments, and adding some minor improvements * Add tests file * Addressing PR comments * fix linter checks * Storing and exposing the upgraded from TE info * Fix showing errors on mac * A more appropiate status code for not-supported upgrade * Fixing tests * Handling permissions errors * More server logging around upgrade failures * Apply text changes suggested from code review Co-authored-by: Eric Sadur <57730300+esadur@users.noreply.github.com> * Address PR review comments * Only allow to restart the system after an upgrade * Verify file signature before upgrade * Adding limit to the downloaded file * Simplifying the upgrade binary process with backup in memory * Fixing backup/restore mechanism for the binary file * Improve file permissions handling * Askin the permissions for the right place (the parent directory) * Fixing tests * Addressing PR review comments * Fix license headers * Fixing retry layer * Making it work on windows builds * Adding license header * Fixing 2 tests * Fixing tests that need UpgradeFromTE System key mock * Extracting i18n translation * Apply suggestions from code review Co-authored-by: Eric Sadur <57730300+esadur@users.noreply.github.com> * Improving how the errors are written * Fixing another error text * Removing unneeded translation * Fixing upgrade status strings * Update i18n/en.json Co-authored-by: Eric Sadur <57730300+esadur@users.noreply.github.com> * Fixing tests Co-authored-by: Eric Sadur <57730300+esadur@users.noreply.github.com> Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e6c1d5f75b
Коммит
7fe6c94eda
@@ -42,6 +42,7 @@ func TestUnitUpdateConfig(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
mockSystemStore.On("Get").Return(make(model.StringMap), nil)
|
||||
|
||||
@@ -346,6 +346,7 @@ func (s *Server) ClientConfigWithComputed() map[string]string {
|
||||
// by the client.
|
||||
respCfg["NoAccounts"] = strconv.FormatBool(s.IsFirstUserAccount())
|
||||
respCfg["MaxPostSize"] = strconv.Itoa(s.MaxPostSize())
|
||||
respCfg["UpgradedFromTE"] = strconv.FormatBool(s.isUpgradedFromTE())
|
||||
respCfg["InstallationDate"] = ""
|
||||
if installationDate, err := s.getSystemInstallDate(); err == nil {
|
||||
respCfg["InstallationDate"] = strconv.FormatInt(installationDate, 10)
|
||||
|
||||
@@ -74,6 +74,7 @@ func TestClientConfigWithComputed(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
|
||||
@@ -104,6 +104,7 @@ func TestSAMLSettings(t *testing.T) {
|
||||
mockPostStore := storemocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := storemocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
|
||||
@@ -554,6 +554,7 @@ func TestGetPushNotificationMessage(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
@@ -1126,6 +1127,7 @@ func TestClearPushNotificationSync(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
@@ -1180,6 +1182,7 @@ func TestUpdateMobileAppBadgeSync(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
@@ -1222,6 +1225,7 @@ func TestSendAckToPushProxy(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
@@ -1379,6 +1383,7 @@ func BenchmarkPushNotificationThroughput(b *testing.B) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ func TestPluginPublicKeys(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
|
||||
@@ -459,6 +459,7 @@ func TestImageProxy(t *testing.T) {
|
||||
mockPostStore := storemocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := storemocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
|
||||
@@ -13,10 +13,12 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/getsentry/sentry-go"
|
||||
@@ -44,6 +46,7 @@ import (
|
||||
"github.com/mattermost/mattermost-server/v5/services/searchengine/bleveengine"
|
||||
"github.com/mattermost/mattermost-server/v5/services/timezones"
|
||||
"github.com/mattermost/mattermost-server/v5/services/tracing"
|
||||
"github.com/mattermost/mattermost-server/v5/services/upgrader"
|
||||
"github.com/mattermost/mattermost-server/v5/store"
|
||||
"github.com/mattermost/mattermost-server/v5/store/localcachelayer"
|
||||
"github.com/mattermost/mattermost-server/v5/store/retrylayer"
|
||||
@@ -723,6 +726,51 @@ func (s *Server) Shutdown() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Restart() error {
|
||||
percentage, err := s.UpgradeToE0Status()
|
||||
if err != nil || percentage != 100 {
|
||||
return errors.Wrap(err, "unable to restart because the system has not been upgraded")
|
||||
}
|
||||
s.Shutdown()
|
||||
|
||||
argv0, err := exec.LookPath(os.Args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = os.Stat(argv0); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mlog.Info("Restarting server")
|
||||
return syscall.Exec(argv0, os.Args, os.Environ())
|
||||
}
|
||||
|
||||
func (s *Server) isUpgradedFromTE() bool {
|
||||
val, err := s.Store.System().GetByName(model.SYSTEM_UPGRADED_FROM_TE_ID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return val.Value == "true"
|
||||
}
|
||||
|
||||
func (s *Server) CanIUpgradeToE0() error {
|
||||
return upgrader.CanIUpgradeToE0()
|
||||
}
|
||||
|
||||
func (s *Server) UpgradeToE0() error {
|
||||
if err := upgrader.UpgradeToE0(); err != nil {
|
||||
return err
|
||||
}
|
||||
upgradedFromTE := &model.System{Name: model.SYSTEM_UPGRADED_FROM_TE_ID, Value: "true"}
|
||||
s.Store.System().Save(upgradedFromTE)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) UpgradeToE0Status() (int64, error) {
|
||||
return upgrader.UpgradeToE0Status()
|
||||
}
|
||||
|
||||
// Go creates a goroutine, but maintains a record of it to ensure that execution completes before
|
||||
// the server is shutdown.
|
||||
func (s *Server) Go(f func()) {
|
||||
|
||||
@@ -131,6 +131,7 @@ func TestHubSessionRevokeRace(t *testing.T) {
|
||||
mockPostStore := mocks.PostStore{}
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user