mirror of https://gitee.com/answerdev/answer.git
feat: install configuration files and initialize basic information
This commit is contained in:
parent
23b4a44ce3
commit
9c8838a1b0
|
@ -1,6 +1,7 @@
|
|||
package conf
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -11,28 +12,28 @@ import (
|
|||
"github.com/answerdev/answer/internal/service/service_config"
|
||||
"github.com/answerdev/answer/pkg/writer"
|
||||
"github.com/segmentfault/pacman/contrib/conf/viper"
|
||||
"sigs.k8s.io/yaml"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// AllConfig all config
|
||||
type AllConfig struct {
|
||||
Debug bool `json:"debug" mapstructure:"debug"`
|
||||
Data *Data `json:"data" mapstructure:"data"`
|
||||
Server *Server `json:"server" mapstructure:"server"`
|
||||
I18n *translator.I18n `json:"i18n" mapstructure:"i18n"`
|
||||
Swaggerui *router.SwaggerConfig `json:"swaggerui" mapstructure:"swaggerui"`
|
||||
ServiceConfig *service_config.ServiceConfig `json:"service_config" mapstructure:"service_config"`
|
||||
Debug bool `json:"debug" mapstructure:"debug" yaml:"debug"`
|
||||
Server *Server `json:"server" mapstructure:"server" yaml:"server"`
|
||||
Data *Data `json:"data" mapstructure:"data" yaml:"data"`
|
||||
I18n *translator.I18n `json:"i18n" mapstructure:"i18n" yaml:"i18n"`
|
||||
ServiceConfig *service_config.ServiceConfig `json:"service_config" mapstructure:"service_config" yaml:"service_config"`
|
||||
Swaggerui *router.SwaggerConfig `json:"swaggerui" mapstructure:"swaggerui" yaml:"swaggerui"`
|
||||
}
|
||||
|
||||
// Server server config
|
||||
type Server struct {
|
||||
HTTP *server.HTTP `json:"http" mapstructure:"http"`
|
||||
HTTP *server.HTTP `json:"http" mapstructure:"http" yaml:"http"`
|
||||
}
|
||||
|
||||
// Data data config
|
||||
type Data struct {
|
||||
Database *data.Database `json:"database" mapstructure:"database"`
|
||||
Cache *data.CacheConf `json:"cache" mapstructure:"cache"`
|
||||
Database *data.Database `json:"database" mapstructure:"database" yaml:"database"`
|
||||
Cache *data.CacheConf `json:"cache" mapstructure:"cache" yaml:"cache"`
|
||||
}
|
||||
|
||||
// ReadConfig read config
|
||||
|
@ -53,9 +54,11 @@ func ReadConfig(configFilePath string) (c *AllConfig, err error) {
|
|||
|
||||
// RewriteConfig rewrite config file path
|
||||
func RewriteConfig(configFilePath string, allConfig *AllConfig) error {
|
||||
content, err := yaml.Marshal(allConfig)
|
||||
if err != nil {
|
||||
buf := bytes.Buffer{}
|
||||
enc := yaml.NewEncoder(&buf)
|
||||
enc.SetIndent(2)
|
||||
if err := enc.Encode(allConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return writer.ReplaceFile(configFilePath, string(content))
|
||||
return writer.ReplaceFile(configFilePath, buf.String())
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ package data
|
|||
|
||||
// Database database config
|
||||
type Database struct {
|
||||
Driver string `json:"driver" mapstructure:"driver"`
|
||||
Connection string `json:"connection" mapstructure:"connection"`
|
||||
ConnMaxLifeTime int `json:"conn_max_life_time" mapstructure:"conn_max_life_time"`
|
||||
MaxOpenConn int `json:"max_open_conn" mapstructure:"max_open_conn"`
|
||||
MaxIdleConn int `json:"max_idle_conn" mapstructure:"max_idle_conn"`
|
||||
Driver string `json:"driver" mapstructure:"driver" yaml:"driver"`
|
||||
Connection string `json:"connection" mapstructure:"connection" yaml:"connection"`
|
||||
ConnMaxLifeTime int `json:"conn_max_life_time" mapstructure:"conn_max_life_time" yaml:"conn_max_life_time,omitempty"`
|
||||
MaxOpenConn int `json:"max_open_conn" mapstructure:"max_open_conn" yaml:"max_open_conn,omitempty"`
|
||||
MaxIdleConn int `json:"max_idle_conn" mapstructure:"max_idle_conn" yaml:"max_idle_conn,omitempty"`
|
||||
}
|
||||
|
||||
// CacheConf cache
|
||||
type CacheConf struct {
|
||||
FilePath string `json:"file_path" mapstructure:"file_path"`
|
||||
FilePath string `json:"file_path" mapstructure:"file_path" yaml:"file_path"`
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@ package translator
|
|||
|
||||
// I18n i18n config
|
||||
type I18n struct {
|
||||
BundleDir string `json:"bundle_dir" mapstructure:"bundle_dir"`
|
||||
BundleDir string `json:"bundle_dir" mapstructure:"bundle_dir" yaml:"bundle_dir"`
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package install
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/answerdev/answer/configs"
|
||||
"github.com/answerdev/answer/internal/base/conf"
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
|
@ -15,11 +18,6 @@ import (
|
|||
"github.com/segmentfault/pacman/log"
|
||||
)
|
||||
|
||||
// 1、校验配置文件 post installation/config-file/check
|
||||
//2、校验数据库 post installation/db/check
|
||||
//3、创建配置文件和数据库 post installation/init
|
||||
//4、配置网站基本信息和超级管理员信息 post installation/base-info
|
||||
|
||||
// LangOptions get installation language options
|
||||
// @Summary get installation language options
|
||||
// @Description get installation language options
|
||||
|
@ -63,6 +61,7 @@ func CheckConfigFile(ctx *gin.Context) {
|
|||
// @Tags installation
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body install.CheckDatabaseReq true "CheckDatabaseReq"
|
||||
// @Success 200 {object} handler.RespBody{data=install.CheckConfigFileResp{}}
|
||||
// @Router /installation/db/check [post]
|
||||
func CheckDatabase(ctx *gin.Context) {
|
||||
|
@ -76,7 +75,7 @@ func CheckDatabase(ctx *gin.Context) {
|
|||
Driver: req.DbType,
|
||||
Connection: req.GetConnection(),
|
||||
}
|
||||
resp.ConnectionSuccess = cli.CheckDB(dataConf, true)
|
||||
resp.ConnectionSuccess = cli.CheckDB(dataConf, false)
|
||||
if !resp.ConnectionSuccess {
|
||||
handler.HandleResponse(ctx, errors.BadRequest(reason.DatabaseConnectionFailed), schema.ErrTypeAlert)
|
||||
return
|
||||
|
@ -90,6 +89,7 @@ func CheckDatabase(ctx *gin.Context) {
|
|||
// @Tags installation
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body install.CheckDatabaseReq true "CheckDatabaseReq"
|
||||
// @Success 200 {object} handler.RespBody{data=install.CheckConfigFileResp{}}
|
||||
// @Router /installation/init [post]
|
||||
func InitEnvironment(ctx *gin.Context) {
|
||||
|
@ -137,6 +137,7 @@ func InitEnvironment(ctx *gin.Context) {
|
|||
// @Tags installation
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param data body install.InitBaseInfoReq true "InitBaseInfoReq"
|
||||
// @Success 200 {object} handler.RespBody{data=install.CheckConfigFileResp{}}
|
||||
// @Router /installation/base-info [post]
|
||||
func InitBaseInfo(ctx *gin.Context) {
|
||||
|
@ -145,8 +146,31 @@ func InitBaseInfo(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// 修改配置文件
|
||||
// 修改管理员和对应信息
|
||||
c, err := conf.ReadConfig(confPath)
|
||||
if err != nil {
|
||||
log.Errorf("read config failed %s", err)
|
||||
handler.HandleResponse(ctx, errors.BadRequest(reason.ReadConfigFailed), nil)
|
||||
return
|
||||
}
|
||||
c.ServiceConfig.WebHost = req.SiteURL
|
||||
if err := conf.RewriteConfig(confPath, c); err != nil {
|
||||
log.Errorf("rewrite config failed %s", err)
|
||||
handler.HandleResponse(ctx, errors.BadRequest(reason.ReadConfigFailed), nil)
|
||||
return
|
||||
}
|
||||
|
||||
err = migrations.UpdateInstallInfo(c.Data.Database, req.Language, req.SiteName, req.SiteURL, req.ContactEmail,
|
||||
req.AdminName, req.AdminPassword, req.AdminEmail)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
handler.HandleResponse(ctx, errors.BadRequest(reason.InstallConfigFailed), nil)
|
||||
return
|
||||
}
|
||||
|
||||
handler.HandleResponse(ctx, nil, nil)
|
||||
go func() {
|
||||
time.Sleep(1 * time.Second)
|
||||
os.Exit(0)
|
||||
}()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/answerdev/answer/internal/base/data"
|
||||
"github.com/answerdev/answer/internal/entity"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
|
@ -55,11 +56,6 @@ func InitDB(dataConf *data.Database) (err error) {
|
|||
return fmt.Errorf("init admin user failed: %s", err)
|
||||
}
|
||||
|
||||
err = initSiteInfo(engine)
|
||||
if err != nil {
|
||||
return fmt.Errorf("init site info failed: %s", err)
|
||||
}
|
||||
|
||||
err = initConfigTable(engine)
|
||||
if err != nil {
|
||||
return fmt.Errorf("init config table: %s", err)
|
||||
|
@ -82,12 +78,67 @@ func initAdminUser(engine *xorm.Engine) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func initSiteInfo(engine *xorm.Engine) error {
|
||||
func initSiteInfo(engine *xorm.Engine, language, siteName, siteURL, contactEmail string) error {
|
||||
_, err := engine.InsertOne(&entity.SiteInfo{
|
||||
Type: "interface",
|
||||
Content: `{"logo":"","theme":"black","language":"en_US"}`,
|
||||
Content: fmt.Sprintf(`{"logo":"","theme":"black","language":%s}`, language),
|
||||
Status: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = engine.InsertOne(&entity.SiteInfo{
|
||||
Type: "general",
|
||||
Content: fmt.Sprintf(`{"name":"%s","site_url":"%s","contact_email":"%s"}`,
|
||||
siteName, siteURL, contactEmail),
|
||||
Status: 1,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func updateAdminInfo(engine *xorm.Engine, adminName, adminPassword, adminEmail string) error {
|
||||
generateFromPassword, err := bcrypt.GenerateFromPassword([]byte(adminPassword), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("")
|
||||
}
|
||||
adminPassword = string(generateFromPassword)
|
||||
|
||||
// update admin info
|
||||
_, err = engine.ID("1").Update(&entity.User{
|
||||
Username: adminName,
|
||||
Pass: adminPassword,
|
||||
EMail: adminEmail,
|
||||
DisplayName: "admin",
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("update admin user info failed: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateInstallInfo update some init data about the admin interface and admin password
|
||||
func UpdateInstallInfo(dataConf *data.Database, language string,
|
||||
siteName string,
|
||||
siteURL string,
|
||||
contactEmail string,
|
||||
adminName string,
|
||||
adminPassword string,
|
||||
adminEmail string) error {
|
||||
|
||||
engine, err := data.NewDB(false, dataConf)
|
||||
if err != nil {
|
||||
return fmt.Errorf("database connection error: %s", err)
|
||||
}
|
||||
|
||||
err = updateAdminInfo(engine, adminName, adminPassword, adminEmail)
|
||||
if err != nil {
|
||||
return fmt.Errorf("update admin info failed: %s", err)
|
||||
}
|
||||
|
||||
err = initSiteInfo(engine, language, siteName, siteURL, contactEmail)
|
||||
if err != nil {
|
||||
return fmt.Errorf("init site info failed: %s", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ package router
|
|||
|
||||
// SwaggerConfig struct describes configure for the Swagger API endpoint
|
||||
type SwaggerConfig struct {
|
||||
Show bool `json:"show"`
|
||||
Protocol string `json:"protocol"`
|
||||
Host string `json:"host"`
|
||||
Address string `json:"address"`
|
||||
Show bool `json:"show" mapstructure:"show" yaml:"show"`
|
||||
Protocol string `json:"protocol" mapstructure:"protocol" yaml:"protocol"`
|
||||
Host string `json:"host" mapstructure:"host" yaml:"host"`
|
||||
Address string `json:"address" mapstructure:"address" yaml:"address"`
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package service_config
|
||||
|
||||
type ServiceConfig struct {
|
||||
SecretKey string `json:"secret_key" mapstructure:"secret_key"`
|
||||
WebHost string `json:"web_host" mapstructure:"web_host"`
|
||||
UploadPath string `json:"upload_path" mapstructure:"upload_path"`
|
||||
SecretKey string `json:"secret_key" mapstructure:"secret_key" yaml:"secret_key"`
|
||||
WebHost string `json:"web_host" mapstructure:"web_host" yaml:"web_host"`
|
||||
UploadPath string `json:"upload_path" mapstructure:"upload_path" yaml:"upload_path"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue