• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

api/H09-Feb-2021-8260

common/H09-Feb-2021-292235

geoip/H09-Feb-2021-350280

monitor/H09-Feb-2021-362293

pkg/H09-Feb-2021-202154

testdata/H09-Feb-2021-2723

vendor/H03-May-2022-2,476,8131,692,963

workerpool/H09-Feb-2021-232165

.gitignoreH A D09-Feb-202133 54

LICENSEH A D09-Feb-20211.6 KiB3629

MakefileH A D09-Feb-2021272 118

README.mdH A D09-Feb-20214.5 KiB156128

go.modH A D09-Feb-2021235 118

go.sumH A D09-Feb-202131.3 KiB327326

main.goH A D09-Feb-20213.2 KiB10453

mirrors.dev.tomlH A D09-Feb-20211.7 KiB8475

mirrors.tomlH A D09-Feb-20216.7 KiB328292

mirrorselect.dev.tomlH A D09-Feb-20211.1 KiB4834

mirrorselect.tomlH A D09-Feb-20211.1 KiB4834

README.md

1DragonFly pkg mirrorselect
2--------------------------
3
4**Mirrorselect** is an HTTP backend service that selects the
5[pkg(8)](https://man.dragonflybsd.org/?command=pkg&section=8)
6mirrors according to their "distances" to the client.
7
8The "distance" of a mirror is determined by:
9
10* whether locate in the same country as the client
11* whether locate on the same continent as the client
12* great-circle distance between its coordinate and the client's
13
14The selected mirrors and their ordering are:
15
16* Prefer mirrors of the same **country** as the client.
17* If not, then prefer mirrors of the same **continent**.
18* If not, fallback to the *default* mirror.
19* If multiple mirrors in the same country/continent, order them by
20  *distance* to the client (calculated via latitude/longitude).
21* Append the *default* mirror to the last as fallback.
22* If cannot determine client's location, just return the *default* mirror.
23
24Features
25--------
26* Simple and small:
27  - simple config files
28  - few direct dependencies:
29  [gin-gonic/gin](https://github.com/gin-gonic/gin),
30  [oschwald/maxminddb-golang](https://github.com/oschwald/maxminddb-golang),
31  [spf13/viper](https://github.com/spf13/viper),
32  [jlaffaye/ftp](https://github.com/jlaffaye/ftp)
33* Stand-alone:
34  - use offline IP geolocation database
35    (open [MaxMind DB format](https://maxmind.github.io/MaxMind-DB/))
36  - support both [MaxMind](https://www.maxmind.com) and
37  [DB-IP](https://db-ip.com) dataset
38* Built-in mirror monitor:
39  - periodically check mirror status
40  - support HTTP, HTTPS and FTP
41  - use a hysteresis to smooth status flipping
42  - run a command when a mirror is down/up to publish events
43
44Implementation
45--------------
46This mirror selection implementation leverages pkg(8)'s **HTTP**
47mirror type of repository.
48Basically, the repository URL provides a sequence of lines beginning with
49`URL:` followed by any amount of white space and one URL for a repository
50mirror.
51Then, pkg(8) tries these mirrors in the order listed until a download
52succeeds.
53
54See also: [pkg-repository(5)](https://man.dragonflybsd.org/?command=pkg-repository&section=5)
55
56For example, configure the pkg(8) repos as:
57```
58AUTO: {
59	url: https://pkg.dragonflybsd.org/pkg/${ABI}/LATEST
60	mirror_type: HTTP
61}
62```
63
64And upon client's request, the service returns, e.g.,:
65```
66URL: https://mirror.sjtu.edu.cn/dragonflybsd/dports/dragonfly:5.10:x86:64/LATEST
67URL: ...
68URL: https://mirror-master.dragonflybsd.org/dports/dragonfly:5.10:x86:64/LATEST
69```
70
71NOTE: The `${ABI}` is expanded by pkg(8) on the client side.
72
73Deployment
74----------
751. Prepare the mirror list file `mirrors.toml`, listing all available
76   pkg(8) mirrors and their locations.
772. Obtain one of the following **free** IP geolocation database
78   (choose **MMDB** binary format):
79   * [DB-IP Lite data](https://db-ip.com/db/download/ip-to-city-lite)
80     <br>
81     *Recommended*, more entries and higher precision, no sign-up required.
82   * [MaxMind GeoLite2 data](https://dev.maxmind.com/geoip/geoip2/geolite2/)
83     <br>
84     NOTE: sign-up required to download the database.
853. Create the main config file `mirrorselect.toml`.
864. Run **mirrorselect** as a **normal** user (e.g., `nobody`).
875. Publish this service via Nginx/Apache.
88
89### Nginx proxy example
90
91```nginx
92server {
93    listen       80 http2;
94    server_name  pkg.dragonflybsd.org;
95
96    location / {
97        proxy_http_version  1.1;
98        proxy_set_header    Host $host;
99        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
100        proxy_pass          http://localhost:3130;
101    }
102}
103```
104
105### Apache proxy example
106
107```apache
108<VirtualHost *:80>
109    ServerName  pkg.dragonflybsd.org
110
111    ProxyPreserveHost On
112    ProxyPass         / http://localhost:3130/
113    ProxyPassReverse  / http://localhost:3130/
114</VirtualHost>
115```
116
117### On DragonFly BSD
118
1191. Install the `www/mirrorselect` package:
120
121        pkg install mirrorselect
122
1232. Enable and start the `mirrorselect` service:
124
125        rcenable mirrorselect
126        rcstart mirrorselect
127
1283. Configure Nginx/Apache to export the service.
129
130Services
131--------
132* `/`
133  <br>
134  For testing, just reply a `pong`, same as the `/ping` below.
135* `/ping`
136  <br>
137  For testing, just reply a `pong`.
138* `/ip`
139  <br>
140  Show the client's IP as well as its location information,
141  queried from the geolocation database.
142* `/mirrors`
143  <br>
144  Return a JSON object containing the information and status of all mirrors.
145* `/pkg/:abi/*path`
146  <br>
147  Return the selected mirrors based on the client's location.
148  <br>
149  NOTE: The `:abi/*path` part would be returned as-is.
150
151License
152-------
153The 3-Clause BSD License
154
155Copyright (c) 2021 The DragonFly Project.
156