mirror of
https://github.com/restic/restic.git
synced 2026-02-23 17:26:24 +00:00
Compare commits
665 Commits
v0.9.6
...
debug-wron
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
271eabd239 | ||
|
|
0333ef3325 | ||
|
|
b7e1ece1e0 | ||
|
|
c5300a2c56 | ||
|
|
1bd92896d7 | ||
|
|
9dba01021e | ||
|
|
23f6b8c3fd | ||
|
|
79a50e3b1f | ||
|
|
b8a5ca2d10 | ||
|
|
916b2d303b | ||
|
|
a06f5c28c0 | ||
|
|
c2f3eee5af | ||
|
|
62345abe4a | ||
|
|
e024fc6d4d | ||
|
|
0db9024aad | ||
|
|
21ba15577e | ||
|
|
2fb1957ca4 | ||
|
|
9a88fb253b | ||
|
|
f14436953a | ||
|
|
11fbaaae9a | ||
|
|
3ed84ff0c6 | ||
|
|
8e965ed4eb | ||
|
|
5f0fa2129e | ||
|
|
04dfa19c7e | ||
|
|
6509c207f4 | ||
|
|
445b845267 | ||
|
|
3ff37215df | ||
|
|
5d379b5359 | ||
|
|
e708628cfd | ||
|
|
bb4b3481a6 | ||
|
|
ad3a52e6f0 | ||
|
|
e8b4d8d8bc | ||
|
|
1aa61e6def | ||
|
|
8d7d6ad2d5 | ||
|
|
fe09e6f865 | ||
|
|
1e3c9a2c11 | ||
|
|
e21dcb0eea | ||
|
|
31b8d7a639 | ||
|
|
5695f9ebd2 | ||
|
|
8091151638 | ||
|
|
ae179ee63e | ||
|
|
0590e3e12d | ||
|
|
3807d13bdc | ||
|
|
63be3704d9 | ||
|
|
35419de232 | ||
|
|
863a590a81 | ||
|
|
7c0b6a82db | ||
|
|
96a912b65a | ||
|
|
b44ecde8b0 | ||
|
|
39fe1e96fe | ||
|
|
4ba237bb93 | ||
|
|
ce87fbd7dc | ||
|
|
b27375f5ce | ||
|
|
720e0ee0c7 | ||
|
|
27db3ec262 | ||
|
|
f80b07b2c8 | ||
|
|
6003dada14 | ||
|
|
41a45ae908 | ||
|
|
8299c5559c | ||
|
|
56883817d8 | ||
|
|
f0cd16e5ea | ||
|
|
a03fe4562e | ||
|
|
efc075df87 | ||
|
|
f500b0d90e | ||
|
|
c193cea119 | ||
|
|
f0d49ca600 | ||
|
|
164d8af3dd | ||
|
|
052564007a | ||
|
|
6099f81692 | ||
|
|
9d7f616190 | ||
|
|
295ddb9e57 | ||
|
|
e638b46a13 | ||
|
|
d6cfe857b7 | ||
|
|
2964d2ad15 | ||
|
|
0c9efa9c2a | ||
|
|
37a5e2d681 | ||
|
|
4b0fcaed45 | ||
|
|
645a6efaf2 | ||
|
|
dc2e664209 | ||
|
|
a449450021 | ||
|
|
603bb0e309 | ||
|
|
27456f6545 | ||
|
|
c458e114d4 | ||
|
|
45e9a55c62 | ||
|
|
307a6ba3a3 | ||
|
|
50da20d93d | ||
|
|
5fd3dbccb7 | ||
|
|
35655a481b | ||
|
|
30cb553c8d | ||
|
|
2f3eeff2e7 | ||
|
|
356ac404cd | ||
|
|
ab769abeaf | ||
|
|
4036991c91 | ||
|
|
88c8e903d2 | ||
|
|
740758a5fa | ||
|
|
862ee4b2c9 | ||
|
|
958dc6aafc | ||
|
|
88cc444779 | ||
|
|
4a424af1d5 | ||
|
|
bc65da2baf | ||
|
|
b79f18209f | ||
|
|
8388e67c4b | ||
|
|
0acc3c5923 | ||
|
|
54a124de3b | ||
|
|
bcc3bddcf4 | ||
|
|
17c53efb0d | ||
|
|
7959796269 | ||
|
|
375c2a56de | ||
|
|
b8eacd1364 | ||
|
|
e73c281142 | ||
|
|
fdd3b14db3 | ||
|
|
f4282aa6fd | ||
|
|
40ee17167e | ||
|
|
f3e933f0c1 | ||
|
|
0ae02f3030 | ||
|
|
e401859afb | ||
|
|
af4100e07d | ||
|
|
ea5bbe0857 | ||
|
|
6822a58413 | ||
|
|
09d39e260d | ||
|
|
1579d2a8ec | ||
|
|
eba5dd831f | ||
|
|
9ffb698c8d | ||
|
|
efbb850d92 | ||
|
|
cfd57c480a | ||
|
|
e105a3f391 | ||
|
|
5d8cfff3f2 | ||
|
|
673dda77c0 | ||
|
|
1ab4c710e1 | ||
|
|
feedf0ebce | ||
|
|
1a490acd67 | ||
|
|
187518a8a3 | ||
|
|
a232c833dc | ||
|
|
c84643c6a9 | ||
|
|
8390a8aaf3 | ||
|
|
1e1a1f3078 | ||
|
|
abe9fa261f | ||
|
|
6001b45bf7 | ||
|
|
6bee0aafc2 | ||
|
|
8252ea8e3d | ||
|
|
137d20a06a | ||
|
|
c4e2203e45 | ||
|
|
7d0fa1a686 | ||
|
|
a23d90d270 | ||
|
|
2630411530 | ||
|
|
b9b82d878d | ||
|
|
8b8e230771 | ||
|
|
7c3c6fa431 | ||
|
|
29908906b7 | ||
|
|
bbeb439f41 | ||
|
|
ce14df303b | ||
|
|
3c6671b18b | ||
|
|
86ff1f2bf6 | ||
|
|
0cce6dc31c | ||
|
|
6253ff0187 | ||
|
|
e9943e864f | ||
|
|
a687261804 | ||
|
|
4df8861e09 | ||
|
|
00cedd22aa | ||
|
|
f361ed66de | ||
|
|
7b50a65492 | ||
|
|
c18b119a9b | ||
|
|
61035d68bc | ||
|
|
97f7855de3 | ||
|
|
d44df9d00d | ||
|
|
8d0ba55ecd | ||
|
|
34ea960559 | ||
|
|
5ea01b00df | ||
|
|
48d0ab5276 | ||
|
|
2a79c1a44d | ||
|
|
fd02407863 | ||
|
|
aea9f7d286 | ||
|
|
028c9a5343 | ||
|
|
94136132e3 | ||
|
|
009bd907f2 | ||
|
|
14b312f00d | ||
|
|
206cadfab4 | ||
|
|
4875f7b659 | ||
|
|
6f2093e491 | ||
|
|
16f31b2f73 | ||
|
|
0d65b78168 | ||
|
|
95ebba85ff | ||
|
|
59b343a9bf | ||
|
|
1557c58eef | ||
|
|
c504aa505c | ||
|
|
1b20f6beec | ||
|
|
10e3340863 | ||
|
|
3cf29a777d | ||
|
|
fd1f7b7268 | ||
|
|
090a73f7c5 | ||
|
|
1cfb01a8a6 | ||
|
|
ce62d3d689 | ||
|
|
8c36317b71 | ||
|
|
60a5c35de9 | ||
|
|
9333f707fa | ||
|
|
429f97b887 | ||
|
|
40832b2927 | ||
|
|
c8a94eced7 | ||
|
|
ee6e981b4e | ||
|
|
96fd982f6a | ||
|
|
6ff0082c02 | ||
|
|
95c1d7d959 | ||
|
|
07f4e7d10b | ||
|
|
f003410402 | ||
|
|
9ad8250a78 | ||
|
|
655430550b | ||
|
|
1823b8195c | ||
|
|
311ad2d2d0 | ||
|
|
a10b44a265 | ||
|
|
baf3a9aa3b | ||
|
|
ffe6dce7e7 | ||
|
|
8ce0ce387f | ||
|
|
3c44598bf6 | ||
|
|
3bb55fd6bf | ||
|
|
36efefa7bd | ||
|
|
ac4b8c98ac | ||
|
|
4dcd6abf37 | ||
|
|
cb3f531050 | ||
|
|
23fcbb275a | ||
|
|
6e3215a80d | ||
|
|
9abef3bf1a | ||
|
|
b10dce541e | ||
|
|
4f221c4022 | ||
|
|
f5c448aa65 | ||
|
|
c0fc85d303 | ||
|
|
0c48e515f0 | ||
|
|
97950ab81a | ||
|
|
59fca85844 | ||
|
|
e207257714 | ||
|
|
82e1cbed4f | ||
|
|
8903b6c88a | ||
|
|
93583c01b1 | ||
|
|
88664ba222 | ||
|
|
121233e1b3 | ||
|
|
8cc9514879 | ||
|
|
2e7d475029 | ||
|
|
d3a286928a | ||
|
|
c46edcd9d6 | ||
|
|
1ede018ea6 | ||
|
|
b77e933d80 | ||
|
|
d0329cf3eb | ||
|
|
dc31529fc3 | ||
|
|
4784540f04 | ||
|
|
84ea2389ae | ||
|
|
b4a7ce86cf | ||
|
|
7ee0964880 | ||
|
|
f6f11400c2 | ||
|
|
e2dc5034d3 | ||
|
|
9a1b3cb5d9 | ||
|
|
b22655367c | ||
|
|
068a3ce23f | ||
|
|
ee05501ce7 | ||
|
|
014600bee6 | ||
|
|
d9a80e07b9 | ||
|
|
d19f05c960 | ||
|
|
460e2ffbf6 | ||
|
|
49b6aac3fa | ||
|
|
2f8335554c | ||
|
|
37113282ca | ||
|
|
337725c354 | ||
|
|
2ddb7ffb7e | ||
|
|
81dcfea11a | ||
|
|
55071ee367 | ||
|
|
dcf9ded977 | ||
|
|
bcf44a9c3f | ||
|
|
a7b4c19abf | ||
|
|
d3fcfeba3a | ||
|
|
e69449bf2c | ||
|
|
da4193c3ef | ||
|
|
fe6445e0f4 | ||
|
|
ea81a0e282 | ||
|
|
80a11960dd | ||
|
|
d6f739ec22 | ||
|
|
b98598e55f | ||
|
|
d5f86effa1 | ||
|
|
c34c731698 | ||
|
|
412623b848 | ||
|
|
bbe8b73f03 | ||
|
|
91e8d998cd | ||
|
|
9a4796594a | ||
|
|
15374d22e9 | ||
|
|
88ad58d6cd | ||
|
|
591a8c4cdf | ||
|
|
ec9a53b7e8 | ||
|
|
34a3adfd8d | ||
|
|
9867c4bbb4 | ||
|
|
efb4a981cf | ||
|
|
2447f3f110 | ||
|
|
b25978a53c | ||
|
|
b0a8c4ad6c | ||
|
|
908b23fda0 | ||
|
|
4508d406ef | ||
|
|
7048cc3e58 | ||
|
|
eb7c00387c | ||
|
|
bc0501d72c | ||
|
|
17995dec7a | ||
|
|
e915cedc3d | ||
|
|
cdcaecd27d | ||
|
|
b43ab67a22 | ||
|
|
7ddfd6cabe | ||
|
|
b1b3f1ecb6 | ||
|
|
fa135f72bf | ||
|
|
51c22f4223 | ||
|
|
1a5b66f33b | ||
|
|
da6a34e044 | ||
|
|
fe69b83074 | ||
|
|
08d24ff99e | ||
|
|
d8b80e9862 | ||
|
|
1c84aceb39 | ||
|
|
575ed9a47e | ||
|
|
8f811642c3 | ||
|
|
f4b9544ab2 | ||
|
|
367449dede | ||
|
|
7042bafea5 | ||
|
|
744a15247d | ||
|
|
3ba19869be | ||
|
|
0fed6a8dfc | ||
|
|
643bbbe156 | ||
|
|
eca0f0ad24 | ||
|
|
08dee8a52b | ||
|
|
b112533812 | ||
|
|
5e63294355 | ||
|
|
84b6f1ec53 | ||
|
|
06fb4ea3f0 | ||
|
|
e38d415173 | ||
|
|
d81a396944 | ||
|
|
0b21ec44b7 | ||
|
|
bd36731119 | ||
|
|
38a2f9c07b | ||
|
|
5af2815627 | ||
|
|
b55de2260d | ||
|
|
9be4fe3e84 | ||
|
|
05116e4787 | ||
|
|
04f79b9642 | ||
|
|
8b358935a0 | ||
|
|
66d089e239 | ||
|
|
49d3efe547 | ||
|
|
9762bec091 | ||
|
|
0eb8553c87 | ||
|
|
d3692f5b81 | ||
|
|
1c0b61204b | ||
|
|
2ee654763b | ||
|
|
b7b479b668 | ||
|
|
4cf9656f12 | ||
|
|
2580eef2aa | ||
|
|
2d7ab9115f | ||
|
|
a178e5628e | ||
|
|
af66a62c04 | ||
|
|
9ea1a78bd4 | ||
|
|
184103647a | ||
|
|
c81b122374 | ||
|
|
48f97f3567 | ||
|
|
3ce9893e0b | ||
|
|
248c7c3828 | ||
|
|
f8316948d1 | ||
|
|
be54ceff66 | ||
|
|
ea97ff1ba4 | ||
|
|
01b9581453 | ||
|
|
3cd927d180 | ||
|
|
bf7b1f12ea | ||
|
|
8554332894 | ||
|
|
3e93b36ca4 | ||
|
|
573a2fb240 | ||
|
|
c847aace35 | ||
|
|
9d1fb94c6c | ||
|
|
020cab8e08 | ||
|
|
07da61baee | ||
|
|
37c95bf5da | ||
|
|
c86d2f23aa | ||
|
|
96ec04d74d | ||
|
|
9c3414374a | ||
|
|
3d530dfc91 | ||
|
|
c43f5b2664 | ||
|
|
38087e40d9 | ||
|
|
bbc960f957 | ||
|
|
309598c237 | ||
|
|
03d23e6faa | ||
|
|
b10acd2af7 | ||
|
|
9175795fdb | ||
|
|
5d8d70542f | ||
|
|
7c23381a2b | ||
|
|
34181b13a2 | ||
|
|
bcd47ec3a2 | ||
|
|
a666a6d576 | ||
|
|
e388d962a5 | ||
|
|
758b44b9c0 | ||
|
|
3b7a3711e6 | ||
|
|
9b0e718852 | ||
|
|
82c908871d | ||
|
|
ddf0b8cd0b | ||
|
|
2d0c138c9b | ||
|
|
ef325ffc02 | ||
|
|
0f67ae813a | ||
|
|
7a165f32a9 | ||
|
|
36c69e3ca7 | ||
|
|
35d8413639 | ||
|
|
c66a0e408c | ||
|
|
70f4c014ef | ||
|
|
f0d8710611 | ||
|
|
bd3e280f6d | ||
|
|
2746dcdb5f | ||
|
|
5729d967f5 | ||
|
|
f9f6124558 | ||
|
|
8074879c5f | ||
|
|
7bda28f31f | ||
|
|
255ba83c4b | ||
|
|
7dc200c593 | ||
|
|
9ac90cf5cd | ||
|
|
b84f5177cb | ||
|
|
4cf1c8e8da | ||
|
|
58719e1f47 | ||
|
|
d42c169458 | ||
|
|
8598bb042b | ||
|
|
c6b74962df | ||
|
|
2c72924ffb | ||
|
|
02bec13ef2 | ||
|
|
64976b1a4d | ||
|
|
6a607d6ded | ||
|
|
6fedf1a7f4 | ||
|
|
df946fd9f8 | ||
|
|
4e6a9767de | ||
|
|
1bc80c3c8d | ||
|
|
0fcef2ec23 | ||
|
|
212607dc8a | ||
|
|
190d8e2f51 | ||
|
|
f4cd2a7120 | ||
|
|
aba270df7e | ||
|
|
b5543cff5d | ||
|
|
285b5236c2 | ||
|
|
bb1e258bb7 | ||
|
|
182655bc88 | ||
|
|
74bc7141c1 | ||
|
|
1361341c58 | ||
|
|
ce4a2f4ca6 | ||
|
|
cf979e2b81 | ||
|
|
d92e2c5769 | ||
|
|
7419844885 | ||
|
|
1d66bb9e62 | ||
|
|
0b2c31b05b | ||
|
|
dd7b4f54f5 | ||
|
|
6896c6449b | ||
|
|
735a8074d5 | ||
|
|
70347e95d5 | ||
|
|
0fa3091c78 | ||
|
|
91906911b0 | ||
|
|
fae7f78057 | ||
|
|
ac9ec4b990 | ||
|
|
087c770161 | ||
|
|
6856d1e422 | ||
|
|
8c1261ff02 | ||
|
|
26704be17f | ||
|
|
2c3360db98 | ||
|
|
cba6ad8d8e | ||
|
|
2a3312ac35 | ||
|
|
c35c4e0cbf | ||
|
|
84475aa3a8 | ||
|
|
f12f9ae240 | ||
|
|
5cc1760fdf | ||
|
|
32ac5486e9 | ||
|
|
c4336978eb | ||
|
|
649cbec6c5 | ||
|
|
b17bd7f860 | ||
|
|
68f1e9c524 | ||
|
|
1ee2306033 | ||
|
|
c882a92cd6 | ||
|
|
f54db5d796 | ||
|
|
843e7f404e | ||
|
|
d465b5b9ad | ||
|
|
9f7cd69f13 | ||
|
|
f97a680887 | ||
|
|
42a3db05b0 | ||
|
|
070d43e290 | ||
|
|
d4bd32a37e | ||
|
|
e7d7b85d59 | ||
|
|
be5a0ff59f | ||
|
|
c5100d5632 | ||
|
|
956a1b0f96 | ||
|
|
fab626a3df | ||
|
|
4f00564574 | ||
|
|
f77477129f | ||
|
|
2e31120f89 | ||
|
|
8fb2c0d3c1 | ||
|
|
072cf7b02d | ||
|
|
df66daa5c9 | ||
|
|
9790d8ce1c | ||
|
|
16710454f4 | ||
|
|
08ec6c9f17 | ||
|
|
7910ff4c0e | ||
|
|
c4da9d1e90 | ||
|
|
3ed61987a2 | ||
|
|
9dba7a2577 | ||
|
|
a1352906e2 | ||
|
|
b7c0d4d8bf | ||
|
|
f033850aa0 | ||
|
|
bdf7ba20cb | ||
|
|
3ee6b8ec63 | ||
|
|
4a400f94bb | ||
|
|
1a1c572bac | ||
|
|
5a7c27ddb6 | ||
|
|
fb842759fc | ||
|
|
7aa2f8a61e | ||
|
|
08bf3bae79 | ||
|
|
e7b741b2d7 | ||
|
|
6bee62e346 | ||
|
|
bc74cd3ae5 | ||
|
|
90243ed1c4 | ||
|
|
0ce81d88b6 | ||
|
|
c03bc88b29 | ||
|
|
b8da7b1f4d | ||
|
|
f1b4d97945 | ||
|
|
90fc639a67 | ||
|
|
2b5a6d255a | ||
|
|
f004dbe605 | ||
|
|
9efbe98879 | ||
|
|
7d9300efca | ||
|
|
c38aaaa768 | ||
|
|
8941041355 | ||
|
|
18fee4806f | ||
|
|
47d4d5bf1b | ||
|
|
74a64c47e4 | ||
|
|
a23e9c86ba | ||
|
|
4de12bf593 | ||
|
|
c542a509f0 | ||
|
|
8cf3bb8737 | ||
|
|
b46cc6d57e | ||
|
|
4a2156d3f0 | ||
|
|
41fee11f66 | ||
|
|
b592614061 | ||
|
|
b7c3039eb2 | ||
|
|
a307797c11 | ||
|
|
a03f107144 | ||
|
|
a141ab1bda | ||
|
|
52abec967f | ||
|
|
2828a9c2b0 | ||
|
|
cec7d581f3 | ||
|
|
12aa1e61da | ||
|
|
95da6c1c1d | ||
|
|
0c03a80fc4 | ||
|
|
b1c77172c2 | ||
|
|
c0373cd307 | ||
|
|
28121090c2 | ||
|
|
44a57d66c3 | ||
|
|
266f9dbe16 | ||
|
|
60e4a88f17 | ||
|
|
c50f91b7f9 | ||
|
|
e851d29565 | ||
|
|
b67b7ebfe6 | ||
|
|
751eba0e68 | ||
|
|
7447c44484 | ||
|
|
c8a672fa29 | ||
|
|
863ba76494 | ||
|
|
8526cc6647 | ||
|
|
694b7a17e7 | ||
|
|
5cd0bce452 | ||
|
|
58bd165253 | ||
|
|
65d3fb6b33 | ||
|
|
f165048172 | ||
|
|
de5516a90e | ||
|
|
4f6fd9fb98 | ||
|
|
9a9101d144 | ||
|
|
616f9499ae | ||
|
|
a40ac37550 | ||
|
|
99fd80a585 | ||
|
|
2464f7c4d1 | ||
|
|
b5c7778428 | ||
|
|
c52198d12c | ||
|
|
f17ffa0283 | ||
|
|
5e2afd91e7 | ||
|
|
79b882e901 | ||
|
|
1b502fa9ef | ||
|
|
e1969d1e33 | ||
|
|
6ac6bca7a1 | ||
|
|
3a6feb0596 | ||
|
|
2f8aa2ce30 | ||
|
|
f2bf06a419 | ||
|
|
71900248ab | ||
|
|
23055aaadf | ||
|
|
8bf6a3af97 | ||
|
|
27d6e5e186 | ||
|
|
4214b1746e | ||
|
|
f6f240573a | ||
|
|
ecdf49679e | ||
|
|
e1f722d266 | ||
|
|
2d47381b1d | ||
|
|
294ca55967 | ||
|
|
78c518ccac | ||
|
|
42a3292bcf | ||
|
|
ef70a2fcb3 | ||
|
|
af20015725 | ||
|
|
680a14afa1 | ||
|
|
bf199e5ca7 | ||
|
|
ae127a412d | ||
|
|
5ae7e6f945 | ||
|
|
d8da9c4401 | ||
|
|
daf3bfc882 | ||
|
|
94f4f13388 | ||
|
|
4615bdfd70 | ||
|
|
299f5971f2 | ||
|
|
7a1352ae87 | ||
|
|
72734d59b5 | ||
|
|
3679669aae | ||
|
|
3ed54e762e | ||
|
|
fea835b4e2 | ||
|
|
16b321b140 | ||
|
|
b58dfda212 | ||
|
|
b229aa5cf1 | ||
|
|
81c0b031f9 | ||
|
|
760863e7f9 | ||
|
|
a135699397 | ||
|
|
94a4d45dfb | ||
|
|
4de384087d | ||
|
|
57815d9cd6 | ||
|
|
644673bcf2 | ||
|
|
e7cdf2acbb | ||
|
|
0f22f008ed | ||
|
|
c184da21d0 | ||
|
|
ef5efc6a82 | ||
|
|
688014487b | ||
|
|
38ddfbc4d3 | ||
|
|
da48b925ff | ||
|
|
4bcd56fbae | ||
|
|
6e9778ae0e | ||
|
|
63c67be908 | ||
|
|
d70a4a9350 | ||
|
|
2cd9c7ef16 | ||
|
|
6ec5dc8016 | ||
|
|
fe430a680a | ||
|
|
69a0d0ee90 | ||
|
|
4557881066 | ||
|
|
9b5d069ade | ||
|
|
c56cbfe95b | ||
|
|
97e5ce4344 | ||
|
|
72bd467e23 | ||
|
|
d818b7618b | ||
|
|
1c3812a6f6 | ||
|
|
ec91b80f09 | ||
|
|
18a336c154 | ||
|
|
d21a13f1ee | ||
|
|
e0eac30ee5 | ||
|
|
fccb579471 | ||
|
|
6c700f95b5 | ||
|
|
95d070c147 | ||
|
|
da4473aba6 | ||
|
|
6e85a58045 | ||
|
|
476e2e8762 | ||
|
|
246bb46e82 | ||
|
|
fe0361ffcb | ||
|
|
952469473f | ||
|
|
02108f202e | ||
|
|
b02357f542 | ||
|
|
f2aeaef8f1 | ||
|
|
547702d285 | ||
|
|
599831f874 | ||
|
|
14c90d9e85 | ||
|
|
c41bbb3761 | ||
|
|
8a54a0f5ac | ||
|
|
c0a5530950 | ||
|
|
77ef92b95c | ||
|
|
69f75bbf70 | ||
|
|
30519f01ff | ||
|
|
7cacba0394 | ||
|
|
1596d06f8e | ||
|
|
db20c0b8d0 | ||
|
|
3ca306d69a | ||
|
|
5d272e5c08 |
27
.github/ISSUE_TEMPLATE.md
vendored
27
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,27 +0,0 @@
|
|||||||
<!--
|
|
||||||
|
|
||||||
Welcome! If you have a question or are unsure if you should open an issue,
|
|
||||||
please use the forum instead!
|
|
||||||
|
|
||||||
https://forum.restic.net
|
|
||||||
|
|
||||||
The forum is a better place for questions about restic or general suggestions
|
|
||||||
and topics, e.g. usage or documentation questions! This issue tracker is mainly
|
|
||||||
for tracking bugs and feature requests directly relating to the development of
|
|
||||||
the software itself, rather than the project.
|
|
||||||
|
|
||||||
Thanks for understanding, and for contributing to the project!
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
Output of `restic version`
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Please add the version of restic you're currently using here, this helps us
|
|
||||||
later to see what has changed in restic when we revisit this issue after some
|
|
||||||
time.
|
|
||||||
-->
|
|
||||||
|
|
||||||
Describe the issue
|
|
||||||
------------------
|
|
||||||
4
.github/ISSUE_TEMPLATE/Bug.md
vendored
4
.github/ISSUE_TEMPLATE/Bug.md
vendored
@@ -83,8 +83,8 @@ Do you have an idea how to solve the issue?
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Did restic help you or made you happy in any way?
|
Did restic help you today? Did it make you happy in any way?
|
||||||
-------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Answering this question is not required, but if you have anything positive to share, please do so here!
|
Answering this question is not required, but if you have anything positive to share, please do so here!
|
||||||
|
|||||||
8
.github/ISSUE_TEMPLATE/Feature.md
vendored
8
.github/ISSUE_TEMPLATE/Feature.md
vendored
@@ -39,16 +39,16 @@ Please describe the feature you'd like us to add here.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
What are you trying to do?
|
What are you trying to do? What problem would this solve?
|
||||||
--------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
This section should contain a brief description what you're trying to do, which
|
This section should contain a brief description what you're trying to do, which
|
||||||
would be possible after implementing the new feature.
|
would be possible after implementing the new feature.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Did restic help you or made you happy in any way?
|
Did restic help you today? Did it make you happy in any way?
|
||||||
-------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Answering this question is not required, but if you have anything positive to share, please do so here!
|
Answering this question is not required, but if you have anything positive to share, please do so here!
|
||||||
|
|||||||
4
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
4
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
contact_links:
|
||||||
|
- name: restic forum
|
||||||
|
url: https://forum.restic.net
|
||||||
|
about: Please ask questions about using restic here, do not open an issue for questions.
|
||||||
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
11
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -10,11 +10,11 @@ your time and add more commits. If you're done and ready for review, please
|
|||||||
check the last box.
|
check the last box.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
What is the purpose of this change? What does it change?
|
What does this PR change? What problem does it solve?
|
||||||
--------------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Describe the changes here, as detailed as needed.
|
Describe the changes and their purpose here, as detailed as needed.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Was the change discussed in an issue or in the forum before?
|
Was the change discussed in an issue or in the forum before?
|
||||||
@@ -23,14 +23,15 @@ Was the change discussed in an issue or in the forum before?
|
|||||||
<!--
|
<!--
|
||||||
Link issues and relevant forum posts here.
|
Link issues and relevant forum posts here.
|
||||||
|
|
||||||
If this PR resolves an issue on GitHub, use "closes #1234" so that the issue is
|
If this PR resolves an issue on GitHub, use "Closes #1234" so that the issue
|
||||||
closed automatically when this PR is merged.
|
is closed automatically when this PR is merged.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
Checklist
|
Checklist
|
||||||
---------
|
---------
|
||||||
|
|
||||||
- [ ] I have read the [Contribution Guidelines](https://github.com/restic/restic/blob/master/CONTRIBUTING.md#providing-patches)
|
- [ ] I have read the [Contribution Guidelines](https://github.com/restic/restic/blob/master/CONTRIBUTING.md#providing-patches)
|
||||||
|
- [ ] I have enabled [maintainer edits for this PR](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork)
|
||||||
- [ ] I have added tests for all changes in this PR
|
- [ ] I have added tests for all changes in this PR
|
||||||
- [ ] I have added documentation for the changes (in the manual)
|
- [ ] I have added documentation for the changes (in the manual)
|
||||||
- [ ] There's a new file in `changelog/unreleased/` that describes the changes for our users (template [here](https://github.com/restic/restic/blob/master/changelog/TEMPLATE))
|
- [ ] There's a new file in `changelog/unreleased/` that describes the changes for our users (template [here](https://github.com/restic/restic/blob/master/changelog/TEMPLATE))
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
/restic
|
/restic
|
||||||
/.vagrant
|
/.vagrant
|
||||||
|
/.vscode
|
||||||
|
|||||||
16
.travis.yml
16
.travis.yml
@@ -4,7 +4,7 @@ sudo: false
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
go: "1.10.x"
|
go: "1.13.x"
|
||||||
env: RESTIC_TEST_FUSE=0 RESTIC_TEST_CLOUD_BACKENDS=0
|
env: RESTIC_TEST_FUSE=0 RESTIC_TEST_CLOUD_BACKENDS=0
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
@@ -12,15 +12,7 @@ matrix:
|
|||||||
- $HOME/gopath/pkg/mod
|
- $HOME/gopath/pkg/mod
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
go: "1.11.x"
|
go: "1.14.x"
|
||||||
env: RESTIC_TEST_FUSE=0 RESTIC_TEST_CLOUD_BACKENDS=0
|
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- $HOME/.cache/go-build
|
|
||||||
- $HOME/gopath/pkg/mod
|
|
||||||
|
|
||||||
- os: linux
|
|
||||||
go: "1.12.x"
|
|
||||||
env: RESTIC_TEST_FUSE=0 RESTIC_TEST_CLOUD_BACKENDS=0
|
env: RESTIC_TEST_FUSE=0 RESTIC_TEST_CLOUD_BACKENDS=0
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
@@ -29,7 +21,7 @@ matrix:
|
|||||||
|
|
||||||
# only run fuse and cloud backends tests on Travis for the latest Go on Linux
|
# only run fuse and cloud backends tests on Travis for the latest Go on Linux
|
||||||
- os: linux
|
- os: linux
|
||||||
go: "1.13.x"
|
go: "1.15.x"
|
||||||
sudo: true
|
sudo: true
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
@@ -37,7 +29,7 @@ matrix:
|
|||||||
- $HOME/gopath/pkg/mod
|
- $HOME/gopath/pkg/mod
|
||||||
|
|
||||||
- os: osx
|
- os: osx
|
||||||
go: "1.13.x"
|
go: "1.15.x"
|
||||||
env: RESTIC_TEST_FUSE=0 RESTIC_TEST_CLOUD_BACKENDS=0
|
env: RESTIC_TEST_FUSE=0 RESTIC_TEST_CLOUD_BACKENDS=0
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
|
|||||||
679
CHANGELOG.md
679
CHANGELOG.md
@@ -1,3 +1,642 @@
|
|||||||
|
Changelog for restic 0.11.0 (2020-11-05)
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
The following sections list the changes in restic 0.11.0 relevant to
|
||||||
|
restic users. The changes are ordered by importance.
|
||||||
|
|
||||||
|
Summary
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Fix #1212: Restore timestamps and permissions on intermediate directories
|
||||||
|
* Fix #1756: Mark repository files as read-only when using the local backend
|
||||||
|
* Fix #2241: Hide password in REST backend repository URLs
|
||||||
|
* Fix #2319: Correctly dump directories into tar files
|
||||||
|
* Fix #2491: Don't require `self-update --output` placeholder file
|
||||||
|
* Fix #2834: Fix rare cases of backup command hanging forever
|
||||||
|
* Fix #2938: Fix manpage formatting
|
||||||
|
* Fix #2942: Make --exclude-larger-than handle disappearing files
|
||||||
|
* Fix #2951: Restic generate, help and self-update no longer check passwords
|
||||||
|
* Fix #2979: Make snapshots --json output [] instead of null when no snapshots
|
||||||
|
* Enh #2969: Optimize check for unchanged files during backup
|
||||||
|
* Enh #340: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||||
|
* Enh #2849: Authenticate to Google Cloud Storage with access token
|
||||||
|
* Enh #1458: New option --repository-file
|
||||||
|
* Enh #2978: Warn if parent snapshot cannot be loaded during backup
|
||||||
|
|
||||||
|
Details
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Bugfix #1212: Restore timestamps and permissions on intermediate directories
|
||||||
|
|
||||||
|
When using the `--include` option of the restore command, restic restored timestamps and
|
||||||
|
permissions only on directories selected by the include pattern. Intermediate directories,
|
||||||
|
which are necessary to restore files located in sub- directories, were created with default
|
||||||
|
permissions. We've fixed the restore command to restore timestamps and permissions for these
|
||||||
|
directories as well.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1212
|
||||||
|
https://github.com/restic/restic/issues/1402
|
||||||
|
https://github.com/restic/restic/pull/2906
|
||||||
|
|
||||||
|
* Bugfix #1756: Mark repository files as read-only when using the local backend
|
||||||
|
|
||||||
|
Files stored in a local repository were marked as writeable on the filesystem for non-Windows
|
||||||
|
systems, which did not prevent accidental file modifications outside of restic. In addition,
|
||||||
|
the local backend did not work with certain filesystems and network mounts which do not permit
|
||||||
|
modifications of file permissions.
|
||||||
|
|
||||||
|
Restic now marks files stored in a local repository as read-only on the filesystem on
|
||||||
|
non-Windows systems. The error handling is improved to support more filesystems.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1756
|
||||||
|
https://github.com/restic/restic/issues/2157
|
||||||
|
https://github.com/restic/restic/pull/2989
|
||||||
|
|
||||||
|
* Bugfix #2241: Hide password in REST backend repository URLs
|
||||||
|
|
||||||
|
When using a password in the REST backend repository URL, the password could in some cases be
|
||||||
|
included in the output from restic, e.g. when initializing a repo or during an error.
|
||||||
|
|
||||||
|
The password is now replaced with "***" where applicable.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2241
|
||||||
|
https://github.com/restic/restic/pull/2658
|
||||||
|
|
||||||
|
* Bugfix #2319: Correctly dump directories into tar files
|
||||||
|
|
||||||
|
The dump command previously wrote directories in a tar file in a way which can cause
|
||||||
|
compatibility problems. This caused, for example, 7zip on Windows to not open tar files
|
||||||
|
containing directories. In addition it was not possible to dump directories with extended
|
||||||
|
attributes. These compatibility problems are now corrected.
|
||||||
|
|
||||||
|
In addition, a tar file now includes the name of the owner and group of a file.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2319
|
||||||
|
https://github.com/restic/restic/pull/3039
|
||||||
|
|
||||||
|
* Bugfix #2491: Don't require `self-update --output` placeholder file
|
||||||
|
|
||||||
|
`restic self-update --output /path/to/new-restic` used to require that new-restic was an
|
||||||
|
existing file, to be overwritten. Now it's possible to download an updated restic binary to a
|
||||||
|
new path, without first having to create a placeholder file.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2491
|
||||||
|
https://github.com/restic/restic/pull/2937
|
||||||
|
|
||||||
|
* Bugfix #2834: Fix rare cases of backup command hanging forever
|
||||||
|
|
||||||
|
We've fixed an issue with the backup progress reporting which could cause restic to hang
|
||||||
|
forever right before finishing a backup.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2834
|
||||||
|
https://github.com/restic/restic/pull/2963
|
||||||
|
|
||||||
|
* Bugfix #2938: Fix manpage formatting
|
||||||
|
|
||||||
|
The manpage formatting in restic v0.10.0 was garbled, which is fixed now.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2938
|
||||||
|
https://github.com/restic/restic/pull/2977
|
||||||
|
|
||||||
|
* Bugfix #2942: Make --exclude-larger-than handle disappearing files
|
||||||
|
|
||||||
|
There was a small bug in the backup command's --exclude-larger-than option where files that
|
||||||
|
disappeared between scanning and actually backing them up to the repository caused a panic.
|
||||||
|
This is now fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2942
|
||||||
|
|
||||||
|
* Bugfix #2951: Restic generate, help and self-update no longer check passwords
|
||||||
|
|
||||||
|
The commands `restic cache`, `generate`, `help` and `self-update` don't need passwords, but
|
||||||
|
they previously did run the RESTIC_PASSWORD_COMMAND (if set in the environment), prompting
|
||||||
|
users to authenticate for no reason. They now skip running the password command.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2951
|
||||||
|
https://github.com/restic/restic/pull/2987
|
||||||
|
|
||||||
|
* Bugfix #2979: Make snapshots --json output [] instead of null when no snapshots
|
||||||
|
|
||||||
|
Restic previously output `null` instead of `[]` for the `--json snapshots` command, when
|
||||||
|
there were no snapshots in the repository. This caused some minor problems when parsing the
|
||||||
|
output, but is now fixed such that `[]` is output when the list of snapshots is empty.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2979
|
||||||
|
https://github.com/restic/restic/pull/2984
|
||||||
|
|
||||||
|
* Enhancement #2969: Optimize check for unchanged files during backup
|
||||||
|
|
||||||
|
During a backup restic skips processing files which have not changed since the last backup run.
|
||||||
|
Previously this required opening each file once which can be slow on network filesystems. The
|
||||||
|
backup command now checks for file changes before opening a file. This considerably reduces
|
||||||
|
the time to create a backup on network filesystems.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2969
|
||||||
|
https://github.com/restic/restic/pull/2970
|
||||||
|
|
||||||
|
* Enhancement #340: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||||
|
|
||||||
|
Volume Shadow Copy Service allows read access to files that are locked by another process using
|
||||||
|
an exclusive lock through a filesystem snapshot. Restic was unable to backup those files
|
||||||
|
before. This update enables backing up these files.
|
||||||
|
|
||||||
|
This needs to be enabled explicitely using the --use-fs-snapshot option of the backup
|
||||||
|
command.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/340
|
||||||
|
https://github.com/restic/restic/pull/2274
|
||||||
|
|
||||||
|
* Enhancement #2849: Authenticate to Google Cloud Storage with access token
|
||||||
|
|
||||||
|
When using the GCS backend, it is now possible to authenticate with OAuth2 access tokens
|
||||||
|
instead of a credentials file by setting the GOOGLE_ACCESS_TOKEN environment variable.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2849
|
||||||
|
|
||||||
|
* Enhancement #1458: New option --repository-file
|
||||||
|
|
||||||
|
We've added a new command-line option --repository-file as an alternative to -r. This allows
|
||||||
|
to read the repository URL from a file in order to prevent certain types of information leaks,
|
||||||
|
especially for URLs containing credentials.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1458
|
||||||
|
https://github.com/restic/restic/issues/2900
|
||||||
|
https://github.com/restic/restic/pull/2910
|
||||||
|
|
||||||
|
* Enhancement #2978: Warn if parent snapshot cannot be loaded during backup
|
||||||
|
|
||||||
|
During a backup restic uses the parent snapshot to check whether a file was changed and has to be
|
||||||
|
backed up again. For this check the backup has to read the directories contained in the old
|
||||||
|
snapshot. If a tree blob cannot be loaded, restic now warns about this problem with the backup
|
||||||
|
repository.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2978
|
||||||
|
|
||||||
|
|
||||||
|
Changelog for restic 0.10.0 (2020-09-19)
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
The following sections list the changes in restic 0.10.0 relevant to
|
||||||
|
restic users. The changes are ordered by importance.
|
||||||
|
|
||||||
|
Summary
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Fix #1863: Report correct number of directories processed by backup
|
||||||
|
* Fix #2254: Fix tar issues when dumping `/`
|
||||||
|
* Fix #2281: Handle format verbs like '%' properly in `find` output
|
||||||
|
* Fix #2298: Do not hang when run as a background job
|
||||||
|
* Fix #2389: Fix mangled json output of backup command
|
||||||
|
* Fix #2390: Refresh lock timestamp
|
||||||
|
* Fix #2429: Backup --json reports total_bytes_processed as 0
|
||||||
|
* Fix #2469: Fix incorrect bytes stats in `diff` command
|
||||||
|
* Fix #2518: Do not crash with Synology NAS sftp server
|
||||||
|
* Fix #2531: Fix incorrect size calculation in `stats --mode restore-size`
|
||||||
|
* Fix #2537: Fix incorrect file counts in `stats --mode restore-size`
|
||||||
|
* Fix #2592: SFTP backend supports IPv6 addresses
|
||||||
|
* Fix #2607: Honor RESTIC_CACHE_DIR environment variable on Mac and Windows
|
||||||
|
* Fix #2668: Don't abort the stats command when data blobs are missing
|
||||||
|
* Fix #2674: Add stricter prune error checks
|
||||||
|
* Fix #2899: Fix possible crash in the progress bar of check --read-data
|
||||||
|
* Chg #2482: Remove vendored dependencies
|
||||||
|
* Chg #2546: Return exit code 3 when failing to backup all source data
|
||||||
|
* Chg #2600: Update dependencies, require Go >= 1.13
|
||||||
|
* Chg #1597: Honor the --no-lock flag in the mount command
|
||||||
|
* Enh #1570: Support specifying multiple host flags for various commands
|
||||||
|
* Enh #1680: Optimize `restic mount`
|
||||||
|
* Enh #2072: Display snapshot date when using `restic find`
|
||||||
|
* Enh #2175: Allow specifying user and host when creating keys
|
||||||
|
* Enh #2277: Add support for ppc64le
|
||||||
|
* Enh #2395: Ignore sync errors when operation not supported by local filesystem
|
||||||
|
* Enh #2427: Add flag `--iexclude-file` to backup command
|
||||||
|
* Enh #2569: Support excluding files by their size
|
||||||
|
* Enh #2571: Self-heal missing file parts during backup of unchanged files
|
||||||
|
* Enh #2858: Support filtering snapshots by tag and path in the stats command
|
||||||
|
* Enh #323: Add command for copying snapshots between repositories
|
||||||
|
* Enh #551: Use optimized library for hash calculation of file chunks
|
||||||
|
* Enh #2195: Simplify and improve restore performance
|
||||||
|
* Enh #2328: Improve speed of check command
|
||||||
|
* Enh #2423: Support user@domain parsing as user
|
||||||
|
* Enh #2576: Improve the chunking algorithm
|
||||||
|
* Enh #2598: Improve speed of diff command
|
||||||
|
* Enh #2599: Slightly reduce memory usage of prune and stats commands
|
||||||
|
* Enh #2733: S3 backend: Add support for WebIdentityTokenFile
|
||||||
|
* Enh #2773: Optimize handling of new index entries
|
||||||
|
* Enh #2781: Reduce memory consumption of in-memory index
|
||||||
|
* Enh #2786: Optimize `list blobs` command
|
||||||
|
* Enh #2790: Optimized file access in restic mount
|
||||||
|
* Enh #2840: Speed-up file deletion in forget, prune and rebuild-index
|
||||||
|
|
||||||
|
Details
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Bugfix #1863: Report correct number of directories processed by backup
|
||||||
|
|
||||||
|
The directory statistics calculation was fixed to report the actual number of processed
|
||||||
|
directories instead of always zero.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1863
|
||||||
|
|
||||||
|
* Bugfix #2254: Fix tar issues when dumping `/`
|
||||||
|
|
||||||
|
We've fixed an issue with dumping either `/` or files on the first sublevel e.g. `/foo` to tar.
|
||||||
|
This also fixes tar dumping issues on Windows where this issue could also happen.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2254
|
||||||
|
https://github.com/restic/restic/issues/2357
|
||||||
|
https://github.com/restic/restic/pull/2255
|
||||||
|
|
||||||
|
* Bugfix #2281: Handle format verbs like '%' properly in `find` output
|
||||||
|
|
||||||
|
The JSON or "normal" output of the `find` command can now deal with file names that contain
|
||||||
|
substrings which the Golang `fmt` package considers "format verbs" like `%s`.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2281
|
||||||
|
|
||||||
|
* Bugfix #2298: Do not hang when run as a background job
|
||||||
|
|
||||||
|
Restic did hang on exit while restoring the terminal configuration when it was started as a
|
||||||
|
background job, for example using `restic ... &`. This has been fixed by only restoring the
|
||||||
|
terminal configuration when restic is interrupted while reading a password from the
|
||||||
|
terminal.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2298
|
||||||
|
|
||||||
|
* Bugfix #2389: Fix mangled json output of backup command
|
||||||
|
|
||||||
|
We've fixed a race condition in the json output of the backup command that could cause multiple
|
||||||
|
lines to get mixed up. We've also ensured that the backup summary is printed last.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2389
|
||||||
|
https://github.com/restic/restic/pull/2545
|
||||||
|
|
||||||
|
* Bugfix #2390: Refresh lock timestamp
|
||||||
|
|
||||||
|
Long-running operations did not refresh lock timestamp, resulting in locks becoming stale.
|
||||||
|
This is now fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2390
|
||||||
|
|
||||||
|
* Bugfix #2429: Backup --json reports total_bytes_processed as 0
|
||||||
|
|
||||||
|
We've fixed the json output of total_bytes_processed. The non-json output was already fixed
|
||||||
|
with pull request #2138 but left the json output untouched.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2429
|
||||||
|
|
||||||
|
* Bugfix #2469: Fix incorrect bytes stats in `diff` command
|
||||||
|
|
||||||
|
In some cases, the wrong number of bytes (e.g. 16777215.998 TiB) were reported by the `diff`
|
||||||
|
command. This is now fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2469
|
||||||
|
|
||||||
|
* Bugfix #2518: Do not crash with Synology NAS sftp server
|
||||||
|
|
||||||
|
It was found that when restic is used to store data on an sftp server on a Synology NAS with a
|
||||||
|
relative path (one which does not start with a slash), it may go into an endless loop trying to
|
||||||
|
create directories on the server. We've fixed this bug by using a function in the sftp library
|
||||||
|
instead of our own implementation.
|
||||||
|
|
||||||
|
The bug was discovered because the Synology sftp server behaves erratic with non-absolute
|
||||||
|
path (e.g. `home/restic-repo`). This can be resolved by just using an absolute path instead
|
||||||
|
(`/home/restic-repo`). We've also added a paragraph in the FAQ.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2518
|
||||||
|
https://github.com/restic/restic/issues/2363
|
||||||
|
https://github.com/restic/restic/pull/2530
|
||||||
|
|
||||||
|
* Bugfix #2531: Fix incorrect size calculation in `stats --mode restore-size`
|
||||||
|
|
||||||
|
The restore-size mode of stats was counting hard-linked files as if they were independent.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2531
|
||||||
|
|
||||||
|
* Bugfix #2537: Fix incorrect file counts in `stats --mode restore-size`
|
||||||
|
|
||||||
|
The restore-size mode of stats was failing to count empty directories and some files with hard
|
||||||
|
links.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2537
|
||||||
|
|
||||||
|
* Bugfix #2592: SFTP backend supports IPv6 addresses
|
||||||
|
|
||||||
|
The SFTP backend now supports IPv6 addresses natively, without relying on aliases in the
|
||||||
|
external SSH configuration.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2592
|
||||||
|
|
||||||
|
* Bugfix #2607: Honor RESTIC_CACHE_DIR environment variable on Mac and Windows
|
||||||
|
|
||||||
|
On Mac and Windows, the RESTIC_CACHE_DIR environment variable was ignored. This variable can
|
||||||
|
now be used on all platforms to set the directory where restic stores caches.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2607
|
||||||
|
|
||||||
|
* Bugfix #2668: Don't abort the stats command when data blobs are missing
|
||||||
|
|
||||||
|
Runing the stats command in the blobs-per-file mode on a repository with missing data blobs
|
||||||
|
previously resulted in a crash.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2668
|
||||||
|
|
||||||
|
* Bugfix #2674: Add stricter prune error checks
|
||||||
|
|
||||||
|
Additional checks were added to the prune command in order to improve resiliency to backend,
|
||||||
|
hardware and/or networking issues. The checks now detect a few more cases where such outside
|
||||||
|
factors could potentially cause data loss.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2674
|
||||||
|
|
||||||
|
* Bugfix #2899: Fix possible crash in the progress bar of check --read-data
|
||||||
|
|
||||||
|
We've fixed a possible crash while displaying the progress bar for the check --read-data
|
||||||
|
command. The crash occurred when the length of the progress bar status exceeded the terminal
|
||||||
|
width, which only happened for very narrow terminal windows.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2899
|
||||||
|
https://forum.restic.net/t/restic-rclone-pcloud-connection-issues/2963/15
|
||||||
|
|
||||||
|
* Change #2482: Remove vendored dependencies
|
||||||
|
|
||||||
|
We've removed the vendored dependencies (in the subdir `vendor/`). When building restic, the
|
||||||
|
Go compiler automatically fetches the dependencies. It will also cryptographically verify
|
||||||
|
that the correct code has been fetched by using the hashes in `go.sum` (see the link to the
|
||||||
|
documentation below).
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2482
|
||||||
|
https://golang.org/cmd/go/#hdr-Module_downloading_and_verification
|
||||||
|
|
||||||
|
* Change #2546: Return exit code 3 when failing to backup all source data
|
||||||
|
|
||||||
|
The backup command used to return a zero exit code as long as a snapshot could be created
|
||||||
|
successfully, even if some of the source files could not be read (in which case the snapshot
|
||||||
|
would contain the rest of the files).
|
||||||
|
|
||||||
|
This made it hard for automation/scripts to detect failures/incomplete backups by looking at
|
||||||
|
the exit code. Restic now returns the following exit codes for the backup command:
|
||||||
|
|
||||||
|
- 0 when the command was successful - 1 when there was a fatal error (no snapshot created) - 3 when
|
||||||
|
some source data could not be read (incomplete snapshot created)
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/956
|
||||||
|
https://github.com/restic/restic/issues/2064
|
||||||
|
https://github.com/restic/restic/issues/2526
|
||||||
|
https://github.com/restic/restic/issues/2364
|
||||||
|
https://github.com/restic/restic/pull/2546
|
||||||
|
|
||||||
|
* Change #2600: Update dependencies, require Go >= 1.13
|
||||||
|
|
||||||
|
Restic now requires Go to be at least 1.13. This allows simplifications in the build process and
|
||||||
|
removing workarounds.
|
||||||
|
|
||||||
|
This is also probably the last version of restic still supporting mounting repositories via
|
||||||
|
fuse on macOS. The library we're using for fuse does not support macOS any more and osxfuse is not
|
||||||
|
open source any more.
|
||||||
|
|
||||||
|
https://github.com/bazil/fuse/issues/224
|
||||||
|
https://github.com/osxfuse/osxfuse/issues/590
|
||||||
|
https://github.com/restic/restic/pull/2600
|
||||||
|
https://github.com/restic/restic/pull/2852
|
||||||
|
https://github.com/restic/restic/pull/2927
|
||||||
|
|
||||||
|
* Change #1597: Honor the --no-lock flag in the mount command
|
||||||
|
|
||||||
|
The mount command now does not lock the repository if given the --no-lock flag. This allows to
|
||||||
|
mount repositories which are archived on a read only backend/filesystem.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1597
|
||||||
|
https://github.com/restic/restic/pull/2821
|
||||||
|
|
||||||
|
* Enhancement #1570: Support specifying multiple host flags for various commands
|
||||||
|
|
||||||
|
Previously commands didn't take more than one `--host` or `-H` argument into account, which
|
||||||
|
could be limiting with e.g. the `forget` command.
|
||||||
|
|
||||||
|
The `dump`, `find`, `forget`, `ls`, `mount`, `restore`, `snapshots`, `stats` and `tag`
|
||||||
|
commands will now take into account multiple `--host` and `-H` flags.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1570
|
||||||
|
|
||||||
|
* Enhancement #1680: Optimize `restic mount`
|
||||||
|
|
||||||
|
We've optimized the FUSE implementation used within restic. `restic mount` is now more
|
||||||
|
responsive and uses less memory.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1680
|
||||||
|
https://github.com/restic/restic/pull/2587
|
||||||
|
https://github.com/restic/restic/pull/2787
|
||||||
|
|
||||||
|
* Enhancement #2072: Display snapshot date when using `restic find`
|
||||||
|
|
||||||
|
Added the respective snapshot date to the output of `restic find`.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2072
|
||||||
|
|
||||||
|
* Enhancement #2175: Allow specifying user and host when creating keys
|
||||||
|
|
||||||
|
When adding a new key to the repository, the username and hostname for the new key can be
|
||||||
|
specified on the command line. This allows overriding the defaults, for example if you would
|
||||||
|
prefer to use the FQDN to identify the host or if you want to add keys for several different hosts
|
||||||
|
without having to run the key add command on those hosts.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2175
|
||||||
|
|
||||||
|
* Enhancement #2277: Add support for ppc64le
|
||||||
|
|
||||||
|
Adds support for ppc64le, the processor architecture from IBM.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2277
|
||||||
|
|
||||||
|
* Enhancement #2395: Ignore sync errors when operation not supported by local filesystem
|
||||||
|
|
||||||
|
The local backend has been modified to work with filesystems which doesn't support the `sync`
|
||||||
|
operation. This operation is normally used by restic to ensure that data files are fully
|
||||||
|
written to disk before continuing.
|
||||||
|
|
||||||
|
For these limited filesystems, saving a file in the backend would previously fail with an
|
||||||
|
"operation not supported" error. This error is now ignored, which means that e.g. an SMB mount
|
||||||
|
on macOS can now be used as storage location for a repository.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2395
|
||||||
|
https://forum.restic.net/t/sync-errors-on-mac-over-smb/1859
|
||||||
|
|
||||||
|
* Enhancement #2427: Add flag `--iexclude-file` to backup command
|
||||||
|
|
||||||
|
The backup command now supports the flag `--iexclude-file` which is a case-insensitive
|
||||||
|
version of `--exclude-file`.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2427
|
||||||
|
https://github.com/restic/restic/pull/2898
|
||||||
|
|
||||||
|
* Enhancement #2569: Support excluding files by their size
|
||||||
|
|
||||||
|
The `backup` command now supports the `--exclude-larger-than` option to exclude files which
|
||||||
|
are larger than the specified maximum size. This can for example be useful to exclude
|
||||||
|
unimportant files with a large file size.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2569
|
||||||
|
https://github.com/restic/restic/pull/2914
|
||||||
|
|
||||||
|
* Enhancement #2571: Self-heal missing file parts during backup of unchanged files
|
||||||
|
|
||||||
|
We've improved the resilience of restic to certain types of repository corruption.
|
||||||
|
|
||||||
|
For files that are unchanged since the parent snapshot, the backup command now verifies that
|
||||||
|
all parts of the files still exist in the repository. Parts that are missing, e.g. from a damaged
|
||||||
|
repository, are backed up again. This verification was already run for files that were
|
||||||
|
modified since the parent snapshot, but is now also done for unchanged files.
|
||||||
|
|
||||||
|
Note that restic will not backup file parts that are referenced in the index but where the actual
|
||||||
|
data is not present on disk, as this situation can only be detected by restic check. Please
|
||||||
|
ensure that you run `restic check` regularly.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2571
|
||||||
|
https://github.com/restic/restic/pull/2827
|
||||||
|
|
||||||
|
* Enhancement #2858: Support filtering snapshots by tag and path in the stats command
|
||||||
|
|
||||||
|
We've added filtering snapshots by `--tag tagList` and by `--path path` to the `stats`
|
||||||
|
command. This includes filtering of only 'latest' snapshots or all snapshots in a repository.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2858
|
||||||
|
https://github.com/restic/restic/pull/2859
|
||||||
|
https://forum.restic.net/t/stats-for-a-host-and-filtered-snapshots/3020
|
||||||
|
|
||||||
|
* Enhancement #323: Add command for copying snapshots between repositories
|
||||||
|
|
||||||
|
We've added a copy command, allowing you to copy snapshots from one repository to another.
|
||||||
|
|
||||||
|
Note that this process will have to read (download) and write (upload) the entire snapshot(s)
|
||||||
|
due to the different encryption keys used on the source and destination repository. Also, the
|
||||||
|
transferred files are not re-chunked, which may break deduplication between files already
|
||||||
|
stored in the destination repo and files copied there using this command.
|
||||||
|
|
||||||
|
To fully support deduplication between repositories when the copy command is used, the init
|
||||||
|
command now supports the `--copy-chunker-params` option, which initializes the new
|
||||||
|
repository with identical parameters for splitting files into chunks as an already existing
|
||||||
|
repository. This allows copied snapshots to be equally deduplicated in both repositories.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/323
|
||||||
|
https://github.com/restic/restic/pull/2606
|
||||||
|
https://github.com/restic/restic/pull/2928
|
||||||
|
|
||||||
|
* Enhancement #551: Use optimized library for hash calculation of file chunks
|
||||||
|
|
||||||
|
We've switched the library used to calculate the hashes of file chunks, which are used for
|
||||||
|
deduplication, to the optimized Minio SHA-256 implementation.
|
||||||
|
|
||||||
|
Depending on the CPU it improves the hashing throughput by 10-30%. Modern x86 CPUs with the SHA
|
||||||
|
Extension should be about two to three times faster.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/551
|
||||||
|
https://github.com/restic/restic/pull/2709
|
||||||
|
|
||||||
|
* Enhancement #2195: Simplify and improve restore performance
|
||||||
|
|
||||||
|
Significantly improves restore performance of large files (i.e. 50M+):
|
||||||
|
https://github.com/restic/restic/issues/2074
|
||||||
|
https://forum.restic.net/t/restore-using-rclone-gdrive-backend-is-slow/1112/8
|
||||||
|
https://forum.restic.net/t/degraded-restore-performance-s3-backend/1400
|
||||||
|
|
||||||
|
Fixes "not enough cache capacity" error during restore:
|
||||||
|
https://github.com/restic/restic/issues/2244
|
||||||
|
|
||||||
|
NOTE: This new implementation does not guarantee order in which blobs are written to the target
|
||||||
|
files and, for example, the last blob of a file can be written to the file before any of the
|
||||||
|
preceeding file blobs. It is therefore possible to have gaps in the data written to the target
|
||||||
|
files if restore fails or interrupted by the user.
|
||||||
|
|
||||||
|
The implementation will try to preallocate space for the restored files on the filesystem to
|
||||||
|
prevent file fragmentation. This ensures good read performance for large files, like for
|
||||||
|
example VM images. If preallocating space is not supported by the filesystem, then this step is
|
||||||
|
silently skipped.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2195
|
||||||
|
https://github.com/restic/restic/pull/2893
|
||||||
|
|
||||||
|
* Enhancement #2328: Improve speed of check command
|
||||||
|
|
||||||
|
We've improved the check command to traverse trees only once independent of whether they are
|
||||||
|
contained in multiple snapshots. The check command is now much faster for repositories with a
|
||||||
|
large number of snapshots.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2284
|
||||||
|
https://github.com/restic/restic/pull/2328
|
||||||
|
|
||||||
|
* Enhancement #2423: Support user@domain parsing as user
|
||||||
|
|
||||||
|
Added the ability for user@domain-like users to be authenticated over SFTP servers.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2423
|
||||||
|
|
||||||
|
* Enhancement #2576: Improve the chunking algorithm
|
||||||
|
|
||||||
|
We've updated the chunker library responsible for splitting files into smaller blocks. It
|
||||||
|
should improve the chunking throughput by 5-15% depending on the CPU.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2820
|
||||||
|
https://github.com/restic/restic/pull/2576
|
||||||
|
https://github.com/restic/restic/pull/2845
|
||||||
|
|
||||||
|
* Enhancement #2598: Improve speed of diff command
|
||||||
|
|
||||||
|
We've improved the performance of the diff command when comparing snapshots with similar
|
||||||
|
content. It should run up to twice as fast as before.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2598
|
||||||
|
|
||||||
|
* Enhancement #2599: Slightly reduce memory usage of prune and stats commands
|
||||||
|
|
||||||
|
The prune and the stats command kept directory identifiers in memory twice while searching for
|
||||||
|
used blobs.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2599
|
||||||
|
|
||||||
|
* Enhancement #2733: S3 backend: Add support for WebIdentityTokenFile
|
||||||
|
|
||||||
|
We've added support for EKS IAM roles for service accounts feature to the S3 backend.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2703
|
||||||
|
https://github.com/restic/restic/pull/2733
|
||||||
|
|
||||||
|
* Enhancement #2773: Optimize handling of new index entries
|
||||||
|
|
||||||
|
Restic now uses less memory for backups which add a lot of data, e.g. large initial backups. In
|
||||||
|
addition, we've improved the stability in some edge cases.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2773
|
||||||
|
|
||||||
|
* Enhancement #2781: Reduce memory consumption of in-memory index
|
||||||
|
|
||||||
|
We've improved how the index is stored in memory. This change can reduce memory usage for large
|
||||||
|
repositories by up to 50% (depending on the operation).
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2781
|
||||||
|
https://github.com/restic/restic/pull/2812
|
||||||
|
|
||||||
|
* Enhancement #2786: Optimize `list blobs` command
|
||||||
|
|
||||||
|
We've changed the implementation of `list blobs` which should be now a bit faster and consume
|
||||||
|
almost no memory even for large repositories.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2786
|
||||||
|
|
||||||
|
* Enhancement #2790: Optimized file access in restic mount
|
||||||
|
|
||||||
|
Reading large (> 100GiB) files from restic mountpoints is now faster, and the speedup is
|
||||||
|
greater for larger files.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2790
|
||||||
|
|
||||||
|
* Enhancement #2840: Speed-up file deletion in forget, prune and rebuild-index
|
||||||
|
|
||||||
|
We've sped up the file deletion for the commands forget, prune and rebuild-index, especially
|
||||||
|
for remote repositories. Deletion was sequential before and is now run in parallel.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2840
|
||||||
|
|
||||||
|
|
||||||
Changelog for restic 0.9.6 (2019-11-22)
|
Changelog for restic 0.9.6 (2019-11-22)
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
@@ -12,6 +651,7 @@ Summary
|
|||||||
* Fix #2249: Read fresh metadata for unmodified files
|
* Fix #2249: Read fresh metadata for unmodified files
|
||||||
* Fix #2301: Add upper bound for t in --read-data-subset=n/t
|
* Fix #2301: Add upper bound for t in --read-data-subset=n/t
|
||||||
* Fix #2321: Check errors when loading index files
|
* Fix #2321: Check errors when loading index files
|
||||||
|
* Enh #2179: Use ctime when checking for file changes
|
||||||
* Enh #2306: Allow multiple retries for interactive password input
|
* Enh #2306: Allow multiple retries for interactive password input
|
||||||
* Enh #2330: Make `--group-by` accept both singular and plural
|
* Enh #2330: Make `--group-by` accept both singular and plural
|
||||||
* Enh #2350: Add option to configure S3 region
|
* Enh #2350: Add option to configure S3 region
|
||||||
@@ -60,6 +700,21 @@ Details
|
|||||||
https://github.com/restic/restic/pull/2321
|
https://github.com/restic/restic/pull/2321
|
||||||
https://forum.restic.net/t/check-rebuild-index-prune/1848/13
|
https://forum.restic.net/t/check-rebuild-index-prune/1848/13
|
||||||
|
|
||||||
|
* Enhancement #2179: Use ctime when checking for file changes
|
||||||
|
|
||||||
|
Previously, restic only checked a file's mtime (along with other non-timestamp metadata) to
|
||||||
|
decide if a file has changed. This could cause restic to not notice that a file has changed (and
|
||||||
|
therefore continue to store the old version, as opposed to the modified version) if something
|
||||||
|
edits the file and then resets the timestamp. Restic now also checks the ctime of files, so any
|
||||||
|
modifications to a file should be noticed, and the modified file will be backed up. The ctime
|
||||||
|
check will be disabled if the --ignore-inode flag was given.
|
||||||
|
|
||||||
|
If this change causes problems for you, please open an issue, and we can look in to adding a
|
||||||
|
seperate flag to disable just the ctime check.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2179
|
||||||
|
https://github.com/restic/restic/pull/2212
|
||||||
|
|
||||||
* Enhancement #2306: Allow multiple retries for interactive password input
|
* Enhancement #2306: Allow multiple retries for interactive password input
|
||||||
|
|
||||||
Restic used to quit if the repository password was typed incorrectly once. Restic will now ask
|
Restic used to quit if the repository password was typed incorrectly once. Restic will now ask
|
||||||
@@ -101,7 +756,6 @@ Summary
|
|||||||
* Enh #1895: Add case insensitive include & exclude options
|
* Enh #1895: Add case insensitive include & exclude options
|
||||||
* Enh #1937: Support streaming JSON output for backup
|
* Enh #1937: Support streaming JSON output for backup
|
||||||
* Enh #2155: Add Openstack application credential auth for Swift
|
* Enh #2155: Add Openstack application credential auth for Swift
|
||||||
* Enh #2179: Use ctime when checking for file changes
|
|
||||||
* Enh #2184: Add --json support to forget command
|
* Enh #2184: Add --json support to forget command
|
||||||
* Enh #2037: Add group-by option to snapshots command
|
* Enh #2037: Add group-by option to snapshots command
|
||||||
* Enh #2124: Ability to dump folders to tar via stdout
|
* Enh #2124: Ability to dump folders to tar via stdout
|
||||||
@@ -167,21 +821,6 @@ Details
|
|||||||
|
|
||||||
https://github.com/restic/restic/issues/2155
|
https://github.com/restic/restic/issues/2155
|
||||||
|
|
||||||
* Enhancement #2179: Use ctime when checking for file changes
|
|
||||||
|
|
||||||
Previously, restic only checked a file's mtime (along with other non-timestamp metadata) to
|
|
||||||
decide if a file has changed. This could cause restic to not notice that a file has changed (and
|
|
||||||
therefore continue to store the old version, as opposed to the modified version) if something
|
|
||||||
edits the file and then resets the timestamp. Restic now also checks the ctime of files, so any
|
|
||||||
modifications to a file should be noticed, and the modified file will be backed up. The ctime
|
|
||||||
check will be disabled if the --ignore-inode flag was given.
|
|
||||||
|
|
||||||
If this change causes problems for you, please open an issue, and we can look in to adding a
|
|
||||||
seperate flag to disable just the ctime check.
|
|
||||||
|
|
||||||
https://github.com/restic/restic/issues/2179
|
|
||||||
https://github.com/restic/restic/pull/2212
|
|
||||||
|
|
||||||
* Enhancement #2184: Add --json support to forget command
|
* Enhancement #2184: Add --json support to forget command
|
||||||
|
|
||||||
The forget command now supports the --json argument, outputting the information about what is
|
The forget command now supports the --json argument, outputting the information about what is
|
||||||
@@ -1361,10 +2000,10 @@ Details
|
|||||||
|
|
||||||
Exploiting the vulnerability requires a Linux/Unix system which saves backups via restic and
|
Exploiting the vulnerability requires a Linux/Unix system which saves backups via restic and
|
||||||
a Windows systems which restores files from the repo. In addition, the attackers need to be able
|
a Windows systems which restores files from the repo. In addition, the attackers need to be able
|
||||||
to create create files with arbitrary names which are then saved to the restic repo. For
|
to create files with arbitrary names which are then saved to the restic repo. For example, by
|
||||||
example, by creating a file named "..\test.txt" (which is a perfectly legal filename on Linux)
|
creating a file named "..\test.txt" (which is a perfectly legal filename on Linux) and
|
||||||
and restoring a snapshot containing this file on Windows, it would be written to the parent of
|
restoring a snapshot containing this file on Windows, it would be written to the parent of the
|
||||||
the target directory.
|
target directory.
|
||||||
|
|
||||||
We'd like to thank Tyler Spivey for reporting this responsibly!
|
We'd like to thank Tyler Spivey for reporting this responsibly!
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ help also.
|
|||||||
|
|
||||||
The restic project uses the GitHub infrastructure (see the
|
The restic project uses the GitHub infrastructure (see the
|
||||||
[project page](https://github.com/restic/restic)) for all related discussions
|
[project page](https://github.com/restic/restic)) for all related discussions
|
||||||
as well as the `#restic` channel on `irc.freenode.net`.
|
as well as the [forum](https://forum.restic.net/) and the `#restic` channel
|
||||||
|
on [irc.freenode.net](https://kiwiirc.com/nextclient/irc.freenode.net/restic).
|
||||||
|
|
||||||
If you want to find an area that currently needs improving have a look at the
|
If you want to find an area that currently needs improving have a look at the
|
||||||
open issues listed at the
|
open issues listed at the
|
||||||
@@ -25,7 +26,10 @@ for discussing enhancement to the restic tools.
|
|||||||
|
|
||||||
If you are unsure what to do, please have a look at the issues, especially
|
If you are unsure what to do, please have a look at the issues, especially
|
||||||
those tagged
|
those tagged
|
||||||
[minor complexity](https://github.com/restic/restic/labels/minor%20complexity).
|
[minor complexity](https://github.com/restic/restic/labels/help%3A%20minor%20complexity)
|
||||||
|
or [good first issue](https://github.com/restic/restic/labels/help%3A%20good%20first%20issue).
|
||||||
|
If you are already a bit experienced with the restic internals, take a look
|
||||||
|
at the issues tagged as [help wanted](https://github.com/restic/restic/labels/help%3A%20wanted).
|
||||||
|
|
||||||
|
|
||||||
Reporting Bugs
|
Reporting Bugs
|
||||||
@@ -46,15 +50,12 @@ Remember, the easier it is for us to reproduce the bug, the earlier it will be
|
|||||||
corrected!
|
corrected!
|
||||||
|
|
||||||
In addition, you can compile restic with debug support by running
|
In addition, you can compile restic with debug support by running
|
||||||
`go run -mod=vendor build.go -tags debug` and instructing it to create a debug
|
`go run build.go -tags debug` and instructing it to create a debug
|
||||||
log by setting the environment variable `DEBUG_LOG` to a file, e.g. like this:
|
log by setting the environment variable `DEBUG_LOG` to a file, e.g. like this:
|
||||||
|
|
||||||
$ export DEBUG_LOG=/tmp/restic-debug.log
|
$ export DEBUG_LOG=/tmp/restic-debug.log
|
||||||
$ restic backup ~/work
|
$ restic backup ~/work
|
||||||
|
|
||||||
For Go < 1.11, you need to remove the `-mod=vendor` option from the build
|
|
||||||
command.
|
|
||||||
|
|
||||||
Please be aware that the debug log file will contain potentially sensitive
|
Please be aware that the debug log file will contain potentially sensitive
|
||||||
things like file and directory names, so please either redact it before
|
things like file and directory names, so please either redact it before
|
||||||
uploading it somewhere or post only the parts that are really relevant.
|
uploading it somewhere or post only the parts that are really relevant.
|
||||||
@@ -63,16 +64,11 @@ uploading it somewhere or post only the parts that are really relevant.
|
|||||||
Development Environment
|
Development Environment
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
The repository contains several sets of directories with code: `cmd/` and
|
The repository contains the code written for restic in the directories
|
||||||
`internal/` contain the code written for restic, whereas `vendor/` contains
|
`cmd/` and `internal/`.
|
||||||
copies of libraries restic depends on. The libraries are managed with the
|
|
||||||
command `go mod vendor`.
|
|
||||||
|
|
||||||
Go >= 1.11
|
Restic requires Go version 1.13 or later for compiling. Clone the repo (without
|
||||||
----------
|
having `$GOPATH` set) and `cd` into the directory:
|
||||||
|
|
||||||
For Go version 1.11 or later, you should clone the repo (without having
|
|
||||||
`$GOPATH` set) and `cd` into the directory:
|
|
||||||
|
|
||||||
$ unset GOPATH
|
$ unset GOPATH
|
||||||
$ git clone https://github.com/restic/restic
|
$ git clone https://github.com/restic/restic
|
||||||
@@ -82,40 +78,12 @@ Then use the `go` tool to build restic:
|
|||||||
|
|
||||||
$ go build ./cmd/restic
|
$ go build ./cmd/restic
|
||||||
$ ./restic version
|
$ ./restic version
|
||||||
restic 0.9.2-dev (compiled manually) compiled with go1.11 on linux/amd64
|
restic 0.10.0-dev (compiled manually) compiled with go1.15.2 on linux/amd64
|
||||||
|
|
||||||
You can run all tests with the following command:
|
You can run all tests with the following command:
|
||||||
|
|
||||||
$ go test ./...
|
$ go test ./...
|
||||||
|
|
||||||
Go < 1.11
|
|
||||||
---------
|
|
||||||
|
|
||||||
In order to compile restic with Go before 1.11, it needs to be checked out at
|
|
||||||
the right path within a `GOPATH`. The concept of a `GOPATH` is explained in
|
|
||||||
["How to write Go code"](https://golang.org/doc/code.html).
|
|
||||||
|
|
||||||
If you do not have a directory with Go code yet, executing the following
|
|
||||||
instructions in your shell will create one for you and check out the restic
|
|
||||||
repo:
|
|
||||||
|
|
||||||
$ export GOPATH="$HOME/go"
|
|
||||||
$ mkdir -p "$GOPATH/src/github.com/restic"
|
|
||||||
$ cd "$GOPATH/src/github.com/restic"
|
|
||||||
$ git clone https://github.com/restic/restic
|
|
||||||
$ cd restic
|
|
||||||
|
|
||||||
You can then build restic as follows:
|
|
||||||
|
|
||||||
$ go build ./cmd/restic
|
|
||||||
$ ./restic version
|
|
||||||
restic compiled manually
|
|
||||||
compiled with go1.8.3 on linux/amd64
|
|
||||||
|
|
||||||
The following commands can be used to run all the tests:
|
|
||||||
|
|
||||||
$ go test ./...
|
|
||||||
|
|
||||||
Providing Patches
|
Providing Patches
|
||||||
=================
|
=================
|
||||||
|
|
||||||
@@ -128,20 +96,19 @@ down to the following steps:
|
|||||||
GitHub. For a new feature, please add an issue before starting to work on
|
GitHub. For a new feature, please add an issue before starting to work on
|
||||||
it, so that duplicate work is prevented.
|
it, so that duplicate work is prevented.
|
||||||
|
|
||||||
1. First we would kindly ask you to fork our project on GitHub if you haven't
|
1. Next, fork our project on GitHub if you haven't done so already.
|
||||||
done so already.
|
|
||||||
|
|
||||||
2. Clone the repository locally and create a new branch. If you are working on
|
2. Clone your fork of the repository locally and **create a new branch** for
|
||||||
the code itself, please set up the development environment as described in
|
your changes. If you are working on the code itself, please set up the
|
||||||
the previous section.
|
development environment as described in the previous section.
|
||||||
|
|
||||||
3. Then commit your changes as fine grained as possible, as smaller patches,
|
3. Commit your changes to the new branch as fine grained as possible, as
|
||||||
that handle one and only one issue are easier to discuss and merge.
|
smaller patches, for individual changes, are easier to discuss and merge.
|
||||||
|
|
||||||
4. Push the new branch with your changes to your fork of the repository.
|
4. Push the new branch with your changes to your fork of the repository.
|
||||||
|
|
||||||
5. Create a pull request by visiting the GitHub website, it will guide you
|
5. Create a pull request by visiting the GitHub website, it will guide you
|
||||||
through the process.
|
through the process. Please [allow edits from maintainers](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork).
|
||||||
|
|
||||||
6. You will receive comments on your code and the feature or bug that they
|
6. You will receive comments on your code and the feature or bug that they
|
||||||
address. Maybe you need to rework some minor things, in this case push new
|
address. Maybe you need to rework some minor things, in this case push new
|
||||||
@@ -149,20 +116,19 @@ down to the following steps:
|
|||||||
existing commit, use common sense to decide which is better), they will be
|
existing commit, use common sense to decide which is better), they will be
|
||||||
automatically added to the pull request.
|
automatically added to the pull request.
|
||||||
|
|
||||||
7. If your pull request changes anything that users should be aware
|
7. If your pull request changes anything that users should be aware of
|
||||||
of (a bugfix, a new feature, ...) please add an entry as a new
|
(a bugfix, a new feature, ...) please add an entry as a new file in
|
||||||
file in `changelog/unreleased` including the issue number in the
|
`changelog/unreleased` including the issue number in the filename (e.g.
|
||||||
filename (e.g. `issue-8756`). Use the template in
|
`issue-8756`). Use the template in `changelog/TEMPLATE` for the content.
|
||||||
`changelog/TEMPLATE` for the content. It will be used in the
|
It will be used in the announcement of the next stable release. While
|
||||||
announcement of the next stable release. While writing, ask
|
writing, ask yourself: If I were the user, what would I need to be aware
|
||||||
yourself: If I were the user, what would I need to be aware of
|
of with this change?
|
||||||
with this change.
|
|
||||||
|
|
||||||
8. Once your code looks good and passes all the tests, we'll merge it. Thanks
|
8. Once your code looks good and passes all the tests, we'll merge it. Thanks
|
||||||
a lot for your contribution!
|
a lot for your contribution!
|
||||||
|
|
||||||
Please provide the patches for each bug or feature in a separate branch and
|
Please provide the patches for each bug or feature in a separate branch and
|
||||||
open up a pull request for each.
|
open up a pull request for each, as this simplifies discussion and merging.
|
||||||
|
|
||||||
The restic project uses the `gofmt` tool for Go source indentation, so please
|
The restic project uses the `gofmt` tool for Go source indentation, so please
|
||||||
run
|
run
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -3,7 +3,7 @@
|
|||||||
all: restic
|
all: restic
|
||||||
|
|
||||||
restic:
|
restic:
|
||||||
go run -mod=vendor build.go || go run build.go
|
go run build.go
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f restic
|
rm -f restic
|
||||||
|
|||||||
114
README.md
Normal file
114
README.md
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
[](https://restic.readthedocs.io/en/latest/?badge=latest)
|
||||||
|
[](https://travis-ci.com/restic/restic)
|
||||||
|
[](https://ci.appveyor.com/project/fd0/restic/branch/master)
|
||||||
|
[](https://goreportcard.com/report/github.com/restic/restic)
|
||||||
|
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
restic is a backup program that is fast, efficient and secure. It supports the three major operating systems (Linux, macOS, Windows) and a few smaller ones (FreeBSD, OpenBSD).
|
||||||
|
|
||||||
|
For detailed usage and installation instructions check out the [documentation](https://restic.readthedocs.io/en/latest).
|
||||||
|
|
||||||
|
You can ask questions in our [Discourse forum](https://forum.restic.net).
|
||||||
|
|
||||||
|
Quick start
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Once you've [installed](https://restic.readthedocs.io/en/latest/020_installation.html) restic, start
|
||||||
|
off with creating a repository for your backups:
|
||||||
|
|
||||||
|
$ restic init --repo /tmp/backup
|
||||||
|
enter password for new backend:
|
||||||
|
enter password again:
|
||||||
|
created restic backend 085b3c76b9 at /tmp/backup
|
||||||
|
Please note that knowledge of your password is required to access the repository.
|
||||||
|
Losing your password means that your data is irrecoverably lost.
|
||||||
|
|
||||||
|
and add some data:
|
||||||
|
|
||||||
|
$ restic --repo /tmp/backup backup ~/work
|
||||||
|
enter password for repository:
|
||||||
|
scan [/home/user/work]
|
||||||
|
scanned 764 directories, 1816 files in 0:00
|
||||||
|
[0:29] 100.00% 54.732 MiB/s 1.582 GiB / 1.582 GiB 2580 / 2580 items 0 errors ETA 0:00
|
||||||
|
duration: 0:29, 54.47MiB/s
|
||||||
|
snapshot 40dc1520 saved
|
||||||
|
|
||||||
|
Next you can either use `restic restore` to restore files or use `restic
|
||||||
|
mount` to mount the repository via fuse and browse the files from previous
|
||||||
|
snapshots.
|
||||||
|
|
||||||
|
For more options check out the [online documentation](https://restic.readthedocs.io/en/latest/).
|
||||||
|
|
||||||
|
# Backends
|
||||||
|
|
||||||
|
Saving a backup on the same machine is nice but not a real backup strategy.
|
||||||
|
Therefore, restic supports the following backends for storing backups natively:
|
||||||
|
|
||||||
|
- [Local directory](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#local)
|
||||||
|
- [sftp server (via SSH)](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#sftp)
|
||||||
|
- [HTTP REST server](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#rest-server) ([protocol](doc/100_references.rst#rest-backend), [rest-server](https://github.com/restic/rest-server))
|
||||||
|
- [AWS S3](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#amazon-s3) (either from Amazon or using the [Minio](https://minio.io) server)
|
||||||
|
- [OpenStack Swift](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#openstack-swift)
|
||||||
|
- [BackBlaze B2](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2)
|
||||||
|
- [Microsoft Azure Blob Storage](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#microsoft-azure-blob-storage)
|
||||||
|
- [Google Cloud Storage](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#google-cloud-storage)
|
||||||
|
- And many other services via the [rclone](https://rclone.org) [Backend](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#other-services-via-rclone)
|
||||||
|
|
||||||
|
# Design Principles
|
||||||
|
|
||||||
|
Restic is a program that does backups right and was designed with the
|
||||||
|
following principles in mind:
|
||||||
|
|
||||||
|
- **Easy:** Doing backups should be a frictionless process, otherwise
|
||||||
|
you might be tempted to skip it. Restic should be easy to configure
|
||||||
|
and use, so that, in the event of a data loss, you can just restore
|
||||||
|
it. Likewise, restoring data should not be complicated.
|
||||||
|
|
||||||
|
- **Fast**: Backing up your data with restic should only be limited by
|
||||||
|
your network or hard disk bandwidth so that you can backup your files
|
||||||
|
every day. Nobody does backups if it takes too much time. Restoring
|
||||||
|
backups should only transfer data that is needed for the files that
|
||||||
|
are to be restored, so that this process is also fast.
|
||||||
|
|
||||||
|
- **Verifiable**: Much more important than backup is restore, so restic
|
||||||
|
enables you to easily verify that all data can be restored.
|
||||||
|
|
||||||
|
- **Secure**: Restic uses cryptography to guarantee confidentiality and
|
||||||
|
integrity of your data. The location the backup data is stored is
|
||||||
|
assumed not to be a trusted environment (e.g. a shared space where
|
||||||
|
others like system administrators are able to access your backups).
|
||||||
|
Restic is built to secure your data against such attackers.
|
||||||
|
|
||||||
|
- **Efficient**: With the growth of data, additional snapshots should
|
||||||
|
only take the storage of the actual increment. Even more, duplicate
|
||||||
|
data should be de-duplicated before it is actually written to the
|
||||||
|
storage back end to save precious backup space.
|
||||||
|
|
||||||
|
# Reproducible Builds
|
||||||
|
|
||||||
|
The binaries released with each restic version starting at 0.6.1 are
|
||||||
|
[reproducible](https://reproducible-builds.org/), which means that you can
|
||||||
|
reproduce a byte identical version from the source code for that
|
||||||
|
release. Instructions on how to do that are contained in the
|
||||||
|
[builder repository](https://github.com/restic/builder).
|
||||||
|
|
||||||
|
News
|
||||||
|
----
|
||||||
|
|
||||||
|
You can follow the restic project on Twitter [@resticbackup](https://twitter.com/resticbackup) or by subscribing to
|
||||||
|
the [project blog](https://restic.net/blog/).
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
Restic is licensed under [BSD 2-Clause License](https://opensource.org/licenses/BSD-2-Clause). You can find the
|
||||||
|
complete text in [``LICENSE``](LICENSE).
|
||||||
|
|
||||||
|
Sponsorship
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Backend integration tests for Google Cloud Storage and Microsoft Azure Blob
|
||||||
|
Storage are sponsored by [AppsCode](https://appscode.com)!
|
||||||
|
|
||||||
|
[](https://appscode.com)
|
||||||
135
README.rst
135
README.rst
@@ -1,135 +0,0 @@
|
|||||||
|Documentation| |Build Status| |Build status| |Report Card| |Say Thanks| |TestCoverage| |Reviewed by Hound|
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
------------
|
|
||||||
|
|
||||||
restic is a backup program that is fast, efficient and secure. It supports the three major operating systems (Linux, macOS, Windows) and a few smaller ones (FreeBSD, OpenBSD).
|
|
||||||
|
|
||||||
For detailed usage and installation instructions check out the `documentation <https://restic.readthedocs.io/en/latest>`__.
|
|
||||||
|
|
||||||
You can ask questions in our `Discourse forum <https://forum.restic.net>`__.
|
|
||||||
|
|
||||||
Quick start
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Once you've `installed
|
|
||||||
<https://restic.readthedocs.io/en/latest/020_installation.html>`__ restic, start
|
|
||||||
off with creating a repository for your backups:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ restic init --repo /tmp/backup
|
|
||||||
enter password for new backend:
|
|
||||||
enter password again:
|
|
||||||
created restic backend 085b3c76b9 at /tmp/backup
|
|
||||||
Please note that knowledge of your password is required to access the repository.
|
|
||||||
Losing your password means that your data is irrecoverably lost.
|
|
||||||
|
|
||||||
and add some data:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ restic --repo /tmp/backup backup ~/work
|
|
||||||
enter password for repository:
|
|
||||||
scan [/home/user/work]
|
|
||||||
scanned 764 directories, 1816 files in 0:00
|
|
||||||
[0:29] 100.00% 54.732 MiB/s 1.582 GiB / 1.582 GiB 2580 / 2580 items 0 errors ETA 0:00
|
|
||||||
duration: 0:29, 54.47MiB/s
|
|
||||||
snapshot 40dc1520 saved
|
|
||||||
|
|
||||||
Next you can either use ``restic restore`` to restore files or use ``restic
|
|
||||||
mount`` to mount the repository via fuse and browse the files from previous
|
|
||||||
snapshots.
|
|
||||||
|
|
||||||
For more options check out the `online documentation <https://restic.readthedocs.io/en/latest/>`__.
|
|
||||||
|
|
||||||
Backends
|
|
||||||
--------
|
|
||||||
|
|
||||||
Saving a backup on the same machine is nice but not a real backup strategy.
|
|
||||||
Therefore, restic supports the following backends for storing backups natively:
|
|
||||||
|
|
||||||
- `Local directory <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#local>`__
|
|
||||||
- `sftp server (via SSH) <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#sftp>`__
|
|
||||||
- `HTTP REST server <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#rest-server>`__ (`protocol <doc/100_references.rst#rest-backend>`__ `rest-server <https://github.com/restic/rest-server>`__)
|
|
||||||
- `AWS S3 <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#amazon-s3>`__ (either from Amazon or using the `Minio <https://minio.io>`__ server)
|
|
||||||
- `OpenStack Swift <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#openstack-swift>`__
|
|
||||||
- `BackBlaze B2 <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2>`__
|
|
||||||
- `Microsoft Azure Blob Storage <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#microsoft-azure-blob-storage>`__
|
|
||||||
- `Google Cloud Storage <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#google-cloud-storage>`__
|
|
||||||
- And many other services via the `rclone <https://rclone.org>`__ `Backend <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#other-services-via-rclone>`__
|
|
||||||
|
|
||||||
Design Principles
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
Restic is a program that does backups right and was designed with the
|
|
||||||
following principles in mind:
|
|
||||||
|
|
||||||
- **Easy:** Doing backups should be a frictionless process, otherwise
|
|
||||||
you might be tempted to skip it. Restic should be easy to configure
|
|
||||||
and use, so that, in the event of a data loss, you can just restore
|
|
||||||
it. Likewise, restoring data should not be complicated.
|
|
||||||
|
|
||||||
- **Fast**: Backing up your data with restic should only be limited by
|
|
||||||
your network or hard disk bandwidth so that you can backup your files
|
|
||||||
every day. Nobody does backups if it takes too much time. Restoring
|
|
||||||
backups should only transfer data that is needed for the files that
|
|
||||||
are to be restored, so that this process is also fast.
|
|
||||||
|
|
||||||
- **Verifiable**: Much more important than backup is restore, so restic
|
|
||||||
enables you to easily verify that all data can be restored.
|
|
||||||
|
|
||||||
- **Secure**: Restic uses cryptography to guarantee confidentiality and
|
|
||||||
integrity of your data. The location the backup data is stored is
|
|
||||||
assumed not to be a trusted environment (e.g. a shared space where
|
|
||||||
others like system administrators are able to access your backups).
|
|
||||||
Restic is built to secure your data against such attackers.
|
|
||||||
|
|
||||||
- **Efficient**: With the growth of data, additional snapshots should
|
|
||||||
only take the storage of the actual increment. Even more, duplicate
|
|
||||||
data should be de-duplicated before it is actually written to the
|
|
||||||
storage back end to save precious backup space.
|
|
||||||
|
|
||||||
Reproducible Builds
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
The binaries released with each restic version starting at 0.6.1 are
|
|
||||||
`reproducible <https://reproducible-builds.org/>`__, which means that you can
|
|
||||||
easily reproduce a byte identical version from the source code for that
|
|
||||||
release. Instructions on how to do that are contained in the
|
|
||||||
`builder repository <https://github.com/restic/builder>`__.
|
|
||||||
|
|
||||||
News
|
|
||||||
----
|
|
||||||
|
|
||||||
You can follow the restic project on Twitter `@resticbackup <https://twitter.com/resticbackup>`__ or by subscribing to
|
|
||||||
the `development blog <https://restic.net/blog/>`__.
|
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
Restic is licensed under `BSD 2-Clause License <https://opensource.org/licenses/BSD-2-Clause>`__. You can find the
|
|
||||||
complete text in ``LICENSE``.
|
|
||||||
|
|
||||||
Sponsorship
|
|
||||||
-----------
|
|
||||||
|
|
||||||
Backend integration tests for Google Cloud Storage and Microsoft Azure Blob
|
|
||||||
Storage are sponsored by `AppsCode <https://appscode.com>`__!
|
|
||||||
|
|
||||||
|AppsCode|
|
|
||||||
|
|
||||||
.. |Documentation| image:: https://readthedocs.org/projects/restic/badge/?version=latest
|
|
||||||
:target: https://restic.readthedocs.io/en/latest/?badge=latest
|
|
||||||
.. |Build Status| image:: https://travis-ci.com/restic/restic.svg?branch=master
|
|
||||||
:target: https://travis-ci.com/restic/restic
|
|
||||||
.. |Build status| image:: https://ci.appveyor.com/api/projects/status/nuy4lfbgfbytw92q/branch/master?svg=true
|
|
||||||
:target: https://ci.appveyor.com/project/fd0/restic/branch/master
|
|
||||||
.. |Report Card| image:: https://goreportcard.com/badge/github.com/restic/restic
|
|
||||||
:target: https://goreportcard.com/report/github.com/restic/restic
|
|
||||||
.. |Say Thanks| image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg
|
|
||||||
:target: https://saythanks.io/to/restic
|
|
||||||
.. |AppsCode| image:: https://cdn.appscode.com/images/logo/appscode/ac-logo-color.png
|
|
||||||
:target: https://appscode.com
|
|
||||||
.. |Reviewed by Hound| image:: https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg
|
|
||||||
:target: https://houndci.com
|
|
||||||
@@ -20,13 +20,13 @@ init:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
- rmdir c:\go /s /q
|
- rmdir c:\go /s /q
|
||||||
- appveyor DownloadFile https://dl.google.com/go/go1.13.4.windows-amd64.msi
|
- appveyor DownloadFile https://dl.google.com/go/go1.15.2.windows-amd64.msi
|
||||||
- msiexec /i go1.13.4.windows-amd64.msi /q
|
- msiexec /i go1.15.2.windows-amd64.msi /q
|
||||||
- go version
|
- go version
|
||||||
- go env
|
- go env
|
||||||
- appveyor DownloadFile http://sourceforge.netcologne.de/project/gnuwin32/tar/1.13-1/tar-1.13-1-bin.zip -FileName tar.zip
|
- appveyor DownloadFile https://sourceforge.netcologne.de/project/gnuwin32/tar/1.13-1/tar-1.13-1-bin.zip -FileName tar.zip
|
||||||
- 7z x tar.zip bin/tar.exe
|
- 7z x tar.zip bin/tar.exe
|
||||||
- set PATH=bin/;%PATH%
|
- set PATH=bin/;%PATH%
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- go run -mod=vendor run_integration_tests.go
|
- go run run_integration_tests.go
|
||||||
|
|||||||
273
build.go
273
build.go
@@ -3,22 +3,15 @@
|
|||||||
// This program aims to make building Go programs for end users easier by just
|
// This program aims to make building Go programs for end users easier by just
|
||||||
// calling it with `go run`, without having to setup a GOPATH.
|
// calling it with `go run`, without having to setup a GOPATH.
|
||||||
//
|
//
|
||||||
// For Go < 1.11, it'll create a new GOPATH in a temporary directory, then run
|
// This program needs Go >= 1.12. It'll use Go modules for compilation. It
|
||||||
// `go build` on the package configured as Main in the Config struct.
|
// builds the package configured as Main in the Config struct.
|
||||||
//
|
|
||||||
// For Go >= 1.11 if the file go.mod is present, it'll use Go modules and not
|
|
||||||
// setup a GOPATH. It builds the package configured as Main in the Config
|
|
||||||
// struct with `go build -mod=vendor` to use the vendored dependencies.
|
|
||||||
// The variable GOPROXY is set to `off` so that no network calls are made. All
|
|
||||||
// files are copied to a temporary directory before `go build` is called within
|
|
||||||
// that directory.
|
|
||||||
|
|
||||||
// BSD 2-Clause License
|
// BSD 2-Clause License
|
||||||
//
|
//
|
||||||
// Copyright (c) 2016-2018, Alexander Neumann <alexander@bumpern.de>
|
// Copyright (c) 2016-2018, Alexander Neumann <alexander@bumpern.de>
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
// This file has been copied from the repository at:
|
// This file has been derived from the repository at:
|
||||||
// https://github.com/fd0/build-go
|
// https://github.com/fd0/build-go
|
||||||
//
|
//
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
@@ -65,7 +58,7 @@ var config = Config{
|
|||||||
Main: "./cmd/restic", // package name for the main package
|
Main: "./cmd/restic", // package name for the main package
|
||||||
DefaultBuildTags: []string{"selfupdate"}, // specify build tags which are always used
|
DefaultBuildTags: []string{"selfupdate"}, // specify build tags which are always used
|
||||||
Tests: []string{"./..."}, // tests to run
|
Tests: []string{"./..."}, // tests to run
|
||||||
MinVersion: GoVersion{Major: 1, Minor: 10, Patch: 0}, // minimum Go version supported
|
MinVersion: GoVersion{Major: 1, Minor: 11, Patch: 0}, // minimum Go version supported
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config configures the build.
|
// Config configures the build.
|
||||||
@@ -79,125 +72,13 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
verbose bool
|
verbose bool
|
||||||
keepGopath bool
|
runTests bool
|
||||||
runTests bool
|
enableCGO bool
|
||||||
enableCGO bool
|
enablePIE bool
|
||||||
enablePIE bool
|
goVersion = ParseGoVersion(runtime.Version())
|
||||||
goVersion = ParseGoVersion(runtime.Version())
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// copy all Go files in src to dst, creating directories on the fly, so calling
|
|
||||||
//
|
|
||||||
// copy("/tmp/gopath/src/github.com/restic/restic", "/home/u/restic")
|
|
||||||
//
|
|
||||||
// with "/home/u/restic" containing the file "foo.go" yields the following tree
|
|
||||||
// at "/tmp/gopath":
|
|
||||||
//
|
|
||||||
// /tmp/gopath
|
|
||||||
// └── src
|
|
||||||
// └── github.com
|
|
||||||
// └── restic
|
|
||||||
// └── restic
|
|
||||||
// └── foo.go
|
|
||||||
func copy(dst, src string) error {
|
|
||||||
verbosePrintf("copy contents of %v to %v\n", src, dst)
|
|
||||||
return filepath.Walk(src, func(name string, fi os.FileInfo, err error) error {
|
|
||||||
if name == src {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == ".git" {
|
|
||||||
return filepath.SkipDir
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi.IsDir() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
intermediatePath, err := filepath.Rel(src, name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fileSrc := filepath.Join(src, intermediatePath)
|
|
||||||
fileDst := filepath.Join(dst, intermediatePath)
|
|
||||||
|
|
||||||
return copyFile(fileDst, fileSrc)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func directoryExists(dirname string) bool {
|
|
||||||
stat, err := os.Stat(dirname)
|
|
||||||
if err != nil && os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return stat.IsDir()
|
|
||||||
}
|
|
||||||
|
|
||||||
func fileExists(filename string) bool {
|
|
||||||
stat, err := os.Stat(filename)
|
|
||||||
if err != nil && os.IsNotExist(err) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return stat.Mode().IsRegular()
|
|
||||||
}
|
|
||||||
|
|
||||||
// copyFile creates dst from src, preserving file attributes and timestamps.
|
|
||||||
func copyFile(dst, src string) error {
|
|
||||||
fi, err := os.Stat(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fsrc, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
|
|
||||||
fmt.Printf("MkdirAll(%v)\n", filepath.Dir(dst))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fdst, err := os.Create(dst)
|
|
||||||
if err != nil {
|
|
||||||
_ = fsrc.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = io.Copy(fdst, fsrc)
|
|
||||||
if err != nil {
|
|
||||||
_ = fsrc.Close()
|
|
||||||
_ = fdst.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = fdst.Close()
|
|
||||||
if err != nil {
|
|
||||||
_ = fsrc.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = fsrc.Close()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = os.Chmod(dst, fi.Mode())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.Chtimes(dst, fi.ModTime(), fi.ModTime())
|
|
||||||
}
|
|
||||||
|
|
||||||
// die prints the message with fmt.Fprintf() to stderr and exits with an error
|
// die prints the message with fmt.Fprintf() to stderr and exits with an error
|
||||||
// code.
|
// code.
|
||||||
func die(message string, args ...interface{}) {
|
func die(message string, args ...interface{}) {
|
||||||
@@ -211,7 +92,6 @@ func showUsage(output io.Writer) {
|
|||||||
fmt.Fprintf(output, "OPTIONS:\n")
|
fmt.Fprintf(output, "OPTIONS:\n")
|
||||||
fmt.Fprintf(output, " -v --verbose output more messages\n")
|
fmt.Fprintf(output, " -v --verbose output more messages\n")
|
||||||
fmt.Fprintf(output, " -t --tags specify additional build tags\n")
|
fmt.Fprintf(output, " -t --tags specify additional build tags\n")
|
||||||
fmt.Fprintf(output, " -k --keep-tempdir do not remove the temporary directory after build\n")
|
|
||||||
fmt.Fprintf(output, " -T --test run tests\n")
|
fmt.Fprintf(output, " -T --test run tests\n")
|
||||||
fmt.Fprintf(output, " -o --output set output file name\n")
|
fmt.Fprintf(output, " -o --output set output file name\n")
|
||||||
fmt.Fprintf(output, " --enable-cgo use CGO to link against libc\n")
|
fmt.Fprintf(output, " --enable-cgo use CGO to link against libc\n")
|
||||||
@@ -219,7 +99,6 @@ func showUsage(output io.Writer) {
|
|||||||
fmt.Fprintf(output, " --goos value set GOOS for cross-compilation\n")
|
fmt.Fprintf(output, " --goos value set GOOS for cross-compilation\n")
|
||||||
fmt.Fprintf(output, " --goarch value set GOARCH for cross-compilation\n")
|
fmt.Fprintf(output, " --goarch value set GOARCH for cross-compilation\n")
|
||||||
fmt.Fprintf(output, " --goarm value set GOARM for cross-compilation\n")
|
fmt.Fprintf(output, " --goarm value set GOARM for cross-compilation\n")
|
||||||
fmt.Fprintf(output, " --tempdir dir use a specific directory for compilation\n")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func verbosePrintf(message string, args ...interface{}) {
|
func verbosePrintf(message string, args ...interface{}) {
|
||||||
@@ -230,49 +109,39 @@ func verbosePrintf(message string, args ...interface{}) {
|
|||||||
fmt.Printf("build: "+message, args...)
|
fmt.Printf("build: "+message, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanEnv returns a clean environment with GOPATH, GOBIN and GO111MODULE
|
// printEnv prints Go-relevant environment variables in a nice way using verbosePrintf.
|
||||||
// removed (if present).
|
func printEnv(env []string) {
|
||||||
func cleanEnv() (env []string) {
|
verbosePrintf("environment (GO*):\n")
|
||||||
removeKeys := map[string]struct{}{
|
for _, v := range env {
|
||||||
"GOPATH": struct{}{},
|
// ignore environment variables which do not start with GO*.
|
||||||
"GOBIN": struct{}{},
|
if !strings.HasPrefix(v, "GO") {
|
||||||
"GO111MODULE": struct{}{},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range os.Environ() {
|
|
||||||
data := strings.SplitN(v, "=", 2)
|
|
||||||
name := data[0]
|
|
||||||
|
|
||||||
if _, ok := removeKeys[name]; ok {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
verbosePrintf(" %s\n", v)
|
||||||
env = append(env, v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return env
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// build runs "go build args..." with GOPATH set to gopath.
|
// build runs "go build args..." with GOPATH set to gopath.
|
||||||
func build(cwd string, env map[string]string, args ...string) error {
|
func build(cwd string, env map[string]string, args ...string) error {
|
||||||
a := []string{"build"}
|
a := []string{"build"}
|
||||||
|
|
||||||
if goVersion.AtLeast(GoVersion{1, 10, 0}) {
|
// try to remove all absolute paths from resulting binary
|
||||||
verbosePrintf("Go version is at least 1.10, using new syntax for -gcflags\n")
|
if goVersion.AtLeast(GoVersion{1, 13, 0}) {
|
||||||
// use new prefix
|
// use the new flag introduced by Go 1.13
|
||||||
|
a = append(a, "-trimpath")
|
||||||
|
} else {
|
||||||
|
// otherwise try to trim as many paths as possible
|
||||||
a = append(a, "-asmflags", fmt.Sprintf("all=-trimpath=%s", cwd))
|
a = append(a, "-asmflags", fmt.Sprintf("all=-trimpath=%s", cwd))
|
||||||
a = append(a, "-gcflags", fmt.Sprintf("all=-trimpath=%s", cwd))
|
a = append(a, "-gcflags", fmt.Sprintf("all=-trimpath=%s", cwd))
|
||||||
} else {
|
|
||||||
a = append(a, "-asmflags", fmt.Sprintf("-trimpath=%s", cwd))
|
|
||||||
a = append(a, "-gcflags", fmt.Sprintf("-trimpath=%s", cwd))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if enablePIE {
|
if enablePIE {
|
||||||
a = append(a, "-buildmode=pie")
|
a = append(a, "-buildmode=pie")
|
||||||
}
|
}
|
||||||
|
|
||||||
a = append(a, args...)
|
a = append(a, args...)
|
||||||
cmd := exec.Command("go", a...)
|
cmd := exec.Command("go", a...)
|
||||||
cmd.Env = append(cleanEnv(), "GOPROXY=off")
|
cmd.Env = os.Environ()
|
||||||
for k, v := range env {
|
for k, v := range env {
|
||||||
cmd.Env = append(cmd.Env, k+"="+v)
|
cmd.Env = append(cmd.Env, k+"="+v)
|
||||||
}
|
}
|
||||||
@@ -280,6 +149,8 @@ func build(cwd string, env map[string]string, args ...string) error {
|
|||||||
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
|
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printEnv(cmd.Env)
|
||||||
|
|
||||||
cmd.Dir = cwd
|
cmd.Dir = cwd
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
@@ -294,7 +165,7 @@ func build(cwd string, env map[string]string, args ...string) error {
|
|||||||
func test(cwd string, env map[string]string, args ...string) error {
|
func test(cwd string, env map[string]string, args ...string) error {
|
||||||
args = append([]string{"test", "-count", "1"}, args...)
|
args = append([]string{"test", "-count", "1"}, args...)
|
||||||
cmd := exec.Command("go", args...)
|
cmd := exec.Command("go", args...)
|
||||||
cmd.Env = append(cleanEnv(), "GOPROXY=off")
|
cmd.Env = os.Environ()
|
||||||
for k, v := range env {
|
for k, v := range env {
|
||||||
cmd.Env = append(cmd.Env, k+"="+v)
|
cmd.Env = append(cmd.Env, k+"="+v)
|
||||||
}
|
}
|
||||||
@@ -305,6 +176,8 @@ func test(cwd string, env map[string]string, args ...string) error {
|
|||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
printEnv(cmd.Env)
|
||||||
|
|
||||||
verbosePrintf("chdir %q\n", cwd)
|
verbosePrintf("chdir %q\n", cwd)
|
||||||
verbosePrintf("go %q\n", args)
|
verbosePrintf("go %q\n", args)
|
||||||
|
|
||||||
@@ -454,6 +327,10 @@ func (v GoVersion) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
if !goVersion.AtLeast(GoVersion{1, 12, 0}) {
|
||||||
|
die("Go version (%v) is too old, restic requires Go >= 1.12\n", goVersion)
|
||||||
|
}
|
||||||
|
|
||||||
if !goVersion.AtLeast(config.MinVersion) {
|
if !goVersion.AtLeast(config.MinVersion) {
|
||||||
fmt.Fprintf(os.Stderr, "%s detected, this program requires at least %s\n", goVersion, config.MinVersion)
|
fmt.Fprintf(os.Stderr, "%s detected, this program requires at least %s\n", goVersion, config.MinVersion)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@@ -464,15 +341,13 @@ func main() {
|
|||||||
skipNext := false
|
skipNext := false
|
||||||
params := os.Args[1:]
|
params := os.Args[1:]
|
||||||
|
|
||||||
goEnv := map[string]string{}
|
env := map[string]string{
|
||||||
buildEnv := map[string]string{
|
"GO111MODULE": "on", // make sure we build in Module mode
|
||||||
"GOOS": runtime.GOOS,
|
"GOOS": runtime.GOOS,
|
||||||
"GOARCH": runtime.GOARCH,
|
"GOARCH": runtime.GOARCH,
|
||||||
"GOARM": "",
|
"GOARM": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
tempdir := ""
|
|
||||||
|
|
||||||
var outputFilename string
|
var outputFilename string
|
||||||
|
|
||||||
for i, arg := range params {
|
for i, arg := range params {
|
||||||
@@ -484,8 +359,6 @@ func main() {
|
|||||||
switch arg {
|
switch arg {
|
||||||
case "-v", "--verbose":
|
case "-v", "--verbose":
|
||||||
verbose = true
|
verbose = true
|
||||||
case "-k", "--keep-gopath":
|
|
||||||
keepGopath = true
|
|
||||||
case "-t", "-tags", "--tags":
|
case "-t", "-tags", "--tags":
|
||||||
if i+1 >= len(params) {
|
if i+1 >= len(params) {
|
||||||
die("-t given but no tag specified")
|
die("-t given but no tag specified")
|
||||||
@@ -495,9 +368,6 @@ func main() {
|
|||||||
case "-o", "--output":
|
case "-o", "--output":
|
||||||
skipNext = true
|
skipNext = true
|
||||||
outputFilename = params[i+1]
|
outputFilename = params[i+1]
|
||||||
case "--tempdir":
|
|
||||||
skipNext = true
|
|
||||||
tempdir = params[i+1]
|
|
||||||
case "-T", "--test":
|
case "-T", "--test":
|
||||||
runTests = true
|
runTests = true
|
||||||
case "--enable-cgo":
|
case "--enable-cgo":
|
||||||
@@ -506,13 +376,13 @@ func main() {
|
|||||||
enablePIE = true
|
enablePIE = true
|
||||||
case "--goos":
|
case "--goos":
|
||||||
skipNext = true
|
skipNext = true
|
||||||
buildEnv["GOOS"] = params[i+1]
|
env["GOOS"] = params[i+1]
|
||||||
case "--goarch":
|
case "--goarch":
|
||||||
skipNext = true
|
skipNext = true
|
||||||
buildEnv["GOARCH"] = params[i+1]
|
env["GOARCH"] = params[i+1]
|
||||||
case "--goarm":
|
case "--goarm":
|
||||||
skipNext = true
|
skipNext = true
|
||||||
buildEnv["GOARM"] = params[i+1]
|
env["GOARM"] = params[i+1]
|
||||||
case "-h":
|
case "-h":
|
||||||
showUsage(os.Stdout)
|
showUsage(os.Stdout)
|
||||||
return
|
return
|
||||||
@@ -525,8 +395,12 @@ func main() {
|
|||||||
|
|
||||||
verbosePrintf("detected Go version %v\n", goVersion)
|
verbosePrintf("detected Go version %v\n", goVersion)
|
||||||
|
|
||||||
|
preserveSymbols := false
|
||||||
for i := range buildTags {
|
for i := range buildTags {
|
||||||
buildTags[i] = strings.TrimSpace(buildTags[i])
|
buildTags[i] = strings.TrimSpace(buildTags[i])
|
||||||
|
if buildTags[i] == "debug" || buildTags[i] == "profile" {
|
||||||
|
preserveSymbols = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verbosePrintf("build tags: %s\n", buildTags)
|
verbosePrintf("build tags: %s\n", buildTags)
|
||||||
@@ -538,7 +412,7 @@ func main() {
|
|||||||
|
|
||||||
if outputFilename == "" {
|
if outputFilename == "" {
|
||||||
outputFilename = config.Name
|
outputFilename = config.Name
|
||||||
if buildEnv["GOOS"] == "windows" {
|
if env["GOOS"] == "windows" {
|
||||||
outputFilename += ".exe"
|
outputFilename += ".exe"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -553,7 +427,11 @@ func main() {
|
|||||||
if version != "" {
|
if version != "" {
|
||||||
constants["main.version"] = version
|
constants["main.version"] = version
|
||||||
}
|
}
|
||||||
ldflags := "-s -w " + constants.LDFlags()
|
ldflags := constants.LDFlags()
|
||||||
|
if !preserveSymbols {
|
||||||
|
// Strip debug symbols.
|
||||||
|
ldflags = "-s -w " + ldflags
|
||||||
|
}
|
||||||
verbosePrintf("ldflags: %s\n", ldflags)
|
verbosePrintf("ldflags: %s\n", ldflags)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -567,57 +445,18 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildTarget := filepath.FromSlash(mainPackage)
|
buildTarget := filepath.FromSlash(mainPackage)
|
||||||
buildCWD := ""
|
buildCWD, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
if goVersion.AtLeast(GoVersion{1, 11, 0}) && fileExists("go.mod") {
|
die("unable to determine current working directory: %v\n", err)
|
||||||
verbosePrintf("Go >= 1.11 and 'go.mod' found, building with modules\n")
|
|
||||||
buildCWD = root
|
|
||||||
|
|
||||||
buildArgs = append(buildArgs, "-mod=vendor")
|
|
||||||
testArgs = append(testArgs, "-mod=vendor")
|
|
||||||
|
|
||||||
goEnv["GO111MODULE"] = "on"
|
|
||||||
buildEnv["GO111MODULE"] = "on"
|
|
||||||
} else {
|
|
||||||
if tempdir == "" {
|
|
||||||
tempdir, err = ioutil.TempDir("", fmt.Sprintf("%v-build-", config.Name))
|
|
||||||
if err != nil {
|
|
||||||
die("TempDir(): %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
verbosePrintf("Go < 1.11 or 'go.mod' not found, create GOPATH at %v\n", tempdir)
|
|
||||||
targetdir := filepath.Join(tempdir, "src", filepath.FromSlash(config.Namespace))
|
|
||||||
if err = copy(targetdir, root); err != nil {
|
|
||||||
die("copying files from %v to %v/src failed: %v\n", root, tempdir, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if !keepGopath {
|
|
||||||
verbosePrintf("remove %v\n", tempdir)
|
|
||||||
if err = os.RemoveAll(tempdir); err != nil {
|
|
||||||
die("remove GOPATH at %s failed: %v\n", tempdir, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
verbosePrintf("leaving temporary GOPATH at %v\n", tempdir)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
buildCWD = targetdir
|
|
||||||
|
|
||||||
goEnv["GOPATH"] = tempdir
|
|
||||||
buildEnv["GOPATH"] = tempdir
|
|
||||||
}
|
}
|
||||||
|
|
||||||
verbosePrintf("environment:\n go: %v\n build: %v\n", goEnv, buildEnv)
|
|
||||||
|
|
||||||
buildArgs = append(buildArgs,
|
buildArgs = append(buildArgs,
|
||||||
"-tags", strings.Join(buildTags, " "),
|
"-tags", strings.Join(buildTags, " "),
|
||||||
"-ldflags", ldflags,
|
"-ldflags", ldflags,
|
||||||
"-o", output, buildTarget,
|
"-o", output, buildTarget,
|
||||||
)
|
)
|
||||||
|
|
||||||
err = build(buildCWD, buildEnv, buildArgs...)
|
err = build(buildCWD, env, buildArgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
die("build failed: %v\n", err)
|
die("build failed: %v\n", err)
|
||||||
}
|
}
|
||||||
@@ -627,7 +466,7 @@ func main() {
|
|||||||
|
|
||||||
testArgs = append(testArgs, config.Tests...)
|
testArgs = append(testArgs, config.Tests...)
|
||||||
|
|
||||||
err = test(buildCWD, goEnv, testArgs...)
|
err = test(buildCWD, env, testArgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
die("running tests failed: %v\n", err)
|
die("running tests failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|||||||
9
changelog/0.10.0_2020-09-19/issue-1570
Normal file
9
changelog/0.10.0_2020-09-19/issue-1570
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Enhancement: Support specifying multiple host flags for various commands
|
||||||
|
|
||||||
|
Previously commands didn't take more than one `--host` or `-H` argument into account, which could be limiting with e.g.
|
||||||
|
the `forget` command.
|
||||||
|
|
||||||
|
The `dump`, `find`, `forget`, `ls`, `mount`, `restore`, `snapshots`, `stats` and `tag` commands will now take into account
|
||||||
|
multiple `--host` and `-H` flags.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1570
|
||||||
8
changelog/0.10.0_2020-09-19/issue-1680
Normal file
8
changelog/0.10.0_2020-09-19/issue-1680
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Enhancement: Optimize `restic mount`
|
||||||
|
|
||||||
|
We've optimized the FUSE implementation used within restic.
|
||||||
|
`restic mount` is now more responsive and uses less memory.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1680
|
||||||
|
https://github.com/restic/restic/pull/2587
|
||||||
|
https://github.com/restic/restic/pull/2787
|
||||||
6
changelog/0.10.0_2020-09-19/issue-1863
Normal file
6
changelog/0.10.0_2020-09-19/issue-1863
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Bugfix: Report correct number of directories processed by backup
|
||||||
|
|
||||||
|
The directory statistics calculation was fixed to report the actual number
|
||||||
|
of processed directories instead of always zero.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1863
|
||||||
5
changelog/0.10.0_2020-09-19/issue-2072
Normal file
5
changelog/0.10.0_2020-09-19/issue-2072
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Enhancement: Display snapshot date when using `restic find`
|
||||||
|
|
||||||
|
Added the respective snapshot date to the output of `restic find`.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2072
|
||||||
9
changelog/0.10.0_2020-09-19/issue-2175
Normal file
9
changelog/0.10.0_2020-09-19/issue-2175
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Enhancement: Allow specifying user and host when creating keys
|
||||||
|
|
||||||
|
When adding a new key to the repository, the username and hostname for the new
|
||||||
|
key can be specified on the command line. This allows overriding the defaults,
|
||||||
|
for example if you would prefer to use the FQDN to identify the host or if you
|
||||||
|
want to add keys for several different hosts without having to run the key add
|
||||||
|
command on those hosts.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2175
|
||||||
9
changelog/0.10.0_2020-09-19/issue-2254
Normal file
9
changelog/0.10.0_2020-09-19/issue-2254
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: Fix tar issues when dumping `/`
|
||||||
|
|
||||||
|
We've fixed an issue with dumping either `/` or files on the first sublevel
|
||||||
|
e.g. `/foo` to tar. This also fixes tar dumping issues on Windows where this
|
||||||
|
issue could also happen.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2254
|
||||||
|
https://github.com/restic/restic/issues/2357
|
||||||
|
https://github.com/restic/restic/pull/2255
|
||||||
5
changelog/0.10.0_2020-09-19/issue-2277
Normal file
5
changelog/0.10.0_2020-09-19/issue-2277
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Enhancement: Add support for ppc64le
|
||||||
|
|
||||||
|
Adds support for ppc64le, the processor architecture from IBM.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2277
|
||||||
7
changelog/0.10.0_2020-09-19/issue-2281
Normal file
7
changelog/0.10.0_2020-09-19/issue-2281
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Bugfix: Handle format verbs like '%' properly in `find` output
|
||||||
|
|
||||||
|
The JSON or "normal" output of the `find` command can now deal with file names
|
||||||
|
that contain substrings which the Golang `fmt` package considers "format verbs"
|
||||||
|
like `%s`.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2281
|
||||||
8
changelog/0.10.0_2020-09-19/issue-2298
Normal file
8
changelog/0.10.0_2020-09-19/issue-2298
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Bugfix: Do not hang when run as a background job
|
||||||
|
|
||||||
|
Restic did hang on exit while restoring the terminal configuration when it was
|
||||||
|
started as a background job, for example using `restic ... &`. This has been
|
||||||
|
fixed by only restoring the terminal configuration when restic is interrupted
|
||||||
|
while reading a password from the terminal.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2298
|
||||||
8
changelog/0.10.0_2020-09-19/issue-2389
Normal file
8
changelog/0.10.0_2020-09-19/issue-2389
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Bugfix: Fix mangled json output of backup command
|
||||||
|
|
||||||
|
We've fixed a race condition in the json output of the backup command
|
||||||
|
that could cause multiple lines to get mixed up. We've also ensured that
|
||||||
|
the backup summary is printed last.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2389
|
||||||
|
https://github.com/restic/restic/pull/2545
|
||||||
5
changelog/0.10.0_2020-09-19/issue-2390
Normal file
5
changelog/0.10.0_2020-09-19/issue-2390
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Bugfix: Refresh lock timestamp
|
||||||
|
|
||||||
|
Long-running operations did not refresh lock timestamp, resulting in locks becoming stale. This is now fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2390
|
||||||
12
changelog/0.10.0_2020-09-19/issue-2395
Normal file
12
changelog/0.10.0_2020-09-19/issue-2395
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Enhancement: Ignore sync errors when operation not supported by local filesystem
|
||||||
|
|
||||||
|
The local backend has been modified to work with filesystems which doesn't support
|
||||||
|
the `sync` operation. This operation is normally used by restic to ensure that data
|
||||||
|
files are fully written to disk before continuing.
|
||||||
|
|
||||||
|
For these limited filesystems, saving a file in the backend would previously fail with
|
||||||
|
an "operation not supported" error. This error is now ignored, which means that e.g.
|
||||||
|
an SMB mount on macOS can now be used as storage location for a repository.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2395
|
||||||
|
https://forum.restic.net/t/sync-errors-on-mac-over-smb/1859
|
||||||
7
changelog/0.10.0_2020-09-19/issue-2427
Normal file
7
changelog/0.10.0_2020-09-19/issue-2427
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Enhancement: Add flag `--iexclude-file` to backup command
|
||||||
|
|
||||||
|
The backup command now supports the flag `--iexclude-file` which is a
|
||||||
|
case-insensitive version of `--exclude-file`.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2427
|
||||||
|
https://github.com/restic/restic/pull/2898
|
||||||
6
changelog/0.10.0_2020-09-19/issue-2429
Normal file
6
changelog/0.10.0_2020-09-19/issue-2429
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Bugfix: backup --json reports total_bytes_processed as 0
|
||||||
|
|
||||||
|
We've fixed the json output of total_bytes_processed. The non-json output
|
||||||
|
was already fixed with pull request #2138 but left the json output untouched.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2429
|
||||||
5
changelog/0.10.0_2020-09-19/issue-2469
Normal file
5
changelog/0.10.0_2020-09-19/issue-2469
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Bugfix: Fix incorrect bytes stats in `diff` command
|
||||||
|
|
||||||
|
In some cases, the wrong number of bytes (e.g. 16777215.998 TiB) were reported by the `diff` command. This is now fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2469
|
||||||
9
changelog/0.10.0_2020-09-19/issue-2482
Normal file
9
changelog/0.10.0_2020-09-19/issue-2482
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Change: Remove vendored dependencies
|
||||||
|
|
||||||
|
We've removed the vendored dependencies (in the subdir `vendor/`). When
|
||||||
|
building restic, the Go compiler automatically fetches the dependencies. It
|
||||||
|
will also cryptographically verify that the correct code has been fetched by
|
||||||
|
using the hashes in `go.sum` (see the link to the documentation below).
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2482
|
||||||
|
https://golang.org/cmd/go/#hdr-Module_downloading_and_verification
|
||||||
16
changelog/0.10.0_2020-09-19/issue-2518
Normal file
16
changelog/0.10.0_2020-09-19/issue-2518
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Bugfix: Do not crash with Synology NAS sftp server
|
||||||
|
|
||||||
|
It was found that when restic is used to store data on an sftp server on a
|
||||||
|
Synology NAS with a relative path (one which does not start with a slash), it
|
||||||
|
may go into an endless loop trying to create directories on the server. We've
|
||||||
|
fixed this bug by using a function in the sftp library instead of our own
|
||||||
|
implementation.
|
||||||
|
|
||||||
|
The bug was discovered because the Synology sftp server behaves erratic with
|
||||||
|
non-absolute path (e.g. `home/restic-repo`). This can be resolved by just using
|
||||||
|
an absolute path instead (`/home/restic-repo`). We've also added a paragraph in
|
||||||
|
the FAQ.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2518
|
||||||
|
https://github.com/restic/restic/issues/2363
|
||||||
|
https://github.com/restic/restic/pull/2530
|
||||||
5
changelog/0.10.0_2020-09-19/issue-2531
Normal file
5
changelog/0.10.0_2020-09-19/issue-2531
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Bugfix: Fix incorrect size calculation in `stats --mode restore-size`
|
||||||
|
|
||||||
|
The restore-size mode of stats was counting hard-linked files as if they were independent.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2531
|
||||||
5
changelog/0.10.0_2020-09-19/issue-2537
Normal file
5
changelog/0.10.0_2020-09-19/issue-2537
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Bugfix: Fix incorrect file counts in `stats --mode restore-size`
|
||||||
|
|
||||||
|
The restore-size mode of stats was failing to count empty directories and some files with hard links.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2537
|
||||||
8
changelog/0.10.0_2020-09-19/issue-2569
Normal file
8
changelog/0.10.0_2020-09-19/issue-2569
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Enhancement: Support excluding files by their size
|
||||||
|
|
||||||
|
The `backup` command now supports the `--exclude-larger-than` option to exclude files which are
|
||||||
|
larger than the specified maximum size. This can for example be useful to exclude unimportant
|
||||||
|
files with a large file size.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2569
|
||||||
|
https://github.com/restic/restic/pull/2914
|
||||||
16
changelog/0.10.0_2020-09-19/issue-2571
Normal file
16
changelog/0.10.0_2020-09-19/issue-2571
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
Enhancement: Self-heal missing file parts during backup of unchanged files
|
||||||
|
|
||||||
|
We've improved the resilience of restic to certain types of repository corruption.
|
||||||
|
|
||||||
|
For files that are unchanged since the parent snapshot, the backup command now
|
||||||
|
verifies that all parts of the files still exist in the repository. Parts that are
|
||||||
|
missing, e.g. from a damaged repository, are backed up again. This verification
|
||||||
|
was already run for files that were modified since the parent snapshot, but is
|
||||||
|
now also done for unchanged files.
|
||||||
|
|
||||||
|
Note that restic will not backup file parts that are referenced in the index but
|
||||||
|
where the actual data is not present on disk, as this situation can only be
|
||||||
|
detected by restic check. Please ensure that you run `restic check` regularly.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2571
|
||||||
|
https://github.com/restic/restic/pull/2827
|
||||||
9
changelog/0.10.0_2020-09-19/issue-2858
Normal file
9
changelog/0.10.0_2020-09-19/issue-2858
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Enhancement: Support filtering snapshots by tag and path in the stats command
|
||||||
|
|
||||||
|
We've added filtering snapshots by `--tag tagList` and by `--path path` to
|
||||||
|
the `stats` command. This includes filtering of only 'latest' snapshots or
|
||||||
|
all snapshots in a repository.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2858
|
||||||
|
https://github.com/restic/restic/pull/2859
|
||||||
|
https://forum.restic.net/t/stats-for-a-host-and-filtered-snapshots/3020
|
||||||
20
changelog/0.10.0_2020-09-19/issue-323
Normal file
20
changelog/0.10.0_2020-09-19/issue-323
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
Enhancement: Add command for copying snapshots between repositories
|
||||||
|
|
||||||
|
We've added a copy command, allowing you to copy snapshots from one
|
||||||
|
repository to another.
|
||||||
|
|
||||||
|
Note that this process will have to read (download) and write (upload) the
|
||||||
|
entire snapshot(s) due to the different encryption keys used on the source
|
||||||
|
and destination repository. Also, the transferred files are not re-chunked,
|
||||||
|
which may break deduplication between files already stored in the
|
||||||
|
destination repo and files copied there using this command.
|
||||||
|
|
||||||
|
To fully support deduplication between repositories when the copy command is
|
||||||
|
used, the init command now supports the `--copy-chunker-params` option,
|
||||||
|
which initializes the new repository with identical parameters for splitting
|
||||||
|
files into chunks as an already existing repository. This allows copied
|
||||||
|
snapshots to be equally deduplicated in both repositories.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/323
|
||||||
|
https://github.com/restic/restic/pull/2606
|
||||||
|
https://github.com/restic/restic/pull/2928
|
||||||
10
changelog/0.10.0_2020-09-19/issue-551
Normal file
10
changelog/0.10.0_2020-09-19/issue-551
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Enhancement: Use optimized library for hash calculation of file chunks
|
||||||
|
|
||||||
|
We've switched the library used to calculate the hashes of file chunks, which
|
||||||
|
are used for deduplication, to the optimized Minio SHA-256 implementation.
|
||||||
|
|
||||||
|
Depending on the CPU it improves the hashing throughput by 10-30%. Modern x86
|
||||||
|
CPUs with the SHA Extension should be about two to three times faster.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/551
|
||||||
|
https://github.com/restic/restic/pull/2709
|
||||||
23
changelog/0.10.0_2020-09-19/pull-2195
Normal file
23
changelog/0.10.0_2020-09-19/pull-2195
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
Enhancement: Simplify and improve restore performance
|
||||||
|
|
||||||
|
Significantly improves restore performance of large files (i.e. 50M+):
|
||||||
|
https://github.com/restic/restic/issues/2074
|
||||||
|
https://forum.restic.net/t/restore-using-rclone-gdrive-backend-is-slow/1112/8
|
||||||
|
https://forum.restic.net/t/degraded-restore-performance-s3-backend/1400
|
||||||
|
|
||||||
|
Fixes "not enough cache capacity" error during restore:
|
||||||
|
https://github.com/restic/restic/issues/2244
|
||||||
|
|
||||||
|
NOTE: This new implementation does not guarantee order in which blobs
|
||||||
|
are written to the target files and, for example, the last blob of a
|
||||||
|
file can be written to the file before any of the preceeding file blobs.
|
||||||
|
It is therefore possible to have gaps in the data written to the target
|
||||||
|
files if restore fails or interrupted by the user.
|
||||||
|
|
||||||
|
The implementation will try to preallocate space for the restored files
|
||||||
|
on the filesystem to prevent file fragmentation. This ensures good read
|
||||||
|
performance for large files, like for example VM images. If preallocating
|
||||||
|
space is not supported by the filesystem, then this step is silently skipped.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2195
|
||||||
|
https://github.com/restic/restic/pull/2893
|
||||||
8
changelog/0.10.0_2020-09-19/pull-2328
Normal file
8
changelog/0.10.0_2020-09-19/pull-2328
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Enhancement: Improve speed of check command
|
||||||
|
|
||||||
|
We've improved the check command to traverse trees only once independent of
|
||||||
|
whether they are contained in multiple snapshots. The check command is now much
|
||||||
|
faster for repositories with a large number of snapshots.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2328
|
||||||
|
https://github.com/restic/restic/issues/2284
|
||||||
5
changelog/0.10.0_2020-09-19/pull-2423
Normal file
5
changelog/0.10.0_2020-09-19/pull-2423
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Enhancement: support user@domain parsing as user
|
||||||
|
|
||||||
|
Added the ability for user@domain-like users to be authenticated over SFTP servers.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2423
|
||||||
19
changelog/0.10.0_2020-09-19/pull-2546
Normal file
19
changelog/0.10.0_2020-09-19/pull-2546
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Change: Return exit code 3 when failing to backup all source data
|
||||||
|
|
||||||
|
The backup command used to return a zero exit code as long as a snapshot
|
||||||
|
could be created successfully, even if some of the source files could not
|
||||||
|
be read (in which case the snapshot would contain the rest of the files).
|
||||||
|
|
||||||
|
This made it hard for automation/scripts to detect failures/incomplete
|
||||||
|
backups by looking at the exit code. Restic now returns the following exit
|
||||||
|
codes for the backup command:
|
||||||
|
|
||||||
|
- 0 when the command was successful
|
||||||
|
- 1 when there was a fatal error (no snapshot created)
|
||||||
|
- 3 when some source data could not be read (incomplete snapshot created)
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2546
|
||||||
|
https://github.com/restic/restic/issues/956
|
||||||
|
https://github.com/restic/restic/issues/2064
|
||||||
|
https://github.com/restic/restic/issues/2526
|
||||||
|
https://github.com/restic/restic/issues/2364
|
||||||
9
changelog/0.10.0_2020-09-19/pull-2576
Normal file
9
changelog/0.10.0_2020-09-19/pull-2576
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Enhancement: Improve the chunking algorithm
|
||||||
|
|
||||||
|
We've updated the chunker library responsible for splitting files into smaller
|
||||||
|
blocks. It should improve the chunking throughput by 5-15% depending on the
|
||||||
|
CPU.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2576
|
||||||
|
https://github.com/restic/restic/pull/2845
|
||||||
|
https://github.com/restic/restic/issues/2820
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2592
Normal file
6
changelog/0.10.0_2020-09-19/pull-2592
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Bugfix: SFTP backend supports IPv6 addresses
|
||||||
|
|
||||||
|
The SFTP backend now supports IPv6 addresses natively, without relying on
|
||||||
|
aliases in the external SSH configuration.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2592
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2598
Normal file
6
changelog/0.10.0_2020-09-19/pull-2598
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Enhancement: Improve speed of diff command
|
||||||
|
|
||||||
|
We've improved the performance of the diff command when comparing snapshots
|
||||||
|
with similar content. It should run up to twice as fast as before.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2598
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2599
Normal file
6
changelog/0.10.0_2020-09-19/pull-2599
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Enhancement: Slightly reduce memory usage of prune and stats commands
|
||||||
|
|
||||||
|
The prune and the stats command kept directory identifiers in memory twice
|
||||||
|
while searching for used blobs.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2599
|
||||||
14
changelog/0.10.0_2020-09-19/pull-2600
Normal file
14
changelog/0.10.0_2020-09-19/pull-2600
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Change: Update dependencies, require Go >= 1.13
|
||||||
|
|
||||||
|
Restic now requires Go to be at least 1.13. This allows simplifications in the
|
||||||
|
build process and removing workarounds.
|
||||||
|
|
||||||
|
This is also probably the last version of restic still supporting mounting
|
||||||
|
repositories via fuse on macOS. The library we're using for fuse does not
|
||||||
|
support macOS any more and osxfuse is not open source any more.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2600
|
||||||
|
https://github.com/restic/restic/pull/2852
|
||||||
|
https://github.com/restic/restic/pull/2927
|
||||||
|
https://github.com/bazil/fuse/issues/224
|
||||||
|
https://github.com/osxfuse/osxfuse/issues/590
|
||||||
7
changelog/0.10.0_2020-09-19/pull-2607
Normal file
7
changelog/0.10.0_2020-09-19/pull-2607
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Bugfix: Honor RESTIC_CACHE_DIR environment variable on Mac and Windows
|
||||||
|
|
||||||
|
On Mac and Windows, the RESTIC_CACHE_DIR environment variable was ignored.
|
||||||
|
This variable can now be used on all platforms to set the directory where
|
||||||
|
restic stores caches.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2607
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2668
Normal file
6
changelog/0.10.0_2020-09-19/pull-2668
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Bugfix: Don't abort the stats command when data blobs are missing
|
||||||
|
|
||||||
|
Runing the stats command in the blobs-per-file mode on a repository with
|
||||||
|
missing data blobs previously resulted in a crash.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2668
|
||||||
8
changelog/0.10.0_2020-09-19/pull-2674
Normal file
8
changelog/0.10.0_2020-09-19/pull-2674
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Bugfix: Add stricter prune error checks
|
||||||
|
|
||||||
|
Additional checks were added to the prune command in order to improve
|
||||||
|
resiliency to backend, hardware and/or networking issues. The checks now
|
||||||
|
detect a few more cases where such outside factors could potentially cause
|
||||||
|
data loss.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2674
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2733
Normal file
6
changelog/0.10.0_2020-09-19/pull-2733
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Enhancement: S3 backend: Add support for WebIdentityTokenFile
|
||||||
|
|
||||||
|
We've added support for EKS IAM roles for service accounts feature to the S3 backend.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2733
|
||||||
|
https://github.com/restic/restic/issues/2703
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2773
Normal file
6
changelog/0.10.0_2020-09-19/pull-2773
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Enhancement: Optimize handling of new index entries
|
||||||
|
|
||||||
|
Restic now uses less memory for backups which add a lot of data, e.g. large initial backups.
|
||||||
|
In addition, we've improved the stability in some edge cases.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2773
|
||||||
8
changelog/0.10.0_2020-09-19/pull-2781
Normal file
8
changelog/0.10.0_2020-09-19/pull-2781
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Enhancement: Reduce memory consumption of in-memory index
|
||||||
|
|
||||||
|
We've improved how the index is stored in memory.
|
||||||
|
This change can reduce memory usage for large repositories by up to 50%
|
||||||
|
(depending on the operation).
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2781
|
||||||
|
https://github.com/restic/restic/pull/2812
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2786
Normal file
6
changelog/0.10.0_2020-09-19/pull-2786
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Enhancement: Optimize `list blobs` command
|
||||||
|
|
||||||
|
We've changed the implementation of `list blobs` which should be now a bit faster
|
||||||
|
and consume almost no memory even for large repositories.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2786
|
||||||
6
changelog/0.10.0_2020-09-19/pull-2790
Normal file
6
changelog/0.10.0_2020-09-19/pull-2790
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Enhancement: Optimized file access in restic mount
|
||||||
|
|
||||||
|
Reading large (> 100GiB) files from restic mountpoints is now faster,
|
||||||
|
and the speedup is greater for larger files.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2790
|
||||||
8
changelog/0.10.0_2020-09-19/pull-2821
Normal file
8
changelog/0.10.0_2020-09-19/pull-2821
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Change: Honor the --no-lock flag in the mount command
|
||||||
|
|
||||||
|
The mount command now does not lock the repository if given the
|
||||||
|
--no-lock flag. This allows to mount repositories which are archived
|
||||||
|
on a read only backend/filesystem.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1597
|
||||||
|
https://github.com/restic/restic/pull/2821
|
||||||
7
changelog/0.10.0_2020-09-19/pull-2840
Normal file
7
changelog/0.10.0_2020-09-19/pull-2840
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Enhancement: Speed-up file deletion in forget, prune and rebuild-index
|
||||||
|
|
||||||
|
We've sped up the file deletion for the commands forget, prune and
|
||||||
|
rebuild-index, especially for remote repositories.
|
||||||
|
Deletion was sequential before and is now run in parallel.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2840
|
||||||
9
changelog/0.10.0_2020-09-19/pull-2899
Normal file
9
changelog/0.10.0_2020-09-19/pull-2899
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: Fix possible crash in the progress bar of check --read-data
|
||||||
|
|
||||||
|
We've fixed a possible crash while displaying the progress bar for the
|
||||||
|
check --read-data command. The crash occurred when the length of the
|
||||||
|
progress bar status exceeded the terminal width, which only happened for
|
||||||
|
very narrow terminal windows.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2899
|
||||||
|
https://forum.restic.net/t/restic-rclone-pcloud-connection-issues/2963/15
|
||||||
11
changelog/0.11.0_2020-11-05/issue-1212
Normal file
11
changelog/0.11.0_2020-11-05/issue-1212
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Bugfix: Restore timestamps and permissions on intermediate directories
|
||||||
|
|
||||||
|
When using the `--include` option of the restore command, restic restored
|
||||||
|
timestamps and permissions only on directories selected by the include pattern.
|
||||||
|
Intermediate directories, which are necessary to restore files located in sub-
|
||||||
|
directories, were created with default permissions. We've fixed the restore
|
||||||
|
command to restore timestamps and permissions for these directories as well.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1212
|
||||||
|
https://github.com/restic/restic/issues/1402
|
||||||
|
https://github.com/restic/restic/pull/2906
|
||||||
15
changelog/0.11.0_2020-11-05/issue-1756
Normal file
15
changelog/0.11.0_2020-11-05/issue-1756
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Bugfix: Mark repository files as read-only when using the local backend
|
||||||
|
|
||||||
|
Files stored in a local repository were marked as writeable on the
|
||||||
|
filesystem for non-Windows systems, which did not prevent accidental file
|
||||||
|
modifications outside of restic. In addition, the local backend did not work
|
||||||
|
with certain filesystems and network mounts which do not permit modifications
|
||||||
|
of file permissions.
|
||||||
|
|
||||||
|
restic now marks files stored in a local repository as read-only on the
|
||||||
|
filesystem on non-Windows systems. The error handling is improved to support
|
||||||
|
more filesystems.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1756
|
||||||
|
https://github.com/restic/restic/issues/2157
|
||||||
|
https://github.com/restic/restic/pull/2989
|
||||||
10
changelog/0.11.0_2020-11-05/issue-2241
Normal file
10
changelog/0.11.0_2020-11-05/issue-2241
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Bugfix: Hide password in REST backend repository URLs
|
||||||
|
|
||||||
|
When using a password in the REST backend repository URL,
|
||||||
|
the password could in some cases be included in the output
|
||||||
|
from restic, e.g. when initializing a repo or during an error.
|
||||||
|
|
||||||
|
The password is now replaced with "***" where applicable.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2241
|
||||||
|
https://github.com/restic/restic/pull/2658
|
||||||
12
changelog/0.11.0_2020-11-05/issue-2319
Normal file
12
changelog/0.11.0_2020-11-05/issue-2319
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Bugfix: Correctly dump directories into tar files
|
||||||
|
|
||||||
|
The dump command previously wrote directories in a tar file in a way which
|
||||||
|
can cause compatibility problems. This caused, for example, 7zip on Windows
|
||||||
|
to not open tar files containing directories. In addition it was not possible
|
||||||
|
to dump directories with extended attributes. These compatibility problems
|
||||||
|
are now corrected.
|
||||||
|
|
||||||
|
In addition, a tar file now includes the name of the owner and group of a file.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2319
|
||||||
|
https://github.com/restic/restic/pull/3039
|
||||||
9
changelog/0.11.0_2020-11-05/issue-2491
Normal file
9
changelog/0.11.0_2020-11-05/issue-2491
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: Don't require `self-update --output` placeholder file
|
||||||
|
|
||||||
|
`restic self-update --output /path/to/new-restic` used to require that
|
||||||
|
new-restic was an existing file, to be overwritten. Now it's possible
|
||||||
|
to download an updated restic binary to a new path, without first
|
||||||
|
having to create a placeholder file.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2491
|
||||||
|
https://github.com/restic/restic/pull/2937
|
||||||
7
changelog/0.11.0_2020-11-05/issue-2834
Normal file
7
changelog/0.11.0_2020-11-05/issue-2834
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Bugfix: Fix rare cases of backup command hanging forever
|
||||||
|
|
||||||
|
We've fixed an issue with the backup progress reporting which could cause
|
||||||
|
restic to hang forever right before finishing a backup.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2834
|
||||||
|
https://github.com/restic/restic/pull/2963
|
||||||
6
changelog/0.11.0_2020-11-05/issue-2938
Normal file
6
changelog/0.11.0_2020-11-05/issue-2938
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Bugfix: Fix manpage formatting
|
||||||
|
|
||||||
|
The manpage formatting in restic v0.10.0 was garbled, which is fixed now.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2938
|
||||||
|
https://github.com/restic/restic/pull/2977
|
||||||
7
changelog/0.11.0_2020-11-05/issue-2942
Normal file
7
changelog/0.11.0_2020-11-05/issue-2942
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Bugfix: Make --exclude-larger-than handle disappearing files
|
||||||
|
|
||||||
|
There was a small bug in the backup command's --exclude-larger-than
|
||||||
|
option where files that disappeared between scanning and actually
|
||||||
|
backing them up to the repository caused a panic. This is now fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2942
|
||||||
9
changelog/0.11.0_2020-11-05/issue-2951
Normal file
9
changelog/0.11.0_2020-11-05/issue-2951
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: restic generate, help and self-update no longer check passwords
|
||||||
|
|
||||||
|
The commands `restic cache`, `generate`, `help` and `self-update` don't need
|
||||||
|
passwords, but they previously did run the RESTIC_PASSWORD_COMMAND (if set in
|
||||||
|
the environment), prompting users to authenticate for no reason. They now skip
|
||||||
|
running the password command.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2951
|
||||||
|
https://github.com/restic/restic/pull/2987
|
||||||
9
changelog/0.11.0_2020-11-05/issue-2969
Normal file
9
changelog/0.11.0_2020-11-05/issue-2969
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Enhancement: Optimize check for unchanged files during backup
|
||||||
|
|
||||||
|
During a backup restic skips processing files which have not changed since the last backup run.
|
||||||
|
Previously this required opening each file once which can be slow on network filesystems. The
|
||||||
|
backup command now checks for file changes before opening a file. This considerably reduces
|
||||||
|
the time to create a backup on network filesystems.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2969
|
||||||
|
https://github.com/restic/restic/pull/2970
|
||||||
9
changelog/0.11.0_2020-11-05/issue-2979
Normal file
9
changelog/0.11.0_2020-11-05/issue-2979
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: Make snapshots --json output [] instead of null when no snapshots
|
||||||
|
|
||||||
|
Restic previously output `null` instead of `[]` for the `--json snapshots`
|
||||||
|
command, when there were no snapshots in the repository. This caused some
|
||||||
|
minor problems when parsing the output, but is now fixed such that `[]` is
|
||||||
|
output when the list of snapshots is empty.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2979
|
||||||
|
https://github.com/restic/restic/pull/2984
|
||||||
12
changelog/0.11.0_2020-11-05/issue-340
Normal file
12
changelog/0.11.0_2020-11-05/issue-340
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Enhancement: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||||
|
|
||||||
|
Volume Shadow Copy Service allows read access to files that are locked by
|
||||||
|
another process using an exclusive lock through a filesystem snapshot. Restic
|
||||||
|
was unable to backup those files before. This update enables backing up these
|
||||||
|
files.
|
||||||
|
|
||||||
|
This needs to be enabled explicitely using the --use-fs-snapshot option of the
|
||||||
|
backup command.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/340
|
||||||
|
https://github.com/restic/restic/pull/2274
|
||||||
7
changelog/0.11.0_2020-11-05/pull-2849
Normal file
7
changelog/0.11.0_2020-11-05/pull-2849
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Enhancement: Authenticate to Google Cloud Storage with access token
|
||||||
|
|
||||||
|
When using the GCS backend, it is now possible to authenticate with OAuth2
|
||||||
|
access tokens instead of a credentials file by setting the GOOGLE_ACCESS_TOKEN
|
||||||
|
environment variable.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2849
|
||||||
10
changelog/0.11.0_2020-11-05/pull-2910
Normal file
10
changelog/0.11.0_2020-11-05/pull-2910
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Enhancement: New option --repository-file
|
||||||
|
|
||||||
|
We've added a new command-line option --repository-file as an alternative
|
||||||
|
to -r. This allows to read the repository URL from a file in order to
|
||||||
|
prevent certain types of information leaks, especially for URLs containing
|
||||||
|
credentials.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1458
|
||||||
|
https://github.com/restic/restic/issues/2900
|
||||||
|
https://github.com/restic/restic/pull/2910
|
||||||
8
changelog/0.11.0_2020-11-05/pull-2978
Normal file
8
changelog/0.11.0_2020-11-05/pull-2978
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Enhancement: Warn if parent snapshot cannot be loaded during backup
|
||||||
|
|
||||||
|
During a backup restic uses the parent snapshot to check whether a file was
|
||||||
|
changed and has to be backed up again. For this check the backup has to read
|
||||||
|
the directories contained in the old snapshot. If a tree blob cannot be
|
||||||
|
loaded, restic now warns about this problem with the backup repository.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2978
|
||||||
@@ -7,7 +7,7 @@ vulnerability, but urge all users to upgrade to the latest version of restic.
|
|||||||
|
|
||||||
Exploiting the vulnerability requires a Linux/Unix system which saves backups
|
Exploiting the vulnerability requires a Linux/Unix system which saves backups
|
||||||
via restic and a Windows systems which restores files from the repo. In
|
via restic and a Windows systems which restores files from the repo. In
|
||||||
addition, the attackers need to be able to create create files with arbitrary
|
addition, the attackers need to be able to create files with arbitrary
|
||||||
names which are then saved to the restic repo. For example, by creating a file
|
names which are then saved to the restic repo. For example, by creating a file
|
||||||
named "..\test.txt" (which is a perfectly legal filename on Linux) and
|
named "..\test.txt" (which is a perfectly legal filename on Linux) and
|
||||||
restoring a snapshot containing this file on Windows, it would be written to
|
restoring a snapshot containing this file on Windows, it would be written to
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Details
|
|||||||
{{ range $entry := .Entries }}{{ with $entry }}
|
{{ range $entry := .Entries }}{{ with $entry }}
|
||||||
* {{ .Type }} #{{ .PrimaryID }}: {{ .Title }}
|
* {{ .Type }} #{{ .PrimaryID }}: {{ .Title }}
|
||||||
{{ range $par := .Paragraphs }}
|
{{ range $par := .Paragraphs }}
|
||||||
{{ wrap $par 80 3 }}
|
{{ wrapIndent $par 80 3 }}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ range $url := .IssueURLs }}
|
{{ range $url := .IssueURLs }}
|
||||||
{{ $url -}}
|
{{ $url -}}
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
Bugfix: Fix behavior for foobar (in present tense)
|
# The first line must start with Bugfix:, Enhancement: or Change:,
|
||||||
|
# including the colon. Use present use. Remove lines starting with '#'
|
||||||
|
# from this template.
|
||||||
|
Enhancement: Allow custom bar in the foo command
|
||||||
|
|
||||||
We've fixed the behavior for foobar, a long-standing annoyance for restic
|
# Describe the problem in the past tense, the new behavior in the present
|
||||||
users.
|
# tense. Mention the affected commands, backends, operating systems, etc.
|
||||||
|
# Focus on user-facing behavior, not the implementation.
|
||||||
|
|
||||||
The text in the paragraphs is written in past tense. The last section is a list
|
Restic foo always used the system-wide bar when deciding how to frob an
|
||||||
of issue URLs, PR URLs and other URLs. The first issue ID (or the first PR ID,
|
item in the baz backend. It now permits selecting the bar with --bar or
|
||||||
in case there aren't any issue links) is used as the primary ID.
|
the environment variable RESTIC_BAR. The system-wide bar is still the
|
||||||
|
default.
|
||||||
|
|
||||||
|
# The last section is a list of issue, PR and forum URLs.
|
||||||
|
# The first issue ID determines the filename for the changelog entry:
|
||||||
|
# changelog/unreleased/issue-1234. If there are no relevant issue links,
|
||||||
|
# use the PR ID and call the file pull-55555.
|
||||||
|
|
||||||
https://github.com/restic/restic/issues/1234
|
https://github.com/restic/restic/issues/1234
|
||||||
https://github.com/restic/restic/pull/55555
|
https://github.com/restic/restic/pull/55555
|
||||||
https://forum.restic/.net/foo/bar/baz
|
https://forum.restic.net/foo/bar/baz
|
||||||
|
|||||||
2
changelog/unreleased/.gitignore
vendored
Normal file
2
changelog/unreleased/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# this file is here so the unreleased/ directory is tracked within git, even if
|
||||||
|
# no other changelog files are present.
|
||||||
11
changelog/unreleased/issue-1212
Normal file
11
changelog/unreleased/issue-1212
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Bugfix: Restore timestamps and permissions on intermediate directories
|
||||||
|
|
||||||
|
When using the `--include` option of the restore command, restic restored
|
||||||
|
timestamps and permissions only on directories selected by the include pattern.
|
||||||
|
Intermediate directories, which are necessary to restore files located in sub-
|
||||||
|
directories, were created with default permissions. We've fixed the restore
|
||||||
|
command to restore timestamps and permissions for these directories as well.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1212
|
||||||
|
https://github.com/restic/restic/issues/1402
|
||||||
|
https://github.com/restic/restic/pull/2906
|
||||||
15
changelog/unreleased/issue-1756
Normal file
15
changelog/unreleased/issue-1756
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Bugfix: Mark repository files as read-only when using the local backend
|
||||||
|
|
||||||
|
Files stored in a local repository were marked as writeable on the
|
||||||
|
filesystem for non-Windows systems, which did not prevent accidental file
|
||||||
|
modifications outside of restic. In addition, the local backend did not work
|
||||||
|
with certain filesystems and network mounts which do not permit modifications
|
||||||
|
of file permissions.
|
||||||
|
|
||||||
|
restic now marks files stored in a local repository as read-only on the
|
||||||
|
filesystem on non-Windows systems. The error handling is improved to support
|
||||||
|
more filesystems.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1756
|
||||||
|
https://github.com/restic/restic/issues/2157
|
||||||
|
https://github.com/restic/restic/pull/2989
|
||||||
10
changelog/unreleased/issue-2241
Normal file
10
changelog/unreleased/issue-2241
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Bugfix: Hide password in REST backend repository URLs
|
||||||
|
|
||||||
|
When using a password in the REST backend repository URL,
|
||||||
|
the password could in some cases be included in the output
|
||||||
|
from restic, e.g. when initializing a repo or during an error.
|
||||||
|
|
||||||
|
The password is now replaced with "***" where applicable.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2241
|
||||||
|
https://github.com/restic/restic/pull/2658
|
||||||
12
changelog/unreleased/issue-2319
Normal file
12
changelog/unreleased/issue-2319
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Bugfix: Correctly dump directories into tar files
|
||||||
|
|
||||||
|
The dump command previously wrote directories in a tar file in a way which
|
||||||
|
can cause compatibility problems. This caused, for example, 7zip on Windows
|
||||||
|
to not open tar files containing directories. In addition it was not possible
|
||||||
|
to dump directories with extended attributes. These compatibility problems
|
||||||
|
are now corrected.
|
||||||
|
|
||||||
|
In addition, a tar file now includes the name of the owner and group of a file.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2319
|
||||||
|
https://github.com/restic/restic/pull/3039
|
||||||
9
changelog/unreleased/issue-2491
Normal file
9
changelog/unreleased/issue-2491
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: Don't require `self-update --output` placeholder file
|
||||||
|
|
||||||
|
`restic self-update --output /path/to/new-restic` used to require that
|
||||||
|
new-restic was an existing file, to be overwritten. Now it's possible
|
||||||
|
to download an updated restic binary to a new path, without first
|
||||||
|
having to create a placeholder file.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2491
|
||||||
|
https://github.com/restic/restic/pull/2937
|
||||||
7
changelog/unreleased/issue-2834
Normal file
7
changelog/unreleased/issue-2834
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Bugfix: Fix rare cases of backup command hanging forever
|
||||||
|
|
||||||
|
We've fixed an issue with the backup progress reporting which could cause
|
||||||
|
restic to hang forever right before finishing a backup.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2834
|
||||||
|
https://github.com/restic/restic/pull/2963
|
||||||
6
changelog/unreleased/issue-2938
Normal file
6
changelog/unreleased/issue-2938
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Bugfix: Fix manpage formatting
|
||||||
|
|
||||||
|
The manpage formatting in restic v0.10.0 was garbled, which is fixed now.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2938
|
||||||
|
https://github.com/restic/restic/pull/2977
|
||||||
7
changelog/unreleased/issue-2942
Normal file
7
changelog/unreleased/issue-2942
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Bugfix: Make --exclude-larger-than handle disappearing files
|
||||||
|
|
||||||
|
There was a small bug in the backup command's --exclude-larger-than
|
||||||
|
option where files that disappeared between scanning and actually
|
||||||
|
backing them up to the repository caused a panic. This is now fixed.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2942
|
||||||
9
changelog/unreleased/issue-2951
Normal file
9
changelog/unreleased/issue-2951
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: restic generate, help and self-update no longer check passwords
|
||||||
|
|
||||||
|
The commands `restic cache`, `generate`, `help` and `self-update` don't need
|
||||||
|
passwords, but they previously did run the RESTIC_PASSWORD_COMMAND (if set in
|
||||||
|
the environment), prompting users to authenticate for no reason. They now skip
|
||||||
|
running the password command.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2951
|
||||||
|
https://github.com/restic/restic/pull/2987
|
||||||
9
changelog/unreleased/issue-2969
Normal file
9
changelog/unreleased/issue-2969
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Enhancement: Optimize check for unchanged files during backup
|
||||||
|
|
||||||
|
During a backup restic skips processing files which have not changed since the last backup run.
|
||||||
|
Previously this required opening each file once which can be slow on network filesystems. The
|
||||||
|
backup command now checks for file changes before opening a file. This considerably reduces
|
||||||
|
the time to create a backup on network filesystems.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2969
|
||||||
|
https://github.com/restic/restic/pull/2970
|
||||||
9
changelog/unreleased/issue-2979
Normal file
9
changelog/unreleased/issue-2979
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Bugfix: Make snapshots --json output [] instead of null when no snapshots
|
||||||
|
|
||||||
|
Restic previously output `null` instead of `[]` for the `--json snapshots`
|
||||||
|
command, when there were no snapshots in the repository. This caused some
|
||||||
|
minor problems when parsing the output, but is now fixed such that `[]` is
|
||||||
|
output when the list of snapshots is empty.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/2979
|
||||||
|
https://github.com/restic/restic/pull/2984
|
||||||
12
changelog/unreleased/issue-340
Normal file
12
changelog/unreleased/issue-340
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Enhancement: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||||
|
|
||||||
|
Volume Shadow Copy Service allows read access to files that are locked by
|
||||||
|
another process using an exclusive lock through a filesystem snapshot. Restic
|
||||||
|
was unable to backup those files before. This update enables backing up these
|
||||||
|
files.
|
||||||
|
|
||||||
|
This needs to be enabled explicitely using the --use-fs-snapshot option of the
|
||||||
|
backup command.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/340
|
||||||
|
https://github.com/restic/restic/pull/2274
|
||||||
7
changelog/unreleased/pull-2849
Normal file
7
changelog/unreleased/pull-2849
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Enhancement: Authenticate to Google Cloud Storage with access token
|
||||||
|
|
||||||
|
When using the GCS backend, it is now possible to authenticate with OAuth2
|
||||||
|
access tokens instead of a credentials file by setting the GOOGLE_ACCESS_TOKEN
|
||||||
|
environment variable.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2849
|
||||||
10
changelog/unreleased/pull-2910
Normal file
10
changelog/unreleased/pull-2910
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Enhancement: New option --repository-file
|
||||||
|
|
||||||
|
We've added a new command-line option --repository-file as an alternative
|
||||||
|
to -r. This allows to read the repository URL from a file in order to
|
||||||
|
prevent certain types of information leaks, especially for URLs containing
|
||||||
|
credentials.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/issues/1458
|
||||||
|
https://github.com/restic/restic/issues/2900
|
||||||
|
https://github.com/restic/restic/pull/2910
|
||||||
8
changelog/unreleased/pull-2978
Normal file
8
changelog/unreleased/pull-2978
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Enhancement: Warn if parent snapshot cannot be loaded during backup
|
||||||
|
|
||||||
|
During a backup restic uses the parent snapshot to check whether a file was
|
||||||
|
changed and has to be backed up again. For this check the backup has to read
|
||||||
|
the directories contained in the old snapshot. If a tree blob cannot be
|
||||||
|
loaded, restic now warns about this problem with the backup repository.
|
||||||
|
|
||||||
|
https://github.com/restic/restic/pull/2978
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -17,10 +16,8 @@ var cleanupHandlers struct {
|
|||||||
ch chan os.Signal
|
ch chan os.Signal
|
||||||
}
|
}
|
||||||
|
|
||||||
var stderr = os.Stderr
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cleanupHandlers.ch = make(chan os.Signal)
|
cleanupHandlers.ch = make(chan os.Signal, 1)
|
||||||
go CleanupHandler(cleanupHandlers.ch)
|
go CleanupHandler(cleanupHandlers.ch)
|
||||||
signal.Notify(cleanupHandlers.ch, syscall.SIGINT)
|
signal.Notify(cleanupHandlers.ch, syscall.SIGINT)
|
||||||
}
|
}
|
||||||
@@ -51,7 +48,7 @@ func RunCleanupHandlers() {
|
|||||||
for _, f := range cleanupHandlers.list {
|
for _, f := range cleanupHandlers.list {
|
||||||
err := f()
|
err := f()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(stderr, "error in cleanup handler: %v\n", err)
|
Warnf("error in cleanup handler: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanupHandlers.list = nil
|
cleanupHandlers.list = nil
|
||||||
@@ -61,7 +58,7 @@ func RunCleanupHandlers() {
|
|||||||
func CleanupHandler(c <-chan os.Signal) {
|
func CleanupHandler(c <-chan os.Signal) {
|
||||||
for s := range c {
|
for s := range c {
|
||||||
debug.Log("signal %v received, cleaning up", s)
|
debug.Log("signal %v received, cleaning up", s)
|
||||||
fmt.Fprintf(stderr, "%ssignal %v received, cleaning up\n", ClearLine(), s)
|
Warnf("%ssignal %v received, cleaning up\n", ClearLine(), s)
|
||||||
|
|
||||||
code := 0
|
code := 0
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -25,7 +26,7 @@ import (
|
|||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
"github.com/restic/restic/internal/textfile"
|
"github.com/restic/restic/internal/textfile"
|
||||||
"github.com/restic/restic/internal/ui"
|
"github.com/restic/restic/internal/ui"
|
||||||
"github.com/restic/restic/internal/ui/jsonstatus"
|
"github.com/restic/restic/internal/ui/json"
|
||||||
"github.com/restic/restic/internal/ui/termstatus"
|
"github.com/restic/restic/internal/ui/termstatus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,6 +36,13 @@ var cmdBackup = &cobra.Command{
|
|||||||
Long: `
|
Long: `
|
||||||
The "backup" command creates a new snapshot and saves the files and directories
|
The "backup" command creates a new snapshot and saves the files and directories
|
||||||
given as the arguments.
|
given as the arguments.
|
||||||
|
|
||||||
|
EXIT STATUS
|
||||||
|
===========
|
||||||
|
|
||||||
|
Exit status is 0 if the command was successful.
|
||||||
|
Exit status is 1 if there was a fatal error (no snapshot created).
|
||||||
|
Exit status is 3 if some source data could not be read (incomplete snapshot created).
|
||||||
`,
|
`,
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
if backupOptions.Host == "" {
|
if backupOptions.Host == "" {
|
||||||
@@ -71,50 +79,61 @@ given as the arguments.
|
|||||||
|
|
||||||
// BackupOptions bundles all options for the backup command.
|
// BackupOptions bundles all options for the backup command.
|
||||||
type BackupOptions struct {
|
type BackupOptions struct {
|
||||||
Parent string
|
Parent string
|
||||||
Force bool
|
Force bool
|
||||||
Excludes []string
|
Excludes []string
|
||||||
InsensitiveExcludes []string
|
InsensitiveExcludes []string
|
||||||
ExcludeFiles []string
|
ExcludeFiles []string
|
||||||
ExcludeOtherFS bool
|
InsensitiveExcludeFiles []string
|
||||||
ExcludeIfPresent []string
|
ExcludeOtherFS bool
|
||||||
ExcludeCaches bool
|
ExcludeIfPresent []string
|
||||||
Stdin bool
|
ExcludeCaches bool
|
||||||
StdinFilename string
|
ExcludeLargerThan string
|
||||||
Tags []string
|
Stdin bool
|
||||||
Host string
|
StdinFilename string
|
||||||
FilesFrom []string
|
Tags []string
|
||||||
TimeStamp string
|
Host string
|
||||||
WithAtime bool
|
FilesFrom []string
|
||||||
IgnoreInode bool
|
TimeStamp string
|
||||||
|
WithAtime bool
|
||||||
|
IgnoreInode bool
|
||||||
|
UseFsSnapshot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var backupOptions BackupOptions
|
var backupOptions BackupOptions
|
||||||
|
|
||||||
|
// ErrInvalidSourceData is used to report an incomplete backup
|
||||||
|
var ErrInvalidSourceData = errors.New("failed to read all source data during backup")
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cmdRoot.AddCommand(cmdBackup)
|
cmdRoot.AddCommand(cmdBackup)
|
||||||
|
|
||||||
f := cmdBackup.Flags()
|
f := cmdBackup.Flags()
|
||||||
f.StringVar(&backupOptions.Parent, "parent", "", "use this parent snapshot (default: last snapshot in the repo that has the same target files/directories)")
|
f.StringVar(&backupOptions.Parent, "parent", "", "use this parent `snapshot` (default: last snapshot in the repo that has the same target files/directories)")
|
||||||
f.BoolVarP(&backupOptions.Force, "force", "f", false, `force re-reading the target files/directories (overrides the "parent" flag)`)
|
f.BoolVarP(&backupOptions.Force, "force", "f", false, `force re-reading the target files/directories (overrides the "parent" flag)`)
|
||||||
f.StringArrayVarP(&backupOptions.Excludes, "exclude", "e", nil, "exclude a `pattern` (can be specified multiple times)")
|
f.StringArrayVarP(&backupOptions.Excludes, "exclude", "e", nil, "exclude a `pattern` (can be specified multiple times)")
|
||||||
f.StringArrayVar(&backupOptions.InsensitiveExcludes, "iexclude", nil, "same as `--exclude` but ignores the casing of filenames")
|
f.StringArrayVar(&backupOptions.InsensitiveExcludes, "iexclude", nil, "same as --exclude `pattern` but ignores the casing of filenames")
|
||||||
f.StringArrayVar(&backupOptions.ExcludeFiles, "exclude-file", nil, "read exclude patterns from a `file` (can be specified multiple times)")
|
f.StringArrayVar(&backupOptions.ExcludeFiles, "exclude-file", nil, "read exclude patterns from a `file` (can be specified multiple times)")
|
||||||
|
f.StringArrayVar(&backupOptions.InsensitiveExcludeFiles, "iexclude-file", nil, "same as --exclude-file but ignores casing of `file`names in patterns")
|
||||||
f.BoolVarP(&backupOptions.ExcludeOtherFS, "one-file-system", "x", false, "exclude other file systems")
|
f.BoolVarP(&backupOptions.ExcludeOtherFS, "one-file-system", "x", false, "exclude other file systems")
|
||||||
f.StringArrayVar(&backupOptions.ExcludeIfPresent, "exclude-if-present", nil, "takes filename[:header], exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)")
|
f.StringArrayVar(&backupOptions.ExcludeIfPresent, "exclude-if-present", nil, "takes `filename[:header]`, exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)")
|
||||||
f.BoolVar(&backupOptions.ExcludeCaches, "exclude-caches", false, `excludes cache directories that are marked with a CACHEDIR.TAG file. See http://bford.info/cachedir/spec.html for the Cache Directory Tagging Standard`)
|
f.BoolVar(&backupOptions.ExcludeCaches, "exclude-caches", false, `excludes cache directories that are marked with a CACHEDIR.TAG file. See https://bford.info/cachedir/ for the Cache Directory Tagging Standard`)
|
||||||
|
f.StringVar(&backupOptions.ExcludeLargerThan, "exclude-larger-than", "", "max `size` of the files to be backed up (allowed suffixes: k/K, m/M, g/G, t/T)")
|
||||||
f.BoolVar(&backupOptions.Stdin, "stdin", false, "read backup from stdin")
|
f.BoolVar(&backupOptions.Stdin, "stdin", false, "read backup from stdin")
|
||||||
f.StringVar(&backupOptions.StdinFilename, "stdin-filename", "stdin", "file name to use when reading from stdin")
|
f.StringVar(&backupOptions.StdinFilename, "stdin-filename", "stdin", "`filename` to use when reading from stdin")
|
||||||
f.StringArrayVar(&backupOptions.Tags, "tag", nil, "add a `tag` for the new snapshot (can be specified multiple times)")
|
f.StringArrayVar(&backupOptions.Tags, "tag", nil, "add a `tag` for the new snapshot (can be specified multiple times)")
|
||||||
|
|
||||||
f.StringVarP(&backupOptions.Host, "host", "H", "", "set the `hostname` for the snapshot manually. To prevent an expensive rescan use the \"parent\" flag")
|
f.StringVarP(&backupOptions.Host, "host", "H", "", "set the `hostname` for the snapshot manually. To prevent an expensive rescan use the \"parent\" flag")
|
||||||
f.StringVar(&backupOptions.Host, "hostname", "", "set the `hostname` for the snapshot manually")
|
f.StringVar(&backupOptions.Host, "hostname", "", "set the `hostname` for the snapshot manually")
|
||||||
f.MarkDeprecated("hostname", "use --host")
|
f.MarkDeprecated("hostname", "use --host")
|
||||||
|
|
||||||
f.StringArrayVar(&backupOptions.FilesFrom, "files-from", nil, "read the files to backup from file (can be combined with file args/can be specified multiple times)")
|
f.StringArrayVar(&backupOptions.FilesFrom, "files-from", nil, "read the files to backup from `file` (can be combined with file args/can be specified multiple times)")
|
||||||
f.StringVar(&backupOptions.TimeStamp, "time", "", "time of the backup (ex. '2012-11-01 22:08:41') (default: now)")
|
f.StringVar(&backupOptions.TimeStamp, "time", "", "`time` of the backup (ex. '2012-11-01 22:08:41') (default: now)")
|
||||||
f.BoolVar(&backupOptions.WithAtime, "with-atime", false, "store the atime for all files and directories")
|
f.BoolVar(&backupOptions.WithAtime, "with-atime", false, "store the atime for all files and directories")
|
||||||
f.BoolVar(&backupOptions.IgnoreInode, "ignore-inode", false, "ignore inode number changes when checking for modified files")
|
f.BoolVar(&backupOptions.IgnoreInode, "ignore-inode", false, "ignore inode number changes when checking for modified files")
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
f.BoolVar(&backupOptions.UseFsSnapshot, "use-fs-snapshot", false, "use filesystem snapshot where possible (currently only Windows VSS)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterExisting returns a slice of all existing items, or an error if no
|
// filterExisting returns a slice of all existing items, or an error if no
|
||||||
@@ -229,6 +248,14 @@ func collectRejectByNameFuncs(opts BackupOptions, repo *repository.Repository, t
|
|||||||
opts.Excludes = append(opts.Excludes, excludes...)
|
opts.Excludes = append(opts.Excludes, excludes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(opts.InsensitiveExcludeFiles) > 0 {
|
||||||
|
excludes, err := readExcludePatternsFromFiles(opts.InsensitiveExcludeFiles)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
opts.InsensitiveExcludes = append(opts.InsensitiveExcludes, excludes...)
|
||||||
|
}
|
||||||
|
|
||||||
if len(opts.InsensitiveExcludes) > 0 {
|
if len(opts.InsensitiveExcludes) > 0 {
|
||||||
fs = append(fs, rejectByInsensitivePattern(opts.InsensitiveExcludes))
|
fs = append(fs, rejectByInsensitivePattern(opts.InsensitiveExcludes))
|
||||||
}
|
}
|
||||||
@@ -265,6 +292,14 @@ func collectRejectFuncs(opts BackupOptions, repo *repository.Repository, targets
|
|||||||
fs = append(fs, f)
|
fs = append(fs, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(opts.ExcludeLargerThan) != 0 && !opts.Stdin {
|
||||||
|
f, err := rejectBySize(opts.ExcludeLargerThan)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fs = append(fs, f)
|
||||||
|
}
|
||||||
|
|
||||||
return fs, nil
|
return fs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +399,7 @@ func collectTargets(opts BackupOptions, args []string) (targets []string, err er
|
|||||||
func findParentSnapshot(ctx context.Context, repo restic.Repository, opts BackupOptions, targets []string) (parentID *restic.ID, err error) {
|
func findParentSnapshot(ctx context.Context, repo restic.Repository, opts BackupOptions, targets []string) (parentID *restic.ID, err error) {
|
||||||
// Force using a parent
|
// Force using a parent
|
||||||
if !opts.Force && opts.Parent != "" {
|
if !opts.Force && opts.Parent != "" {
|
||||||
id, err := restic.FindSnapshot(repo, opts.Parent)
|
id, err := restic.FindSnapshot(ctx, repo, opts.Parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Fatalf("invalid id %q: %v", opts.Parent, err)
|
return nil, errors.Fatalf("invalid id %q: %v", opts.Parent, err)
|
||||||
}
|
}
|
||||||
@@ -374,7 +409,7 @@ func findParentSnapshot(ctx context.Context, repo restic.Repository, opts Backup
|
|||||||
|
|
||||||
// Find last snapshot to set it as parent, if not already set
|
// Find last snapshot to set it as parent, if not already set
|
||||||
if !opts.Force && parentID == nil {
|
if !opts.Force && parentID == nil {
|
||||||
id, err := restic.FindLatestSnapshot(ctx, repo, targets, []restic.TagList{}, opts.Host)
|
id, err := restic.FindLatestSnapshot(ctx, repo, targets, []restic.TagList{}, []string{opts.Host})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
parentID = &id
|
parentID = &id
|
||||||
} else if err != restic.ErrNoSnapshotFound {
|
} else if err != restic.ErrNoSnapshotFound {
|
||||||
@@ -407,7 +442,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
var t tomb.Tomb
|
var t tomb.Tomb
|
||||||
|
|
||||||
if gopts.verbosity >= 2 && !gopts.JSON {
|
if gopts.verbosity >= 2 && !gopts.JSON {
|
||||||
term.Print("open repository\n")
|
Verbosef("open repository\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(gopts)
|
||||||
@@ -439,7 +474,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
|
|
||||||
var p ArchiveProgressReporter
|
var p ArchiveProgressReporter
|
||||||
if gopts.JSON {
|
if gopts.JSON {
|
||||||
p = jsonstatus.NewBackup(term, gopts.verbosity)
|
p = json.NewBackup(term, gopts.verbosity)
|
||||||
} else {
|
} else {
|
||||||
p = ui.NewBackup(term, gopts.verbosity)
|
p = ui.NewBackup(term, gopts.verbosity)
|
||||||
}
|
}
|
||||||
@@ -466,7 +501,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
if !gopts.JSON {
|
if !gopts.JSON {
|
||||||
p.V("lock repository")
|
p.V("lock repository")
|
||||||
}
|
}
|
||||||
lock, err := lockRepo(repo)
|
lock, err := lockRepo(gopts.ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -520,6 +555,25 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
}
|
}
|
||||||
|
|
||||||
var targetFS fs.FS = fs.Local{}
|
var targetFS fs.FS = fs.Local{}
|
||||||
|
if runtime.GOOS == "windows" && opts.UseFsSnapshot {
|
||||||
|
if err = fs.HasSufficientPrivilegesForVSS(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
errorHandler := func(item string, err error) error {
|
||||||
|
return p.Error(item, nil, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageHandler := func(msg string, args ...interface{}) {
|
||||||
|
if !gopts.JSON {
|
||||||
|
p.P(msg, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localVss := fs.NewLocalVss(errorHandler, messageHandler)
|
||||||
|
defer localVss.DeleteSnapshots()
|
||||||
|
targetFS = localVss
|
||||||
|
}
|
||||||
if opts.Stdin {
|
if opts.Stdin {
|
||||||
if !gopts.JSON {
|
if !gopts.JSON {
|
||||||
p.V("read data from stdin")
|
p.V("read data from stdin")
|
||||||
@@ -549,7 +603,11 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
arch.SelectByName = selectByNameFilter
|
arch.SelectByName = selectByNameFilter
|
||||||
arch.Select = selectFilter
|
arch.Select = selectFilter
|
||||||
arch.WithAtime = opts.WithAtime
|
arch.WithAtime = opts.WithAtime
|
||||||
arch.Error = p.Error
|
success := true
|
||||||
|
arch.Error = func(item string, fi os.FileInfo, err error) error {
|
||||||
|
success = false
|
||||||
|
return p.Error(item, fi, err)
|
||||||
|
}
|
||||||
arch.CompleteItem = p.CompleteItem
|
arch.CompleteItem = p.CompleteItem
|
||||||
arch.StartFile = p.StartFile
|
arch.StartFile = p.StartFile
|
||||||
arch.CompleteBlob = p.CompleteBlob
|
arch.CompleteBlob = p.CompleteBlob
|
||||||
@@ -567,24 +625,6 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
ParentSnapshot: *parentSnapshotID,
|
ParentSnapshot: *parentSnapshotID,
|
||||||
}
|
}
|
||||||
|
|
||||||
uploader := archiver.IndexUploader{
|
|
||||||
Repository: repo,
|
|
||||||
Start: func() {
|
|
||||||
if !gopts.JSON {
|
|
||||||
p.VV("uploading intermediate index")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Complete: func(id restic.ID) {
|
|
||||||
if !gopts.JSON {
|
|
||||||
p.V("uploaded intermediate index %v", id.Str())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Go(func() error {
|
|
||||||
return uploader.Upload(gopts.ctx, t.Context(gopts.ctx), 30*time.Second)
|
|
||||||
})
|
|
||||||
|
|
||||||
if !gopts.JSON {
|
if !gopts.JSON {
|
||||||
p.V("start backup on %v", targets)
|
p.V("start backup on %v", targets)
|
||||||
}
|
}
|
||||||
@@ -593,19 +633,21 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
return errors.Fatalf("unable to save snapshot: %v", err)
|
return errors.Fatalf("unable to save snapshot: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Finish(id)
|
|
||||||
if !gopts.JSON {
|
|
||||||
p.P("snapshot %s saved\n", id.Str())
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanly shutdown all running goroutines
|
// cleanly shutdown all running goroutines
|
||||||
t.Kill(nil)
|
t.Kill(nil)
|
||||||
|
|
||||||
// let's see if one returned an error
|
// let's see if one returned an error
|
||||||
err = t.Wait()
|
err = t.Wait()
|
||||||
if err != nil {
|
|
||||||
return err
|
// Report finished execution
|
||||||
|
p.Finish(id)
|
||||||
|
if !gopts.JSON {
|
||||||
|
p.P("snapshot %s saved\n", id.Str())
|
||||||
|
}
|
||||||
|
if !success {
|
||||||
|
return ErrInvalidSourceData
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
// Return error if any
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ var cmdCache = &cobra.Command{
|
|||||||
Short: "Operate on local cache directories",
|
Short: "Operate on local cache directories",
|
||||||
Long: `
|
Long: `
|
||||||
The "cache" command allows listing and cleaning local cache directories.
|
The "cache" command allows listing and cleaning local cache directories.
|
||||||
|
|
||||||
|
EXIT STATUS
|
||||||
|
===========
|
||||||
|
|
||||||
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
@@ -46,7 +51,7 @@ func init() {
|
|||||||
|
|
||||||
func runCache(opts CacheOptions, gopts GlobalOptions, args []string) error {
|
func runCache(opts CacheOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
return errors.Fatal("the cache command has no arguments")
|
return errors.Fatal("the cache command expects no arguments, only options - please see `restic help cache` for usage and flags")
|
||||||
}
|
}
|
||||||
|
|
||||||
if gopts.NoCache {
|
if gopts.NoCache {
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@@ -18,6 +16,11 @@ var cmdCat = &cobra.Command{
|
|||||||
Short: "Print internal objects to stdout",
|
Short: "Print internal objects to stdout",
|
||||||
Long: `
|
Long: `
|
||||||
The "cat" command is used to print internal objects to stdout.
|
The "cat" command is used to print internal objects to stdout.
|
||||||
|
|
||||||
|
EXIT STATUS
|
||||||
|
===========
|
||||||
|
|
||||||
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
@@ -39,7 +42,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockRepo(repo)
|
lock, err := lockRepo(gopts.ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -56,7 +59,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// find snapshot id with prefix
|
// find snapshot id with prefix
|
||||||
id, err = restic.FindSnapshot(repo, args[1])
|
id, err = restic.FindSnapshot(gopts.ctx, repo, args[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("could not find snapshot: %v\n", err)
|
return errors.Fatalf("could not find snapshot: %v\n", err)
|
||||||
}
|
}
|
||||||
@@ -71,7 +74,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(buf))
|
Println(string(buf))
|
||||||
return nil
|
return nil
|
||||||
case "index":
|
case "index":
|
||||||
buf, err := repo.LoadAndDecrypt(gopts.ctx, nil, restic.IndexFile, id)
|
buf, err := repo.LoadAndDecrypt(gopts.ctx, nil, restic.IndexFile, id)
|
||||||
@@ -79,9 +82,8 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = os.Stdout.Write(append(buf, '\n'))
|
Println(string(buf))
|
||||||
return err
|
return nil
|
||||||
|
|
||||||
case "snapshot":
|
case "snapshot":
|
||||||
sn := &restic.Snapshot{}
|
sn := &restic.Snapshot{}
|
||||||
err = repo.LoadJSONUnpacked(gopts.ctx, restic.SnapshotFile, id, sn)
|
err = repo.LoadJSONUnpacked(gopts.ctx, restic.SnapshotFile, id, sn)
|
||||||
@@ -94,8 +96,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(buf))
|
Println(string(buf))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
case "key":
|
case "key":
|
||||||
h := restic.Handle{Type: restic.KeyFile, Name: id.String()}
|
h := restic.Handle{Type: restic.KeyFile, Name: id.String()}
|
||||||
@@ -115,7 +116,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(buf))
|
Println(string(buf))
|
||||||
return nil
|
return nil
|
||||||
case "masterkey":
|
case "masterkey":
|
||||||
buf, err := json.MarshalIndent(repo.Key(), "", " ")
|
buf, err := json.MarshalIndent(repo.Key(), "", " ")
|
||||||
@@ -123,7 +124,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(buf))
|
Println(string(buf))
|
||||||
return nil
|
return nil
|
||||||
case "lock":
|
case "lock":
|
||||||
lock, err := restic.LoadLock(gopts.ctx, repo, id)
|
lock, err := restic.LoadLock(gopts.ctx, repo, id)
|
||||||
@@ -136,8 +137,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(string(buf))
|
Println(string(buf))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
|
|
||||||
switch tpe {
|
switch tpe {
|
||||||
case "pack":
|
case "pack":
|
||||||
h := restic.Handle{Type: restic.DataFile, Name: id.String()}
|
h := restic.Handle{Type: restic.PackFile, Name: id.String()}
|
||||||
buf, err := backend.LoadAll(gopts.ctx, nil, repo.Backend(), h)
|
buf, err := backend.LoadAll(gopts.ctx, nil, repo.Backend(), h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -157,28 +157,24 @@ func runCat(gopts GlobalOptions, args []string) error {
|
|||||||
|
|
||||||
hash := restic.Hash(buf)
|
hash := restic.Hash(buf)
|
||||||
if !hash.Equal(id) {
|
if !hash.Equal(id) {
|
||||||
fmt.Fprintf(stderr, "Warning: hash of data does not match ID, want\n %v\ngot:\n %v\n", id.String(), hash.String())
|
Warnf("Warning: hash of data does not match ID, want\n %v\ngot:\n %v\n", id.String(), hash.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = os.Stdout.Write(buf)
|
_, err = globalOptions.stdout.Write(buf)
|
||||||
return err
|
return err
|
||||||
|
|
||||||
case "blob":
|
case "blob":
|
||||||
for _, t := range []restic.BlobType{restic.DataBlob, restic.TreeBlob} {
|
for _, t := range []restic.BlobType{restic.DataBlob, restic.TreeBlob} {
|
||||||
list, found := repo.Index().Lookup(id, t)
|
if !repo.Index().Has(id, t) {
|
||||||
if !found {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
blob := list[0]
|
|
||||||
|
|
||||||
buf := make([]byte, blob.Length)
|
buf, err := repo.LoadBlob(gopts.ctx, t, id, nil)
|
||||||
n, err := repo.LoadBlob(gopts.ctx, t, id, buf)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
buf = buf[:n]
|
|
||||||
|
|
||||||
_, err = os.Stdout.Write(buf)
|
_, err = globalOptions.stdout.Write(buf)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@@ -25,6 +23,11 @@ finds. It can also be used to read all data and therefore simulate a restore.
|
|||||||
|
|
||||||
By default, the "check" command will always load all data directly from the
|
By default, the "check" command will always load all data directly from the
|
||||||
repository and not use a local cache.
|
repository and not use a local cache.
|
||||||
|
|
||||||
|
EXIT STATUS
|
||||||
|
===========
|
||||||
|
|
||||||
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
@@ -95,36 +98,6 @@ func stringToIntSlice(param string) (split []uint, err error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newReadProgress(gopts GlobalOptions, todo restic.Stat) *restic.Progress {
|
|
||||||
if gopts.Quiet {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
readProgress := restic.NewProgress()
|
|
||||||
|
|
||||||
readProgress.OnUpdate = func(s restic.Stat, d time.Duration, ticker bool) {
|
|
||||||
status := fmt.Sprintf("[%s] %s %d / %d items",
|
|
||||||
formatDuration(d),
|
|
||||||
formatPercent(s.Blobs, todo.Blobs),
|
|
||||||
s.Blobs, todo.Blobs)
|
|
||||||
|
|
||||||
if w := stdoutTerminalWidth(); w > 0 {
|
|
||||||
if len(status) > w {
|
|
||||||
max := w - len(status) - 4
|
|
||||||
status = status[:max] + "... "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintProgress("%s", status)
|
|
||||||
}
|
|
||||||
|
|
||||||
readProgress.OnDone = func(s restic.Stat, d time.Duration, ticker bool) {
|
|
||||||
fmt.Printf("\nduration: %s\n", formatDuration(d))
|
|
||||||
}
|
|
||||||
|
|
||||||
return readProgress
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepareCheckCache configures a special cache directory for check.
|
// prepareCheckCache configures a special cache directory for check.
|
||||||
//
|
//
|
||||||
// * if --with-cache is specified, the default cache is used
|
// * if --with-cache is specified, the default cache is used
|
||||||
@@ -169,7 +142,7 @@ func prepareCheckCache(opts CheckOptions, gopts *GlobalOptions) (cleanup func())
|
|||||||
|
|
||||||
func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return errors.Fatal("check has no arguments")
|
return errors.Fatal("the check command expects no arguments, only options - please see `restic help check` for usage and flags")
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup := prepareCheckCache(opts, &gopts)
|
cleanup := prepareCheckCache(opts, &gopts)
|
||||||
@@ -185,7 +158,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
|||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
Verbosef("create exclusive lock for repository\n")
|
Verbosef("create exclusive lock for repository\n")
|
||||||
lock, err := lockRepoExclusive(repo)
|
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -230,7 +203,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
errorsFound = true
|
errorsFound = true
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
Warnf("%v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if orphanedPacks > 0 {
|
if orphanedPacks > 0 {
|
||||||
@@ -244,18 +217,18 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
|||||||
for err := range errChan {
|
for err := range errChan {
|
||||||
errorsFound = true
|
errorsFound = true
|
||||||
if e, ok := err.(checker.TreeError); ok {
|
if e, ok := err.(checker.TreeError); ok {
|
||||||
fmt.Fprintf(os.Stderr, "error for tree %v:\n", e.ID.Str())
|
Warnf("error for tree %v:\n", e.ID.Str())
|
||||||
for _, treeErr := range e.Errors {
|
for _, treeErr := range e.Errors {
|
||||||
fmt.Fprintf(os.Stderr, " %v\n", treeErr)
|
Warnf(" %v\n", treeErr)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(os.Stderr, "error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.CheckUnused {
|
if opts.CheckUnused {
|
||||||
for _, id := range chkr.UnusedBlobs() {
|
for _, id := range chkr.UnusedBlobs() {
|
||||||
Verbosef("unused blob %v\n", id.Str())
|
Verbosef("unused blob %v\n", id)
|
||||||
errorsFound = true
|
errorsFound = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,14 +250,14 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
|||||||
Verbosef("read all data\n")
|
Verbosef("read all data\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
p := newReadProgress(gopts, restic.Stat{Blobs: packCount})
|
p := newProgressMax(!gopts.Quiet, packCount, "packs")
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
|
|
||||||
go chkr.ReadPacks(gopts.ctx, packs, p, errChan)
|
go chkr.ReadPacks(gopts.ctx, packs, p, errChan)
|
||||||
|
|
||||||
for err := range errChan {
|
for err := range errChan {
|
||||||
errorsFound = true
|
errorsFound = true
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
Warnf("%v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
233
cmd/restic/cmd_copy.go
Normal file
233
cmd/restic/cmd_copy.go
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/restic/restic/internal/debug"
|
||||||
|
"github.com/restic/restic/internal/restic"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cmdCopy = &cobra.Command{
|
||||||
|
Use: "copy [flags] [snapshotID ...]",
|
||||||
|
Short: "Copy snapshots from one repository to another",
|
||||||
|
Long: `
|
||||||
|
The "copy" command copies one or more snapshots from one repository to another
|
||||||
|
repository. Note that this will have to read (download) and write (upload) the
|
||||||
|
entire snapshot(s) due to the different encryption keys on the source and
|
||||||
|
destination, and that transferred files are not re-chunked, which may break
|
||||||
|
their deduplication. This can be mitigated by the "--copy-chunker-params"
|
||||||
|
option when initializing a new destination repository using the "init" command.
|
||||||
|
`,
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return runCopy(copyOptions, globalOptions, args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyOptions bundles all options for the copy command.
|
||||||
|
type CopyOptions struct {
|
||||||
|
secondaryRepoOptions
|
||||||
|
Hosts []string
|
||||||
|
Tags restic.TagLists
|
||||||
|
Paths []string
|
||||||
|
}
|
||||||
|
|
||||||
|
var copyOptions CopyOptions
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
cmdRoot.AddCommand(cmdCopy)
|
||||||
|
|
||||||
|
f := cmdCopy.Flags()
|
||||||
|
initSecondaryRepoOptions(f, ©Options.secondaryRepoOptions, "destination", "to copy snapshots to")
|
||||||
|
f.StringArrayVarP(©Options.Hosts, "host", "H", nil, "only consider snapshots for this `host`, when no snapshot ID is given (can be specified multiple times)")
|
||||||
|
f.Var(©Options.Tags, "tag", "only consider snapshots which include this `taglist`, when no snapshot ID is given")
|
||||||
|
f.StringArrayVar(©Options.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`, when no snapshot ID is given")
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCopy(opts CopyOptions, gopts GlobalOptions, args []string) error {
|
||||||
|
dstGopts, err := fillSecondaryGlobalOpts(opts.secondaryRepoOptions, gopts, "destination")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(gopts.ctx)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
srcRepo, err := OpenRepository(gopts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dstRepo, err := OpenRepository(dstGopts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
srcLock, err := lockRepo(ctx, srcRepo)
|
||||||
|
defer unlockRepo(srcLock)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dstLock, err := lockRepo(ctx, dstRepo)
|
||||||
|
defer unlockRepo(dstLock)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Log("Loading source index")
|
||||||
|
if err := srcRepo.LoadIndex(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
debug.Log("Loading destination index")
|
||||||
|
if err := dstRepo.LoadIndex(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dstSnapshotByOriginal := make(map[restic.ID][]*restic.Snapshot)
|
||||||
|
for sn := range FindFilteredSnapshots(ctx, dstRepo, opts.Hosts, opts.Tags, opts.Paths, nil) {
|
||||||
|
if sn.Original != nil && !sn.Original.IsNull() {
|
||||||
|
dstSnapshotByOriginal[*sn.Original] = append(dstSnapshotByOriginal[*sn.Original], sn)
|
||||||
|
}
|
||||||
|
// also consider identical snapshot copies
|
||||||
|
dstSnapshotByOriginal[*sn.ID()] = append(dstSnapshotByOriginal[*sn.ID()], sn)
|
||||||
|
}
|
||||||
|
|
||||||
|
cloner := &treeCloner{
|
||||||
|
srcRepo: srcRepo,
|
||||||
|
dstRepo: dstRepo,
|
||||||
|
visitedTrees: restic.NewIDSet(),
|
||||||
|
buf: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
for sn := range FindFilteredSnapshots(ctx, srcRepo, opts.Hosts, opts.Tags, opts.Paths, args) {
|
||||||
|
Verbosef("\nsnapshot %s of %v at %s)\n", sn.ID().Str(), sn.Paths, sn.Time)
|
||||||
|
|
||||||
|
// check whether the destination has a snapshot with the same persistent ID which has similar snapshot fields
|
||||||
|
srcOriginal := *sn.ID()
|
||||||
|
if sn.Original != nil {
|
||||||
|
srcOriginal = *sn.Original
|
||||||
|
}
|
||||||
|
if originalSns, ok := dstSnapshotByOriginal[srcOriginal]; ok {
|
||||||
|
isCopy := false
|
||||||
|
for _, originalSn := range originalSns {
|
||||||
|
if similarSnapshots(originalSn, sn) {
|
||||||
|
Verbosef("skipping source snapshot %s, was already copied to snapshot %s\n", sn.ID().Str(), originalSn.ID().Str())
|
||||||
|
isCopy = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isCopy {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Verbosef(" copy started, this may take a while...\n")
|
||||||
|
|
||||||
|
if err := cloner.copyTree(ctx, *sn.Tree); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
debug.Log("tree copied")
|
||||||
|
|
||||||
|
if err = dstRepo.Flush(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
debug.Log("flushed packs and saved index")
|
||||||
|
|
||||||
|
// save snapshot
|
||||||
|
sn.Parent = nil // Parent does not have relevance in the new repo.
|
||||||
|
// Use Original as a persistent snapshot ID
|
||||||
|
if sn.Original == nil {
|
||||||
|
sn.Original = sn.ID()
|
||||||
|
}
|
||||||
|
newID, err := dstRepo.SaveJSONUnpacked(ctx, restic.SnapshotFile, sn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
Verbosef("snapshot %s saved\n", newID.Str())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func similarSnapshots(sna *restic.Snapshot, snb *restic.Snapshot) bool {
|
||||||
|
// everything except Parent and Original must match
|
||||||
|
if !sna.Time.Equal(snb.Time) || !sna.Tree.Equal(*snb.Tree) || sna.Hostname != snb.Hostname ||
|
||||||
|
sna.Username != snb.Username || sna.UID != snb.UID || sna.GID != snb.GID ||
|
||||||
|
len(sna.Paths) != len(snb.Paths) || len(sna.Excludes) != len(snb.Excludes) ||
|
||||||
|
len(sna.Tags) != len(snb.Tags) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !sna.HasPaths(snb.Paths) || !sna.HasTags(snb.Tags) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i, a := range sna.Excludes {
|
||||||
|
if a != snb.Excludes[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type treeCloner struct {
|
||||||
|
srcRepo restic.Repository
|
||||||
|
dstRepo restic.Repository
|
||||||
|
visitedTrees restic.IDSet
|
||||||
|
buf []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *treeCloner) copyTree(ctx context.Context, treeID restic.ID) error {
|
||||||
|
// We have already processed this tree
|
||||||
|
if t.visitedTrees.Has(treeID) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tree, err := t.srcRepo.LoadTree(ctx, treeID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("LoadTree(%v) returned error %v", treeID.Str(), err)
|
||||||
|
}
|
||||||
|
t.visitedTrees.Insert(treeID)
|
||||||
|
|
||||||
|
// Do we already have this tree blob?
|
||||||
|
if !t.dstRepo.Index().Has(treeID, restic.TreeBlob) {
|
||||||
|
newTreeID, err := t.dstRepo.SaveTree(ctx, tree)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("SaveTree(%v) returned error %v", treeID.Str(), err)
|
||||||
|
}
|
||||||
|
// Assurance only.
|
||||||
|
if newTreeID != treeID {
|
||||||
|
return fmt.Errorf("SaveTree(%v) returned unexpected id %s", treeID.Str(), newTreeID.Str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: parellize this stuff, likely only needed inside a tree.
|
||||||
|
|
||||||
|
for _, entry := range tree.Nodes {
|
||||||
|
// If it is a directory, recurse
|
||||||
|
if entry.Type == "dir" && entry.Subtree != nil {
|
||||||
|
if err := t.copyTree(ctx, *entry.Subtree); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Copy the blobs for this file.
|
||||||
|
for _, blobID := range entry.Content {
|
||||||
|
// Do we already have this data blob?
|
||||||
|
if t.dstRepo.Index().Has(blobID, restic.DataBlob) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
debug.Log("Copying blob %s\n", blobID.Str())
|
||||||
|
t.buf, err = t.srcRepo.LoadBlob(ctx, restic.DataBlob, blobID, t.buf)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("LoadBlob(%v) returned error %v", blobID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err = t.dstRepo.SaveBlob(ctx, restic.DataBlob, t.buf, blobID, false)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("SaveBlob(%v) returned error %v", blobID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user