Skip to content

Commit d4fb8af

Browse files
committed
Allow reading FileInfo from a dummy file instead of the file itself
1 parent 1f0ecd9 commit d4fb8af

File tree

4 files changed

+76
-16
lines changed

4 files changed

+76
-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: 72 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
package scan
55

66
import (
7+
"encoding/json"
78
"errors"
89
"fmt"
10+
"io/ioutil"
911
"os"
1012
"path/filepath"
1113
"strconv"
@@ -62,6 +64,14 @@ type scan struct {
6264
count uint
6365
}
6466

67+
type DummyFile struct {
68+
Size int64 `json:"Size"`
69+
ModTime string `json:"ModTime"`
70+
Sha1 string `json:"Sha1"`
71+
Sha256 string `json:"Sha256"`
72+
Md5 string `json:"Md5"`
73+
}
74+
6575
// IsScanning returns true is a scan is already in progress for the given mirror
6676
func IsScanning(conn redis.Conn, identifier string) (bool, error) {
6777
return redis.Bool(conn.Do("EXISTS", fmt.Sprintf("SCANNING_%s", identifier)))
@@ -237,11 +247,51 @@ func (s *sourcescanner) walkSource(conn redis.Conn, path string, f os.FileInfo,
237247
return nil, nil
238248
}
239249

250+
var dfData DummyFile
251+
dummyFile := GetConfig().DummyFiles
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+
fi, _ := os.Stat(d.path)
258+
if fi.Size() > 1048576 {
259+
log.Error("File is bigger than 1MB, falling back to normal")
260+
goto skip
261+
}
262+
raw, err := ioutil.ReadFile(path)
263+
if err != nil {
264+
log.error(err.Error())
265+
log.error("Failed to read file, falling back to normal")
266+
dummyFile = false
267+
d.size = f.Size()
268+
d.modTime = f.ModTime()
269+
goto skip
270+
}
271+
272+
var c []DummyFile
273+
err = json.Unmarshal(raw, &c)
274+
if err != nil {
275+
log.Errorf("error decoding json: %v", err)
276+
if e, ok := err.(*json.SyntaxError); ok {
277+
log.Errorf("syntax error at byte offset %d", e.Offset)
278+
}
279+
log.Errorf("json response: %q", c)
280+
return nil, err
281+
}
282+
283+
dfData = c[0]
284+
d.size = dfData.Size
285+
d.modTime, err = time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", dfData.ModTime)
286+
if err != nil {
287+
log.error(err)
288+
}
289+
} else {
290+
d.size = f.Size()
291+
d.modTime = f.ModTime()
292+
}
293+
294+
skip:
245295
// Get the previous file properties
246296
properties, err := redis.Strings(conn.Do("HMGET", fmt.Sprintf("FILE_%s", d.path), "size", "modTime", "sha1", "sha256", "md5"))
247297
if err != nil && err != redis.ErrNil {
@@ -263,21 +313,27 @@ func (s *sourcescanner) walkSource(conn redis.Conn, path string, f os.FileInfo,
263313
(GetConfig().Hashes.MD5 && len(md5) == 0)
264314

265315
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())
316+
if dummyFile {
317+
d.sha1 = dfData.Sha1
318+
d.sha256 = dfData.Sha256
319+
d.md5 = dfData.Md5
269320
} 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)
321+
h, err := filesystem.HashFile(GetConfig().Repository + d.path)
322+
if err != nil {
323+
log.Warningf("%s: hashing failed: %s", d.path, err.Error())
324+
} else {
325+
d.sha1 = h.Sha1
326+
d.sha256 = h.Sha256
327+
d.md5 = h.Md5
328+
if len(d.sha1) > 0 {
329+
log.Infof("%s: SHA1 %s", d.path, d.sha1)
330+
}
331+
if len(d.sha256) > 0 {
332+
log.Infof("%s: SHA256 %s", d.path, d.sha256)
333+
}
334+
if len(d.md5) > 0 {
335+
log.Infof("%s: MD5 %s", d.path, d.md5)
336+
}
281337
}
282338
}
283339
} else {

0 commit comments

Comments
 (0)