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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
|
GIT mirror
--
If you want simple & light self-hosted mirror of this or any other GIT repository, then you may use something
like these examples. I assume Debian and nginx as webserver, but you can easily translate the idea to whatever
Linux or webserver you like.
These examples use cgit as web viewer and git-http-backend for read-only HTTP clone support.
**Install dependencies**
```
apt install nginx git cgit fcgiwrap
```
**Prepare GIT repositories and keep them up to date**
You want to use such script to first clone bare repositories and then periodically update them.
See and obtain the `extras/mirror/github-mirror.sh` script.
Example usage of `update-mirrors.sh`:
```bash
#!/usr/bin/env bash
set -e
githubMirror="/opt/vyos-jenkins/extras/mirror/github-mirror.sh"
export ROOT_PATH="/var/lib/git"
export NAMESPACE="vyos"
export GITHUB_KIND="org"
export GITHUB_SUBJECT="vyos"
$githubMirror
export NAMESPACE="dd010101"
export GITHUB_KIND="user"
export GITHUB_SUBJECT="dd010101"
$githubMirror
# uncomment if you want use automated backup, see the github-mirror-backup.sh for configuration
#/opt/vyos-jenkins/extras/mirror/github-mirror-backup.sh
```
You may also mirror GIT repositories directly:
```bash
#!/usr/bin/env bash
set -e
destination="/var/lib/git/dd010101"
sources=(
"https://github.com/dd010101/vyos-jenkins.git"
"https://github.com/dd010101/vyos-build.git"
"https://github.com/dd010101/vyos-missing.git"
)
if [ ! -f "$destination" ]; then
mkdir -p "$destination"
fi
for gitUrl in "${sources[@]}"
do
directory=$(echo "$gitUrl" | grep -oP '([^/]+).git')
fullPath="$destination/$directory"
if [ -d "$fullPath" ]; then
echo "Updating $gitUrl in $fullPath"
git -C "$fullPath" remote update
else
echo "Cloning $gitUrl as $fullPath"
mkdir -p "$fullPath"
git -C "$fullPath" clone --mirror "$gitUrl" .
fi
done
```
Run the mirror script(s) first time to clone repositories:
```bash
adduser --system --group --disabled-password -d /var/lib/git git
chown -R git: /var/lib/git
su - git -s /bin/bash -c "/your/path/update-mirrors.sh"
```
To keep repositories up to date execute the script(s) periodically for example with CRON:
```
0 * * * * git /your/path/update-mirrors.sh
```
**cgit configuration**
Modify `/etc/cgitrc` and append following:
```
clone-prefix=https://git.some.tld
css=/cgit.css
logo=/cgit.png
root-title=My mirror
root-desc=Welcome to my mirror
max-repo-count=0
snapshots=tar.gz zip
section-from-path=1
scan-path=/var/lib/git/repos
virtual-root=/
```
Adjust the values as you wish. It's important to set the `clone-prefix` to your URL.
**nginx vhost**
Replace `git.some.tld` with your domain and also adjust HTTPS certificates as needed. You may as well use whatever
configuration you like and just pickup location blocks to make git side work with your favorite nginx vhost.
```
server {
listen 80;
listen [::]:80;
server_name git.some.tld;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/git.some.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/git.some.tld/privkey.pem;
server_name git.some.tld;
root /usr/share/cgit;
location / {
try_files $uri @cgit;
}
location @cgit {
fastcgi_param SCRIPT_FILENAME /usr/lib/cgit/cgit.cgi;
fastcgi_param PATH_INFO $uri;
fastcgi_param QUERY_STRING $args;
fastcgi_param HTTP_HOST $server_name;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
}
location ~ /.+/(info/refs|git-upload-pack) {
client_max_body_size 0;
fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend;
fastcgi_param GIT_HTTP_EXPORT_ALL "";
fastcgi_param GIT_PROJECT_ROOT /var/lib/git/repos;
fastcgi_param PATH_INFO $uri;
fastcgi_param LANGUAGE en_US.UTF-8;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
include fastcgi_params;
}
}
```
The `git-http-backend` will use your system language and will send messages in this language to whoever
interacts with it - like with git clone. English-speaking GIT server is more common and that's why I would
recommend using `en_US.UTF-8`. If you have other system locale then you can add `en_US.UTF-8` as secondary
via `dpkg-reconfigure locales` - pick your locale as default and `git-http-backend` can use english via `LANGUAGE`
variable.
This gives your `https://git.some.tld` for viewing
and `git clone https://git.some.tld/namespace/repository.git` support.
The cgit web viewer shows URL for cloning for each repository in summary section.
**Duply backups for github-mirror.sh**
Install additional dependencies:
```bash
apt install duply
```
You may need additional dependencies depending on the duplicity backend you want to use.
Create duply profile:
- Don't forget to update `TARGET` to your specific duplicity backend.
- Check `SOURCE` to match `ROOT_PATH` of github-mirror.sh.
- You may want to tune the `MAX_FULL_BACKUPS` and `MAX_FULLBKP_AGE`:
- `duply github-mirror backup` will create new full after `MAX_FULLBKP_AGE` time period.
- `duply github-mirror purgeFull --force` will automatically delete full backup (and its chain of increments)
if number of full backups (chains) has reached `MAX_FULL_BACKUPS` value.
- Thus, with `MAX_FULL_BACKUPS=3` and `MAX_FULLBKP_AGE=1M` duplicity will create increments until month elapses.
Then it creates new full backup/chain and continues with increments.
If we reach 4th month then oldest full backup/chain is removed.
This will yield 2 full months of increments and partial third month with 1 to 30 days depending on the cycle,
this results in rolling 60-90 days of coverage.
```bash
mkdir -p /etc/duply/github-mirror
cat << 'EOF' > /etc/duply/github-mirror/conf
# gpg encryption settings, simple settings:
# GPG_KEY='disabled' - disables encryption alltogether
# GPG_KEY='<key1>[,<key2>]'; GPG_PW='pass' - encrypt with keys,
# sign if secret key of key1 is available use GPG_PW for sign & decrypt
# Note: you can specify keys via all methods described in gpg manpage,
# section "How to specify a user ID", escape commas (,) via backslash (\)
# e.g. 'Mueller, Horst', 'Bernd' -> 'Mueller\, Horst, Bernd'
# as they are used to separate the entries
# GPG_PW='passphrase' - symmetric encryption using passphrase only
GPG_KEY='disabled'
GPG_PW='_GPG_PASSWORD_'
# backend, credentials & location of the backup target (URL-Format)
# generic syntax is
# scheme://[user[:password]@]host[:port]/[/]path
# e.g.
# sftp://bob:secret@backupserver.com//home/bob/dupbkp
# for details and available backends see duplicity manpage, section URL Format
# http://duplicity.us/vers8/duplicity.1.html#url-format
# BE AWARE:
# some backends (cloudfiles, S3 etc.) need additional env vars to be set to
# work properly, read after the TARGET definition for more details.
# ATTENTION:
# characters other than A-Za-z0-9.-_.~ in the URL have to be
# replaced by their url encoded pendants, see
# http://en.wikipedia.org/wiki/Url_encoding
# if you define the credentials as TARGET_USER, TARGET_PASS below $ME
# will try to url_encode them for you if the need arises.
TARGET=''
#TARGET_PASS=''
# base directory to backup
SOURCE='/opt/github-mirror'
# Number of full backups to keep. Used for the "purgeFull" command.
# See duplicity man page, action "remove-all-but-n-full".
MAX_FULL_BACKUPS=3
# activates duplicity --full-if-older-than option (since duplicity v0.4.4.RC3)
# forces a full backup if last full backup reaches a specified age, for the
# format of MAX_FULLBKP_AGE see duplicity man page, chapter TIME_FORMATS
# Uncomment the following two lines to enable this setting.
MAX_FULLBKP_AGE=1M
DUPL_PARAMS="$DUPL_PARAMS --full-if-older-than $MAX_FULLBKP_AGE "
# sets duplicity --volsize option (available since v0.4.3.RC7)
# set the size of backup chunks to VOLSIZE MB instead of the default 25MB.
# VOLSIZE must be number of MB's to set the volume size to.
# Uncomment the following two lines to enable this setting.
VOLSIZE=50
DUPL_PARAMS="$DUPL_PARAMS --volsize $VOLSIZE "
# more duplicity command line options can be added in the following way
# don't forget to leave a separating space char at the end
DUPL_PARAMS="$DUPL_PARAMS --progress "
EOF
cat << 'EOF' > /etc/duply/github-mirror/exclude
# although called exclude, this file is actually a globbing file list
# duplicity accepts some globbing patterns, even including ones here
# here is an example, this incl. only 'dir/bar' except it's subfolder 'foo'
# - dir/bar/foo
# + dir/bar
# - **
# for more details see duplicity manpage, section File Selection
# http://duplicity.nongnu.org/duplicity.1.html#sect9
EOF
```
Useful links:
- Basic usage: https://duply.net/Documentation
- Full configuration example: https://salsa.debian.org/joowie-guest/maintain_duply/-/blob/debian/2.4.1-1/duply?ref_type=tags#L853
- Can also be created by running `duply NAME create`
Restore:
- List what backups we have:
- `duply github-mirror status`
- We can restore the whole deal:
- Latest: `duply github-mirror restore /some/destination`
- Specific: `duply github-mirror restore /some/destination 2024-07-17T10:00:00+02:00`
- Or just part:
- The path is relative to the `SOURCE`.
- We can also list what is in the backup to see the path:
- Latest: `duply github-mirror list`
- Specific: `duply github-mirror list 2024-07-17T10:00:00+02:00`
- Latest: `duply github-mirror fetch repos/vyos/vyos-1x.git /some/destination`
- Specific: `duply github-mirror fetch repos/vyos/vyos-1x.git 2024-07-17T10:00:00+02:00`
|