[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)
This commit is contained in:
Earl Warren 2023-08-09 00:06:25 +02:00
parent 7a1c5c0f32
commit 353913a26d
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))
}
var DefaultVersionString = "1.0.0"
type ForgejoSemVer struct {
Version string
}
@ -23,7 +25,8 @@ func GetVersion(ctx context.Context) (*version.Version, error) {
}
func GetVersionWithEngine(e db.Engine) (*version.Version, error) {
versionString := "v1.0.0"
versionString := DefaultVersionString
exists, err := e.IsTableExist("forgejo_sem_ver")
if err != nil {
return nil, err

View file

@ -9,6 +9,7 @@ import (
)
var (
ForgejoV6DatabaseVersion = int64(261) // must be updated once v6 / Gitea v1.21 is out
ForgejoV5DatabaseVersion = int64(260)
ForgejoV4DatabaseVersion = int64(244)
)
@ -21,5 +22,5 @@ func fatal(err error) 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)
}
}