Skip to content

Commit 85f6df4

Browse files
committed
Allow reading FileInfo from a dummy file instead of the file itself
The system is using a hybrid mode. This means, that if a file turns out to be an invalid json file, it will be handled "normally"
1 parent 1f0ecd9 commit 85f6df4

File tree

4 files changed

+71
-16
lines changed

4 files changed

+71
-16
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ DisallowRedirects | Disable any mirror trying to do an HTTP redirect
102102
WeightDistributionRange | Multiplier of the distance to the first mirror to find other possible mirrors in order to distribute the load
103103
DisableOnMissingFile | Disable a mirror if an advertised file on rsync/ftp appears to be missing on HTTP
104104
MaxLinkHeaders | Amount of backup mirror locations returned in HTTP headers
105+
DummyFiles | Allows reading file information from a dummy json file. This Allows saving storage on the host.
105106
Fallbacks | A list of possible mirrors to use as fallback if a request fails or if the database is unreachable. **These mirrors are not tracked by mirrorbits.** It is assumed they have all the files available in the local repository.
106107

107108
## Running

config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ var (
3535
CheckInterval: 1,
3636
RepositoryScanInterval: 5,
3737
MaxLinkHeaders: 10,
38+
DummyFiles: false,
3839
Hashes: hashing{
3940
SHA1: true,
4041
SHA256: false,
@@ -70,6 +71,7 @@ type Configuration struct {
7071
CheckInterval int `yaml:"CheckInterval"`
7172
RepositoryScanInterval int `yaml:"RepositoryScanInterval"`
7273
MaxLinkHeaders int `yaml:"MaxLinkHeaders"`
74+
DummyFiles bool `yaml:"DummyFiles"`
7375
Hashes hashing `yaml:"Hashes"`
7476
DisallowRedirects bool `yaml:"DisallowRedirects"`
7577
WeightDistributionRange float32 `yaml:"WeightDistributionRange"`

mirrorbits.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ConcurrentSync: 5
2121
ScanInterval: 30
2222
CheckInterval: 1
2323
RepositoryScanInterval: 5
24+
DummyFiles: false
2425
Hashes:
2526
SHA256: On
2627
SHA1: Off

scan/scan.go

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package scan
55

66
import (
7+
"encoding/json"
78
"errors"
89
"fmt"
910
"os"
@@ -62,6 +63,14 @@ type scan struct {
6263
count uint
6364
}
6465

66+
type DummyFile struct {
67+
Size int64 `json:"Size"`
68+
ModTime string `json:"ModTime"`
69+
Sha1 string `json:"Sha1"`
70+
Sha256 string `json:"Sha256"`
71+
Md5 string `json:"Md5"`
72+
}
73+
6574
// IsScanning returns true is a scan is already in progress for the given mirror
6675
func IsScanning(conn redis.Conn, identifier string) (bool, error) {
6776
return redis.Bool(conn.Do("EXISTS", fmt.Sprintf("SCANNING_%s", identifier)))
@@ -229,6 +238,7 @@ func (s *scan) setLastSync(conn redis.Conn, identifier string, successful bool)
229238
}
230239

231240
type sourcescanner struct {
241+
dummyFile bool
232242
}
233243

234244
// Walk inside the source/reference repository
@@ -237,11 +247,45 @@ func (s *sourcescanner) walkSource(conn redis.Conn, path string, f os.FileInfo,
237247
return nil, nil
238248
}
239249

250+
var dfData DummyFile
251+
dummyFile := s.dummyFile
252+
240253
d := new(filedata)
241254
d.path = path[len(GetConfig().Repository):]
242-
d.size = f.Size()
243-
d.modTime = f.ModTime()
244255

256+
if dummyFile {
257+
file, err := os.Open(path)
258+
if err != nil {
259+
log.Errorf(err.Error())
260+
}
261+
dec := json.NewDecoder(file)
262+
// read open bracket, when there is none, the file is not a json.
263+
// Fallback to normal mode.
264+
_, err = dec.Token()
265+
if err != nil {
266+
goto skipdec
267+
}
268+
err = dec.Decode(&dfData)
269+
skipdec:
270+
if err != nil {
271+
log.Debugf("Failed to read file: %s", err.Error())
272+
dummyFile = false
273+
d.size = f.Size()
274+
d.modTime = f.ModTime()
275+
goto skip
276+
}
277+
278+
d.size = dfData.Size
279+
d.modTime, err = time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", dfData.ModTime)
280+
if err != nil {
281+
log.Errorf(err.Error())
282+
}
283+
} else {
284+
d.size = f.Size()
285+
d.modTime = f.ModTime()
286+
}
287+
288+
skip:
245289
// Get the previous file properties
246290
properties, err := redis.Strings(conn.Do("HMGET", fmt.Sprintf("FILE_%s", d.path), "size", "modTime", "sha1", "sha256", "md5"))
247291
if err != nil && err != redis.ErrNil {
@@ -263,21 +307,27 @@ func (s *sourcescanner) walkSource(conn redis.Conn, path string, f os.FileInfo,
263307
(GetConfig().Hashes.MD5 && len(md5) == 0)
264308

265309
if rehash || size != d.size || !modTime.Equal(d.modTime) {
266-
h, err := filesystem.HashFile(GetConfig().Repository + d.path)
267-
if err != nil {
268-
log.Warningf("%s: hashing failed: %s", d.path, err.Error())
310+
if dummyFile {
311+
d.sha1 = dfData.Sha1
312+
d.sha256 = dfData.Sha256
313+
d.md5 = dfData.Md5
269314
} else {
270-
d.sha1 = h.Sha1
271-
d.sha256 = h.Sha256
272-
d.md5 = h.Md5
273-
if len(d.sha1) > 0 {
274-
log.Infof("%s: SHA1 %s", d.path, d.sha1)
275-
}
276-
if len(d.sha256) > 0 {
277-
log.Infof("%s: SHA256 %s", d.path, d.sha256)
278-
}
279-
if len(d.md5) > 0 {
280-
log.Infof("%s: MD5 %s", d.path, d.md5)
315+
h, err := filesystem.HashFile(GetConfig().Repository + d.path)
316+
if err != nil {
317+
log.Warningf("%s: hashing failed: %s", d.path, err.Error())
318+
} else {
319+
d.sha1 = h.Sha1
320+
d.sha256 = h.Sha256
321+
d.md5 = h.Md5
322+
if len(d.sha1) > 0 {
323+
log.Infof("%s: SHA1 %s", d.path, d.sha1)
324+
}
325+
if len(d.sha256) > 0 {
326+
log.Infof("%s: SHA256 %s", d.path, d.sha256)
327+
}
328+
if len(d.md5) > 0 {
329+
log.Infof("%s: MD5 %s", d.path, d.md5)
330+
}
281331
}
282332
}
283333
} else {
@@ -292,6 +342,7 @@ func (s *sourcescanner) walkSource(conn redis.Conn, path string, f os.FileInfo,
292342
// ScanSource starts a scan of the local repository
293343
func ScanSource(r *database.Redis, forceRehash bool, stop chan bool) (err error) {
294344
s := &sourcescanner{}
345+
s.dummyFile = GetConfig().DummyFiles
295346

296347
conn := r.Get()
297348
defer conn.Close()

0 commit comments

Comments
 (0)