-
Notifications
You must be signed in to change notification settings - Fork 0
/
runtime.go
158 lines (129 loc) · 3.6 KB
/
runtime.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package runtime
import (
"database/sql"
"errors"
"fmt"
"github.com/Luna-CY/v2ray-helper/common/configurator"
"github.com/Luna-CY/v2ray-helper/staticfile/migrationstatic"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/sqlite3"
_ "github.com/golang-migrate/migrate/v4/source/file"
"io/ioutil"
"os"
"path/filepath"
)
var rootPath = ""
// InitRuntime 初始化运行环境
func InitRuntime(path string) error {
if err := os.MkdirAll(filepath.Join(path, "config"), 0755); nil != err {
return errors.New(fmt.Sprintf("初始化运行环境失败: %v", err))
}
mainConfigPath := filepath.Join(path, "config", "main.config.yaml")
mainConfigExists, err := fileExists(mainConfigPath)
if nil != err {
return err
}
if !mainConfigExists {
if err := configurator.GetDefaultMailConfig().Save(mainConfigPath); nil != err {
return err
}
}
dbPath := filepath.Join(path, "main.db")
dbExists, err := fileExists(dbPath)
if nil != err {
return err
}
if !dbExists {
if err := Migrate(dbPath, "1.0.0"); nil != err {
return err
}
}
rootPath = path
return nil
}
// Migrate 数据库迁移
func Migrate(db, version string) error {
td, err := ioutil.TempDir("", "")
if nil != err {
return errors.New(fmt.Sprintf("无法创建临时目录: %v", err))
}
defer func() {
_ = os.RemoveAll(td)
}()
for _, name := range migrationstatic.AssetNames() {
if err := os.MkdirAll(filepath.Join(td, filepath.Dir(name)), 0755); nil != err {
return errors.New(fmt.Sprintf("无法创建migration: %v", err))
}
tf, err := os.OpenFile(filepath.Join(td, name), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if nil != err {
return errors.New(fmt.Sprintf("无法创建migration: %v", err))
}
if _, err := tf.Write(migrationstatic.MustAsset(name)); nil != err {
return errors.New(fmt.Sprintf("无法创建migration: %v", err))
}
tf.Close()
}
sqlDb, err := sql.Open("sqlite3", db)
if nil != err {
return errors.New(fmt.Sprintf("无法打开数据库驱动: %v\n", err))
}
defer sqlDb.Close()
driver, err := sqlite3.WithInstance(sqlDb, &sqlite3.Config{})
if nil != err {
return errors.New(fmt.Sprintf("无法打开Migrate驱动: %v\n", err))
}
defer driver.Close()
m, err := migrate.NewWithDatabaseInstance(fmt.Sprintf("file://%v/%v/%v", td, "migrations", version), "sqlite3", driver)
if nil != err {
return errors.New(fmt.Sprintf("创建Migrate失败: %v\n", err))
}
defer m.Close()
if err := m.Up(); nil != err {
if migrate.ErrNoChange != err {
return errors.New(fmt.Sprintf("执行数据库迁移失败: %v\n", err))
}
}
return nil
}
// AbsRootPath 获取项目运行绝对目录
func AbsRootPath(homeDir string) string {
if "" != homeDir {
if filepath.IsAbs(homeDir) {
return homeDir
}
if "." != homeDir {
absPath, err := filepath.Abs(homeDir)
if nil == err {
return absPath
}
}
}
// 取到执行文件所在的目录作为根目录,否则在其他目录通过文件位置运行时会找不到配置文件
executable, err := os.Executable()
if nil != err {
return ""
}
return filepath.Dir(executable)
}
// GetRootPath 获取根目录
func GetRootPath() string {
return rootPath
}
const CertDirName = "certs"
// GetCertificatePath 获取证书目录的路径
func GetCertificatePath() string {
return filepath.Join(rootPath, CertDirName)
}
func fileExists(path string) (bool, error) {
stat, err := os.Stat(path)
if nil != err {
if os.IsNotExist(err) {
return false, nil
}
return false, errors.New(fmt.Sprintf("获取文件信息失败: %v", err))
}
if stat.IsDir() {
return false, nil
}
return true, nil
}