mirror of
https://github.com/nezhahq/nezha.git
synced 2025-01-22 12:48:14 -05:00
Refactor: Load UserTemplates from embedded yaml file (#575)
* Refactor: Load UserTemplates from embedded yaml file * feat: add version field to UserTemplates * refactor: use shell script to fetch frontends * chore: add *-dist to .gitignore * refactor: rename to FrontendTemplates BREAKING CHANGE: This commit changes the `user_templates` filed in the communication json between backend and the admin-frontend. Keep user config.yml `user_template` filed.
This commit is contained in:
parent
96cbec9dd3
commit
8f8a30c02c
45
.github/workflows/release.yml
vendored
45
.github/workflows/release.yml
vendored
@ -25,49 +25,18 @@ jobs:
|
|||||||
container:
|
container:
|
||||||
image: goreleaser/goreleaser-cross:v1.23
|
image: goreleaser/goreleaser-cross:v1.23
|
||||||
steps:
|
steps:
|
||||||
|
- run: |
|
||||||
|
apt update && apt install unzip curl -y
|
||||||
|
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq
|
||||||
|
chmod +x /usr/bin/yq
|
||||||
|
|
||||||
- run: git config --global --add safe.directory /__w/nezha/nezha
|
- run: git config --global --add safe.directory /__w/nezha/nezha
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: clean cache
|
- name: Prepare frontends' dists
|
||||||
run: |
|
run: |
|
||||||
rm -rf cmd/dashboard/*-dist
|
chmod +x ./script/fetch-frontends.sh && ./script/fetch-frontends.sh
|
||||||
|
|
||||||
- uses: robinraju/release-downloader@v1
|
|
||||||
with:
|
|
||||||
repository: nezhahq/admin-frontend
|
|
||||||
tag: v1.1.1
|
|
||||||
fileName: dist.zip
|
|
||||||
latest: true
|
|
||||||
extract: true
|
|
||||||
|
|
||||||
- name: prepare admin-frontend dists
|
|
||||||
run: |
|
|
||||||
mv dist cmd/dashboard/admin-dist
|
|
||||||
|
|
||||||
- uses: robinraju/release-downloader@v1
|
|
||||||
with:
|
|
||||||
repository: nezhahq/user-frontend
|
|
||||||
tag: v1.1.1
|
|
||||||
fileName: dist.zip
|
|
||||||
latest: true
|
|
||||||
extract: true
|
|
||||||
|
|
||||||
- name: prepare admin-frontend dists
|
|
||||||
run: |
|
|
||||||
mv dist cmd/dashboard/user-dist
|
|
||||||
|
|
||||||
- uses: robinraju/release-downloader@v1
|
|
||||||
with:
|
|
||||||
repository: hi2shark/nazhua
|
|
||||||
tag: v0.4.9
|
|
||||||
fileName: dist.zip
|
|
||||||
latest: true
|
|
||||||
extract: true
|
|
||||||
|
|
||||||
- name: prepare nazhua-frontend dists
|
|
||||||
run: |
|
|
||||||
mv dist cmd/dashboard/nazhua-dist
|
|
||||||
|
|
||||||
- name: Fetch IPInfo GeoIP Database
|
- name: Fetch IPInfo GeoIP Database
|
||||||
env:
|
env:
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -17,8 +17,7 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/cmd/dashboard/data
|
/cmd/dashboard/data
|
||||||
/cmd/dashboard/main
|
/cmd/dashboard/main
|
||||||
/cmd/dashboard/admin-dist/*
|
/cmd/dashboard/*-dist
|
||||||
/cmd/dashboard/user-dist/*
|
|
||||||
!/cmd/dashboard/admin-dist/.gitkeep
|
!/cmd/dashboard/admin-dist/.gitkeep
|
||||||
!/cmd/dashboard/user-dist/.gitkeep
|
!/cmd/dashboard/user-dist/.gitkeep
|
||||||
/config.yml
|
/config.yml
|
||||||
|
@ -25,7 +25,7 @@ func listConfig(c *gin.Context) (model.SettingResponse, error) {
|
|||||||
conf := model.SettingResponse{
|
conf := model.SettingResponse{
|
||||||
Config: *singleton.Conf,
|
Config: *singleton.Conf,
|
||||||
Version: singleton.Version,
|
Version: singleton.Version,
|
||||||
UserTemplates: singleton.UserTemplates,
|
FrontendTemplates: singleton.FrontendTemplates,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !authorized {
|
if !authorized {
|
||||||
@ -59,8 +59,8 @@ func updateConfig(c *gin.Context) (any, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var userTemplateValid bool
|
var userTemplateValid bool
|
||||||
for _, v := range singleton.UserTemplates {
|
for _, v := range singleton.FrontendTemplates {
|
||||||
if v.Path == sf.UserTemplate {
|
if v.Path == sf.UserTemplate && sf.UserTemplate != "admin-dist" {
|
||||||
userTemplateValid = true
|
userTemplateValid = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 初始化 dao 包
|
// 初始化 dao 包
|
||||||
|
singleton.InitFrontendTemplates()
|
||||||
singleton.InitConfigFromPath(dashboardCliParam.ConfigFile)
|
singleton.InitConfigFromPath(dashboardCliParam.ConfigFile)
|
||||||
singleton.InitTimezoneAndCache()
|
singleton.InitTimezoneAndCache()
|
||||||
singleton.InitDBFromPath(dashboardCliParam.DatebaseLocation)
|
singleton.InitDBFromPath(dashboardCliParam.DatebaseLocation)
|
||||||
|
@ -56,7 +56,7 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read 读取配置文件并应用
|
// Read 读取配置文件并应用
|
||||||
func (c *Config) Read(path string, userTemplates []UserTemplate) error {
|
func (c *Config) Read(path string, frontendTemplates []FrontendTemplate) error {
|
||||||
c.k = koanf.New(".")
|
c.k = koanf.New(".")
|
||||||
c.filePath = path
|
c.filePath = path
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ func (c *Config) Read(path string, userTemplates []UserTemplate) error {
|
|||||||
c.Location = "Asia/Shanghai"
|
c.Location = "Asia/Shanghai"
|
||||||
}
|
}
|
||||||
var userTemplateValid bool
|
var userTemplateValid bool
|
||||||
for _, v := range userTemplates {
|
for _, v := range frontendTemplates {
|
||||||
if v.Path == c.UserTemplate {
|
if v.Path == c.UserTemplate && c.UserTemplate != "admin-dist" {
|
||||||
userTemplateValid = true
|
userTemplateValid = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,19 @@ type SettingForm struct {
|
|||||||
EnablePlainIPInNotification bool `json:"enable_plain_ip_in_notification,omitempty" validate:"optional"`
|
EnablePlainIPInNotification bool `json:"enable_plain_ip_in_notification,omitempty" validate:"optional"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserTemplate struct {
|
type FrontendTemplate struct {
|
||||||
Path string `json:"path,omitempty"`
|
Path string `json:"path,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Repository string `json:"repository,omitempty"`
|
Repository string `json:"repository,omitempty"`
|
||||||
Author string `json:"author,omitempty"`
|
Author string `json:"author,omitempty"`
|
||||||
Community bool `json:"community,omitempty"`
|
Community bool `json:"community,omitempty"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
IsAdmin string `json:"is_admin,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingResponse struct {
|
type SettingResponse struct {
|
||||||
Config
|
Config
|
||||||
|
|
||||||
Version string `json:"version,omitempty"`
|
Version string `json:"version,omitempty"`
|
||||||
UserTemplates []UserTemplate `json:"user_templates,omitempty"`
|
FrontendTemplates []FrontendTemplate `json:"frontend_templates,omitempty"`
|
||||||
}
|
}
|
||||||
|
40
script/fetch-frontends.sh
Executable file
40
script/fetch-frontends.sh
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")/..")"
|
||||||
|
TEMPLATES_FILE="$ROOT_DIR/service/singleton/frontend-templates.yaml"
|
||||||
|
|
||||||
|
download_and_extract() {
|
||||||
|
local repository="$1"
|
||||||
|
local version="$2"
|
||||||
|
local targetDir="$3"
|
||||||
|
local TMP_DIR
|
||||||
|
|
||||||
|
TMP_DIR="$(mktemp -d)"
|
||||||
|
|
||||||
|
echo "Downloading from repository: $repository, version: $version"
|
||||||
|
|
||||||
|
pushd "$TMP_DIR" || exit
|
||||||
|
|
||||||
|
curl -L -o "dist.zip" "$repository/releases/download/$version/dist.zip"
|
||||||
|
|
||||||
|
[ -e "$targetDir" ] && rm -r "$targetDir"
|
||||||
|
unzip -q dist.zip
|
||||||
|
mv dist "$targetDir"
|
||||||
|
|
||||||
|
rm "dist.zip"
|
||||||
|
popd || exit
|
||||||
|
}
|
||||||
|
|
||||||
|
count=$(yq eval '. | length' "$TEMPLATES_FILE")
|
||||||
|
|
||||||
|
for i in $(seq 0 $(("$count"-1))); do
|
||||||
|
path=$(yq -r ".[$i].path" "$TEMPLATES_FILE")
|
||||||
|
repository=$(yq -r ".[$i].repository" "$TEMPLATES_FILE")
|
||||||
|
version=$(yq -r ".[$i].version" "$TEMPLATES_FILE")
|
||||||
|
|
||||||
|
if [[ -n $path && -n $repository && -n $version ]]; then
|
||||||
|
download_and_extract "$repository" "$version" "$ROOT_DIR/cmd/dashboard/$path"
|
||||||
|
fi
|
||||||
|
done
|
17
service/singleton/frontend-templates.yaml
Normal file
17
service/singleton/frontend-templates.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
- path: "admin-dist"
|
||||||
|
name: "OfficialAdmin"
|
||||||
|
repository: "https://github.com/nezhahq/admin-frontend"
|
||||||
|
author: "nezhahq"
|
||||||
|
version: "v1.1.1"
|
||||||
|
isadmin: true
|
||||||
|
- path: "user-dist"
|
||||||
|
name: "Official"
|
||||||
|
repository: "https://github.com/hamster1963/nezha-dash-v1"
|
||||||
|
author: "hamster1963"
|
||||||
|
version: "v1.2.5"
|
||||||
|
- path: "nazhua-dist"
|
||||||
|
name: "Nazhua"
|
||||||
|
repository: "https://github.com/hi2shark/nazhua"
|
||||||
|
author: "hi2hi"
|
||||||
|
version: "v0.4.10"
|
||||||
|
community: true
|
@ -1,10 +1,12 @@
|
|||||||
package singleton
|
package singleton
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "embed"
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
"gorm.io/driver/sqlite"
|
"gorm.io/driver/sqlite"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
@ -19,23 +21,13 @@ var (
|
|||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
DB *gorm.DB
|
DB *gorm.DB
|
||||||
Loc *time.Location
|
Loc *time.Location
|
||||||
UserTemplates = []model.UserTemplate{
|
FrontendTemplates []model.FrontendTemplate
|
||||||
{
|
|
||||||
Path: "user-dist",
|
|
||||||
Name: "Official",
|
|
||||||
Repository: "https://github.com/hamster1963/nezha-dash",
|
|
||||||
Author: "hamster1963",
|
|
||||||
}, {
|
|
||||||
Path: "nazhua-dist",
|
|
||||||
Name: "Nazhua",
|
|
||||||
Repository: "https://github.com/hi2shark/nazhua",
|
|
||||||
Author: "hi2hi",
|
|
||||||
Community: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
DashboardBootTime = uint64(time.Now().Unix())
|
DashboardBootTime = uint64(time.Now().Unix())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed frontend-templates.yaml
|
||||||
|
var frontendTemplatesYAML []byte
|
||||||
|
|
||||||
func InitTimezoneAndCache() {
|
func InitTimezoneAndCache() {
|
||||||
var err error
|
var err error
|
||||||
Loc, err = time.LoadLocation(Conf.Location)
|
Loc, err = time.LoadLocation(Conf.Location)
|
||||||
@ -56,10 +48,18 @@ func LoadSingleton() {
|
|||||||
initDDNS()
|
initDDNS()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitFrontendTemplates 从内置文件中加载FrontendTemplates
|
||||||
|
func InitFrontendTemplates() {
|
||||||
|
err := yaml.Unmarshal(frontendTemplatesYAML, &FrontendTemplates)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// InitConfigFromPath 从给出的文件路径中加载配置
|
// InitConfigFromPath 从给出的文件路径中加载配置
|
||||||
func InitConfigFromPath(path string) {
|
func InitConfigFromPath(path string) {
|
||||||
Conf = &model.Config{}
|
Conf = &model.Config{}
|
||||||
err := Conf.Read(path, UserTemplates)
|
err := Conf.Read(path, FrontendTemplates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user