最近需要更新 Gogs
到 Gitea
但是官方表示 只能升级老版本的 折腾了一下 升级成功了 这里做个记录
准备工作
- 做好数据库和Git仓库的备份
- 做好数据库和Git仓库的备份
- 做好数据库和Git仓库的备份
- 准备一个Docker环境 用于快速切换版本
- 一双明亮的双眼 仔细阅读升级指南
- 前置数据准备
- 找到
Gogs
的Repo
目录 仓库数据 - 找到
Gogs
的Data
目录 头像等自定义数据
- 找到
迁移数据到Gitea1.0.2版本
- 找一个你要保存数据的目录 (本案例指定为
/data/gitea
) - 通过 Docker 容器安装 1.0.2 的
Gitea
- 执行下列命令 启动一个容器
1
docker run --rm -p 3000:3000 -v /data/gitea:/data --name gitea gitea/gitea:1.0.2
- 打开
http://主机IP:3000
完成安装流程 Ctrl + C
关闭容器- 复制 repo 数据 到
/data/gitea/git/repositories
注意原有目录结构 - 复制 data 数据 到
/data/gitea/gitea
注意原有目录结构 - 修改
/data/gitea/gitea/conf/app.ini
文件配置 - 复制原有配置文件的密钥到
/data/gitea/gitea/conf/app.ini
1
2
3[security]
INSTALL_LOCK = true
SECRET_KEY = xxxx - 设置之前复制目录的权限为
git
执行chown git:git /data/gitea -R
- 修改数据库
version
表的version
记录值为13
1
UPDATE `version` SET `version` = 13 WHERE `id` = 1
- 再次启动容器 访问
http://主机IP:3000
查看是否存在问题
逐步升级到最新版
- 尝试使用新版本的镜像启动 执行下列命令
1
docker run --rm -p 3000:3000 -v $(pwd):/data --name gitea gitea/gitea:1.1.4
- 启动后 数据库会开始自动迁移 看到
Listen: http://0.0.0.0:3000
的时候 关闭容器 - 按照步骤 依次完成下列版本升级
1.0.2
>1.1.4
>1.2.3
(这次应该从这里开始) >1.3.3
>1.4.3
>1.5.3
>1.6.4
>1.7.6
>1.8.3
>1.9.6
>1.10.2
- 最后一个版本可以运行之后 使用下列命令运行 保证自动重启
1
docker run -p 3000:3000 -v /data/gitea:/data --restart=always --name gitea gitea/gitea:1.10.2
异常问题解决
Failed to initialize ORM engine: migrate: do migrate: Avatar user is not exist
- 此问题应该存在
1.0.2
=>1.1.4
的时候发生 - 检查了一下
1.1.4
的源代码 https://github.com/go-gitea/gitea/blob/34182c87ec50f647fc6f5b97ba201c3bd42f0728/models/migrations/v20.go#L221
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21names, err := d.Readdirnames(0)
if err != nil {
return err
}
type User struct {
ID int64 `xorm:"pk autoincr"`
Avatar string
UseCustomAvatar bool
}
for _, name := range names {
... 省略
var user User
if has, err := x.ID(userID).Get(&user); err != nil {
return err
} else if !has {
// 问题在这里 主要是 有对应的头像文件 但是没找到数据库对应的ID
return errors.New("Avatar user is not exist")
}
} - 发现是 通过数据头像目录获取头像 检查数据库数据的时候报错
- 先把
/data/avatar(/data/gitea/gitea/avatar)
目录
ORM engine initialization failed: migrate: do migrate: Repository 464 is not exist
- 此问题应该存在
1.7.6
=>1.8.4
的时候发生 - 检查
1.8.4
的源代码 https://github.com/go-gitea/gitea/blob/11f6ed4f83/models/migrations/v82.go#L71 - 发现问题在这里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26releases := make([]*Release, 0, batchSize)
if err = sess.Limit(batchSize, start).Asc("id").Where("is_tag=?", false).Find(&releases); err != nil {
return err
}
if len(releases) == 0 {
break
}
for _, release := range releases {
gitRepo, ok := gitRepoCache[release.RepoID]
if !ok {
repo, ok := repoCache[release.RepoID]
if !ok {
repo = new(Repository)
has, err := sess.ID(release.RepoID).Get(repo)
if err != nil {
return err
} else if !has {
// 问题在这里 主要是 有Release相关数据 但是没有找到对应的仓库
return fmt.Errorf("Repository %d is not exist", release.RepoID)
}
repoCache[release.RepoID] = repo
}
}
} - 先去检查
releases
表 搜索RepoID
等于对应报错的记录 - 备份相关记录数据
- 删除有问题的数据 然后重启
404 问题解决
方案一
- 使用 API 更新 配置
- 去个人管理页面 生成一个
Token
- 通过API 更新仓库信息
curl -X PATCH "https://{{host}}/api/v1/repos/{{user}}/{{repo}}?access_token={{token}}" -H "accept: application/json" -H "Content-Type: application/json" -d "{}"
- 此方案需要一个项目一个项目修复
方案二
- 数据库批量解决此问题
1
2
3
4
5
6INSERT INTO repo_unit ( "repo_id", "type", "config" )
SELECT repository.id, types.*, '{}' FROM repository
LEFT JOIN repo_unit ON repository.id = repo_id
LEFT JOIN ( SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 ) AS types ON ( 1 = 1 )
WHERE
repo_id IS NULL; - 此方案有可能导致部分项目配置重置
推送代码时提示钩子异常
- 提示类似下列错误
1
2
3
4remote: ./hooks/pre-receive.d/pre-receive: line 2: /opt/gogs/gogs: No such file or directory
To https://gitea.xxx.xxx/xxx/xxx.git
! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://gitea.xxx.xxx/xxx/xxx.git' - 执行删除钩子
find repositories -path \*-receive.d/\*-receive | xargs rm -r