/
config.go
209 lines (181 loc) · 5.82 KB
/
config.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package main
import (
"fmt"
"github.com/lolgopher/synology-filesync/protocol"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"log"
"net"
"os"
"runtime"
"strconv"
)
type Address struct {
IP string `yaml:"ip"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Path string `yaml:"path"`
}
type DB struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Database string `yaml:"database"`
}
type FileDB struct {
Filename string `yaml:"filename"`
}
type Config struct {
DownloadType string `yaml:"download_type"`
Synology *Address `yaml:"synology,omitempty"`
UploadType string `yaml:"upload_type"`
SSH *Address `yaml:"ssh,omitempty"`
DBType string `yaml:"db_type"`
YAML *FileDB `yaml:"yaml,omitempty"`
LocalPath string `yaml:"local_path"`
SpareSpace uint64 `yaml:"spare_space"`
SyncCycle int `yaml:"sync_cycle"`
DownloadWorker int `yaml:"download_worker"`
DownloadDelay int `yaml:"download_delay"`
DownloadRetryDelay int `yaml:"download_retry_delay"`
DownloadRetryCount int `yaml:"download_retry_count"`
UploadDelay int `yaml:"upload_delay"`
UploadRetryDelay int `yaml:"upload_retry_delay"`
UploadRetryCount int `yaml:"upload_retry_count"`
}
var defaultConfig = &Config{
DownloadType: "synology", // Download type(synology, skip(TBD), etc...(TBD))
Synology: &Address{
IP: "1.2.3.4", // FileStation IP address
Port: 5001, // FileStation port
Username: "admin", // FileStation account username
Password: "pass", // FileStation account password
Path: "/photo", // FileStation path to download files
},
UploadType: "ssh", // Upload type(ssh, skip(TBD), etc...(TBD))
SSH: &Address{
IP: "192.168.0.100", // SSH IP address
Port: 22, // SSH port
Username: "user", // SSH username
Password: "pass", // SSH password
Path: "/DCIM", // SSH path to download files
},
DBType: "yaml", // DB type(YAML, JSON(TBD), MySQL(TBD), etc...(TBD))
YAML: &FileDB{
Filename: "metadata.yaml", // FileDB filename
},
LocalPath: "", // Local path to save download files(os.Getwd())
SpareSpace: 1073741824, // Spare space of upload filesystem(Byte)
SyncCycle: 12, // Sync cycle(Hour)
DownloadWorker: runtime.GOMAXPROCS(0), // Number of concurrent downloads(runtime.GOMAXPROCS(0))
DownloadDelay: 10, // Download delay(Second)(TBD)
DownloadRetryDelay: 2, // Download retry delay(Second)(TBD)
DownloadRetryCount: 10, // Download retry count(TBD)
UploadDelay: 10, // Upload delay(Second)
UploadRetryDelay: 2, // Upload retry delay(Second)
UploadRetryCount: 10, // Upload retry count
}
const defaultConfigPath = "./config.yaml"
func initConfig(configPath string) (*Config, error) {
defaultConfig.LocalPath, _ = os.Getwd()
var result *Config
// 설정 파일 확인
if protocol.FileExists(configPath) {
// 파일 읽기
data, err := os.ReadFile(configPath)
if err != nil {
return nil, fmt.Errorf("fail to read %s config file: %v", configPath, err)
}
// YAML 언마샬링
if err := yaml.Unmarshal(data, &result); err != nil {
log.Printf("error to unmarshal read data: %s", string(data))
return nil, fmt.Errorf("fail to unmarshal %s config file: %v", configPath, err)
}
} else {
log.Printf("%s config file not found", configPath)
// 기본 설정 파일 생성
if !protocol.FileExists(defaultConfigPath) {
if err := makeDefaultConfig(); err != nil {
return nil, errors.Wrap(err, "fail to make default config file")
}
}
return nil, os.ErrNotExist
}
return result, verifyConfig(result)
}
func makeDefaultConfig() error {
configData, err := yaml.Marshal(defaultConfig)
if err != nil {
return errors.Wrap(err, "fail to marshal default config")
}
if err := os.WriteFile(defaultConfigPath, configData, 0644); err != nil {
return fmt.Errorf("fail to write %s file: %v", defaultConfigPath, err)
}
log.Println("make default config file")
return nil
}
func verifyConfig(config *Config) error {
// verify synology
if config.DownloadType == "synology" {
// verify ip address
if len(config.Synology.IP) == 0 {
return errors.New("synology ip address is required")
}
// verify port number
if config.Synology.Port == 0 {
return errors.New("synology port is required")
}
if _, err := net.LookupPort("tcp", strconv.Itoa(config.Synology.Port)); err != nil {
return errors.New("invalid synology port number")
}
// verify username and password
if len(config.Synology.Username) == 0 {
return errors.New("synology username is required")
}
if len(config.Synology.Password) == 0 {
return errors.New("synology password is required")
}
// verify path
if len(config.Synology.Path) == 0 {
return errors.New("filestation path is required")
}
}
// verify ssh
if config.UploadType == "ssh" {
// verify ip address
if len(config.SSH.IP) == 0 {
return errors.New("ssh ip address is required")
}
// verify port number
if config.SSH.Port == 0 {
return errors.New("ssh port is required")
}
if _, err := net.LookupPort("tcp", strconv.Itoa(config.SSH.Port)); err != nil {
return errors.New("invalid ssh port number")
}
// verify username and password
if len(config.SSH.Username) == 0 {
return errors.New("ssh username is required")
}
if len(config.SSH.Password) == 0 {
return errors.New("ssh password is required")
}
// verify path
if len(config.SSH.Path) == 0 {
return errors.New("ssh path is required")
}
}
// verify yaml
if config.DBType == "yaml" {
if len(config.YAML.Filename) == 0 {
return errors.New("filename is required")
}
}
// verify local
if len(config.LocalPath) == 0 {
return errors.New("local path is required")
}
return nil
}