feat(patch): upgrade patch module (#7738)

* feat(patch): upgrade patch module

* chore(patch): add docs

* fix(patch): skip and rewrite invalid last launched version

* fix(patch): turn two functions into patches
pull/7754/head
KirCute_ECT 2024-12-30 22:48:33 +08:00 committed by GitHub
parent 42243b1517
commit 5994c17b4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 184 additions and 35 deletions

View File

@ -19,6 +19,7 @@ func Init() {
bootstrap.InitDB()
data.InitData()
bootstrap.InitIndex()
bootstrap.InitUpgradePatch()
}
func Release() {

View File

@ -34,6 +34,8 @@ func InitConfig() {
log.Fatalf("failed to create config file: %+v", err)
}
conf.Conf = conf.DefaultConfig()
LastLaunchedVersion = conf.Version
conf.Conf.LastLaunchedVersion = conf.Version
if !utils.WriteJsonToFile(configPath, conf.Conf) {
log.Fatalf("failed to create default config file")
}
@ -47,6 +49,10 @@ func InitConfig() {
if err != nil {
log.Fatalf("load config error: %+v", err)
}
LastLaunchedVersion = conf.Conf.LastLaunchedVersion
if conf.Version != "dev" || LastLaunchedVersion == "" {
conf.Conf.LastLaunchedVersion = conf.Version
}
// update config.json struct
confBody, err := utils.Json.MarshalIndent(conf.Conf, "", " ")
if err != nil {

View File

@ -64,39 +64,4 @@ func initUser() {
utils.Log.Fatalf("[init user] Failed to get guest user: %v", err)
}
}
hashPwdForOldVersion()
updateAuthnForOldVersion()
}
func hashPwdForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.PwdHash == "" {
user.SetPassword(user.Password)
user.Password = ""
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed update user: %v", err)
}
}
}
}
func updateAuthnForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[update authn for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.Authn == "" {
user.Authn = "[]"
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[update authn for old version] failed update user: %v", err)
}
}
}
}

View File

@ -0,0 +1,67 @@
package bootstrap
import (
"fmt"
"github.com/alist-org/alist/v3/internal/bootstrap/patch"
"github.com/alist-org/alist/v3/internal/conf"
"github.com/alist-org/alist/v3/pkg/utils"
)
var LastLaunchedVersion = ""
func safeCall(v string, i int, f func()) {
defer func() {
if r := recover(); r != nil {
utils.Log.Errorf("Recovered from patch (version: %s, index: %d) panic: %v", v, i, r)
}
}()
f()
}
func getVersion(v string) (major, minor, patchNum int, err error) {
_, err = fmt.Sscanf(v, "v%d.%d.%d", &major, &minor, &patchNum)
return major, minor, patchNum, err
}
func compareVersion(majorA, minorA, patchNumA, majorB, minorB, patchNumB int) bool {
if majorA != majorB {
return majorA > majorB
}
if minorA != minorB {
return minorA > minorB
}
if patchNumA != patchNumB {
return patchNumA > patchNumB
}
return true
}
func InitUpgradePatch() {
if conf.Version == "dev" {
return
}
if LastLaunchedVersion == conf.Version {
return
}
if LastLaunchedVersion == "" {
LastLaunchedVersion = "v0.0.0"
}
major, minor, patchNum, err := getVersion(LastLaunchedVersion)
if err != nil {
utils.Log.Warnf("Failed to parse last launched version %s: %v, skipping all patches and rewrite last launched version", LastLaunchedVersion, err)
return
}
for _, vp := range patch.UpgradePatches {
ma, mi, pn, err := getVersion(vp.Version)
if err != nil {
utils.Log.Errorf("Skip invalid version %s patches: %v", vp.Version, err)
continue
}
if compareVersion(ma, mi, pn, major, minor, patchNum) {
for i, p := range vp.Patches {
safeCall(vp.Version, i, p)
}
}
}
}

View File

@ -0,0 +1,35 @@
package patch
import (
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_24_0"
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_32_0"
"github.com/alist-org/alist/v3/internal/bootstrap/patch/v3_41_0"
)
type VersionPatches struct {
// Version means if the system is upgraded from Version or an earlier one
// to the current version, all patches in Patches will be executed.
Version string
Patches []func()
}
var UpgradePatches = []VersionPatches{
{
Version: "v3.24.0",
Patches: []func(){
v3_24_0.HashPwdForOldVersion,
},
},
{
Version: "v3.32.0",
Patches: []func(){
v3_32_0.UpdateAuthnForOldVersion,
},
},
{
Version: "v3.41.0",
Patches: []func(){
v3_41_0.GrantAdminPermissions,
},
},
}

View File

@ -0,0 +1,26 @@
package v3_24_0
import (
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
)
// HashPwdForOldVersion encode passwords using SHA256
// First published: 75acbcc perf: sha256 for user's password (close #3552) by Andy Hsu
func HashPwdForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.PwdHash == "" {
user.SetPassword(user.Password)
user.Password = ""
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[hash pwd for old version] failed update user: %v", err)
}
}
}
}

View File

@ -0,0 +1,25 @@
package v3_32_0
import (
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
)
// UpdateAuthnForOldVersion updates users' authn
// First published: bdfc159 fix: webauthn logspam (#6181) by itsHenry
func UpdateAuthnForOldVersion() {
users, _, err := op.GetUsers(1, -1)
if err != nil {
utils.Log.Fatalf("[update authn for old version] failed get users: %v", err)
}
for i := range users {
user := users[i]
if user.Authn == "" {
user.Authn = "[]"
if err := db.UpdateUser(&user); err != nil {
utils.Log.Fatalf("[update authn for old version] failed update user: %v", err)
}
}
}
}

View File

@ -0,0 +1,22 @@
package v3_41_0
import (
"github.com/alist-org/alist/v3/internal/op"
"github.com/alist-org/alist/v3/pkg/utils"
)
// GrantAdminPermissions gives admin Permission 0(can see hidden) - 9(webdav manage)
// This patch is written to help users upgrading from older version better adapt to PR AlistGo/alist#7705.
func GrantAdminPermissions() {
admin, err := op.GetAdmin()
if err != nil {
utils.Log.Errorf("Cannot grant permissions to admin: %v", err)
}
if (admin.Permission & 0x3FF) == 0 {
admin.Permission |= 0x3FF
}
err = op.UpdateUser(admin)
if err != nil {
utils.Log.Errorf("Cannot grant permissions to admin: %v", err)
}
}

View File

@ -110,6 +110,7 @@ type Config struct {
S3 S3 `json:"s3" envPrefix:"S3_"`
FTP FTP `json:"ftp" envPrefix:"FTP_"`
SFTP SFTP `json:"sftp" envPrefix:"SFTP_"`
LastLaunchedVersion string `json:"last_launched_version"`
}
func DefaultConfig() *Config {
@ -195,5 +196,6 @@ func DefaultConfig() *Config {
Enable: false,
Listen: ":5222",
},
LastLaunchedVersion: "",
}
}