feat(install): Automatically complete installation based on environment variable.

This commit is contained in:
LinkinStars 2023-02-13 17:07:28 +08:00
parent 1a5cdba578
commit 7380c93eb4
4 changed files with 142 additions and 2 deletions

4
go.mod
View File

@ -38,6 +38,7 @@ require (
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a
github.com/swaggo/gin-swagger v1.5.3
github.com/swaggo/swag v1.8.7
github.com/tidwall/gjson v1.14.4
github.com/yuin/goldmark v1.4.13
golang.org/x/crypto v0.1.0
golang.org/x/net v0.1.0
@ -109,6 +110,8 @@ require (
github.com/spf13/viper v1.13.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
@ -139,4 +142,5 @@ require (
// github action runner Sometimes it will time out.
replace gitee.com/travelliu/dm v1.8.11192 => github.com/aichy126/dm v1.8.11192
replace modernc.org/z v1.2.19 => github.com/aichy126/modernc.org_z v1.2.19

10
go.sum
View File

@ -64,6 +64,8 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
github.com/aichy126/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
github.com/aichy126/modernc.org_z v1.2.19 h1:g4KvQojkFWBJk47OGvKzuudTr5mRF7jORSwobYyc2Sc=
github.com/aichy126/modernc.org_z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -678,6 +680,12 @@ github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9e
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
@ -1287,8 +1295,6 @@ modernc.org/tcl v1.8.13 h1:V0sTNBw0Re86PvXZxuCub3oO9WrSTqALgrwNZNvLFGw=
modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.2.19 h1:BGyRFWhDVn5LFS5OcX4Yd/MlpRTOc7hOPTdcIpCiUao=
modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View File

@ -0,0 +1,125 @@
package install
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"os"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
type Env struct {
AutoInstall string `json:"auto_install"`
DbType string `json:"db_type"`
DbUsername string `json:"db_username"`
DbPassword string `json:"db_password"`
DbHost string `json:"db_host"`
DbName string `json:"db_name"`
DbFile string `json:"db_file"`
Language string `json:"lang"`
SiteName string `json:"site_name"`
SiteURL string `json:"site_url"`
ContactEmail string `json:"contact_email"`
AdminName string `json:"name"`
AdminPassword string `json:"password"`
AdminEmail string `json:"email"`
}
func TryToInstallByEnv() (installByEnv bool, err error) {
env := loadEnv()
if len(env.AutoInstall) == 0 {
return false, nil
}
fmt.Println("[auto-install] try to install by environment variable")
return true, initByEnv(env)
}
func loadEnv() (env *Env) {
return &Env{
AutoInstall: os.Getenv("AUTO_INSTALL"),
DbType: os.Getenv("DB_TYPE"),
DbUsername: os.Getenv("DB_USERNAME"),
DbPassword: os.Getenv("DB_PASSWORD"),
DbHost: os.Getenv("DB_HOST"),
DbName: os.Getenv("DB_NAME"),
DbFile: os.Getenv("DB_FILE"),
Language: os.Getenv("LANGUAGE"),
SiteName: os.Getenv("SITE_NAME"),
SiteURL: os.Getenv("SITE_URL"),
ContactEmail: os.Getenv("CONTACT_EMAIL"),
AdminName: os.Getenv("ADMIN_NAME"),
AdminPassword: os.Getenv("ADMIN_PASSWORD"),
AdminEmail: os.Getenv("ADMIN_EMAIL"),
}
}
func initByEnv(env *Env) (err error) {
gin.SetMode(gin.TestMode)
if err = dbCheck(env); err != nil {
return err
}
if err = initConfigAndDb(env); err != nil {
return err
}
if err = initBaseInfo(env); err != nil {
return err
}
return nil
}
func dbCheck(env *Env) (err error) {
req := &CheckDatabaseReq{
DbType: env.DbType,
DbUsername: env.DbUsername,
DbPassword: env.DbPassword,
DbHost: env.DbHost,
DbName: env.DbName,
DbFile: env.DbFile,
}
return requestAPI(req, "POST", "/installation/db/check", CheckDatabase)
}
func initConfigAndDb(env *Env) (err error) {
req := &CheckDatabaseReq{
DbType: env.DbType,
DbUsername: env.DbUsername,
DbPassword: env.DbPassword,
DbHost: env.DbHost,
DbName: env.DbName,
DbFile: env.DbFile,
}
return requestAPI(req, "POST", "/installation/init", InitEnvironment)
}
func initBaseInfo(env *Env) (err error) {
req := &InitBaseInfoReq{
Language: env.Language,
SiteName: env.SiteName,
SiteURL: env.SiteURL,
ContactEmail: env.ContactEmail,
AdminName: env.AdminName,
AdminPassword: env.AdminPassword,
AdminEmail: env.AdminEmail,
}
return requestAPI(req, "POST", "/installation/base-info", InitBaseInfo)
}
func requestAPI(req interface{}, method, url string, handlerFunc gin.HandlerFunc) error {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
body, _ := json.Marshal(req)
c.Request, _ = http.NewRequest(method, url, bytes.NewBuffer(body))
if method == "POST" {
c.Request.Header.Set("Content-Type", "application/json")
}
handlerFunc(c)
if w.Code != http.StatusOK {
return fmt.Errorf(gjson.Get(w.Body.String(), "msg").String())
}
return nil
}

View File

@ -21,6 +21,11 @@ func Run(configPath string) {
panic(err)
}
// try to install by env
if installByEnv, err := TryToInstallByEnv(); installByEnv && err != nil {
fmt.Printf("[auto-install] try to init by env fail: %v\n", err)
}
installServer := NewInstallHTTPServer()
if len(port) == 0 {
port = "80"