server_v1.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package settings
  2. import (
  3. "github.com/elliotchance/orderedmap/v3"
  4. "github.com/spf13/cast"
  5. "github.com/uozi-tech/cosy/logger"
  6. "github.com/uozi-tech/cosy/settings"
  7. "gopkg.in/ini.v1"
  8. "os"
  9. "reflect"
  10. )
  11. // Note: This section will be deprecated in the future version.
  12. type serverV1 struct {
  13. HttpHost string `json:"http_host" protected:"true"`
  14. HttpPort string `json:"http_port" protected:"true"`
  15. RunMode string `json:"run_mode" protected:"true"`
  16. JwtSecret string `json:"jwt_secret" protected:"true"`
  17. NodeSecret string `json:"node_secret" protected:"true"`
  18. HTTPChallengePort string `json:"http_challenge_port"`
  19. Email string `json:"email" protected:"true"`
  20. Database string `json:"database" protected:"true"`
  21. StartCmd string `json:"start_cmd" protected:"true"`
  22. CADir string `json:"ca_dir"`
  23. Demo bool `json:"demo" protected:"true"`
  24. PageSize int `json:"page_size" protected:"true"`
  25. GithubProxy string `json:"github_proxy"`
  26. CertRenewalInterval int `json:"cert_renewal_interval"`
  27. RecursiveNameservers []string `json:"recursive_nameservers"`
  28. SkipInstallation bool `json:"skip_installation" protected:"true"`
  29. InsecureSkipVerify bool `json:"insecure_skip_verify" protected:"true"`
  30. Name string `json:"name"`
  31. }
  32. type settingsV2 struct {
  33. // Cosy
  34. App settings.App
  35. Server settings.Server
  36. DataBase Database
  37. // Nginx UI
  38. Auth Auth
  39. Casdoor Casdoor
  40. Cert Cert
  41. Cluster Cluster
  42. Crypto Crypto
  43. Http HTTP
  44. Logrotate Logrotate
  45. Nginx Nginx
  46. Node Node
  47. OpenAI OpenAI
  48. Terminal Terminal
  49. WebAuthn WebAuthn
  50. }
  51. func (v1 *serverV1) migrateToV2() (v2 *settingsV2) {
  52. v2 = &settingsV2{}
  53. v2.Server.Host = v1.HttpHost
  54. v2.Server.Port = cast.ToUint(v1.HttpPort)
  55. v2.Server.RunMode = v1.RunMode
  56. v2.App.JwtSecret = v1.JwtSecret
  57. v2.App.PageSize = v1.PageSize
  58. v2.Node.Secret = v1.NodeSecret
  59. v2.Cert.HTTPChallengePort = v1.HTTPChallengePort
  60. v2.Cert.Email = v1.Email
  61. v2.DataBase.Name = v1.Database
  62. v2.Terminal.StartCmd = v1.StartCmd
  63. v2.Cert.CADir = v1.CADir
  64. v2.Node.Demo = v1.Demo
  65. v2.Http.GithubProxy = v1.GithubProxy
  66. v2.Cert.RenewalInterval = v1.CertRenewalInterval
  67. v2.Cert.RecursiveNameservers = v1.RecursiveNameservers
  68. v2.Node.SkipInstallation = v1.SkipInstallation
  69. v2.Http.InsecureSkipVerify = v1.InsecureSkipVerify
  70. v2.Node.Name = v1.Name
  71. if v1.Database == "" {
  72. v2.DataBase.Name = "database"
  73. }
  74. return
  75. }
  76. func isZeroValue(v reflect.Value) bool {
  77. zeroValue := reflect.Zero(v.Type()).Interface()
  78. return reflect.DeepEqual(v.Interface(), zeroValue)
  79. }
  80. func mergeStructs(src, dst interface{}) {
  81. dstVal := reflect.ValueOf(dst).Elem()
  82. srcVal := reflect.ValueOf(src).Elem()
  83. for i := 0; i < dstVal.NumField(); i++ {
  84. dstField := dstVal.Field(i)
  85. srcField := srcVal.Field(i)
  86. if isZeroValue(dstField) {
  87. dstField.Set(srcField)
  88. }
  89. }
  90. return
  91. }
  92. func migrate(confPath string) {
  93. logger.Init("debug")
  94. Conf, err := ini.LoadSources(ini.LoadOptions{
  95. Loose: true,
  96. AllowShadows: true,
  97. }, confPath)
  98. if err != nil {
  99. logger.Fatalf("setting.init, fail to parse 'app.ini': %v", err)
  100. }
  101. var v1 = &serverV1{}
  102. err = Conf.Section("server").MapTo(v1)
  103. if err != nil {
  104. logger.Error(err)
  105. return
  106. }
  107. // If settings is v1, jwt_secret is not empty.
  108. if v1.JwtSecret == "" {
  109. return
  110. }
  111. // Cosy
  112. app := &settings.App{}
  113. server := &settings.Server{}
  114. database := &Database{}
  115. // Nginx UI
  116. auth := &Auth{}
  117. casdoor := &Casdoor{}
  118. cert := &Cert{}
  119. cluster := &Cluster{}
  120. crypto := &Crypto{}
  121. http := &HTTP{}
  122. logrotate := &Logrotate{}
  123. nginx := &Nginx{}
  124. node := &Node{}
  125. openai := &OpenAI{}
  126. terminal := &Terminal{}
  127. webauthn := &WebAuthn{}
  128. var migrated = orderedmap.NewOrderedMap[string, any]()
  129. migrated.Set("app", app)
  130. migrated.Set("server", server)
  131. migrated.Set("database", database)
  132. migrated.Set("auth", auth)
  133. migrated.Set("casdoor", casdoor)
  134. migrated.Set("cert", cert)
  135. migrated.Set("cluster", cluster)
  136. migrated.Set("crypto", crypto)
  137. migrated.Set("http", http)
  138. migrated.Set("logrotate", logrotate)
  139. migrated.Set("nginx", nginx)
  140. migrated.Set("node", node)
  141. migrated.Set("openai", openai)
  142. migrated.Set("terminal", terminal)
  143. migrated.Set("webauthn", webauthn)
  144. for name, ptr := range migrated.AllFromFront() {
  145. err = Conf.Section(name).MapTo(ptr)
  146. if err != nil {
  147. logger.Error("migrate.MapTo %s err: %v", name, err)
  148. }
  149. }
  150. v2 := v1.migrateToV2()
  151. mergeStructs(&v2.App, app)
  152. mergeStructs(&v2.Server, server)
  153. mergeStructs(&v2.DataBase, database)
  154. mergeStructs(&v2.Auth, auth)
  155. mergeStructs(&v2.Casdoor, casdoor)
  156. mergeStructs(&v2.Cert, cert)
  157. mergeStructs(&v2.Cluster, cluster)
  158. mergeStructs(&v2.Crypto, crypto)
  159. mergeStructs(&v2.Http, http)
  160. mergeStructs(&v2.Logrotate, logrotate)
  161. mergeStructs(&v2.Nginx, nginx)
  162. mergeStructs(&v2.Node, node)
  163. mergeStructs(&v2.OpenAI, openai)
  164. mergeStructs(&v2.Terminal, terminal)
  165. mergeStructs(&v2.WebAuthn, webauthn)
  166. Conf = ini.Empty()
  167. for section, ptr := range migrated.AllFromFront() {
  168. err = Conf.Section(section).ReflectFrom(ptr)
  169. if err != nil {
  170. logger.Fatalf("migrate.ReflectFrom %s err: %v", section, err)
  171. }
  172. }
  173. err = Conf.SaveTo(confPath)
  174. if err != nil {
  175. logger.Fatalf("Fail to save the migrated settings: %v", err)
  176. return
  177. }
  178. migrateEnv()
  179. }
  180. func migrateEnv() {
  181. deprecated := orderedmap.NewOrderedMap[string, string]()
  182. deprecated.Set("SERVER_HTTP_HOST", "SERVER_HOST")
  183. deprecated.Set("SERVER_HTTP_PORT", "SERVER_PORT")
  184. deprecated.Set("SERVER_JWT_SECRET", "APP_JWT_SECRET")
  185. deprecated.Set("SERVER_NODE_SECRET", "NODE_SECRET")
  186. deprecated.Set("SERVER_HTTP_CHALLENGE_PORT", "CERT_HTTP_CHALLENGE_PORT")
  187. deprecated.Set("SERVER_EMAIL", "CERT_EMAIL")
  188. deprecated.Set("SERVER_DATABASE", "DATABASE_NAME")
  189. deprecated.Set("SERVER_START_CMD", "TERMINAL_START_CMD")
  190. deprecated.Set("SERVER_CA_DIR", "CERT_CA_DIR")
  191. deprecated.Set("SERVER_DEMO", "NODE_DEMO")
  192. deprecated.Set("SERVER_PAGE_SIZE", "APP_PAGE_SIZE")
  193. deprecated.Set("SERVER_GITHUB_PROXY", "HTTP_GITHUB_PROXY")
  194. deprecated.Set("SERVER_CERT_RENEWAL_INTERVAL", "CERT_RENEWAL_INTERVAL")
  195. deprecated.Set("SERVER_RECURSIVE_NAMESERVERS", "CERT_RECURSIVE_NAMESERVERS")
  196. deprecated.Set("SERVER_SKIP_INSTALLATION", "NODE_SKIP_INSTALLATION")
  197. deprecated.Set("SERVER_NAME", "NODE_NAME")
  198. for d, n := range deprecated.AllFromFront() {
  199. oldValue := os.Getenv(EnvPrefix + d)
  200. if oldValue != "" {
  201. _ = os.Setenv(EnvPrefix+n, oldValue)
  202. logger.Warnf("The environment variable %s is deprecated and has been automatically migrated to %s. "+
  203. "Please update your environment variables as automatic migration may be removed in the future.",
  204. EnvPrefix+d, EnvPrefix+n)
  205. }
  206. }
  207. }