[UPGRADE] add sanity checks for [storage*]

Refs: https://forgejo.org/2023-08-release-v1-20-3-0/
(cherry picked from commit a266dd0ce3)
(cherry picked from commit b9eb5eccd8)
(cherry picked from commit 7fc2028ede)
(cherry picked from commit 0c988e6120)
(cherry picked from commit 7ba05e8c2b)
(cherry picked from commit 2ed5068abe)
(cherry picked from commit 353913a26d)
(cherry picked from commit 4e63a01a8b)
(cherry picked from commit 99f612aed3)
(cherry picked from commit b4fe189cae)
(cherry picked from commit 520295a6f5)
(cherry picked from commit e5a564044b)
(cherry picked from commit 52cc6c26fc)
This commit is contained in:
Earl Warren 2023-08-09 00:06:25 +02:00
parent 62fb498601
commit d58f04bd1d
No known key found for this signature in database
GPG key ID: 0579CB2928A78A00
4 changed files with 212 additions and 2 deletions

View file

@ -14,6 +14,8 @@ func init() {
db.RegisterModel(new(ForgejoSemVer)) db.RegisterModel(new(ForgejoSemVer))
} }
var DefaultVersionString = "1.0.0"
type ForgejoSemVer struct { type ForgejoSemVer struct {
Version string Version string
} }
@ -23,7 +25,8 @@ func GetVersion(ctx context.Context) (*version.Version, error) {
} }
func GetVersionWithEngine(e db.Engine) (*version.Version, error) { func GetVersionWithEngine(e db.Engine) (*version.Version, error) {
versionString := "v1.0.0" versionString := DefaultVersionString
exists, err := e.IsTableExist("forgejo_sem_ver") exists, err := e.IsTableExist("forgejo_sem_ver")
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -9,6 +9,7 @@ import (
) )
var ( var (
ForgejoV6DatabaseVersion = int64(261) // must be updated once v6 / Gitea v1.21 is out
ForgejoV5DatabaseVersion = int64(260) ForgejoV5DatabaseVersion = int64(260)
ForgejoV4DatabaseVersion = int64(244) ForgejoV4DatabaseVersion = int64(244)
) )
@ -21,5 +22,5 @@ func fatal(err error) error {
} }
func PreMigrationSanityChecks(e db.Engine, dbVersion int64, cfg setting.ConfigProvider) error { func PreMigrationSanityChecks(e db.Engine, dbVersion int64, cfg setting.ConfigProvider) error {
return nil return v1TOv5_0_1Included(e, dbVersion, cfg)
} }

View file

@ -0,0 +1,91 @@
// SPDX-License-Identifier: MIT
package forgejo
import (
"fmt"
"strings"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/forgejo/semver"
"code.gitea.io/gitea/modules/setting"
"github.com/hashicorp/go-version"
)
var v1TOv5_0_1IncludedStorageSections = []struct {
section string
storageSection string
}{
{"attachment", "storage.attachments"},
{"lfs", "storage.lfs"},
{"avatar", "storage.avatars"},
{"repo-avatar", "storage.repo-avatars"},
{"repo-archive", "storage.repo-archive"},
{"packages", "storage.packages"},
// the actions sections are not included here because they were experimental at the time
}
func v1TOv5_0_1Included(e db.Engine, dbVersion int64, cfg setting.ConfigProvider) error {
//
// When upgrading from Forgejo > v5 or Gitea > v1.20, no sanity check is necessary
//
if dbVersion > ForgejoV5DatabaseVersion {
return nil
}
//
// When upgrading from a Forgejo point version >= v5.0.1, no sanity
// check is necessary
//
// When upgrading from a Gitea >= v1.20 the sanitiy checks will
// always be done They are necessary for Gitea [v1.20.0..v1.20.2]
// but not for [v1.20.3..] but there is no way to know which point
// release was running prior to the upgrade. This may require the
// Gitea admin to update their app.ini although it is not necessary
// but will have no other consequence.
//
previousServerVersion, err := semver.GetVersionWithEngine(e)
if err != nil {
return err
}
upper, err := version.NewVersion("v5.0.1")
if err != nil {
return err
}
if previousServerVersion.GreaterThan(upper) {
return nil
}
//
// Sanity checks
//
originalCfg, err := cfg.PrepareSaving()
if err != nil {
return err
}
messages := make([]string, 0, 10)
for _, c := range v1TOv5_0_1IncludedStorageSections {
section, _ := originalCfg.GetSection(c.section)
if section == nil {
continue
}
storageSection, _ := originalCfg.GetSection(c.storageSection)
if storageSection == nil {
continue
}
messages = append(messages, fmt.Sprintf("[%s] and [%s] may conflict with each other", c.section, c.storageSection))
}
if originalCfg.Section("storage").HasKey("PATH") {
messages = append(messages, "[storage].PATH is set and may create storage issues")
}
if len(messages) > 0 {
return fatal(fmt.Errorf("%s\nThese issues need to be manually fixed in the app.ini file at %s. Please read https://forgejo.org/2023-08-release-v1-20-3-0/ for instructions", strings.Join(messages, "\n"), cfg.GetFile()))
}
return nil
}

View file

@ -0,0 +1,115 @@
// SPDX-License-Identifier: MIT
package forgejo
import (
"fmt"
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/forgejo/semver"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/log"
"github.com/stretchr/testify/assert"
)
func TestForgejo_v1TOv5_0_1Included(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
logFatal = func(string, ...any) {}
defer func() {
logFatal = log.Fatal
}()
configWithSoragePath := `
[storage]
PATH = /something
`
verifyForgejoV1TOv5_0_1Included(t, configWithSoragePath, "[storage].PATH is set")
for _, c := range v1TOv5_0_1IncludedStorageSections {
config := fmt.Sprintf("[%s]\n[%s]\n", c.section, c.storageSection)
verifyForgejoV1TOv5_0_1Included(t, config, fmt.Sprintf("[%s] and [%s]", c.section, c.storageSection))
}
}
func verifyForgejoV1TOv5_0_1Included(t *testing.T, config, message string) {
ctx := db.DefaultContext
e := db.GetEngine(ctx)
for _, testCase := range []struct {
name string
dbVersion int64
semver string
config string
}{
{
name: "5.0.0 with no " + message,
dbVersion: ForgejoV5DatabaseVersion,
semver: "5.0.0+0-gitea-1.20.1",
config: "",
},
{
name: "5.0.1 with no " + message,
dbVersion: ForgejoV5DatabaseVersion,
semver: "5.0.1+0-gitea-1.20.2",
config: "",
},
{
name: "5.0.2 with " + message,
dbVersion: ForgejoV5DatabaseVersion,
semver: "5.0.2+0-gitea-1.20.3",
config: config,
},
{
name: "6.0.0 with " + message,
dbVersion: ForgejoV6DatabaseVersion,
semver: "6.0.0+0-gitea-1.21.0",
config: config,
},
} {
cfg := configFixture(t, testCase.config)
semver.SetVersionString(ctx, testCase.semver)
assert.NoError(t, v1TOv5_0_1Included(e, testCase.dbVersion, cfg))
}
for _, testCase := range []struct {
name string
dbVersion int64
semver string
config string
}{
{
name: "5.0.0 with " + message,
dbVersion: ForgejoV5DatabaseVersion,
semver: "5.0.0+0-gitea-1.20.1",
config: config,
},
{
name: "5.0.1 with " + message,
dbVersion: ForgejoV5DatabaseVersion,
semver: "5.0.1+0-gitea-1.20.2",
config: config,
},
{
//
// When upgrading from
//
// Forgejo >= 5.0.1+0-gitea-1.20.2
// Gitea > v1.21
//
// The version that the server was running prior to the upgrade
// is not available.
//
name: semver.DefaultVersionString + " with " + message,
dbVersion: ForgejoV4DatabaseVersion,
semver: semver.DefaultVersionString,
config: config,
},
} {
cfg := configFixture(t, testCase.config)
semver.SetVersionString(ctx, testCase.semver)
assert.ErrorContains(t, v1TOv5_0_1Included(e, testCase.dbVersion, cfg), message)
}
}