1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-01-19 08:19:15 +08:00

feat: 应用商店离线包改为从 gitee github 获取

This commit is contained in:
zhengkunwang223 2023-02-10 18:07:29 +08:00 committed by zhengkunwang223
parent 9c1fef0309
commit 80a0dfdfc0
14 changed files with 126 additions and 63 deletions

View File

@ -58,7 +58,7 @@ func (b *BaseApi) UpdateSetting(c *gin.Context) {
return
}
if err := settingService.Update(c, req.Key, req.Value); err != nil {
if err := settingService.Update(req.Key, req.Value); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
@ -240,12 +240,12 @@ func (b *BaseApi) MFABind(c *gin.Context) {
return
}
if err := settingService.Update(c, "MFAStatus", "enable"); err != nil {
if err := settingService.Update("MFAStatus", "enable"); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
if err := settingService.Update(c, "MFASecret", req.Secret); err != nil {
if err := settingService.Update("MFASecret", req.Secret); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}

View File

@ -30,6 +30,8 @@ type SettingInfo struct {
EmailVars string `json:"emailVars"`
WeChatVars string `json:"weChatVars"`
DingVars string `json:"dingVars"`
AppStoreVersion string `json:"appStoreVersion"`
}
type SettingUpdate struct {

View File

@ -333,14 +333,12 @@ func (a AppService) SyncInstalled(installId uint) error {
}
func (a AppService) SyncAppList() error {
if err := getAppFromOss(); err != nil {
if err := getAppFromRepo(); err != nil {
global.LOG.Errorf("get app from oss error: %s", err.Error())
return err
}
appDir := constant.AppResourceDir
listFile := path.Join(appDir, "list.json")
content, err := os.ReadFile(listFile)
if err != nil {
return err
@ -354,22 +352,18 @@ func (a AppService) SyncAppList() error {
tags []*model.Tag
appTags []*model.AppTag
)
for _, t := range list.Tags {
tags = append(tags, &model.Tag{
Key: t.Key,
Name: t.Name,
})
}
oldApps, err := appRepo.GetBy()
if err != nil {
return err
}
appsMap := getApps(oldApps, list.Items)
for _, l := range list.Items {
app := appsMap[l.Key]
icon, err := os.ReadFile(path.Join(appDir, l.Key, "metadata", "logo.png"))
if err != nil {
@ -433,9 +427,7 @@ func (a AppService) SyncAppList() error {
updateArray = append(updateArray, v)
}
}
tx, ctx := getTxAndContext()
if len(addAppArray) > 0 {
if err := appRepo.BatchCreate(ctx, addAppArray); err != nil {
tx.Rollback()
@ -461,7 +453,6 @@ func (a AppService) SyncAppList() error {
return err
}
}
apps := append(addAppArray, updateArray...)
var (
@ -478,7 +469,6 @@ func (a AppService) SyncAppList() error {
})
}
}
for _, d := range a.Details {
d.AppId = a.ID
if d.ID == 0 {
@ -488,7 +478,6 @@ func (a AppService) SyncAppList() error {
}
}
}
if len(addDetails) > 0 {
if err := appDetailRepo.BatchCreate(ctx, addDetails); err != nil {
tx.Rollback()

View File

@ -4,9 +4,8 @@ import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"github.com/1Panel-dev/1Panel/backend/utils/git"
"math"
"net/http"
"os"
"path"
"reflect"
@ -500,46 +499,32 @@ func handleErr(install model.AppInstall, err error, out string) error {
return reErr
}
func getAppFromOss() error {
res, err := http.Get(global.CONF.System.AppOss + "/apps/apps.json")
func getAppFromRepo() error {
repoInfo, err := git.CheckAndGetInfo(global.CONF.System.AppRepoOwner, global.CONF.System.AppRepoName)
if err != nil {
return err
}
appByte, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
var ossConfig dto.AppOssConfig
if err := json.Unmarshal(appByte, &ossConfig); err != nil {
return err
}
appDir := constant.AppResourceDir
content, _ := os.ReadFile(path.Join(appDir, "list.json"))
if content != nil {
oldConfig := &dto.AppOssConfig{}
if err := json.Unmarshal(content, oldConfig); err != nil {
return err
}
if oldConfig.Version == ossConfig.Version {
return nil
}
setting, err := NewISettingService().GetSettingInfo()
if err != nil {
return err
}
if !common.CompareVersion(repoInfo.Version, setting.AppStoreVersion) {
return nil
}
downloadUrl := fmt.Sprintf("%sapps-%s.tar.gz", repoInfo.DownloadPath, repoInfo.Version)
fileOp := files.NewFileOp()
if _, err := fileOp.CopyAndBackup(appDir); err != nil {
return err
}
packagePath := path.Join(constant.ResourceDir, path.Base(ossConfig.Package))
if err := fileOp.DownloadFile(ossConfig.Package, packagePath); err != nil {
packagePath := path.Join(constant.ResourceDir, path.Base(downloadUrl))
if err := fileOp.DownloadFile(downloadUrl, packagePath); err != nil {
return err
}
if err := fileOp.Decompress(packagePath, constant.ResourceDir, files.Zip); err != nil {
if err := fileOp.Decompress(packagePath, constant.ResourceDir, files.TarGz); err != nil {
return err
}
_ = NewISettingService().Update("AppStoreVersion", repoInfo.Version)
defer func() {
_ = fileOp.DeleteFile(packagePath)
}()

View File

@ -17,7 +17,7 @@ type SettingService struct{}
type ISettingService interface {
GetSettingInfo() (*dto.SettingInfo, error)
Update(c *gin.Context, key, value string) error
Update(key, value string) error
UpdatePassword(c *gin.Context, old, new string) error
UpdatePort(port uint) error
HandlePasswordExpired(c *gin.Context, old, new string) error
@ -48,7 +48,7 @@ func (u *SettingService) GetSettingInfo() (*dto.SettingInfo, error) {
return &info, err
}
func (u *SettingService) Update(c *gin.Context, key, value string) error {
func (u *SettingService) Update(key, value string) error {
if key == "ExpirationDays" {
timeout, _ := strconv.Atoi(value)
if err := settingRepo.Update("ExpirationTime", time.Now().AddDate(0, 0, timeout).Format("2006-01-02 15:04:05")); err != nil {

View File

@ -33,7 +33,7 @@ func NewIUpgradeService() IUpgradeService {
}
func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) {
currentVerion, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion"))
currentVersion, err := settingRepo.Get(settingRepo.WithByKey("SystemVersion"))
if err != nil {
return nil, err
}
@ -57,7 +57,7 @@ func (u *UpgradeService) SearchUpgrade() (*dto.UpgradeInfo, error) {
}
}
if len(releaseInfo.NewVersion) != 0 {
isNew, err := compareVersion(currentVerion.Value, releaseInfo.NewVersion)
isNew, err := compareVersion(currentVersion.Value, releaseInfo.NewVersion)
if !isNew && err != nil {
return nil, err
}
@ -183,8 +183,8 @@ func (u *UpgradeService) handleRollback(fileOp files.FileOp, originalDir string,
func (u *UpgradeService) loadLatestFromGithub() (dto.UpgradeInfo, error) {
var info dto.UpgradeInfo
client := github.NewClient(nil)
ctx, cancle := context.WithTimeout(context.Background(), 3*time.Second)
defer cancle()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
stats, res, err := client.Repositories.GetLatestRelease(ctx, "wanghe-fit2cloud", "1Panel")
if res.StatusCode != 200 || err != nil {
return info, fmt.Errorf("load upgrade info from github failed, err: %v", err)
@ -198,8 +198,8 @@ func (u *UpgradeService) loadLatestFromGithub() (dto.UpgradeInfo, error) {
func (u *UpgradeService) loadLatestFromGitee() (dto.UpgradeInfo, error) {
var info dto.UpgradeInfo
client := gitee.NewAPIClient(gitee.NewConfiguration())
ctx, cancle := context.WithTimeout(context.Background(), 3*time.Second)
defer cancle()
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
stats, res, err := client.RepositoriesApi.GetV5ReposOwnerRepoReleasesLatest(ctx, "wanghe-fit2cloud", "1Panel", &gitee.GetV5ReposOwnerRepoReleasesLatestOpts{})
if res.StatusCode != 200 || err != nil {
return info, fmt.Errorf("load upgrade info from gitee failed, err: %v", err)

View File

@ -1,12 +1,14 @@
package configs
type System struct {
Port string `mapstructure:"port"`
DbFile string `mapstructure:"db_file"`
DbPath string `mapstructure:"db_path"`
LogPath string `mapstructure:"log_path"`
DataDir string `mapstructure:"data_dir"`
Cache string `mapstructure:"cache"`
Backup string `mapstructure:"backup"`
AppOss string `mapstructure:"app_oss"`
Port string `mapstructure:"port"`
DbFile string `mapstructure:"db_file"`
DbPath string `mapstructure:"db_path"`
LogPath string `mapstructure:"log_path"`
DataDir string `mapstructure:"data_dir"`
Cache string `mapstructure:"cache"`
Backup string `mapstructure:"backup"`
AppOss string `mapstructure:"app_oss"`
AppRepoOwner string `mapstructure:"app_repo_owner"`
AppRepoName string `mapstructure:"app_repo_name"`
}

View File

@ -32,6 +32,7 @@ var (
ErrTokenParse = errors.New("ErrTokenParse")
ErrPageGenerate = errors.New("generate page info failed")
ErrRepoNotValid = "ErrRepoNotValid"
)
// api

View File

@ -11,7 +11,7 @@ ErrNotLogin: "User is not Login: {{ .detail }}"
ErrNotSafety: "The login status of the current user is unsafe: {{ .detail }}"
ErrPasswordExpired: "The current password has expired: {{ .detail }}"
ErrNotSupportType: "The system does not support the current type: {{ .detail }}"
ErrRepoNotValid: "Remote repository verification failed"
#common
ErrNameIsExist: "Name is already exist"

View File

@ -11,7 +11,7 @@ ErrNotLogin: "用户未登录: {{ .detail }}"
ErrNotSafety: "当前用户登录状态不安全: {{ .detail }}"
ErrPasswordExpired: "当前密码已过期: {{ .detail }}"
ErrNotSupportType: "系统暂不支持当前类型: {{ .detail }}"
ErrRepoNotValid: "远程仓库校验失败!"
#common
ErrNameIsExist: "名称已存在"

View File

@ -139,6 +139,9 @@ var AddTableSetting = &gormigrate.Migration{
if err := tx.Create(&model.Setting{Key: "SystemStatus", Value: "Free"}).Error; err != nil {
return err
}
if err := tx.Create(&model.Setting{Key: "AppStoreVersion", Value: "0"}).Error; err != nil {
return err
}
return nil
},
}

View File

@ -23,7 +23,7 @@ func Init() {
v.SetConfigType("yaml")
if fileOp.Stat("/opt/1panel/conf/app.yaml") {
v.SetConfigName("app")
v.AddConfigPath(path.Join("/opt/1pane/conf"))
v.AddConfigPath(path.Join("/opt/1panel/conf"))
if err := v.ReadInConfig(); err != nil {
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}

79
backend/utils/git/git.go Normal file
View File

@ -0,0 +1,79 @@
package git
import (
"context"
"crypto/tls"
"errors"
"fmt"
"gitee.com/openeuler/go-gitee/gitee"
"github.com/google/go-github/github"
"net/http"
"time"
)
type RepoInfo struct {
RepoType string
Version string
ReleaseNote string
CreatedAt string
DownloadPath string
}
var gitRepoTypes = []string{"gitee", "github"}
func CheckAndGetInfo(owner, repoName string) (*RepoInfo, error) {
for _, repoType := range gitRepoTypes {
url := fmt.Sprintf("https://%s.com/%s/%s", repoType, owner, repoName)
if checkValid(url) {
res, err := getLatestRepoInfo(repoType, owner, repoName)
if err == nil {
return res, nil
}
}
}
return nil, errors.New("remote repo get failed")
}
func checkValid(addr string) bool {
timeout := 2 * time.Second
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := http.Client{
Transport: tr,
Timeout: timeout,
}
if _, err := client.Get(addr); err != nil {
return false
}
return true
}
func getLatestRepoInfo(repoType, owner, repoName string) (*RepoInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
var repoInfo RepoInfo
repoInfo.RepoType = repoType
if repoType == "gitee" {
client := gitee.NewAPIClient(gitee.NewConfiguration())
stats, res, err := client.RepositoriesApi.GetV5ReposOwnerRepoReleasesLatest(ctx, owner, repoName, &gitee.GetV5ReposOwnerRepoReleasesLatestOpts{})
if res.StatusCode != 200 || err != nil {
return nil, err
}
repoInfo.Version = stats.Name
repoInfo.ReleaseNote = stats.Body
repoInfo.CreatedAt = stats.CreatedAt.Format("2006-01-02 15:04:05")
repoInfo.DownloadPath = fmt.Sprintf("https://gitee.com/%s/%s/releases/download/%s/", owner, repoName, repoInfo.Version)
} else {
client := github.NewClient(nil)
stats, res, err := client.Repositories.GetLatestRelease(ctx, owner, repoName)
if res.StatusCode != 200 || err != nil {
return nil, err
}
repoInfo.Version = *stats.Name
repoInfo.ReleaseNote = *stats.Body
repoInfo.CreatedAt = stats.PublishedAt.Add(8 * time.Hour).Format("2006-01-02 15:04:05")
repoInfo.DownloadPath = fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/", owner, repoName, repoInfo.Version)
}
return &repoInfo, nil
}

View File

@ -1,6 +1,8 @@
system:
db_file: 1Panel.db
app_oss: "https://1panel.oss-cn-hangzhou.aliyuncs.com"
app_repo_owner: "1Panel-dev"
app_repo_name: 'appstore'
log:
level: debug