mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-29 16:12:08 +00:00
Compare commits
1118 Commits
release-0.
...
v1.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a357f21aec | ||
|
|
dfb225807b | ||
|
|
b1b6a79dfc | ||
|
|
b25865f5bb | ||
|
|
8e35ce0bde | ||
|
|
9e946ee698 | ||
|
|
cfb663f795 | ||
|
|
a0cd954ce9 | ||
|
|
67203ff972 | ||
|
|
af4b9373fc | ||
|
|
90bb939c4d | ||
|
|
c80f679802 | ||
|
|
76a91a80b2 | ||
|
|
3c8020e922 | ||
|
|
dadb466545 | ||
|
|
5ef0a84128 | ||
|
|
363c2692a1 | ||
|
|
1670aa17b6 | ||
|
|
52e5589b3d | ||
|
|
e576f23c70 | ||
|
|
7b7b96de74 | ||
|
|
ad026107c9 | ||
|
|
92b930d351 | ||
|
|
f18d7300a8 | ||
|
|
faef20d45a | ||
|
|
9b18e238b1 | ||
|
|
5917445511 | ||
|
|
1429f226ed | ||
|
|
c69fa4d0e1 | ||
|
|
53b5b87742 | ||
|
|
e2278ed9d2 | ||
|
|
ffa3251efc | ||
|
|
efdb3796ac | ||
|
|
9d9c232729 | ||
|
|
d5dd39c941 | ||
|
|
d881a10fba | ||
|
|
80692a8a39 | ||
|
|
4accb8512a | ||
|
|
4e1b1f9457 | ||
|
|
de442c1106 | ||
|
|
6522ba7c42 | ||
|
|
a590fc9468 | ||
|
|
539e0b54c6 | ||
|
|
a4e70456a1 | ||
|
|
2254635bcb | ||
|
|
07525bd593 | ||
|
|
635dd27e1a | ||
|
|
2a6929d453 | ||
|
|
b24a603711 | ||
|
|
f2d06bc5e9 | ||
|
|
4543258970 | ||
|
|
22eca22ac8 | ||
|
|
6188cdffb0 | ||
|
|
935107e1a2 | ||
|
|
bf247836e6 | ||
|
|
b24e940399 | ||
|
|
65030f7fbc | ||
|
|
248ee89123 | ||
|
|
52d97e7bd7 | ||
|
|
b8f3a008cb | ||
|
|
25a481f6b1 | ||
|
|
3b9af8c654 | ||
|
|
f80e1dc390 | ||
|
|
3c4dd3e526 | ||
|
|
8336d95f57 | ||
|
|
5f409f12c8 | ||
|
|
65906efffa | ||
|
|
c8bac5bfae | ||
|
|
92ac710dab | ||
|
|
c69b94da76 | ||
|
|
927d2775bf | ||
|
|
1594bdc8d0 | ||
|
|
aa8c0cd471 | ||
|
|
3124570c7f | ||
|
|
1d54996fce | ||
|
|
5841f82ee9 | ||
|
|
1c69bafeeb | ||
|
|
8e098e2f6c | ||
|
|
500d5485b1 | ||
|
|
1bb167ef90 | ||
|
|
11194d1071 | ||
|
|
63964fc6f9 | ||
|
|
d615cc6de0 | ||
|
|
8cde8fdbc7 | ||
|
|
ac00185a5f | ||
|
|
31973fbf04 | ||
|
|
d1025f7547 | ||
|
|
678c02c560 | ||
|
|
7724464017 | ||
|
|
f44bd53cf0 | ||
|
|
2498ac6cab | ||
|
|
afa49f398f | ||
|
|
f829dabcf4 | ||
|
|
eec5cc687e | ||
|
|
bf00754280 | ||
|
|
13cac85c1e | ||
|
|
567802299b | ||
|
|
adb93c33b1 | ||
|
|
e371ba78b0 | ||
|
|
2156124dfc | ||
|
|
db393ec199 | ||
|
|
022099a62e | ||
|
|
55054f67a5 | ||
|
|
75a96dfa92 | ||
|
|
81c2adc059 | ||
|
|
dd96aa76db | ||
|
|
0089fa4d93 | ||
|
|
553df25710 | ||
|
|
764de79cf5 | ||
|
|
f4c64ae75a | ||
|
|
c48586a8c7 | ||
|
|
5d8ba1b90d | ||
|
|
1a339f06ac | ||
|
|
b0bdaeea73 | ||
|
|
08fe7be851 | ||
|
|
67512a3808 | ||
|
|
37c7b618ad | ||
|
|
d143137a70 | ||
|
|
5634a4f463 | ||
|
|
19052994ed | ||
|
|
8cb9ee9eb8 | ||
|
|
0d326a3903 | ||
|
|
d916ae0a25 | ||
|
|
b00e0e834a | ||
|
|
d421fcd85c | ||
|
|
0735ee7218 | ||
|
|
223aec8200 | ||
|
|
870743a28d | ||
|
|
1f4139a5bf | ||
|
|
a2e88c4d3f | ||
|
|
2d81e29276 | ||
|
|
5d3312b7b5 | ||
|
|
fac3cd4a78 | ||
|
|
3ff95eaa40 | ||
|
|
023d43d0fe | ||
|
|
b807b449d6 | ||
|
|
1ded7c7207 | ||
|
|
f3850210aa | ||
|
|
e2bf39a027 | ||
|
|
6513e8f30e | ||
|
|
49f52b54b2 | ||
|
|
74b575200c | ||
|
|
520077c3a9 | ||
|
|
e183c4b597 | ||
|
|
f0f7d31e1b | ||
|
|
9a62d887d3 | ||
|
|
d6c60b2dd5 | ||
|
|
9e7ff4e3d9 | ||
|
|
bb12cbd2d7 | ||
|
|
16a08b82a9 | ||
|
|
c539e8ad63 | ||
|
|
f1319be60b | ||
|
|
7d9fc88eb3 | ||
|
|
0a771e6a53 | ||
|
|
bc7ee686d7 | ||
|
|
81a26e4aad | ||
|
|
caa0bff5a3 | ||
|
|
83c3143825 | ||
|
|
81287e4751 | ||
|
|
0804f34644 | ||
|
|
411d44a673 | ||
|
|
4e2e4cd5c4 | ||
|
|
108d826ca5 | ||
|
|
bbb11a8d23 | ||
|
|
82e464672b | ||
|
|
035c297287 | ||
|
|
02095d21d8 | ||
|
|
5f7bab945d | ||
|
|
ddb335475b | ||
|
|
915b3a1ddf | ||
|
|
a1f26aa3a8 | ||
|
|
9287505f62 | ||
|
|
02c7df9ea0 | ||
|
|
13b6cbb4db | ||
|
|
029cee6bc3 | ||
|
|
1ed5255f17 | ||
|
|
72f5cadc3a | ||
|
|
1ed1a84ebf | ||
|
|
15289295af | ||
|
|
f44ad1ad34 | ||
|
|
e7e2e8c390 | ||
|
|
effa5dbeee | ||
|
|
f3fd902de8 | ||
|
|
ac9b29f2d7 | ||
|
|
93c0ed111f | ||
|
|
0753a2572a | ||
|
|
a053989693 | ||
|
|
6db2283b84 | ||
|
|
9194eba5f0 | ||
|
|
e57eeef208 | ||
|
|
b0afa979ff | ||
|
|
e8e5485b94 | ||
|
|
eafe53560b | ||
|
|
f3663846a2 | ||
|
|
bdb7fe854c | ||
|
|
d995018a3e | ||
|
|
5d8df26b35 | ||
|
|
deb8a27bd4 | ||
|
|
c49e1ff0cc | ||
|
|
5a811b4629 | ||
|
|
5602ca9d29 | ||
|
|
95d2d47b77 | ||
|
|
ee8f8ca1db | ||
|
|
91a35c2f4e | ||
|
|
b3c6e5e483 | ||
|
|
079444410f | ||
|
|
c209f0c0c3 | ||
|
|
d05f8e53d8 | ||
|
|
a1eb8411f9 | ||
|
|
e52b04dfa3 | ||
|
|
8c2c96adeb | ||
|
|
a27e1a4c02 | ||
|
|
757a9862a5 | ||
|
|
363748667b | ||
|
|
d4f9c62449 | ||
|
|
e0bc14d56b | ||
|
|
f27ff115e2 | ||
|
|
b82e221310 | ||
|
|
c96b7b3e40 | ||
|
|
58d34700da | ||
|
|
05b8edf894 | ||
|
|
e5e3bc6b89 | ||
|
|
90c89f764e | ||
|
|
cdd583b8bf | ||
|
|
e0b3e6fa5f | ||
|
|
24d28c8633 | ||
|
|
0462217c9b | ||
|
|
e35cf8845d | ||
|
|
7a04e987ea | ||
|
|
4352158435 | ||
|
|
71f358c160 | ||
|
|
884e512f93 | ||
|
|
26d86f514c | ||
|
|
c0e105f5cd | ||
|
|
6ebedf6b25 | ||
|
|
de79f4d0b7 | ||
|
|
2406994740 | ||
|
|
ac9e0173e8 | ||
|
|
c95abf69b2 | ||
|
|
f3d36afd3a | ||
|
|
0205a43028 | ||
|
|
4e12b08953 | ||
|
|
721d19c7bf | ||
|
|
28612afa27 | ||
|
|
987ce55894 | ||
|
|
4514c2e27d | ||
|
|
660080e6f3 | ||
|
|
dea81bbe15 | ||
|
|
3b5de11c74 | ||
|
|
4ed63edea0 | ||
|
|
8392e6d83f | ||
|
|
42f351b000 | ||
|
|
bf19623e82 | ||
|
|
f2b4e73e2e | ||
|
|
9e19ab8d8b | ||
|
|
26b940c81c | ||
|
|
011db15f1c | ||
|
|
dda76b05a8 | ||
|
|
c7025b98e4 | ||
|
|
58bb7ed3aa | ||
|
|
6f496a8921 | ||
|
|
3155bb159f | ||
|
|
dcd663b8cf | ||
|
|
0471c6ee35 | ||
|
|
15aaa7bb9d | ||
|
|
fc25f0ae89 | ||
|
|
c201a2c103 | ||
|
|
1a55964326 | ||
|
|
eb30ec0666 | ||
|
|
e7e666306c | ||
|
|
8cd46b8a0c | ||
|
|
db9f8e16d9 | ||
|
|
9cd2862c8e | ||
|
|
7e949080cf | ||
|
|
7d28f82540 | ||
|
|
b6cfce2dd9 | ||
|
|
64dd3ed7ad | ||
|
|
e9c131df71 | ||
|
|
662a36df90 | ||
|
|
38ccb40ca1 | ||
|
|
c59d03dfb1 | ||
|
|
c7bb288d87 | ||
|
|
05a88345e5 | ||
|
|
01d0b026e9 | ||
|
|
134323fbf7 | ||
|
|
8870281afc | ||
|
|
6dd007b507 | ||
|
|
e85c367ce5 | ||
|
|
b01b12472f | ||
|
|
475cf2ab60 | ||
|
|
f8f0d15da2 | ||
|
|
6020823aaf | ||
|
|
ff642d739d | ||
|
|
0750b2c789 | ||
|
|
975bec692b | ||
|
|
38604e88fe | ||
|
|
c475108345 | ||
|
|
f2418052e4 | ||
|
|
2cef9d26ec | ||
|
|
5bc6695109 | ||
|
|
8c9ae491f0 | ||
|
|
39bab5ada9 | ||
|
|
316e6cc67e | ||
|
|
6f474016a6 | ||
|
|
bc8f07f963 | ||
|
|
9470983d5f | ||
|
|
94f014101d | ||
|
|
c38def0849 | ||
|
|
66c6d7a026 | ||
|
|
9b9b4f666e | ||
|
|
373e4c9abe | ||
|
|
ce374584c4 | ||
|
|
c59544cb79 | ||
|
|
6ed4e1f147 | ||
|
|
b04d6b02f3 | ||
|
|
7f36f78aee | ||
|
|
892673816b | ||
|
|
c8c03a38e9 | ||
|
|
ede9a8f5b4 | ||
|
|
b87de94723 | ||
|
|
77e648eafa | ||
|
|
d49008dec0 | ||
|
|
b03da3c0ed | ||
|
|
49cb4cd5c3 | ||
|
|
3ed97db550 | ||
|
|
44acdcbc60 | ||
|
|
5d06bd4ab9 | ||
|
|
0328a70ff0 | ||
|
|
8d61cb0384 | ||
|
|
f879670906 | ||
|
|
7251c8ca81 | ||
|
|
02cbb77dea | ||
|
|
d679498c8a | ||
|
|
c326f59627 | ||
|
|
bc93b2bbac | ||
|
|
3116185e5b | ||
|
|
abee09aa2d | ||
|
|
0e0f357cef | ||
|
|
23c0d3f612 | ||
|
|
4beb8aab3c | ||
|
|
b444d3c2f1 | ||
|
|
13eaad0e64 | ||
|
|
956152d6e1 | ||
|
|
bca21a1ec0 | ||
|
|
2f47ca62ad | ||
|
|
a519547efc | ||
|
|
0167539a14 | ||
|
|
985479094f | ||
|
|
a611658436 | ||
|
|
0f442b002d | ||
|
|
a774b54ae7 | ||
|
|
2e3f00f64d | ||
|
|
c3a933d3e3 | ||
|
|
bbd28a9fb9 | ||
|
|
23b1098950 | ||
|
|
1d3d66aa77 | ||
|
|
40c7fbce09 | ||
|
|
6bf29e17aa | ||
|
|
7298a4eda0 | ||
|
|
2a36cdcbf6 | ||
|
|
dcee310745 | ||
|
|
a696cd09f2 | ||
|
|
be42ea782d | ||
|
|
9b635c0e14 | ||
|
|
477e42286c | ||
|
|
21f3169ad3 | ||
|
|
59e0ef4524 | ||
|
|
86293b68b3 | ||
|
|
e4e0ed68a6 | ||
|
|
bb9c3f6a1a | ||
|
|
3f2c28f6bb | ||
|
|
60460f6920 | ||
|
|
7b0d8217de | ||
|
|
f8baf4f4f0 | ||
|
|
b1c0e9c49b | ||
|
|
4d7add1782 | ||
|
|
7af9f8d74e | ||
|
|
ff2db31b32 | ||
|
|
bd662ab613 | ||
|
|
01f2ae76e2 | ||
|
|
a111eed2af | ||
|
|
4c73e23ce8 | ||
|
|
a71e43b2b7 | ||
|
|
1eac10ca9f | ||
|
|
7dfe58d37f | ||
|
|
78bf8fb868 | ||
|
|
7d66fc31bd | ||
|
|
183bea369d | ||
|
|
de09fd7cdc | ||
|
|
f64b37289d | ||
|
|
73514a003b | ||
|
|
7674332313 | ||
|
|
409116fce8 | ||
|
|
503b112638 | ||
|
|
b286c652ec | ||
|
|
89ca2571f3 | ||
|
|
394548afcd | ||
|
|
4ee41a13a0 | ||
|
|
4041044a93 | ||
|
|
5e12a921b5 | ||
|
|
1354e2b6ff | ||
|
|
e29aa74a23 | ||
|
|
ce3f43e876 | ||
|
|
5912fe66e5 | ||
|
|
c006d9246f | ||
|
|
1b031f0cc4 | ||
|
|
88e6a740f2 | ||
|
|
0fec56f488 | ||
|
|
e21940bee1 | ||
|
|
421b64b1fa | ||
|
|
81e741ebfc | ||
|
|
fcf21813a5 | ||
|
|
8dd1cbf62b | ||
|
|
65f3926caa | ||
|
|
31501b79b2 | ||
|
|
6bf837b233 | ||
|
|
f908d5f8c0 | ||
|
|
f8548e1ca1 | ||
|
|
58e471bda0 | ||
|
|
61eab7dca3 | ||
|
|
efc490138c | ||
|
|
80fe640b98 | ||
|
|
21c57c46b3 | ||
|
|
7353294b7f | ||
|
|
7e736ab79d | ||
|
|
5468ccf5cb | ||
|
|
032aaac508 | ||
|
|
ab2fc65c02 | ||
|
|
03b8f5397f | ||
|
|
431602e852 | ||
|
|
cb0a9281f6 | ||
|
|
783c7d850c | ||
|
|
e3e76c2067 | ||
|
|
e4771f582b | ||
|
|
4e0b0c87bb | ||
|
|
3724af259c | ||
|
|
522ee9ad36 | ||
|
|
1b3c444720 | ||
|
|
3d2b031ee4 | ||
|
|
8be6f03ef0 | ||
|
|
e2f84a1242 | ||
|
|
49eeeb04f0 | ||
|
|
e1d414338c | ||
|
|
0ffaeb949d | ||
|
|
ed73be44fd | ||
|
|
988ce573c0 | ||
|
|
780dc4551f | ||
|
|
32835c63f6 | ||
|
|
86c5c25d13 | ||
|
|
250f109c41 | ||
|
|
d8e9b772ff | ||
|
|
88fc6e2141 | ||
|
|
38ad7d71f5 | ||
|
|
e91c841c59 | ||
|
|
902c0f797f | ||
|
|
296dd6617e | ||
|
|
4cd8170386 | ||
|
|
551aaa646d | ||
|
|
0df30c1e89 | ||
|
|
378011baf6 | ||
|
|
b2b1ee44ea | ||
|
|
4583aa7078 | ||
|
|
b15970d3ef | ||
|
|
9df3947745 | ||
|
|
2364393b7c | ||
|
|
ee2b352489 | ||
|
|
890202f2e4 | ||
|
|
3c7737c8b1 | ||
|
|
ca8e951ac6 | ||
|
|
52ecc45ec8 | ||
|
|
8ee406b4bd | ||
|
|
46e87661c0 | ||
|
|
723cda2697 | ||
|
|
5f0ff026b0 | ||
|
|
0a810ced54 | ||
|
|
c1a817b4e9 | ||
|
|
478d12b4ff | ||
|
|
328bc361be | ||
|
|
7913ae1867 | ||
|
|
c0a55e136b | ||
|
|
3054a38bd6 | ||
|
|
381149cedf | ||
|
|
db9dacae54 | ||
|
|
77327db062 | ||
|
|
1675943f44 | ||
|
|
43714caaec | ||
|
|
bbc6caf7fe | ||
|
|
25299513c1 | ||
|
|
e61d3c6ca0 | ||
|
|
c56e3e5af3 | ||
|
|
78cb813210 | ||
|
|
f90b8f9473 | ||
|
|
8a58b217be | ||
|
|
5847dcabba | ||
|
|
ad5146b9b1 | ||
|
|
7e4fca428d | ||
|
|
7c2a6caa5a | ||
|
|
d08c2e1b9c | ||
|
|
96fcf1661a | ||
|
|
6cf3db6244 | ||
|
|
fd8bf14bb6 | ||
|
|
ca107423f0 | ||
|
|
7384cf1115 | ||
|
|
3be3ec434b | ||
|
|
e38e2fc5a1 | ||
|
|
702d0f76c2 | ||
|
|
2ed241b0b7 | ||
|
|
ff0ac68157 | ||
|
|
c34e3b9127 | ||
|
|
d69e819122 | ||
|
|
1906c33eb2 | ||
|
|
32dd33e211 | ||
|
|
246d75811a | ||
|
|
ac317a87ff | ||
|
|
59ca9a3974 | ||
|
|
f983f4fb21 | ||
|
|
f1deff8ffc | ||
|
|
6a60a55ba5 | ||
|
|
5b529d2da0 | ||
|
|
cc47b65830 | ||
|
|
90babe0ed3 | ||
|
|
1b7a64a812 | ||
|
|
1da5702c0f | ||
|
|
5464b3dce8 | ||
|
|
aa9d96f3b7 | ||
|
|
8955199e37 | ||
|
|
e13806e0b8 | ||
|
|
555f73c3ea | ||
|
|
62d8c642d2 | ||
|
|
a4a09f09a2 | ||
|
|
312c6f5c3d | ||
|
|
b92b35d42b | ||
|
|
cdd499dc27 | ||
|
|
6b910e621a | ||
|
|
7dd62f8374 | ||
|
|
0dd1c4b086 | ||
|
|
51652e6a8c | ||
|
|
bdf2615eb0 | ||
|
|
ae4bffe30b | ||
|
|
f7fe949aa7 | ||
|
|
d28f445c5a | ||
|
|
7bdd7f8c87 | ||
|
|
4c5f352a73 | ||
|
|
e6ef2ba9e8 | ||
|
|
b8835d7880 | ||
|
|
a002ae6315 | ||
|
|
09042a9015 | ||
|
|
43cd2ca36f | ||
|
|
71214fa640 | ||
|
|
0d6d146bc1 | ||
|
|
d85872dfb2 | ||
|
|
daf1a75515 | ||
|
|
d27e4f7f05 | ||
|
|
858171e812 | ||
|
|
ce69ff59e0 | ||
|
|
64fd4c7b73 | ||
|
|
6b94f68201 | ||
|
|
f4820bd892 | ||
|
|
7029d627c7 | ||
|
|
0fd7872ef4 | ||
|
|
38c212ecf8 | ||
|
|
411d62fe91 | ||
|
|
fde5a4d1e2 | ||
|
|
b9de44ffbd | ||
|
|
eace0255de | ||
|
|
cbef9da721 | ||
|
|
cff0215906 | ||
|
|
75566c6c20 | ||
|
|
fa14255e53 | ||
|
|
25590a8351 | ||
|
|
22959071bc | ||
|
|
90c5ed0850 | ||
|
|
2781e4e8de | ||
|
|
e5556fe608 | ||
|
|
9ae861c9e2 | ||
|
|
449cac5806 | ||
|
|
5d039e4b23 | ||
|
|
366ca748d4 | ||
|
|
6ff98784fe | ||
|
|
698420b613 | ||
|
|
caa990a272 | ||
|
|
3788014552 | ||
|
|
40e33020d8 | ||
|
|
becd075000 | ||
|
|
eb59b5c593 | ||
|
|
6c9e1f187f | ||
|
|
318fd8a83f | ||
|
|
defb8aa856 | ||
|
|
7abe115674 | ||
|
|
96ad3ec7b4 | ||
|
|
6b70d9225d | ||
|
|
76982d3d02 | ||
|
|
7d497e6f2f | ||
|
|
ec013e6ffd | ||
|
|
cb0e6f4773 | ||
|
|
8bbfc538f1 | ||
|
|
c3c2ea2805 | ||
|
|
4239e61f47 | ||
|
|
9165d514a3 | ||
|
|
6231aaa875 | ||
|
|
681f7043a8 | ||
|
|
d6162e943b | ||
|
|
7c62ed2981 | ||
|
|
0f7f084fb9 | ||
|
|
a15df2761c | ||
|
|
46bed015f5 | ||
|
|
beb22f953b | ||
|
|
e3a7d6a20d | ||
|
|
40882d7ee7 | ||
|
|
400911e96b | ||
|
|
52574b9c0a | ||
|
|
f1cb85134c | ||
|
|
ce41dd7225 | ||
|
|
b818cc2769 | ||
|
|
51379b0150 | ||
|
|
9063808606 | ||
|
|
6e2166c49c | ||
|
|
18b434cb24 | ||
|
|
39d9155267 | ||
|
|
bb65d67a13 | ||
|
|
b5a2ccd510 | ||
|
|
74cb6a2150 | ||
|
|
0152885bb2 | ||
|
|
677491410b | ||
|
|
21a2a2e1f5 | ||
|
|
04aedbb5ac | ||
|
|
22704d283f | ||
|
|
516422c2c4 | ||
|
|
195e6aaf00 | ||
|
|
9cda7eae55 | ||
|
|
bca585162f | ||
|
|
573ce7d0e7 | ||
|
|
6cf3519c3a | ||
|
|
6591b5a09c | ||
|
|
7c4ac05ae5 | ||
|
|
90d9be59d3 | ||
|
|
a7e524db33 | ||
|
|
f3a57b5b8a | ||
|
|
b66c6b1105 | ||
|
|
ef19497205 | ||
|
|
6d4e702cda | ||
|
|
596eea1b8c | ||
|
|
f014cab1fe | ||
|
|
8acc66d02f | ||
|
|
6ef155ddff | ||
|
|
57ce590fae | ||
|
|
028fafb6cf | ||
|
|
d0937a3433 | ||
|
|
db856affcb | ||
|
|
56da761e68 | ||
|
|
9952dfb0ad | ||
|
|
fe19863089 | ||
|
|
e897153328 | ||
|
|
7f1553306a | ||
|
|
b3b065a9fb | ||
|
|
77d05ec1c3 | ||
|
|
cf2c27141b | ||
|
|
ec124673fa | ||
|
|
c36131a024 | ||
|
|
17b3a3b073 | ||
|
|
406b50a71b | ||
|
|
268080ad09 | ||
|
|
4a03370f1d | ||
|
|
38c72b8cc2 | ||
|
|
0ec2de55c0 | ||
|
|
35bb533c2d | ||
|
|
da9ed38c63 | ||
|
|
e24248e07a | ||
|
|
df07b7dc9f | ||
|
|
4af89fa863 | ||
|
|
02f50b9c84 | ||
|
|
1aa712d236 | ||
|
|
bbf769850e | ||
|
|
aeb221eafe | ||
|
|
ffc612ac13 | ||
|
|
f20342aab9 | ||
|
|
7172db8a1e | ||
|
|
e5a8fab9e0 | ||
|
|
ebc379ac02 | ||
|
|
6243a354b8 | ||
|
|
99adc4fa55 | ||
|
|
0e7f442f00 | ||
|
|
37031d5e7c | ||
|
|
480f1942b7 | ||
|
|
01980f0611 | ||
|
|
474efde6ba | ||
|
|
4173515435 | ||
|
|
fe51be6713 | ||
|
|
38e86ceff5 | ||
|
|
611bc92695 | ||
|
|
63dc6c1d9a | ||
|
|
d7dfffa373 | ||
|
|
7575ff22ca | ||
|
|
d579784692 | ||
|
|
30369c2ad5 | ||
|
|
7c3f4ddd74 | ||
|
|
0612c5de70 | ||
|
|
1da3278ad6 | ||
|
|
66bcbc058c | ||
|
|
18c51fbd4b | ||
|
|
3af43b492f | ||
|
|
d009163b67 | ||
|
|
257917767f | ||
|
|
6c398fc42a | ||
|
|
b31c6e1a36 | ||
|
|
a5834b852d | ||
|
|
a0604d6d1a | ||
|
|
9873e648d1 | ||
|
|
f4c99c7774 | ||
|
|
91e45d5689 | ||
|
|
f7a8091645 | ||
|
|
ed0eb865ec | ||
|
|
1d90d02a99 | ||
|
|
cb43ff91ef | ||
|
|
0c88eefc0d | ||
|
|
eb709b8f70 | ||
|
|
82ab2d73ac | ||
|
|
65209cd0f3 | ||
|
|
190d032551 | ||
|
|
ae4bf3d5f8 | ||
|
|
0f1c5c283f | ||
|
|
94b8fae15a | ||
|
|
729a688b36 | ||
|
|
af3af1b520 | ||
|
|
3542f39f5f | ||
|
|
9fdf85130a | ||
|
|
a57acec43d | ||
|
|
c5e3f0eecb | ||
|
|
2073e15a69 | ||
|
|
2e9a83f4c0 | ||
|
|
0fc3e8d852 | ||
|
|
ed2bca83bd | ||
|
|
a6fa7af095 | ||
|
|
e46e89cb61 | ||
|
|
42b54586cd | ||
|
|
8bc7e4f6aa | ||
|
|
889b220a5a | ||
|
|
e3232b7eb6 | ||
|
|
e3222a9e3f | ||
|
|
d95b18bad8 | ||
|
|
907a9fbdd8 | ||
|
|
a28327b47e | ||
|
|
17be71e1ff | ||
|
|
20635106e8 | ||
|
|
6fd9ea9d5f | ||
|
|
368787c184 | ||
|
|
4323e287c9 | ||
|
|
a793cbb62b | ||
|
|
4833607abd | ||
|
|
5161890738 | ||
|
|
3a60853340 | ||
|
|
a5cb2ce4b7 | ||
|
|
80bc3ded14 | ||
|
|
afb8102a44 | ||
|
|
7668bfd495 | ||
|
|
5cc58ed305 | ||
|
|
84f01df828 | ||
|
|
b5e4f85b8c | ||
|
|
1dda7b91cc | ||
|
|
468006e619 | ||
|
|
3eb1160301 | ||
|
|
e6b44539a5 | ||
|
|
fcd27a13da | ||
|
|
69e2f51fbe | ||
|
|
ffef86e38d | ||
|
|
a6dbfe822f | ||
|
|
cda3dff8e3 | ||
|
|
7c36d80ee2 | ||
|
|
f049e0787b | ||
|
|
c9a9dd4508 | ||
|
|
086d0667de | ||
|
|
94617b302d | ||
|
|
779cb42854 | ||
|
|
44a75cee7b | ||
|
|
92283a52d6 | ||
|
|
7d8813a96c | ||
|
|
f0edf7335f | ||
|
|
af64069d65 | ||
|
|
29d75d72e2 | ||
|
|
bc516112da | ||
|
|
211aa7b7fd | ||
|
|
5ccc27aaed | ||
|
|
d34994cb5f | ||
|
|
ae373bdbfb | ||
|
|
889f0af5b8 | ||
|
|
a8c42ab245 | ||
|
|
283a1349bd | ||
|
|
a50367f148 | ||
|
|
7bc27bbbfd | ||
|
|
e94277ac4d | ||
|
|
7aadc39cd6 | ||
|
|
df69b274a0 | ||
|
|
cb321db21f | ||
|
|
9d7ea7483c | ||
|
|
cd4e9f5336 | ||
|
|
a440029c2f | ||
|
|
b31e25bf6e | ||
|
|
729d733986 | ||
|
|
6445dbf1c7 | ||
|
|
133dc185ca | ||
|
|
7a1e6d16cc | ||
|
|
6f7bfe545d | ||
|
|
bd4d97b9e4 | ||
|
|
0e94fa37f9 | ||
|
|
2750aa71b9 | ||
|
|
20f89fbcef | ||
|
|
833a6307a9 | ||
|
|
cf7c8587f0 | ||
|
|
3234124afe | ||
|
|
74043ab428 | ||
|
|
7007f198e1 | ||
|
|
8f5346150c | ||
|
|
bab08ed1a6 | ||
|
|
c6f488f75f | ||
|
|
06b5af449f | ||
|
|
adbcd3703b | ||
|
|
2a34772ed5 | ||
|
|
56f1617049 | ||
|
|
345c3c39b1 | ||
|
|
a25eb03290 | ||
|
|
575c4ddc6d | ||
|
|
030ea6c0ad | ||
|
|
d32f8dbb6c | ||
|
|
adc29a2db0 | ||
|
|
342a1c6437 | ||
|
|
8a5d6f9111 | ||
|
|
79c45133f7 | ||
|
|
9c11ba900c | ||
|
|
ea50ebf2b5 | ||
|
|
ec61bc8654 | ||
|
|
7edbb91cfa | ||
|
|
d29c96387e | ||
|
|
9508e4a20e | ||
|
|
7200a89e39 | ||
|
|
33ee4a8721 | ||
|
|
23d570ec04 | ||
|
|
65cd5c602f | ||
|
|
95b2b90006 | ||
|
|
0c3ac67b6d | ||
|
|
6e53aa0350 | ||
|
|
17d984d4b4 | ||
|
|
5acccaa739 | ||
|
|
1f7a4a1665 | ||
|
|
3aa241a74c | ||
|
|
27003af62a | ||
|
|
c5f5862c9c | ||
|
|
c6ef76d2b3 | ||
|
|
8ac285cf52 | ||
|
|
eb6f742b5d | ||
|
|
fb4d507c8a | ||
|
|
de553a2fc1 | ||
|
|
e7bb592602 | ||
|
|
6f061db9a2 | ||
|
|
2e875521eb | ||
|
|
8ce513acbd | ||
|
|
1c26fbde32 | ||
|
|
430ec2451a | ||
|
|
130512187a | ||
|
|
131afb571e | ||
|
|
74dbf38793 | ||
|
|
652069b5e6 | ||
|
|
8789ae5cb1 | ||
|
|
10c98caade | ||
|
|
fe9d61a9a7 | ||
|
|
0d2efaf991 | ||
|
|
7e2bec46b8 | ||
|
|
4f3c890e82 | ||
|
|
ca5656c279 | ||
|
|
82f1cd87dc | ||
|
|
d2e629f5a8 | ||
|
|
7cebfe2df0 | ||
|
|
39c03008be | ||
|
|
625ba48117 | ||
|
|
d177d94945 | ||
|
|
3b4276a0e4 | ||
|
|
dcae6eb0a2 | ||
|
|
daa61c5f71 | ||
|
|
06d6665abb | ||
|
|
cc359f6ecb | ||
|
|
b0af81e780 | ||
|
|
08e7c54cb6 | ||
|
|
4aea49dbc6 | ||
|
|
f62045623c | ||
|
|
74d59498d7 | ||
|
|
e063b7983a | ||
|
|
dd1e150511 | ||
|
|
c47a364ab3 | ||
|
|
450fa72fbb | ||
|
|
cbcb9c7d79 | ||
|
|
39c4267ace | ||
|
|
64f0d6dffd | ||
|
|
78cbdf95f3 | ||
|
|
85a61b8e8d | ||
|
|
a2a7dbda09 | ||
|
|
7a964ae2ca | ||
|
|
1df9a8a38d | ||
|
|
e11634bfbc | ||
|
|
5329a4d67d | ||
|
|
13f893f1f9 | ||
|
|
b4a52e45cf | ||
|
|
f5d975b06d | ||
|
|
3efe677007 | ||
|
|
7e8c8c69b9 | ||
|
|
d195512062 | ||
|
|
1e2b141e5d | ||
|
|
683f7afc0d | ||
|
|
4e74e77738 | ||
|
|
b71a37dbfc | ||
|
|
9ca76226e2 | ||
|
|
217084cdcc | ||
|
|
f4f602cdf9 | ||
|
|
29b0774022 | ||
|
|
040788bb06 | ||
|
|
09afeb6d3e | ||
|
|
fae00a7622 | ||
|
|
5b89f7b6db | ||
|
|
c6050845a0 | ||
|
|
706ae07d0d | ||
|
|
f349f85b05 | ||
|
|
aea68414cf | ||
|
|
bb8e2e9131 | ||
|
|
1a71437d59 | ||
|
|
dc84e591bb | ||
|
|
c66a139ff9 | ||
|
|
9c41e3fabb | ||
|
|
23abbc9a47 | ||
|
|
f042653886 | ||
|
|
efae9792db | ||
|
|
8327536b59 | ||
|
|
a2c1fece33 | ||
|
|
8e7a2eed77 | ||
|
|
562a719382 | ||
|
|
cfdcd65f41 | ||
|
|
cf336d8019 | ||
|
|
795dc26214 | ||
|
|
2999f158db | ||
|
|
1e08e81537 | ||
|
|
8dd9cded1a | ||
|
|
42f2891485 | ||
|
|
9db5e36b54 | ||
|
|
a70456f5ee | ||
|
|
3646fcce46 | ||
|
|
c18decc89b | ||
|
|
5ce92adff0 | ||
|
|
547625c333 | ||
|
|
eabef08561 | ||
|
|
f5eac0b434 | ||
|
|
32907931e1 | ||
|
|
244994d316 | ||
|
|
39bb3963ee | ||
|
|
ae4aad0890 | ||
|
|
1857257265 | ||
|
|
eb19228d16 | ||
|
|
afc9e9cde1 | ||
|
|
fe286ff564 | ||
|
|
1cc99ffa60 | ||
|
|
31b8ff92df | ||
|
|
eaeb9d677e | ||
|
|
11c176c490 | ||
|
|
539de6d361 | ||
|
|
96b72acb2d | ||
|
|
fa470170cf | ||
|
|
75a9879774 | ||
|
|
a5722262d1 | ||
|
|
dd7bdf05f3 | ||
|
|
255a991c6e | ||
|
|
781b7cd1aa | ||
|
|
51298f84cc | ||
|
|
22e8f23e2c | ||
|
|
e015238e6d | ||
|
|
a697ad164e | ||
|
|
29ac0b4a6c | ||
|
|
ee5afe148c | ||
|
|
7c283e5de8 | ||
|
|
5e28f322cf | ||
|
|
0da5f1ccca | ||
|
|
6426706390 | ||
|
|
636b09a548 | ||
|
|
5ad21854f7 | ||
|
|
57c5485501 | ||
|
|
e4856d17ca | ||
|
|
fb0696d0c3 | ||
|
|
13344076c2 | ||
|
|
25d3597c9a | ||
|
|
4a7457ecfe | ||
|
|
f2072e5868 | ||
|
|
8306566216 | ||
|
|
a927906e52 | ||
|
|
6e9e653f76 | ||
|
|
3481618324 | ||
|
|
65ed8da4b7 | ||
|
|
f1e82a2fe3 | ||
|
|
de12ca4882 | ||
|
|
01b5828ee7 | ||
|
|
e7d00cf5fd | ||
|
|
2dfa7a1a72 | ||
|
|
845c9cfa61 | ||
|
|
6fb11b8087 | ||
|
|
cc9140b3cc | ||
|
|
7be81fe60e | ||
|
|
bc20398119 | ||
|
|
05e86ee734 | ||
|
|
dc273e3bed | ||
|
|
11c3837f9b | ||
|
|
5d7969f4b9 | ||
|
|
9245e9d5dc | ||
|
|
f7a42f378f | ||
|
|
d1e3688468 | ||
|
|
83658e891e | ||
|
|
3db7c038a5 | ||
|
|
6236085327 | ||
|
|
6da32a4955 | ||
|
|
0e0ac10388 | ||
|
|
bd0b874631 | ||
|
|
a522a96789 | ||
|
|
3177140db0 | ||
|
|
d7134b1df2 | ||
|
|
81520a9b86 | ||
|
|
453b0a04f4 | ||
|
|
459fe663ee | ||
|
|
50816ba23b | ||
|
|
2c6fc5bd90 | ||
|
|
6897c2f901 | ||
|
|
e354b1c130 | ||
|
|
e1cf244592 | ||
|
|
d9924e0f3f | ||
|
|
c1f4e6d92d | ||
|
|
e7453ebc98 | ||
|
|
0396ca1dee | ||
|
|
17f6a14d37 | ||
|
|
c0cf61912d | ||
|
|
67b40c7fc8 | ||
|
|
e2561f9073 | ||
|
|
e3d6902ede | ||
|
|
68020d0e4b | ||
|
|
ed2d7b445c | ||
|
|
50d4084fac | ||
|
|
c2c5b9040c | ||
|
|
6f62749c1a | ||
|
|
86b9cc6d15 | ||
|
|
4e2a77d683 | ||
|
|
ca83f000ea | ||
|
|
10d6dd006a | ||
|
|
4065c0f194 | ||
|
|
5643e8ebb5 | ||
|
|
6dbde599bf | ||
|
|
b2ec87f05f | ||
|
|
fb33d93186 | ||
|
|
170034787d | ||
|
|
b92d086712 | ||
|
|
18e2401e79 | ||
|
|
849297e623 | ||
|
|
92e9d307a5 | ||
|
|
09bbe072cd | ||
|
|
5ff582ec42 | ||
|
|
b029860b46 | ||
|
|
8ce2006814 | ||
|
|
24dfef6f15 | ||
|
|
cb7bcea5c3 | ||
|
|
aeb5f6d832 | ||
|
|
16f707aa11 | ||
|
|
2fde1f5fc1 | ||
|
|
3a746a3f73 | ||
|
|
f288902e3e | ||
|
|
7eac6675e8 | ||
|
|
f6761ddd00 | ||
|
|
e313d6200a | ||
|
|
5d74a92cf1 | ||
|
|
f936c55a37 | ||
|
|
ad93135adb | ||
|
|
67263d2652 | ||
|
|
4fcd222777 | ||
|
|
6d6f734bc9 | ||
|
|
014c0e2c4c | ||
|
|
1c950aa17b | ||
|
|
ed7fbc9178 | ||
|
|
20f56e9868 | ||
|
|
5bfd4f64db | ||
|
|
09c20b51e6 | ||
|
|
fbb5ead4e9 | ||
|
|
9fc1711d45 | ||
|
|
c4d1e705d3 | ||
|
|
43b1f9a19e | ||
|
|
ea83ed32f5 | ||
|
|
041cfc2173 | ||
|
|
50a5550291 | ||
|
|
ef5ac7fd05 | ||
|
|
3f3deda3d4 | ||
|
|
9e521aa757 | ||
|
|
a280e8cfd2 | ||
|
|
c4bb6501ca | ||
|
|
9affb3c92a | ||
|
|
e81de2491f | ||
|
|
51928e9177 | ||
|
|
5d8d221157 | ||
|
|
6754955bcd | ||
|
|
fbda82ed63 | ||
|
|
923870390b | ||
|
|
96b0808e3a | ||
|
|
e6624506cf | ||
|
|
6d46b5f1eb | ||
|
|
193fdb7026 | ||
|
|
b6316aff70 | ||
|
|
1f7d5c18f2 | ||
|
|
fd1c8294ce | ||
|
|
2889db72ac | ||
|
|
18d6b233da | ||
|
|
c8989231eb | ||
|
|
05cb059b1a | ||
|
|
ff6e9dd2f3 | ||
|
|
deae0e6ae1 | ||
|
|
3dc093c24a | ||
|
|
c7b52bf1fe | ||
|
|
989169dcfe | ||
|
|
31645d163e | ||
|
|
97e52f2b3c | ||
|
|
961d7f2924 | ||
|
|
f87280d369 |
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Tell us about a problem you are experiencing
|
||||
|
||||
---
|
||||
|
||||
**What steps did you take and what happened:**
|
||||
[A clear and concise description of what the bug is, and what commands you ran.)
|
||||
|
||||
|
||||
**What did you expect to happen:**
|
||||
|
||||
|
||||
**The output of the following commands will help us better understand what's going on**:
|
||||
(Pasting long output into a [GitHub gist](https://gist.github.com) or other pastebin is fine.)
|
||||
|
||||
* `kubectl logs deployment/velero -n velero`
|
||||
* `velero backup describe <backupname>` or `kubectl get backup/<backupname> -n velero -o yaml`
|
||||
* `velero backup logs <backupname>`
|
||||
* `velero restore describe <restorename>` or `kubectl get restore/<restorename> -n velero -o yaml`
|
||||
* `velero restore logs <restorename>`
|
||||
|
||||
|
||||
**Anything else you would like to add:**
|
||||
[Miscellaneous information that will assist in solving the issue.]
|
||||
|
||||
|
||||
**Environment:**
|
||||
|
||||
- Velero version (use `velero version`):
|
||||
- Kubernetes version (use `kubectl version`):
|
||||
- Kubernetes installer & version:
|
||||
- Cloud provider or hardware configuration:
|
||||
- OS (e.g. from `/etc/os-release`):
|
||||
25
.github/ISSUE_TEMPLATE/feature-enhancement-request.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/feature-enhancement-request.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Feature enhancement request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Describe the problem/challenge you have**
|
||||
[A description of the current limitation/problem/challenge that you are experiencing.]
|
||||
|
||||
|
||||
**Describe the solution you'd like**
|
||||
[A clear and concise description of what you want to happen.]
|
||||
|
||||
|
||||
**Anything else you would like to add:**
|
||||
[Miscellaneous information that will assist in solving the issue.]
|
||||
|
||||
|
||||
**Environment:**
|
||||
|
||||
- Velero version (use `velero version`):
|
||||
- Kubernetes version (use `kubectl version`):
|
||||
- Kubernetes installer & version:
|
||||
- Cloud provider or hardware configuration:
|
||||
- OS (e.g. from `/etc/os-release`):
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -26,9 +26,24 @@ _testmain.go
|
||||
|
||||
debug
|
||||
|
||||
/ark
|
||||
/velero
|
||||
.idea/
|
||||
|
||||
.container-*
|
||||
.vimrc
|
||||
.go
|
||||
.DS_Store
|
||||
.push-*
|
||||
.vscode
|
||||
*.diff
|
||||
|
||||
# Jekyll compiled data
|
||||
site/_site
|
||||
site/.sass-cache
|
||||
site/.jekyll
|
||||
site/.jekyll-metadata
|
||||
site/.bundle
|
||||
site/vendor
|
||||
.ruby-version
|
||||
|
||||
.vs
|
||||
|
||||
58
.goreleaser.yml
Normal file
58
.goreleaser.yml
Normal file
@@ -0,0 +1,58 @@
|
||||
# Copyright 2018 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
dist: _output
|
||||
builds:
|
||||
- main: ./cmd/velero/main.go
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
- ppc64le
|
||||
ignore:
|
||||
# don't build arm/arm64 for darwin or windows
|
||||
- goos: darwin
|
||||
goarch: arm
|
||||
- goos: darwin
|
||||
goarch: arm64
|
||||
- goos: darwin
|
||||
goarch: ppc64le
|
||||
- goos: windows
|
||||
goarch: arm
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
- goos: windows
|
||||
goarch: ppc64le
|
||||
ldflags:
|
||||
- -X "github.com/heptio/velero/pkg/buildinfo.Version={{ .Tag }}" -X "github.com/heptio/velero/pkg/buildinfo.GitSHA={{ .FullCommit }}" -X "github.com/heptio/velero/pkg/buildinfo.GitTreeState={{ .Env.GIT_TREE_STATE }}"
|
||||
archives:
|
||||
- name_template: "{{ .ProjectName }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}"
|
||||
wrap_in_directory: true
|
||||
files:
|
||||
- LICENSE
|
||||
- examples/**/*
|
||||
checksum:
|
||||
name_template: 'CHECKSUM'
|
||||
release:
|
||||
github:
|
||||
owner: heptio
|
||||
name: velero
|
||||
draft: true
|
||||
prerelease: auto
|
||||
@@ -1,11 +1,11 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.9.x
|
||||
- 1.12.x
|
||||
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
script: make ci
|
||||
script: hack/ci-check.sh
|
||||
|
||||
220
CHANGELOG.md
220
CHANGELOG.md
@@ -1,197 +1,31 @@
|
||||
# Changelog
|
||||
## Current release:
|
||||
* [CHANGELOG-1.1.md][11]
|
||||
|
||||
#### [v0.8.3](https://github.com/heptio/ark/releases/tag/v0.8.3) - 2018-06-29
|
||||
## Development release:
|
||||
* [Unreleased Changes][0]
|
||||
|
||||
##### Bug Fixes:
|
||||
* Don't restore backup and restore resources to avoid possible data corruption (#622, @ncdc)
|
||||
|
||||
#### [v0.8.2](https://github.com/heptio/ark/releases/tag/v0.8.2) - 2018-06-01
|
||||
|
||||
##### Bug Fixes:
|
||||
* Don't crash when a PVC is missing spec.volumeName (#520, @ncdc)
|
||||
|
||||
#### [v0.8.1](https://github.com/heptio/ark/releases/tag/v0.8.1) - 2018-04-23
|
||||
|
||||
##### Bug Fixes:
|
||||
* Azure: allow pre-v0.8.0 backups with disk snapshots to be restored and deleted (#446 #449, @skriss)
|
||||
|
||||
#### [v0.8.0](https://github.com/heptio/ark/releases/tag/v0.8.0) - 2018-04-19
|
||||
|
||||
##### Highlights:
|
||||
* Backup deletion has been completely revamped to make it simpler and less error-prone. As a user, you still use the `ark backup delete` command to request deletion of a backup and its associated cloud
|
||||
resources; behind the scenes, we've switched to using a new `DeleteBackupRequest` Custom Resource and associated controller for processing deletion requests.
|
||||
* We've reduced the number of required fields in the Ark config. For Azure, `location` is no longer required, and for GCP, `project` is not needed.
|
||||
* Ark now copies tags from volumes to snapshots during backup, and from snapshots to new volumes during restore.
|
||||
|
||||
##### Breaking Changes:
|
||||
* Ark has moved back to a single namespace (`heptio-ark` by default) as part of #383.
|
||||
|
||||
##### All New Features:
|
||||
* Add global `--kubecontext` flag to Ark CLI (#296, @blakebarnett)
|
||||
* Azure: support cross-resource group restores of volumes (#356 #378, @skriss)
|
||||
* AWS/Azure/GCP: copy tags from volumes to snapshots, and from snapshots to volumes (#341, @skriss)
|
||||
* Replace finalizer for backup deletion with `DeleteBackupRequest` custom resource & controller (#383 #431, @ncdc @nrb)
|
||||
* Don't log warnings during restore if an identical object already exists in the cluster (#405, @nrb)
|
||||
* Add bash & zsh completion support (#384, @containscafeine)
|
||||
|
||||
##### Bug Fixes / Other Changes:
|
||||
* Error from the Ark CLI if attempting to restore a non-existent backup (#302, @ncdc)
|
||||
* Enable running the Ark server locally for development purposes (#334, @ncdc)
|
||||
* Add examples to `ark schedule create` documentation (#331, @lypht)
|
||||
* GCP: Remove `project` requirement from Ark config (#345, @skriss)
|
||||
* Add `--from-backup` flag to `ark restore create` and allow custom restore names (#342 #409, @skriss)
|
||||
* Azure: remove `location` requirement from Ark config (#344, @skriss)
|
||||
* Add documentation/examples for storing backups in IBM Cloud Object Storage (#321, @roytman)
|
||||
* Reduce verbosity of hooks logging (#362, @skriss)
|
||||
* AWS: Add minimal IAM policy to documentation (#363 #419, @hopkinsth)
|
||||
* Don't restore events (#374, @sanketjpatel)
|
||||
* Azure: reduce API polling interval from 60s to 5s (#359, @skriss)
|
||||
* Switch from hostPath to emptyDir volume type for minio example (#386, @containscafeine)
|
||||
* Add limit ranges as a prioritized resource for restores (#392, @containscafeine)
|
||||
* AWS: Add documentation on using Ark with kube2iam (#402, @domderen)
|
||||
* Azure: add node selector so Ark pod is scheduled on a linux node (#415, @ffd2subroutine)
|
||||
* Error from the Ark CLI if attempting to get logs for a non-existent restore (#391, @containscafeine)
|
||||
* GCP: Add minimal IAM policy to documentation (#429, @skriss @jody-frankowski)
|
||||
|
||||
##### Upgrading from v0.7.1:
|
||||
Ark v0.7.1 moved the Ark server deployment into a separate namespace, `heptio-ark-server`. As of v0.8.0 we've
|
||||
returned to a single namespace, `heptio-ark`, for all Ark-related resources. If you're currently running v0.7.1,
|
||||
here are the steps you can take to upgrade:
|
||||
|
||||
1. Execute the steps from the **Credentials and configuration** section for your cloud:
|
||||
* [AWS](https://heptio.github.io/ark/v0.8.0/aws-config#credentials-and-configuration)
|
||||
* [Azure](https://heptio.github.io/ark/v0.8.0/azure-config#credentials-and-configuration)
|
||||
* [GCP](https://heptio.github.io/ark/v0.8.0/gcp-config#credentials-and-configuration)
|
||||
|
||||
When you get to the secret creation step, if you don't have your `credentials-ark` file handy,
|
||||
you can copy the existing secret from your `heptio-ark-server` namespace into the `heptio-ark` namespace:
|
||||
```bash
|
||||
kubectl get secret/cloud-credentials -n heptio-ark-server --export -o json | \
|
||||
jq '.metadata.namespace="heptio-ark"' | \
|
||||
kubectl apply -f -
|
||||
```
|
||||
|
||||
2. You can now safely delete the `heptio-ark-server` namespace:
|
||||
```bash
|
||||
kubectl delete namespace heptio-ark-server
|
||||
```
|
||||
|
||||
3. Execute the commands from the **Start the server** section for your cloud:
|
||||
* [AWS](https://heptio.github.io/ark/v0.8.0/aws-config#start-the-server)
|
||||
* [Azure](https://heptio.github.io/ark/v0.8.0/azure-config#start-the-server)
|
||||
* [GCP](https://heptio.github.io/ark/v0.8.0/gcp-config#start-the-server)
|
||||
## Older releases:
|
||||
* [CHANGELOG-1.0.md][10]
|
||||
* [CHANGELOG-0.11.md][9]
|
||||
* [CHANGELOG-0.10.md][8]
|
||||
* [CHANGELOG-0.9.md][7]
|
||||
* [CHANGELOG-0.8.md][6]
|
||||
* [CHANGELOG-0.7.md][5]
|
||||
* [CHANGELOG-0.6.md][4]
|
||||
* [CHANGELOG-0.5.md][3]
|
||||
* [CHANGELOG-0.4.md][2]
|
||||
* [CHANGELOG-0.3.md][1]
|
||||
|
||||
|
||||
#### [v0.7.1](https://github.com/heptio/ark/releases/tag/v0.7.1) - 2018-02-22
|
||||
|
||||
Bug Fixes:
|
||||
* Run the Ark server in its own namespace, separate from backups/schedules/restores/config (#322, @ncdc)
|
||||
|
||||
#### [v0.7.0](https://github.com/heptio/ark/releases/tag/v0.7.0) - 2018-02-15
|
||||
|
||||
New Features:
|
||||
* Run the Ark server in any namespace (#272, @ncdc)
|
||||
* Add ability to delete backups and their associated data (#252, @skriss)
|
||||
* Support both pre and post backup hooks (#243, @ncdc)
|
||||
|
||||
Bug Fixes / Other Changes:
|
||||
* Switch from Update() to Patch() when updating Ark resources (#241, @skriss)
|
||||
* Don't fail the backup if a PVC is not bound to a PV (#256, @skriss)
|
||||
* Restore serviceaccounts prior to workload controllers (#258, @ncdc)
|
||||
* Stop removing annotations from PVs when restoring them (#263, @skriss)
|
||||
* Update GCP client libraries (#249, @skriss)
|
||||
* Clarify backup and restore creation messages (#270, @nrb)
|
||||
* Update S3 bucket creation docs for us-east-1 (#285, @lypht)
|
||||
|
||||
#### [v0.6.0](https://github.com/heptio/ark/tree/v0.6.0) - 2017-11-30
|
||||
|
||||
Highlights:
|
||||
* **Plugins** - We now support user-defined plugins that can extend Ark functionality to meet your custom backup/restore needs without needing to be compiled into the core binary. We support pluggable block and object stores as well as per-item backup and restore actions that can execute arbitrary logic, including modifying the items being backed up or restored. For more information see the [documentation](docs/plugins.md), which includes a reference to a fully-functional sample plugin repository. (#174 #188 #206 #213 #215 #217 #223 #226)
|
||||
* **Describers** - The Ark CLI now includes `describe` commands for `backups`, `restores`, and `schedules` that provide human-friendly representations of the relevant API objects.
|
||||
|
||||
Breaking Changes:
|
||||
* The config object format has changed. In order to upgrade to v0.6.0, the config object will have to be updated to match the new format. See the [examples](examples) and [documentation](docs/config-definition.md) for more information.
|
||||
* The restore object format has changed. The `warnings` and `errors` fields are now ints containing the counts, while full warnings and errors are now stored in the object store instead of etcd. Restore objects created prior to v.0.6.0 should be deleted, or a new bucket used, and the old restore objects deleted from Kubernetes (`kubectl -n heptio-ark delete restore --all`).
|
||||
|
||||
All New Features:
|
||||
* Add `ark plugin add` and `ark plugin remove` commands #217, @skriss
|
||||
* Add plugin support for block/object stores, backup/restore item actions #174 #188 #206 #213 #215 #223 #226, @skriss @ncdc
|
||||
* Improve Azure deployment instructions #216, @ncdc
|
||||
* Change default TTL for backups to 30 days #204, @nrb
|
||||
* Improve logging for backups and restores #199, @ncdc
|
||||
* Add `ark backup describe`, `ark schedule describe` #196, @ncdc
|
||||
* Add `ark restore describe` and move restore warnings/errors to object storage #173 #201 #202, @ncdc
|
||||
* Upgrade to client-go v5.0.1, kubernetes v1.8.2 #157, @ncdc
|
||||
* Add Travis CI support #165 #166, @ncdc
|
||||
|
||||
Bug Fixes:
|
||||
* Fix log location hook prefix stripping #222, @ncdc
|
||||
* When running `ark backup download`, remove file if there's an error #154, @ncdc
|
||||
* Update documentation for AWS KMS Key alias support #163, @lli-hiya
|
||||
* Remove clock from `volume_snapshot_action` #137, @athampy
|
||||
|
||||
#### [v0.5.1](https://github.com/heptio/ark/tree/v0.5.1) - 2017-11-06
|
||||
Bug fixes:
|
||||
* If a Service is headless, retain ClusterIP = None when backing up and restoring.
|
||||
* Use the specifed --label-selector when listing backups, schedules, and restores.
|
||||
* Restore namespace mapping functionality that was accidentally broken in 0.5.0.
|
||||
* Always include namespaces in the backup, regardless of the --include-cluster-resources setting.
|
||||
|
||||
#### [v0.5.0](https://github.com/heptio/ark/tree/v0.5.0) - 2017-10-26
|
||||
Breaking changes:
|
||||
* The backup tar file format has changed. Backups created using previous versions of Ark cannot be restored using v0.5.0.
|
||||
* When backing up one or more specific namespaces, cluster-scoped resources are no longer backed up by default, with the exception of PVs that are used within the target namespace(s). Cluster-scoped resources can still be included by explicitly specifying `--include-cluster-resources`.
|
||||
|
||||
New features:
|
||||
* Add customized user-agent string for Ark CLI
|
||||
* Switch from glog to logrus
|
||||
* Exclude nodes from restoration
|
||||
* Add a FAQ
|
||||
* Record PV availability zone and use it when restoring volumes from snapshots
|
||||
* Back up the PV associated with a PVC
|
||||
* Add `--include-cluster-resources` flag to `ark backup create`
|
||||
* Add `--include-cluster-resources` flag to `ark restore create`
|
||||
* Properly support resource restore priorities across cluster-scoped and namespace-scoped resources
|
||||
* Support `ark create ...` and `ark get ...`
|
||||
* Make ark run as cluster-admin
|
||||
* Add pod exec backup hooks
|
||||
* Support cross-compilation & upgrade to go 1.9
|
||||
|
||||
Bug fixes:
|
||||
* Make config change detection more robust
|
||||
|
||||
#### [v0.4.0](https://github.com/heptio/ark/tree/v0.4.0) - 2017-09-14
|
||||
Breaking changes:
|
||||
* Snapshotting and restoring volumes is now enabled by default
|
||||
* The --namespaces flag for 'ark restore create' has been replaced by --include-namespaces and
|
||||
--exclude-namespaces
|
||||
|
||||
New features:
|
||||
* Support for S3 SSE with KMS
|
||||
* Cloud provider configurations are validated at startup
|
||||
* The persistentVolumeProvider is now optional
|
||||
* Restore objects are garbage collected
|
||||
* Each backup now has an associated log file, viewable via 'ark backup logs'
|
||||
* Each restore now has an associated log file, viewable via 'ark restore logs'
|
||||
* Add --include-resources/--exclude-resources for restores
|
||||
|
||||
Bug fixes:
|
||||
* Only save/use iops for io1 volumes on AWS
|
||||
* When restoring, try to retrieve the Backup directly from object storage if it's not found
|
||||
* When syncing Backups from object storage to Kubernetes, don't return at the first error
|
||||
encountered
|
||||
* More closely match how kubectl performs kubeconfig resolution
|
||||
* Increase default Azure API request timeout to 2 minutes
|
||||
* Update Azure diskURI to match diskName
|
||||
|
||||
#### [v0.3.3](https://github.com/heptio/ark/tree/v0.3.3) - 2017-08-10
|
||||
* Treat the first field in a schedule's cron expression as minutes, not seconds
|
||||
|
||||
#### [v0.3.2](https://github.com/heptio/ark/tree/v0.3.2) - 2017-08-07
|
||||
* Add client-go auth provider plugins for Azure, GCP, OIDC
|
||||
|
||||
#### [v0.3.1](https://github.com/heptio/ark/tree/v0.3.1) - 2017-08-03
|
||||
* Fix Makefile VERSION
|
||||
|
||||
#### [v0.3.0](https://github.com/heptio/ark/tree/v0.3.0) - 2017-08-03
|
||||
* Initial Release
|
||||
[11]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-1.1.md
|
||||
[10]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-1.0.md
|
||||
[9]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.11.md
|
||||
[8]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.10.md
|
||||
[7]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.9.md
|
||||
[6]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.8.md
|
||||
[5]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.7.md
|
||||
[4]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.6.md
|
||||
[3]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.5.md
|
||||
[2]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.4.md
|
||||
[1]: https://github.com/heptio/velero/blob/master/changelogs/CHANGELOG-0.3.md
|
||||
[0]: https://github.com/heptio/velero/blob/master/changelogs/unreleased
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Heptio Ark Community Code of Conduct
|
||||
# Velero Community Code of Conduct
|
||||
|
||||
## Contributor Code of Conduct
|
||||
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
# Contributing
|
||||
|
||||
## CHANGELOG
|
||||
|
||||
Authors are expected to include a changelog file with their pull requests. The changelog file
|
||||
should be a new file created in the `changelogs/unreleased` folder. The file should follow the
|
||||
naming convention of `pr-username` and the contents of the file should be your text for the
|
||||
changelog.
|
||||
|
||||
velero/changelogs/unreleased <- folder
|
||||
000-username <- file
|
||||
|
||||
|
||||
## DCO Sign off
|
||||
|
||||
All authors to the project retain copyright to their work. However, to ensure
|
||||
that they are only submitting work that they have rights to, we are requiring
|
||||
everyone to acknowledge this by signing their work.
|
||||
|
||||
Any copyright notices in this repo should specify the authors as "the Heptio Ark project contributors".
|
||||
Any copyright notices in this repo should specify the authors as "the Velero contributors".
|
||||
|
||||
To sign your work, just add a line like this at the end of your commit message:
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2018, 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -12,18 +12,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: ark.heptio.com/v1
|
||||
kind: Config
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: default
|
||||
persistentVolumeProvider:
|
||||
name: gcp
|
||||
backupStorageProvider:
|
||||
name: gcp
|
||||
bucket: <YOUR_BUCKET>
|
||||
backupSyncPeriod: 30m
|
||||
gcSyncPeriod: 30m
|
||||
scheduleSyncPeriod: 1m
|
||||
restoreOnlyMode: false
|
||||
FROM ubuntu:bionic
|
||||
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "-c", "while true; do sleep 10000; done"]
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2018 the Heptio Ark contributors.
|
||||
# Copyright 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -12,20 +12,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: ark.heptio.com/v1
|
||||
kind: Config
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: default
|
||||
backupStorageProvider:
|
||||
name: aws
|
||||
bucket: <YOUR_BUCKET>
|
||||
config:
|
||||
region: <YOUR_REGION>
|
||||
s3ForcePathStyle: "true"
|
||||
s3Url: <YOUR_URL_ACCESS_POINT>
|
||||
backupSyncPeriod: 30m
|
||||
gcSyncPeriod: 30m
|
||||
scheduleSyncPeriod: 1m
|
||||
---
|
||||
FROM ubuntu:bionic
|
||||
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "-c", "while true; do sleep 10000; done"]
|
||||
33
Dockerfile-velero
Normal file
33
Dockerfile-velero
Normal file
@@ -0,0 +1,33 @@
|
||||
# Copyright 2017, 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM ubuntu:bionic
|
||||
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates wget bzip2 && \
|
||||
wget --quiet https://github.com/restic/restic/releases/download/v0.9.4/restic_0.9.4_linux_amd64.bz2 && \
|
||||
bunzip2 restic_0.9.4_linux_amd64.bz2 && \
|
||||
mv restic_0.9.4_linux_amd64 /usr/bin/restic && \
|
||||
chmod +x /usr/bin/restic && \
|
||||
apt-get remove -y wget bzip2 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
ADD /bin/linux/amd64/velero /velero
|
||||
|
||||
USER nobody:nobody
|
||||
|
||||
ENTRYPOINT ["/velero"]
|
||||
32
Dockerfile-velero-ppc64le
Normal file
32
Dockerfile-velero-ppc64le
Normal file
@@ -0,0 +1,32 @@
|
||||
# Copyright 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM ubuntu:bionic
|
||||
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates wget && \
|
||||
wget --quiet https://oplab9.parqtec.unicamp.br/pub/ppc64el/restic/restic-0.9.4 && \
|
||||
mv restic-0.9.4 /usr/bin/restic && \
|
||||
chmod +x /usr/bin/restic && \
|
||||
apt-get remove -y wget && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
ADD /bin/linux/ppc64le/velero /velero
|
||||
|
||||
USER nobody:nobody
|
||||
|
||||
ENTRYPOINT ["/velero"]
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2018, 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -12,20 +12,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: ark.heptio.com/v1
|
||||
kind: Config
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: default
|
||||
persistentVolumeProvider:
|
||||
name: azure
|
||||
config:
|
||||
apiTimeout: <YOUR_TIMEOUT>
|
||||
backupStorageProvider:
|
||||
name: azure
|
||||
bucket: <YOUR_BUCKET>
|
||||
backupSyncPeriod: 30m
|
||||
gcSyncPeriod: 30m
|
||||
scheduleSyncPeriod: 1m
|
||||
restoreOnlyMode: false
|
||||
FROM ubuntu:bionic
|
||||
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
|
||||
ADD /bin/linux/amd64/velero-restic-restore-helper .
|
||||
|
||||
USER nobody:nobody
|
||||
|
||||
ENTRYPOINT [ "/velero-restic-restore-helper" ]
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -12,14 +12,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM alpine:3.6
|
||||
FROM ubuntu:bionic
|
||||
|
||||
MAINTAINER Andy Goldstein <andy@heptio.com>
|
||||
LABEL maintainer="Steve Kriss <krisss@vmware.com>"
|
||||
|
||||
RUN apk add --no-cache ca-certificates
|
||||
|
||||
ADD /bin/linux/amd64/ark /ark
|
||||
ADD /bin/linux/ppc64le/velero-restic-restore-helper .
|
||||
|
||||
USER nobody:nobody
|
||||
|
||||
ENTRYPOINT ["/ark"]
|
||||
ENTRYPOINT [ "/velero-restic-restore-helper" ]
|
||||
819
Gopkg.lock
generated
819
Gopkg.lock
generated
File diff suppressed because it is too large
Load Diff
102
Gopkg.toml
102
Gopkg.toml
@@ -25,82 +25,110 @@
|
||||
non-go = true
|
||||
go-tests = true
|
||||
|
||||
[[constraint]]
|
||||
name = "cloud.google.com/go"
|
||||
version = "0.11.0"
|
||||
#
|
||||
# Kubernetes packages
|
||||
#
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/Azure/azure-sdk-for-go"
|
||||
version = "~10.2.1-beta"
|
||||
name = "k8s.io/kubernetes"
|
||||
version = "~1.14"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/Azure/go-autorest"
|
||||
version = "~8.1.x"
|
||||
name = "k8s.io/client-go"
|
||||
version = "kubernetes-1.14.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apimachinery"
|
||||
version = "kubernetes-1.14.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/api"
|
||||
version = "kubernetes-1.14.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apiextensions-apiserver"
|
||||
version = "kubernetes-1.14.0"
|
||||
|
||||
# k8s.io/client-go kubernetes-1.14.0 uses v1.1.4
|
||||
[[override]]
|
||||
name = "github.com/json-iterator/go"
|
||||
version = "=1.1.4"
|
||||
|
||||
#
|
||||
# Cloud provider packages
|
||||
#
|
||||
[[constraint]]
|
||||
name = "github.com/aws/aws-sdk-go"
|
||||
version = "1.13.12"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/golang/glog"
|
||||
name = "github.com/Azure/azure-sdk-for-go"
|
||||
version = "~21.4.0"
|
||||
|
||||
# k8s.io/client-go kubernetes-1.14.0 uses v11.1.2
|
||||
[[constraint]]
|
||||
name = "github.com/Azure/go-autorest"
|
||||
version = "11.1.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "cloud.google.com/go"
|
||||
version = "0.11.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "google.golang.org/api"
|
||||
version = "~v0.3.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "golang.org/x/oauth2"
|
||||
branch = "master"
|
||||
|
||||
#
|
||||
# Third party packages
|
||||
#
|
||||
[[constraint]]
|
||||
name = "github.com/robfig/cron"
|
||||
revision = "df38d32658d8788cd446ba74db4bb5375c4b0cb3"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/satori/go.uuid"
|
||||
version = "1.1.0"
|
||||
version = "~1.2.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/satori/uuid"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/afero"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/cobra"
|
||||
version = "0.0.3"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/pflag"
|
||||
version = "1.0.0"
|
||||
version = "1.0.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/stretchr/testify"
|
||||
branch = "master"
|
||||
version = "~1.2.2"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
name = "github.com/hashicorp/go-plugin"
|
||||
revision = "a1bc61569a26c0f65865932c0d55743b0567c494"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "google.golang.org/api"
|
||||
name = "github.com/golang/protobuf"
|
||||
version = "~v1.3.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/kubernetes"
|
||||
version = "~1.9"
|
||||
name = "google.golang.org/grpc"
|
||||
version = "~v1.19.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/client-go"
|
||||
version = "~6.0"
|
||||
name = "github.com/joho/godotenv"
|
||||
version = "~v1.3.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/apimachinery"
|
||||
version = "kubernetes-1.9.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "k8s.io/api"
|
||||
version = "kubernetes-1.9.0"
|
||||
name = "github.com/gobwas/glob"
|
||||
version = "~v0.2.3"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/russross/blackfriday"
|
||||
revision = "93622da34e54fb6529bfb7c57e710f37a8d9cbd8"
|
||||
|
||||
[[constraint]]
|
||||
name = "golang.org/x/sys"
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-plugin"
|
||||
|
||||
171
Makefile
171
Makefile
@@ -1,6 +1,6 @@
|
||||
# Copyright 2016 The Kubernetes Authors.
|
||||
#
|
||||
# Modifications Copyright 2017 the Heptio Ark contributors.
|
||||
# Modifications Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -15,27 +15,30 @@
|
||||
# limitations under the License.
|
||||
|
||||
# The binary to build (just the basename).
|
||||
BIN := ark
|
||||
BIN ?= velero
|
||||
|
||||
# This repo's root import path (under GOPATH).
|
||||
PKG := github.com/heptio/ark
|
||||
PKG := github.com/heptio/velero
|
||||
|
||||
# Where to push the docker image.
|
||||
REGISTRY ?= gcr.io/heptio-images
|
||||
|
||||
# Which architecture to build - see $(ALL_ARCH) for options.
|
||||
# if the 'local' rule is being run, detect the ARCH from 'go env'
|
||||
# if it wasn't specified by the caller.
|
||||
local : ARCH ?= $(shell go env GOOS)-$(shell go env GOARCH)
|
||||
ARCH ?= linux-amd64
|
||||
|
||||
VERSION ?= master
|
||||
|
||||
TAG_LATEST ?= false
|
||||
|
||||
###
|
||||
### These variables should not need tweaking.
|
||||
###
|
||||
|
||||
SRC_DIRS := cmd pkg # directories which hold app source (not vendored)
|
||||
|
||||
CLI_PLATFORMS := linux-amd64 linux-arm linux-arm64 darwin-amd64 windows-amd64
|
||||
CONTAINER_PLATFORMS := linux-amd64 linux-arm linux-arm64
|
||||
CLI_PLATFORMS := linux-amd64 linux-arm linux-arm64 darwin-amd64 windows-amd64 linux-ppc64le
|
||||
CONTAINER_PLATFORMS := linux-amd64 linux-arm linux-arm64 linux-ppc64le
|
||||
|
||||
platform_temp = $(subst -, ,$(ARCH))
|
||||
GOOS = $(word 1, $(platform_temp))
|
||||
@@ -44,7 +47,7 @@ GOARCH = $(word 2, $(platform_temp))
|
||||
# TODO(ncdc): support multiple image architectures once gcr.io supports manifest lists
|
||||
# Set default base image dynamically for each arch
|
||||
ifeq ($(GOARCH),amd64)
|
||||
DOCKERFILE ?= Dockerfile.alpine
|
||||
DOCKERFILE ?= Dockerfile-$(BIN)
|
||||
endif
|
||||
#ifeq ($(GOARCH),arm)
|
||||
# DOCKERFILE ?= Dockerfile.arm #armel/busybox
|
||||
@@ -52,13 +55,18 @@ endif
|
||||
#ifeq ($(GOARCH),arm64)
|
||||
# DOCKERFILE ?= Dockerfile.arm64 #aarch64/busybox
|
||||
#endif
|
||||
ifeq ($(GOARCH),ppc64le)
|
||||
DOCKERFILE ?= Dockerfile-$(BIN)-ppc64le
|
||||
endif
|
||||
|
||||
IMAGE := $(REGISTRY)/$(BIN)
|
||||
IMAGE = $(REGISTRY)/$(BIN)
|
||||
|
||||
# If you want to build all binaries, see the 'all-build' rule.
|
||||
# If you want to build all containers, see the 'all-container' rule.
|
||||
# If you want to build AND push all containers, see the 'all-push' rule.
|
||||
all: build
|
||||
all:
|
||||
@$(MAKE) build
|
||||
@$(MAKE) build BIN=velero-restic-restore-helper
|
||||
|
||||
build-%:
|
||||
@$(MAKE) --no-print-directory ARCH=$* build
|
||||
@@ -75,6 +83,15 @@ all-build: $(addprefix build-, $(CLI_PLATFORMS))
|
||||
|
||||
#all-push: $(addprefix push-, $(CONTAINER_PLATFORMS))
|
||||
|
||||
local: build-dirs
|
||||
GOOS=$(GOOS) \
|
||||
GOARCH=$(GOARCH) \
|
||||
VERSION=$(VERSION) \
|
||||
PKG=$(PKG) \
|
||||
BIN=$(BIN) \
|
||||
OUTPUT_DIR=$$(pwd)/_output/bin/$(GOOS)/$(GOARCH) \
|
||||
./hack/build.sh
|
||||
|
||||
build: _output/bin/$(GOOS)/$(GOARCH)/$(BIN)
|
||||
|
||||
_output/bin/$(GOOS)/$(GOARCH)/$(BIN): build-dirs
|
||||
@@ -90,42 +107,73 @@ _output/bin/$(GOOS)/$(GOARCH)/$(BIN): build-dirs
|
||||
|
||||
TTY := $(shell tty -s && echo "-t")
|
||||
|
||||
BUILDER_IMAGE := ark-builder
|
||||
BUILDER_IMAGE := velero-builder
|
||||
|
||||
# Example: make shell CMD="date > datefile"
|
||||
shell: build-dirs build-image
|
||||
@# the volume bind-mount of $PWD/vendor/k8s.io/api is needed for code-gen to
|
||||
@# function correctly (ref. https://github.com/kubernetes/kubernetes/pull/64567)
|
||||
@docker run \
|
||||
-e GOFLAGS \
|
||||
-i $(TTY) \
|
||||
--rm \
|
||||
-u $$(id -u):$$(id -g) \
|
||||
-v "$$(pwd)/.go/pkg:/go/pkg" \
|
||||
-v "$$(pwd)/.go/std:/go/std" \
|
||||
-v "$$(pwd):/go/src/$(PKG)" \
|
||||
-v "$$(pwd)/_output/bin:/output" \
|
||||
-v "$$(pwd)/.go/std/$(GOOS)/$(GOARCH):/usr/local/go/pkg/$(GOOS)_$(GOARCH)_static" \
|
||||
-v "$$(pwd)/vendor/k8s.io/api:/go/src/k8s.io/api:delegated" \
|
||||
-v "$$(pwd)/.go/pkg:/go/pkg:delegated" \
|
||||
-v "$$(pwd)/.go/std:/go/std:delegated" \
|
||||
-v "$$(pwd):/go/src/$(PKG):delegated" \
|
||||
-v "$$(pwd)/_output/bin:/output:delegated" \
|
||||
-v "$$(pwd)/.go/std/$(GOOS)/$(GOARCH):/usr/local/go/pkg/$(GOOS)_$(GOARCH)_static:delegated" \
|
||||
-v "$$(pwd)/.go/go-build:/.cache/go-build:delegated" \
|
||||
-w /go/src/$(PKG) \
|
||||
$(BUILDER_IMAGE) \
|
||||
/bin/sh $(CMD)
|
||||
|
||||
DOTFILE_IMAGE = $(subst :,_,$(subst /,_,$(IMAGE))-$(VERSION))
|
||||
|
||||
# Use a slightly customized build/push targets since we don't have a Go binary to build for the fsfreeze image
|
||||
build-fsfreeze: BIN = fsfreeze-pause
|
||||
build-fsfreeze:
|
||||
@cp $(DOCKERFILE) _output/.dockerfile-$(BIN).alpine
|
||||
@docker build --pull -t $(IMAGE):$(VERSION) -f _output/.dockerfile-$(BIN).alpine _output
|
||||
@docker images -q $(IMAGE):$(VERSION) > .container-$(DOTFILE_IMAGE)
|
||||
|
||||
push-fsfreeze: BIN = fsfreeze-pause
|
||||
push-fsfreeze:
|
||||
@docker push $(IMAGE):$(VERSION)
|
||||
ifeq ($(TAG_LATEST), true)
|
||||
docker tag $(IMAGE):$(VERSION) $(IMAGE):latest
|
||||
docker push $(IMAGE):latest
|
||||
endif
|
||||
@docker images -q $(REGISTRY)/fsfreeze-pause:$(VERSION) > .container-$(DOTFILE_IMAGE)
|
||||
|
||||
all-containers:
|
||||
$(MAKE) container
|
||||
$(MAKE) container BIN=velero-restic-restore-helper
|
||||
$(MAKE) build-fsfreeze
|
||||
|
||||
container: verify test .container-$(DOTFILE_IMAGE) container-name
|
||||
.container-$(DOTFILE_IMAGE): _output/bin/$(GOOS)/$(GOARCH)/$(BIN) $(DOCKERFILE)
|
||||
@cp $(DOCKERFILE) _output/.dockerfile-$(GOOS)-$(GOARCH)
|
||||
@docker build -t $(IMAGE):$(VERSION) -f _output/.dockerfile-$(GOOS)-$(GOARCH) _output
|
||||
@cp $(DOCKERFILE) _output/.dockerfile-$(BIN)-$(GOOS)-$(GOARCH)
|
||||
@docker build --pull -t $(IMAGE):$(VERSION) -f _output/.dockerfile-$(BIN)-$(GOOS)-$(GOARCH) _output
|
||||
@docker images -q $(IMAGE):$(VERSION) > $@
|
||||
|
||||
container-name:
|
||||
@echo "container: $(IMAGE):$(VERSION)"
|
||||
|
||||
all-push:
|
||||
$(MAKE) push
|
||||
$(MAKE) push BIN=velero-restic-restore-helper
|
||||
$(MAKE) push-fsfreeze
|
||||
|
||||
|
||||
push: .push-$(DOTFILE_IMAGE) push-name
|
||||
.push-$(DOTFILE_IMAGE): .container-$(DOTFILE_IMAGE)
|
||||
@docker push $(IMAGE):$(VERSION)
|
||||
@if git describe --tags --exact-match >/dev/null 2>&1; \
|
||||
then \
|
||||
docker tag $(IMAGE):$(VERSION) $(IMAGE):latest; \
|
||||
docker push $(IMAGE):latest; \
|
||||
fi
|
||||
ifeq ($(TAG_LATEST), true)
|
||||
docker tag $(IMAGE):$(VERSION) $(IMAGE):latest
|
||||
docker push $(IMAGE):latest
|
||||
endif
|
||||
@docker images -q $(IMAGE):$(VERSION) > $@
|
||||
|
||||
push-name:
|
||||
@@ -134,7 +182,12 @@ push-name:
|
||||
SKIP_TESTS ?=
|
||||
test: build-dirs
|
||||
ifneq ($(SKIP_TESTS), 1)
|
||||
@$(MAKE) shell CMD="-c 'hack/test.sh $(SRC_DIRS)'"
|
||||
@$(MAKE) shell CMD="-c 'hack/test.sh $(WHAT)'"
|
||||
endif
|
||||
|
||||
test-local: build-dirs
|
||||
ifneq ($(SKIP_TESTS), 1)
|
||||
hack/test.sh $(WHAT)
|
||||
endif
|
||||
|
||||
verify:
|
||||
@@ -145,40 +198,56 @@ endif
|
||||
update:
|
||||
@$(MAKE) shell CMD="-c 'hack/update-all.sh'"
|
||||
|
||||
release: all-tar-bin checksum
|
||||
|
||||
checksum:
|
||||
@cd _output/release; \
|
||||
sha256sum *.tar.gz > CHECKSUM; \
|
||||
cat CHECKSUM; \
|
||||
sha256sum CHECKSUM
|
||||
|
||||
all-tar-bin: $(addprefix tar-bin-, $(CLI_PLATFORMS))
|
||||
|
||||
tar-bin-%:
|
||||
$(MAKE) ARCH=$* VERSION=$(VERSION) tar-bin
|
||||
|
||||
GIT_DESCRIBE = $(shell git describe --tags --always --dirty)
|
||||
tar-bin: build
|
||||
mkdir -p _output/release
|
||||
|
||||
# We do the subshell & wildcard ls so we can pick up $(BIN).exe for windows
|
||||
(cd _output/bin/$(GOOS)/$(GOARCH) && ls $(BIN)*) | \
|
||||
tar \
|
||||
-C _output/bin/$(GOOS)/$(GOARCH) \
|
||||
--files-from=- \
|
||||
-zcf _output/release/$(BIN)-$(GIT_DESCRIBE)-$(GOOS)-$(GOARCH).tar.gz
|
||||
|
||||
build-dirs:
|
||||
@mkdir -p _output/bin/$(GOOS)/$(GOARCH)
|
||||
@mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH)
|
||||
@mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build
|
||||
|
||||
build-image:
|
||||
cd hack/build-image && docker build -t $(BUILDER_IMAGE) .
|
||||
cd hack/build-image && docker build --pull -t $(BUILDER_IMAGE) .
|
||||
|
||||
clean:
|
||||
rm -rf .container-* _output/.dockerfile-* .push-*
|
||||
rm -rf .go _output
|
||||
docker rmi $(BUILDER_IMAGE)
|
||||
|
||||
ci: build verify test
|
||||
ci: all verify test
|
||||
|
||||
changelog:
|
||||
hack/changelog.sh
|
||||
|
||||
release:
|
||||
hack/goreleaser.sh
|
||||
|
||||
serve-docs:
|
||||
docker run \
|
||||
--rm \
|
||||
-v "$$(pwd)/site:/srv/jekyll" \
|
||||
-it -p 4000:4000 \
|
||||
jekyll/jekyll \
|
||||
jekyll serve --livereload --incremental
|
||||
|
||||
# gen-docs generates a new versioned docs directory under site/docs. It follows
|
||||
# the following process:
|
||||
# 1. Copies the contents of the most recently tagged docs directory into the new
|
||||
# directory, to establish a useful baseline to diff against.
|
||||
# 2. Adds all copied content from step 1 to git's staging area via 'git add'.
|
||||
# 3. Replaces the contents of the new docs directory with the contents of the
|
||||
# 'master' docs directory, updating any version-specific links (e.g. to a
|
||||
# specific branch of the GitHub repository) to use the new version
|
||||
# 4. Copies the previous version's ToC file and runs 'git add' to establish
|
||||
# a useful baseline to diff against.
|
||||
# 5. Replaces the content of the new ToC file with the master ToC.
|
||||
# 6. Update site/_config.yml and site/_data/toc-mapping.yml to include entries
|
||||
# for the new version.
|
||||
#
|
||||
# The unstaged changes in the working directory can now easily be diff'ed against the
|
||||
# staged changes using 'git diff' to review all docs changes made since the previous
|
||||
# tagged version. Once the unstaged changes are ready, they can be added to the
|
||||
# staging area using 'git add' and then committed.
|
||||
#
|
||||
# To run gen-docs: "NEW_DOCS_VERSION=v1.1.0 make gen-docs"
|
||||
#
|
||||
# **NOTE**: there are additional manual steps required to finalize the process of generating
|
||||
# a new versioned docs site. The full process is documented in site/README-JEKYLL.md.
|
||||
gen-docs:
|
||||
@hack/gen-docs.sh
|
||||
|
||||
218
README.md
218
README.md
@@ -1,184 +1,52 @@
|
||||
# Heptio Ark
|
||||
|
||||
**Maintainers:** [Heptio][0]
|
||||
![100]
|
||||
|
||||
[![Build Status][1]][2]
|
||||
|
||||
## Overview
|
||||
|
||||
Ark gives you tools to back up and restore your Kubernetes cluster resources and persistent volumes. Ark lets you:
|
||||
Velero (formerly Heptio Ark) gives you tools to back up and restore your Kubernetes cluster resources and persistent volumes. Velero lets you:
|
||||
|
||||
* Take backups of your cluster and restore in case of loss.
|
||||
* Copy cluster resources across cloud providers. NOTE: Cloud volume migrations are not yet supported.
|
||||
* Replicate your production environment for development and testing environments.
|
||||
* Migrate cluster resources to other clusters.
|
||||
* Replicate your production cluster to development and testing clusters.
|
||||
|
||||
Ark consists of:
|
||||
Velero consists of:
|
||||
|
||||
* A server that runs on your cluster
|
||||
* A command-line client that runs locally
|
||||
|
||||
You can run Velero in clusters on a cloud provider or on-premises. For detailed information, see [Compatible Storage Providers][99].
|
||||
|
||||
## Installation
|
||||
|
||||
We strongly recommend that you use an [official release][6] of Velero. The tarballs for each release contain the
|
||||
`velero` command-line client. Follow the [installation instructions][28] to get started.
|
||||
|
||||
_The code and sample YAML files in the master branch of the Velero repository are under active development and are not guaranteed to be stable. Use them at your own risk!_
|
||||
|
||||
## More information
|
||||
|
||||
[The documentation][29] provides detailed information about building from source, architecture, extending Ark, and more.
|
||||
[The documentation][29] provides a getting started guide, plus information about building from source, architecture, extending Velero, and more.
|
||||
|
||||
## Getting started
|
||||
|
||||
The following example sets up the Ark server and client, then backs up and restores a sample application.
|
||||
|
||||
For simplicity, the example uses Minio, an S3-compatible storage service that runs locally on your cluster. See [Set up Ark with your cloud provider][3] for how to run on a cloud provider.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* Access to a Kubernetes cluster, version 1.7 or later. Version 1.7.5 or later is required to run `ark backup delete`.
|
||||
* A DNS server on the cluster
|
||||
* `kubectl` installed
|
||||
|
||||
### Download
|
||||
|
||||
Clone or fork the Ark repository:
|
||||
|
||||
```
|
||||
git clone git@github.com:heptio/ark.git
|
||||
```
|
||||
|
||||
NOTE: Make sure to check out the appropriate version. We recommend that you check out the latest tagged version. The master branch is under active development and might not be stable.
|
||||
|
||||
### Set up server
|
||||
|
||||
1. Start the server and the local storage service. In the root directory of Ark, run:
|
||||
|
||||
```bash
|
||||
kubectl apply -f examples/common/00-prereqs.yaml
|
||||
kubectl apply -f examples/minio/
|
||||
```
|
||||
|
||||
NOTE: If you get an error about Config creation, wait for a minute, then run the commands again.
|
||||
|
||||
1. Deploy the example nginx application:
|
||||
|
||||
```bash
|
||||
kubectl apply -f examples/nginx-app/base.yaml
|
||||
```
|
||||
|
||||
1. Check to see that both the Ark and nginx deployments are successfully created:
|
||||
|
||||
```
|
||||
kubectl get deployments -l component=ark --namespace=heptio-ark
|
||||
kubectl get deployments --namespace=nginx-example
|
||||
```
|
||||
|
||||
### Install client
|
||||
|
||||
For this example, we recommend that you [download a pre-built release][26].
|
||||
|
||||
You can also [build from source][7].
|
||||
|
||||
Make sure that you install somewhere in your `$PATH`.
|
||||
|
||||
### Back up
|
||||
|
||||
1. Create a backup for any object that matches the `app=nginx` label selector:
|
||||
|
||||
```
|
||||
ark backup create nginx-backup --selector app=nginx
|
||||
```
|
||||
|
||||
1. Simulate a disaster:
|
||||
|
||||
```
|
||||
kubectl delete namespace nginx-example
|
||||
```
|
||||
|
||||
1. To check that the nginx deployment and service are gone, run:
|
||||
|
||||
```
|
||||
kubectl get deployments --namespace=nginx-example
|
||||
kubectl get services --namespace=nginx-example
|
||||
kubectl get namespace/nginx-example
|
||||
```
|
||||
|
||||
You should get no results.
|
||||
|
||||
NOTE: You might need to wait for a few minutes for the namespace to be fully cleaned up.
|
||||
|
||||
### Restore
|
||||
|
||||
1. Run:
|
||||
|
||||
```
|
||||
ark restore create --from-backup nginx-backup
|
||||
```
|
||||
|
||||
1. Run:
|
||||
|
||||
```
|
||||
ark restore get
|
||||
```
|
||||
|
||||
After the restore finishes, the output looks like the following:
|
||||
|
||||
```
|
||||
NAME BACKUP STATUS WARNINGS ERRORS CREATED SELECTOR
|
||||
nginx-backup-20170727200524 nginx-backup Completed 0 0 2017-07-27 20:05:24 +0000 UTC <none>
|
||||
```
|
||||
|
||||
NOTE: The restore can take a few moments to finish. During this time, the `STATUS` column reads `InProgress`.
|
||||
|
||||
After a successful restore, the `STATUS` column is `Completed`, and `WARNINGS` and `ERRORS` are 0. All objects in the `nginx-example` namespacee should be just as they were before you deleted them.
|
||||
|
||||
If there are errors or warnings, you can look at them in detail:
|
||||
|
||||
```
|
||||
ark restore describe <RESTORE_NAME>
|
||||
```
|
||||
|
||||
For more information, see [the debugging information][18].
|
||||
|
||||
### Clean up
|
||||
|
||||
If you want to delete any backups you created, including data in object storage and persistent
|
||||
volume snapshots, you can run:
|
||||
|
||||
```
|
||||
ark backup delete BACKUP_NAME
|
||||
```
|
||||
|
||||
This asks the Ark server to delete all backup data associated with `BACKUP_NAME`. You need to do
|
||||
this for each backup you want to permanently delete. A future version of Ark will allow you to
|
||||
delete multiple backups by name or label selector.
|
||||
|
||||
Once fully removed, the backup is no longer visible when you run:
|
||||
|
||||
```
|
||||
ark backup get BACKUP_NAME
|
||||
```
|
||||
|
||||
If you want to uninstall Ark but preserve the backup data in object storage and persistent volume
|
||||
snapshots, it is safe to remove the `heptio-ark` namespace and everything else created for this
|
||||
example:
|
||||
|
||||
```
|
||||
kubectl delete -f examples/common/
|
||||
kubectl delete -f examples/minio/
|
||||
kubectl delete -f examples/nginx-app/base.yaml
|
||||
```
|
||||
Please use the version selector at the top of the site to ensure you are using the appropriate documentation for your version of Velero.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If you encounter issues, review the [troubleshooting docs][30], [file an issue][4], or talk to us on the [Kubernetes Slack team][25] channel `#ark-dr`.
|
||||
If you encounter issues, review the [troubleshooting docs][30], [file an issue][4], or talk to us on the [#velero channel][25] on the Kubernetes Slack server.
|
||||
|
||||
## Contributing
|
||||
|
||||
Thanks for taking the time to join our community and start contributing!
|
||||
|
||||
Feedback and discussion is available on [the mailing list][24].
|
||||
Feedback and discussion are available on [the mailing list][24].
|
||||
|
||||
#### Before you start
|
||||
### Before you start
|
||||
|
||||
* Please familiarize yourself with the [Code of Conduct][8] before contributing.
|
||||
* See [CONTRIBUTING.md][5] for instructions on the developer certificate of origin that we require.
|
||||
* Read how [we're using ZenHub][26] for project and roadmap planning
|
||||
|
||||
#### Pull requests
|
||||
### Pull requests
|
||||
|
||||
* We welcome pull requests. Feel free to dig through the [issues][4] and jump in.
|
||||
|
||||
@@ -186,33 +54,27 @@ Feedback and discussion is available on [the mailing list][24].
|
||||
|
||||
See [the list of releases][6] to find out about feature changes.
|
||||
|
||||
[0]: https://github.com/heptio
|
||||
[1]: https://travis-ci.org/heptio/ark.svg?branch=master
|
||||
[2]: https://travis-ci.org/heptio/ark
|
||||
[3]: /docs/cloud-common.md
|
||||
[4]: https://github.com/heptio/ark/issues
|
||||
[5]: https://github.com/heptio/ark/blob/master/CONTRIBUTING.md
|
||||
[6]: https://github.com/heptio/ark/releases
|
||||
[7]: /docs/build-from-scratch.md
|
||||
[8]: https://github.com/heptio/ark/blob/master/CODE_OF_CONDUCT.md
|
||||
[1]: https://travis-ci.org/heptio/velero.svg?branch=master
|
||||
[2]: https://travis-ci.org/heptio/velero
|
||||
|
||||
[4]: https://github.com/heptio/velero/issues
|
||||
[5]: https://github.com/heptio/velero/blob/master/CONTRIBUTING.md
|
||||
[6]: https://github.com/heptio/velero/releases
|
||||
|
||||
[8]: https://github.com/heptio/velero/blob/master/CODE_OF_CONDUCT.md
|
||||
[9]: https://kubernetes.io/docs/setup/
|
||||
[10]: https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-with-homebrew-on-macos
|
||||
[11]: https://kubernetes.io/docs/tasks/tools/install-kubectl/#tabset-1
|
||||
[12]: https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/README.md
|
||||
[13]: /docs/output-file-format.md
|
||||
[14]: https://github.com/kubernetes/kubernetes
|
||||
[15]: https://aws.amazon.com/
|
||||
[16]: https://cloud.google.com/
|
||||
[17]: https://azure.microsoft.com/
|
||||
[18]: /docs/debugging-restores.md
|
||||
[19]: /docs/img/backup-process.png
|
||||
[20]: https://kubernetes.io/docs/concepts/api-extension/custom-resources/#customresourcedefinitions
|
||||
[21]: https://kubernetes.io/docs/concepts/api-extension/custom-resources/#custom-controllers
|
||||
[22]: https://github.com/coreos/etcd
|
||||
[24]: http://j.hept.io/ark-list
|
||||
[25]: http://slack.kubernetes.io/
|
||||
[26]: https://github.com/heptio/ark/releases
|
||||
[27]: /docs/hooks.md
|
||||
[28]: /docs/plugins.md
|
||||
[29]: https://heptio.github.io/ark/
|
||||
[30]: /docs/troubleshooting.md
|
||||
|
||||
[24]: https://groups.google.com/forum/#!forum/projectvelero
|
||||
[25]: https://kubernetes.slack.com/messages/velero
|
||||
[26]: https://velero.io/docs/zenhub
|
||||
|
||||
[28]: https://velero.io/docs/install-overview
|
||||
[29]: https://velero.io/docs/
|
||||
[30]: https://velero.io/docs/troubleshooting
|
||||
|
||||
[99]: https://velero.io/docs/support-matrix
|
||||
[100]: /site/docs/master/img/velero.png
|
||||
|
||||
40
ROADMAP.md
40
ROADMAP.md
@@ -1,40 +0,0 @@
|
||||
# Heptio Ark Roadmap
|
||||
|
||||
## Upcoming Versions
|
||||
|
||||
The following versions, dates, and features are approximate and are subject to change.
|
||||
|
||||
### v0.9.0 - ~ 2018-06-14
|
||||
- Backup targets
|
||||
- Snapshot & restore non-cloud volumes - [#19](https://github.com/heptio/ark/issues/19)
|
||||
- Backup & restore across multiple regions and zones - [#103](https://github.com/heptio/ark/issues/103)
|
||||
- Ability to clone PVs - [#192](https://github.com/heptio/ark/issues/192)
|
||||
- Ark install command - [#52](https://github.com/heptio/ark/issues/52)
|
||||
- Backup & restore progress reporting - [#20](https://github.com/heptio/ark/issues/20) [#21](https://github.com/heptio/ark/issues/21)
|
||||
|
||||
|
||||
## Released Versions
|
||||
|
||||
### v0.8.0 - 2018-04-19
|
||||
|
||||
[See release notes](https://github.com/heptio/ark/blob/master/CHANGELOG.md#v080---2018-04-19).
|
||||
|
||||
### v0.7.0 - 2018-02-15
|
||||
|
||||
[See release notes](https://github.com/heptio/ark/blob/master/CHANGELOG.md#v070---2018-02-15).
|
||||
|
||||
### v0.6.0 - 2017-11-30
|
||||
|
||||
[See release notes](https://github.com/heptio/ark/blob/master/CHANGELOG.md#v060---2017-11-30).
|
||||
|
||||
### v0.5.0 - 2017-10-26
|
||||
|
||||
[See release notes](https://github.com/heptio/ark/blob/master/CHANGELOG.md#v050---2017-10-26).
|
||||
|
||||
### v0.4.0 - 2017-09-14
|
||||
|
||||
[See release notes](https://github.com/heptio/ark/blob/master/CHANGELOG.md#v040---2017-09-14).
|
||||
|
||||
### v0.3.0 - 2017-08-03
|
||||
|
||||
[See release notes](https://github.com/heptio/ark/blob/master/CHANGELOG.md#v030---2017-08-03).
|
||||
@@ -1,5 +1,5 @@
|
||||
# Ark Support
|
||||
# Velero Support
|
||||
|
||||
Thanks for trying out Ark! We welcome all feedback, please consider joining our mailing list:
|
||||
Thanks for trying out Velero! We welcome all feedback, please consider joining our mailing list:
|
||||
|
||||
- [Mailing List](http://j.hept.io/ark-list)
|
||||
- [Mailing List](https://groups.google.com/forum/#!forum/projectvelero)
|
||||
|
||||
261
changelogs/CHANGELOG-0.10.md
Normal file
261
changelogs/CHANGELOG-0.10.md
Normal file
@@ -0,0 +1,261 @@
|
||||
- [v0.10.2](#v0102)
|
||||
- [v0.10.1](#v0101)
|
||||
- [v0.10.0](#v0100)
|
||||
|
||||
## v0.10.2
|
||||
#### 2019-02-28
|
||||
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.10.2
|
||||
|
||||
### Changes
|
||||
* upgrade restic to v0.9.4 & replace --hostname flag with --host (#1156, @skriss)
|
||||
* use 'restic stats' instead of 'restic check' to determine if repo exists (#1171, @skriss)
|
||||
* Fix concurrency bug in code ensuring restic repository exists (#1235, @skriss)
|
||||
|
||||
## v0.10.1
|
||||
#### 2019-01-10
|
||||
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.10.1
|
||||
|
||||
### Changes
|
||||
* Fix minio setup job command (#1118, @acbramley)
|
||||
* Add debugging-install link in doc get-started.md (#1131, @hex108)
|
||||
* `ark version`: show full git SHA & combine git tree state indicator with git SHA line (#1124, @skriss)
|
||||
* Delete spec.priority in pod restore action (#879, @mwieczorek)
|
||||
* Allow to use AWS Signature v1 for creating signed AWS urls (#811, @bashofmann)
|
||||
* add multizone/regional support to gcp (#765, @wwitzel3)
|
||||
* Fixed the newline output when deleting a schedule. (#1120, @jwhitcraft)
|
||||
* Remove obsolete make targets and rename 'make goreleaser' to 'make release' (#1114, @skriss)
|
||||
* Update to go 1.11 (#1069, @gliptak)
|
||||
* Update CHANGELOGs (#1063, @wwitzel3)
|
||||
* Initialize empty schedule metrics on server init (#1054, @cbeneke)
|
||||
* Added brew reference (#1051, @omerlh)
|
||||
* Remove default token from all service accounts (#1048, @ncdc)
|
||||
* Add pprof support to the Ark server (#234, @ncdc)
|
||||
|
||||
## v0.10.0
|
||||
#### 2018-11-15
|
||||
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.10.0
|
||||
|
||||
### Highlights
|
||||
- We've introduced two new custom resource definitions, `BackupStorageLocation` and `VolumeSnapshotLocation`, that replace the `Config` CRD from
|
||||
previous versions. As part of this, you may now configure more than one possible location for where backups and snapshots are stored, and when you
|
||||
create a `Backup` you can select the location where you'd like that particular backup to be stored. See the [Locations documentation][2] for an overview
|
||||
of this feature.
|
||||
- Ark's plugin system has been significantly refactored to improve robustness and ease of development. Plugin processes are now automatically restarted
|
||||
if they unexpectedly terminate. Additionally, plugin binaries can now contain more than one plugin implementation (e.g. and object store *and* a block store,
|
||||
or many backup item actions).
|
||||
- The sync process, which ensures that Backup custom resources exist for each backup in object storage, has been revamped to run much more frequently (once
|
||||
per minute rather than once per hour), to use significantly fewer cloud provider API calls, and to not generate spurious Kubernetes API errors.
|
||||
- Ark can now be configured to store all data under a prefix within an object storage bucket. This means that you no longer need a separate bucket per Ark
|
||||
instance; you can now have all of your clusters' Ark backups go into a single bucket, with each cluster having its own prefix/subdirectory
|
||||
within that bucket.
|
||||
- Restic backup data is now automatically stored within the same bucket/prefix as the rest of the Ark data. A separate bucket is no longer required (or allowed).
|
||||
- Ark resources (backups, restores, schedules) can now be bulk-deleted through the `ark` CLI, using the `--all` or `--selector` flags, or by specifying
|
||||
multiple resource names as arguments to the `delete` commands.
|
||||
- The `ark` CLI now supports waiting for backups and restores to complete with the `--wait` flag for `ark backup create` and `ark restore create`
|
||||
- Restores can be created directly from the most recent backup for a schedule, using `ark restore create --from-schedule SCHEDULE_NAME`
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
Heptio Ark v0.10 contains a number of breaking changes. Upgrading will require some additional steps beyond just updating your client binary and your
|
||||
container image tag. We've provided a [detailed set of instructions][1] to help you with the upgrade process. **Please read and follow these instructions
|
||||
carefully to ensure a successful upgrade!**
|
||||
|
||||
- The `Config` CRD has been replaced by `BackupStorageLocation` and `VolumeSnapshotLocation` CRDs.
|
||||
- The interface for external plugins (object/block stores, backup/restore item actions) has changed. If you have authored any custom plugins, they'll
|
||||
need to be updated for v0.10.
|
||||
- The [`ObjectStore.ListCommonPrefixes`](https://github.com/heptio/ark/blob/master/pkg/cloudprovider/object_store.go#L50) signature has changed to add a `prefix` parameter.
|
||||
- Registering plugins has changed. Create a new plugin server with the `NewServer` function, and register plugins with the appropriate functions. See the [`Server`](https://github.com/heptio/ark/blob/master/pkg/plugin/server.go#L37) interface for details.
|
||||
- The organization of Ark data in object storage has changed. Existing data will need to be moved around to conform to the new layout.
|
||||
|
||||
### All Changes
|
||||
- [b9de44ff](https://github.com/heptio/ark/commit/b9de44ff) update docs to reference config/ dir within release tarballs
|
||||
- [eace0255](https://github.com/heptio/ark/commit/eace0255) goreleaser: update example image tags to match version being released
|
||||
- [cff02159](https://github.com/heptio/ark/commit/cff02159) add rbac content, rework get-started for NodePort and publicUrl, add versioning information
|
||||
- [fa14255e](https://github.com/heptio/ark/commit/fa14255e) add content for docs issue 819
|
||||
- [22959071](https://github.com/heptio/ark/commit/22959071) add doc explaining locations
|
||||
- [e5556fe6](https://github.com/heptio/ark/commit/e5556fe6) Added qps and burst to server's client
|
||||
- [9ae861c9](https://github.com/heptio/ark/commit/9ae861c9) Support a separate URL base for pre-signed URLs
|
||||
- [698420b6](https://github.com/heptio/ark/commit/698420b6) Update storage-layout-reorg-v0.10.md
|
||||
- [6c9e1f18](https://github.com/heptio/ark/commit/6c9e1f18) lower some noisy logs to debug level
|
||||
- [318fd8a8](https://github.com/heptio/ark/commit/318fd8a8) add troubleshooting for loadbalancer restores
|
||||
- [defb8aa8](https://github.com/heptio/ark/commit/defb8aa8) remove code that checks directly for a backup from restore controller
|
||||
- [7abe1156](https://github.com/heptio/ark/commit/7abe1156) Move clearing up of metadata before plugin's actions
|
||||
- [ec013e6f](https://github.com/heptio/ark/commit/ec013e6f) Document upgrading plugins in the deployment
|
||||
- [d6162e94](https://github.com/heptio/ark/commit/d6162e94) fix goreleaser bugs
|
||||
- [a15df276](https://github.com/heptio/ark/commit/a15df276) Add correct link and change role
|
||||
- [46bed015](https://github.com/heptio/ark/commit/46bed015) add 0.10 breaking changes warning to readme in master
|
||||
- [e3a7d6a2](https://github.com/heptio/ark/commit/e3a7d6a2) add content for issue 994
|
||||
- [400911e9](https://github.com/heptio/ark/commit/400911e9) address docs issue #978
|
||||
- [b818cc27](https://github.com/heptio/ark/commit/b818cc27) don't require a default provider VSL if there's only 1
|
||||
- [90638086](https://github.com/heptio/ark/commit/90638086) v0.10 changelog
|
||||
- [6e2166c4](https://github.com/heptio/ark/commit/6e2166c4) add docs page on versions and upgrading
|
||||
- [18b434cb](https://github.com/heptio/ark/commit/18b434cb) goreleaser scripts for building/creating a release on a workstation
|
||||
- [bb65d67a](https://github.com/heptio/ark/commit/bb65d67a) update restic prerequisite with min k8s version
|
||||
- [b5a2ccd5](https://github.com/heptio/ark/commit/b5a2ccd5) Silence git detached HEAD advice in build container
|
||||
- [67749141](https://github.com/heptio/ark/commit/67749141) instructions for upgrading to v0.10
|
||||
- [516422c2](https://github.com/heptio/ark/commit/516422c2) sync controller: fill in missing .spec.storageLocation
|
||||
- [195e6aaf](https://github.com/heptio/ark/commit/195e6aaf) fix bug preventing PV snapshots from v0.10 backups from restoring
|
||||
- [bca58516](https://github.com/heptio/ark/commit/bca58516) Run 'make update' to update formatting
|
||||
- [573ce7d0](https://github.com/heptio/ark/commit/573ce7d0) Update formatting script
|
||||
- [90d9be59](https://github.com/heptio/ark/commit/90d9be59) support restoring/deleting legacy backups with .status.volumeBackups
|
||||
- [ef194972](https://github.com/heptio/ark/commit/ef194972) rename variables #967
|
||||
- [6d4e702c](https://github.com/heptio/ark/commit/6d4e702c) fix broken link
|
||||
- [596eea1b](https://github.com/heptio/ark/commit/596eea1b) restore storageclasses before pvs and pvcs
|
||||
- [f014cab1](https://github.com/heptio/ark/commit/f014cab1) backup describer: show snapshot summary by default, details optionally
|
||||
- [8acc66d0](https://github.com/heptio/ark/commit/8acc66d0) remove pvProviderExists param from NewRestoreController
|
||||
- [57ce590f](https://github.com/heptio/ark/commit/57ce590f) create a struct for multiple return of same type in restore_contoroller #967
|
||||
- [028fafb6](https://github.com/heptio/ark/commit/028fafb6) Corrected grammatical error
|
||||
- [db856aff](https://github.com/heptio/ark/commit/db856aff) Specify return arguments
|
||||
- [9952dfb0](https://github.com/heptio/ark/commit/9952dfb0) Address #424: Add CRDs to list of prioritized resources
|
||||
- [cf2c2714](https://github.com/heptio/ark/commit/cf2c2714) fix bugs in GetBackupVolumeSnapshots and add test
|
||||
- [ec124673](https://github.com/heptio/ark/commit/ec124673) remove all references to Config from docs/examples
|
||||
- [c36131a0](https://github.com/heptio/ark/commit/c36131a0) remove Config-related code
|
||||
- [406b50a7](https://github.com/heptio/ark/commit/406b50a7) update restore process using snapshot locations
|
||||
- [268080ad](https://github.com/heptio/ark/commit/268080ad) avoid panics if can't get block store during deletion
|
||||
- [4a03370f](https://github.com/heptio/ark/commit/4a03370f) update backup deletion controller for snapshot locations
|
||||
- [38c72b8c](https://github.com/heptio/ark/commit/38c72b8c) include snapshot locations in created schedule's backup spec
|
||||
- [0ec2de55](https://github.com/heptio/ark/commit/0ec2de55) azure: update blockstore to allow storing snaps in different resource group
|
||||
- [35bb533c](https://github.com/heptio/ark/commit/35bb533c) close gzip writer before uploading volumesnapshots file
|
||||
- [da9ed38c](https://github.com/heptio/ark/commit/da9ed38c) store volume snapshot info as JSON in backup storage
|
||||
- [e24248e0](https://github.com/heptio/ark/commit/e24248e0) add --volume-snapshot-locations flag to ark backup create
|
||||
- [df07b7dc](https://github.com/heptio/ark/commit/df07b7dc) update backup code to work with volume snapshot locations
|
||||
- [4af89fa8](https://github.com/heptio/ark/commit/4af89fa8) add unit test for getDefaultVolumeSnapshotLocations
|
||||
- [02f50b9c](https://github.com/heptio/ark/commit/02f50b9c) add default-volume-snapshot-locations to server cmd
|
||||
- [1aa712d2](https://github.com/heptio/ark/commit/1aa712d2) Default and validate VolumeSnapshotLocations
|
||||
- [bbf76985](https://github.com/heptio/ark/commit/bbf76985) add create CLI command for snapshot locations
|
||||
- [aeb221ea](https://github.com/heptio/ark/commit/aeb221ea) Add printer for snapshot locations
|
||||
- [ffc612ac](https://github.com/heptio/ark/commit/ffc612ac) Add volume snapshot CLI get command
|
||||
- [f20342aa](https://github.com/heptio/ark/commit/f20342aa) Add VolumeLocation and Snapshot.
|
||||
- [7172db8a](https://github.com/heptio/ark/commit/7172db8a) upgrade to restic v0.9.3
|
||||
- [99adc4fa](https://github.com/heptio/ark/commit/99adc4fa) Remove broken references to docs that are not existing
|
||||
- [474efde6](https://github.com/heptio/ark/commit/474efde6) Fixed relative link for image
|
||||
- [41735154](https://github.com/heptio/ark/commit/41735154) don't require a default backup storage location to exist
|
||||
- [0612c5de](https://github.com/heptio/ark/commit/0612c5de) templatize error message in DeleteOptions
|
||||
- [66bcbc05](https://github.com/heptio/ark/commit/66bcbc05) add support for bulk deletion to ark schedule delete
|
||||
- [3af43b49](https://github.com/heptio/ark/commit/3af43b49) add azure-specific code to support multi-location restic
|
||||
- [d009163b](https://github.com/heptio/ark/commit/d009163b) update restic to support multiple backup storage locations
|
||||
- [f4c99c77](https://github.com/heptio/ark/commit/f4c99c77) Change link for the support matrix
|
||||
- [91e45d56](https://github.com/heptio/ark/commit/91e45d56) Fix broken storage providers link
|
||||
- [ed0eb865](https://github.com/heptio/ark/commit/ed0eb865) fix backup storage location example YAMLs
|
||||
- [eb709b8f](https://github.com/heptio/ark/commit/eb709b8f) only sync a backup location if it's changed since last sync
|
||||
- [af3af1b5](https://github.com/heptio/ark/commit/af3af1b5) clarify Azure resource group usage in docs
|
||||
- [9fdf8513](https://github.com/heptio/ark/commit/9fdf8513) Minor code cleanup
|
||||
- [2073e15a](https://github.com/heptio/ark/commit/2073e15a) Fix formatting for live site
|
||||
- [0fc3e8d8](https://github.com/heptio/ark/commit/0fc3e8d8) add documentation on running Ark on-premises
|
||||
- [e46e89cb](https://github.com/heptio/ark/commit/e46e89cb) have restic share main Ark bucket
|
||||
- [42b54586](https://github.com/heptio/ark/commit/42b54586) refactor to make valid dirs part of an object store layout
|
||||
- [8bc7e4f6](https://github.com/heptio/ark/commit/8bc7e4f6) store backups & restores in backups/, restores/ subdirs in obj storage
|
||||
- [e3232b7e](https://github.com/heptio/ark/commit/e3232b7e) add support for bulk deletion to ark restore delete
|
||||
- [17be71e1](https://github.com/heptio/ark/commit/17be71e1) remove deps used for docs gen
|
||||
- [20635106](https://github.com/heptio/ark/commit/20635106) remove script for generating docs
|
||||
- [6fd9ea9d](https://github.com/heptio/ark/commit/6fd9ea9d) remove cli reference docs and related scripts
|
||||
- [4833607a](https://github.com/heptio/ark/commit/4833607a) Fix infinite sleep in fsfreeze container
|
||||
- [7668bfd4](https://github.com/heptio/ark/commit/7668bfd4) Add links for Portworx plugin support
|
||||
- [468006e6](https://github.com/heptio/ark/commit/468006e6) Fix Portworx name in doc
|
||||
- [e6b44539](https://github.com/heptio/ark/commit/e6b44539) Make fsfreeze image building consistent
|
||||
- [fcd27a13](https://github.com/heptio/ark/commit/fcd27a13) get a new metadata accessor after calling backup item actions
|
||||
- [ffef86e3](https://github.com/heptio/ark/commit/ffef86e3) Adding support for the AWS_CLUSTER_NAME env variable allowing to claim volumes ownership
|
||||
- [cda3dff8](https://github.com/heptio/ark/commit/cda3dff8) Document single binary plugins
|
||||
- [f049e078](https://github.com/heptio/ark/commit/f049e078) Remove ROADMAP.md, update ZenHub link to Ark board
|
||||
- [94617b30](https://github.com/heptio/ark/commit/94617b30) convert all controllers to use genericController, logContext -> log
|
||||
- [779cb428](https://github.com/heptio/ark/commit/779cb428) Document SignatureDoesNotMatch error and triaging
|
||||
- [7d8813a9](https://github.com/heptio/ark/commit/7d8813a9) move ObjectStore mock into pkg/cloudprovider/mocks
|
||||
- [f0edf733](https://github.com/heptio/ark/commit/f0edf733) add a BackupStore to pkg/persistence that supports prefixes
|
||||
- [af64069d](https://github.com/heptio/ark/commit/af64069d) create pkg/persistence and move relevant code from pkg/cloudprovider into it
|
||||
- [29d75d72](https://github.com/heptio/ark/commit/29d75d72) move object and block store interfaces to their own files
|
||||
- [211aa7b7](https://github.com/heptio/ark/commit/211aa7b7) Set schedule labels to subsequent backups
|
||||
- [d34994cb](https://github.com/heptio/ark/commit/d34994cb) set azure restic env vars based on default backup location's config
|
||||
- [a50367f1](https://github.com/heptio/ark/commit/a50367f1) Regenerate CLI docs
|
||||
- [7bc27bbb](https://github.com/heptio/ark/commit/7bc27bbb) Pin cobra version
|
||||
- [e94277ac](https://github.com/heptio/ark/commit/e94277ac) Update pflag version
|
||||
- [df69b274](https://github.com/heptio/ark/commit/df69b274) azure: update documentation and examples
|
||||
- [cb321db2](https://github.com/heptio/ark/commit/cb321db2) azure: refactor to not use helpers/ pkg, validate all env/config inputs
|
||||
- [9d7ea748](https://github.com/heptio/ark/commit/9d7ea748) azure: support different RGs/storage accounts per backup location
|
||||
- [cd4e9f53](https://github.com/heptio/ark/commit/cd4e9f53) azure: fix for breaking change in blob.GetSASURI
|
||||
- [a440029c](https://github.com/heptio/ark/commit/a440029c) bump Azure SDK version and include storage mgmt package
|
||||
- [b31e25bf](https://github.com/heptio/ark/commit/b31e25bf) server: remove unused code, replace deprecated func
|
||||
- [729d7339](https://github.com/heptio/ark/commit/729d7339) controllers: take a newPluginManager func in constructors
|
||||
- [6445dbf1](https://github.com/heptio/ark/commit/6445dbf1) Update examples and docs for backup locations
|
||||
- [133dc185](https://github.com/heptio/ark/commit/133dc185) backup sync: process the default location first
|
||||
- [7a1e6d16](https://github.com/heptio/ark/commit/7a1e6d16) generic controller: allow controllers with only a resync func
|
||||
- [6f7bfe54](https://github.com/heptio/ark/commit/6f7bfe54) remove Config CRD's BackupStorageProvider & other obsolete code
|
||||
- [bd4d97b9](https://github.com/heptio/ark/commit/bd4d97b9) move server's defaultBackupLocation into config struct
|
||||
- [0e94fa37](https://github.com/heptio/ark/commit/0e94fa37) update sync controller for backup locations
|
||||
- [2750aa71](https://github.com/heptio/ark/commit/2750aa71) Use backup storage location during restore
|
||||
- [20f89fbc](https://github.com/heptio/ark/commit/20f89fbc) use the default backup storage location for restic
|
||||
- [833a6307](https://github.com/heptio/ark/commit/833a6307) Add storage location to backup get/describe
|
||||
- [cf7c8587](https://github.com/heptio/ark/commit/cf7c8587) download request: fix setting of log level for plugin manager
|
||||
- [3234124a](https://github.com/heptio/ark/commit/3234124a) backup deletion: fix setting of log level in plugin manager
|
||||
- [74043ab4](https://github.com/heptio/ark/commit/74043ab4) download request controller: fix bug in determining expiration
|
||||
- [7007f198](https://github.com/heptio/ark/commit/7007f198) refactor download request controller test and add test cases
|
||||
- [8f534615](https://github.com/heptio/ark/commit/8f534615) download request controller: use backup location for object store
|
||||
- [bab08ed1](https://github.com/heptio/ark/commit/bab08ed1) backup deletion controller: use backup location for object store
|
||||
- [c6f488f7](https://github.com/heptio/ark/commit/c6f488f7) Use backup location in the backup controller
|
||||
- [06b5af44](https://github.com/heptio/ark/commit/06b5af44) add create and get CLI commands for backup locations
|
||||
- [adbcd370](https://github.com/heptio/ark/commit/adbcd370) add --default-backup-storage-location flag to server cmd
|
||||
- [2a34772e](https://github.com/heptio/ark/commit/2a34772e) Add --storage-location argument to create commands
|
||||
- [56f16170](https://github.com/heptio/ark/commit/56f16170) Correct metadata for BackupStorageLocationList
|
||||
- [345c3c39](https://github.com/heptio/ark/commit/345c3c39) Generate clients for BackupStorageLocation
|
||||
- [a25eb032](https://github.com/heptio/ark/commit/a25eb032) Add BackupStorageLocation API type
|
||||
- [575c4ddc](https://github.com/heptio/ark/commit/575c4ddc) apply annotations on single line, no restore mode
|
||||
- [030ea6c0](https://github.com/heptio/ark/commit/030ea6c0) minor word updates and command wrapping
|
||||
- [d32f8dbb](https://github.com/heptio/ark/commit/d32f8dbb) Update hooks/fsfreeze example
|
||||
- [342a1c64](https://github.com/heptio/ark/commit/342a1c64) add an ark bug command
|
||||
- [9c11ba90](https://github.com/heptio/ark/commit/9c11ba90) Add DigitalOcean to S3-compatible backup providers
|
||||
- [ea50ebf2](https://github.com/heptio/ark/commit/ea50ebf2) Fix map merging logic
|
||||
- [9508e4a2](https://github.com/heptio/ark/commit/9508e4a2) Switch Config CRD elements to server flags
|
||||
- [0c3ac67b](https://github.com/heptio/ark/commit/0c3ac67b) start using a namespaced label on restored objects, deprecate old label
|
||||
- [6e53aa03](https://github.com/heptio/ark/commit/6e53aa03) Bring back 'make local'
|
||||
- [5acccaa7](https://github.com/heptio/ark/commit/5acccaa7) add bulk deletion support to ark backup delete
|
||||
- [3aa241a7](https://github.com/heptio/ark/commit/3aa241a7) Preserve node ports during restore when annotations hold specification.
|
||||
- [c5f5862c](https://github.com/heptio/ark/commit/c5f5862c) Add --wait support to ark backup create
|
||||
- [eb6f742b](https://github.com/heptio/ark/commit/eb6f742b) Document CRD not found errors
|
||||
- [fb4d507c](https://github.com/heptio/ark/commit/fb4d507c) Extend doc about synchronization
|
||||
- [e7bb5926](https://github.com/heptio/ark/commit/e7bb5926) Add --wait support to `ark restore create`
|
||||
- [8ce513ac](https://github.com/heptio/ark/commit/8ce513ac) Only delete unused backup if they are complete
|
||||
- [1c26fbde](https://github.com/heptio/ark/commit/1c26fbde) remove SnapshotService, replace with direct BlockStore usage
|
||||
- [13051218](https://github.com/heptio/ark/commit/13051218) Refactor plugin management
|
||||
- [74dbf387](https://github.com/heptio/ark/commit/74dbf387) Add restore failed phase and metrics
|
||||
- [8789ae5c](https://github.com/heptio/ark/commit/8789ae5c) update testify to latest released version
|
||||
- [fe9d61a9](https://github.com/heptio/ark/commit/fe9d61a9) Add schedule command info to quickstart
|
||||
- [ca5656c2](https://github.com/heptio/ark/commit/ca5656c2) fix bug preventing backup item action item updates from saving
|
||||
- [d2e629f5](https://github.com/heptio/ark/commit/d2e629f5) Delete backups from etcd if they're not in storage
|
||||
- [625ba481](https://github.com/heptio/ark/commit/625ba481) Fix ZenHub link on Readme.md
|
||||
- [dcae6eb0](https://github.com/heptio/ark/commit/dcae6eb0) Update gcp-config.md
|
||||
- [06d6665a](https://github.com/heptio/ark/commit/06d6665a) check s3URL scheme upon AWS ObjectStore Init()
|
||||
- [cc359f6e](https://github.com/heptio/ark/commit/cc359f6e) Add contributor docs for our ZenHub usage
|
||||
- [f6204562](https://github.com/heptio/ark/commit/f6204562) cleanup service account action log statement
|
||||
- [450fa72f](https://github.com/heptio/ark/commit/450fa72f) Initialize schedule Prometheus metrics to have them created beforehand (see https://prometheus.io/docs/practices/instrumentation/#avoid-missing-metrics)
|
||||
- [39c4267a](https://github.com/heptio/ark/commit/39c4267a) Clarify that object storage should per-cluster
|
||||
- [78cbdf95](https://github.com/heptio/ark/commit/78cbdf95) delete old deletion requests for backup when processing a new one
|
||||
- [85a61b8e](https://github.com/heptio/ark/commit/85a61b8e) return nil error if 404 encountered when deleting snapshots
|
||||
- [a2a7dbda](https://github.com/heptio/ark/commit/a2a7dbda) fix tagging latest by using make's ifeq
|
||||
- [b4a52e45](https://github.com/heptio/ark/commit/b4a52e45) Add commands for context to the bug template
|
||||
- [3efe6770](https://github.com/heptio/ark/commit/3efe6770) Update Ark library code to work with Kubernetes 1.11
|
||||
- [7e8c8c69](https://github.com/heptio/ark/commit/7e8c8c69) Add some basic troubleshooting commands
|
||||
- [d1955120](https://github.com/heptio/ark/commit/d1955120) require namespace for backups/etc. to exist at server startup
|
||||
- [683f7afc](https://github.com/heptio/ark/commit/683f7afc) switch to using .status.startTimestamp for sorting backups
|
||||
- [b71a37db](https://github.com/heptio/ark/commit/b71a37db) Record backup completion time before uploading
|
||||
- [217084cd](https://github.com/heptio/ark/commit/217084cd) Add example ark version command to issue templates
|
||||
- [040788bb](https://github.com/heptio/ark/commit/040788bb) Add minor improvements and aws example<Plug>delimitMateCR
|
||||
- [5b89f7b6](https://github.com/heptio/ark/commit/5b89f7b6) Skip backup sync if it already exists in k8s
|
||||
- [c6050845](https://github.com/heptio/ark/commit/c6050845) restore controller: switch to 'c' for receiver name
|
||||
- [706ae07d](https://github.com/heptio/ark/commit/706ae07d) enable a schedule to be provided as the source for a restore
|
||||
- [aea68414](https://github.com/heptio/ark/commit/aea68414) fix up Slack link in troubleshooting on master branch
|
||||
- [bb8e2e91](https://github.com/heptio/ark/commit/bb8e2e91) Document how to run the Ark server locally
|
||||
- [dc84e591](https://github.com/heptio/ark/commit/dc84e591) Remove outdated namespace deletion content
|
||||
- [23abbc9a](https://github.com/heptio/ark/commit/23abbc9a) fix paths
|
||||
- [f0426538](https://github.com/heptio/ark/commit/f0426538) use posix-compliant conditional for checking TAG_LATEST
|
||||
- [cf336d80](https://github.com/heptio/ark/commit/cf336d80) Added new templates
|
||||
- [795dc262](https://github.com/heptio/ark/commit/795dc262) replace pkg/restore's osFileSystem with pkg/util/filesystem's
|
||||
- [eabef085](https://github.com/heptio/ark/commit/eabef085) Update generated Ark code based on the 1.11 k8s.io/code-generator script
|
||||
- [f5eac0b4](https://github.com/heptio/ark/commit/f5eac0b4) Update vendored library code for Kubernetes 1.11
|
||||
|
||||
[1]: https://heptio.github.io/velero/v0.10.0/upgrading-to-v0.10
|
||||
[2]: locations.md
|
||||
32
changelogs/CHANGELOG-0.11.md
Normal file
32
changelogs/CHANGELOG-0.11.md
Normal file
@@ -0,0 +1,32 @@
|
||||
## v0.11.1
|
||||
#### 2019-05-17
|
||||
|
||||
### Download
|
||||
- https://github.com/heptio/velero/releases/tag/v0.11.1
|
||||
|
||||
### Highlights
|
||||
* Added the `velero migrate-backups` command to migrate legacy Ark backup metadata to the current Velero format in object storage. This command needs to be run in preparation for upgrading to v1.0, **if** you have backups that were originally created prior to v0.11 (i.e. when the project was named Ark).
|
||||
|
||||
## v0.11.0
|
||||
#### 2019-02-28
|
||||
|
||||
### Download
|
||||
- https://github.com/heptio/velero/releases/tag/v0.11.0
|
||||
|
||||
### Highlights
|
||||
* Heptio Ark is now Velero! This release is the first one to use the new name. For details on the changes and how to migrate to v0.11, see the [migration instructions][1]. **Please follow the instructions to ensure a successful upgrade to v0.11.**
|
||||
* Restic has been upgraded to v0.9.4, which brings significantly faster restores thanks to a new multi-threaded restorer.
|
||||
* Velero now waits for terminating namespaces and persistent volumes to delete before attempting to restore them, rather than trying and failing to restore them while they're being deleted.
|
||||
|
||||
### All Changes
|
||||
* Fix concurrency bug in code ensuring restic repository exists (#1235, @skriss)
|
||||
* Wait for PVs and namespaces to delete before attempting to restore them. (#826, @nrb)
|
||||
* Set the zones for GCP regional disks on restore. This requires the `compute.zones.get` permission on the GCP serviceaccount in order to work correctly. (#1200, @nrb)
|
||||
* Renamed Heptio Ark to Velero. Changed internal imports, environment variables, and binary name. (#1184, @nrb)
|
||||
* use 'restic stats' instead of 'restic check' to determine if repo exists (#1171, @skriss)
|
||||
* upgrade restic to v0.9.4 & replace --hostname flag with --host (#1156, @skriss)
|
||||
* Clarify restore log when object unchanged (#1153, @daved)
|
||||
* Add backup-version file in backup tarball. (#1117, @wwitzel3)
|
||||
* add ServerStatusRequest CRD and show server version in `ark version` output (#1116, @skriss)
|
||||
|
||||
[1]: https://heptio.github.io/velero/v0.11.0/migrating-to-velero
|
||||
39
changelogs/CHANGELOG-0.3.md
Normal file
39
changelogs/CHANGELOG-0.3.md
Normal file
@@ -0,0 +1,39 @@
|
||||
- [v0.3.3](#v033)
|
||||
- [v0.3.2](#v032)
|
||||
- [v0.3.1](#v031)
|
||||
- [v0.3.0](#v030)
|
||||
|
||||
## v0.3.3
|
||||
#### 2017-08-10
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.3.3
|
||||
|
||||
### Bug Fixes
|
||||
* Treat the first field in a schedule's cron expression as minutes, not seconds
|
||||
|
||||
|
||||
## v0.3.2
|
||||
#### 2017-08-07
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.3.2
|
||||
|
||||
### New Features
|
||||
* Add client-go auth provider plugins for Azure, GCP, OIDC
|
||||
|
||||
|
||||
## v0.3.1
|
||||
#### 2017-08-03
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.3.1
|
||||
|
||||
### Bug Fixes
|
||||
* Fix Makefile VERSION
|
||||
|
||||
|
||||
## v0.3.0
|
||||
#### 2017-08-03
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.3.0
|
||||
|
||||
### All New Features
|
||||
* Initial Release
|
||||
29
changelogs/CHANGELOG-0.4.md
Normal file
29
changelogs/CHANGELOG-0.4.md
Normal file
@@ -0,0 +1,29 @@
|
||||
- [v0.4.0](#v040)
|
||||
|
||||
## v0.4.0
|
||||
#### 2017-09-14
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.4.0
|
||||
|
||||
### Breaking changes
|
||||
* Snapshotting and restoring volumes is now enabled by default
|
||||
* The --namespaces flag for 'ark restore create' has been replaced by --include-namespaces and
|
||||
--exclude-namespaces
|
||||
|
||||
### New features
|
||||
* Support for S3 SSE with KMS
|
||||
* Cloud provider configurations are validated at startup
|
||||
* The persistentVolumeProvider is now optional
|
||||
* Restore objects are garbage collected
|
||||
* Each backup now has an associated log file, viewable via 'ark backup logs'
|
||||
* Each restore now has an associated log file, viewable via 'ark restore logs'
|
||||
* Add --include-resources/--exclude-resources for restores
|
||||
|
||||
### Bug fixes
|
||||
* Only save/use iops for io1 volumes on AWS
|
||||
* When restoring, try to retrieve the Backup directly from object storage if it's not found
|
||||
* When syncing Backups from object storage to Kubernetes, don't return at the first error
|
||||
encountered
|
||||
* More closely match how kubectl performs kubeconfig resolution
|
||||
* Increase default Azure API request timeout to 2 minutes
|
||||
* Update Azure diskURI to match diskName
|
||||
41
changelogs/CHANGELOG-0.5.md
Normal file
41
changelogs/CHANGELOG-0.5.md
Normal file
@@ -0,0 +1,41 @@
|
||||
- [v0.5.1](#v051)
|
||||
- [v0.5.0](#v050)
|
||||
|
||||
## v0.5.1
|
||||
#### 2017-11-06
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.5.1
|
||||
|
||||
### Bug fixes
|
||||
* If a Service is headless, retain ClusterIP = None when backing up and restoring.
|
||||
* Use the specifed --label-selector when listing backups, schedules, and restores.
|
||||
* Restore namespace mapping functionality that was accidentally broken in 0.5.0.
|
||||
* Always include namespaces in the backup, regardless of the --include-cluster-resources setting.
|
||||
|
||||
|
||||
## v0.5.0
|
||||
#### 2017-10-26
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.5.0
|
||||
|
||||
### Breaking changes
|
||||
* The backup tar file format has changed. Backups created using previous versions of Ark cannot be restored using v0.5.0.
|
||||
* When backing up one or more specific namespaces, cluster-scoped resources are no longer backed up by default, with the exception of PVs that are used within the target namespace(s). Cluster-scoped resources can still be included by explicitly specifying `--include-cluster-resources`.
|
||||
|
||||
### New features
|
||||
* Add customized user-agent string for Ark CLI
|
||||
* Switch from glog to logrus
|
||||
* Exclude nodes from restoration
|
||||
* Add a FAQ
|
||||
* Record PV availability zone and use it when restoring volumes from snapshots
|
||||
* Back up the PV associated with a PVC
|
||||
* Add `--include-cluster-resources` flag to `ark backup create`
|
||||
* Add `--include-cluster-resources` flag to `ark restore create`
|
||||
* Properly support resource restore priorities across cluster-scoped and namespace-scoped resources
|
||||
* Support `ark create ...` and `ark get ...`
|
||||
* Make ark run as cluster-admin
|
||||
* Add pod exec backup hooks
|
||||
* Support cross-compilation & upgrade to go 1.9
|
||||
|
||||
### Bug fixes
|
||||
* Make config change detection more robust
|
||||
31
changelogs/CHANGELOG-0.6.md
Normal file
31
changelogs/CHANGELOG-0.6.md
Normal file
@@ -0,0 +1,31 @@
|
||||
- [v0.6.0](#v060)
|
||||
|
||||
## v0.6.0
|
||||
#### 2017-11-30
|
||||
### Download
|
||||
- https://github.com/heptio/ark/tree/v0.6.0
|
||||
|
||||
### Highlights
|
||||
* **Plugins** - We now support user-defined plugins that can extend Ark functionality to meet your custom backup/restore needs without needing to be compiled into the core binary. We support pluggable block and object stores as well as per-item backup and restore actions that can execute arbitrary logic, including modifying the items being backed up or restored. For more information see the [documentation](docs/plugins.md), which includes a reference to a fully-functional sample plugin repository. (#174 #188 #206 #213 #215 #217 #223 #226)
|
||||
* **Describers** - The Ark CLI now includes `describe` commands for `backups`, `restores`, and `schedules` that provide human-friendly representations of the relevant API objects.
|
||||
|
||||
### Breaking Changes
|
||||
* The config object format has changed. In order to upgrade to v0.6.0, the config object will have to be updated to match the new format. See the [examples](examples) and [documentation](docs/config-definition.md) for more information.
|
||||
* The restore object format has changed. The `warnings` and `errors` fields are now ints containing the counts, while full warnings and errors are now stored in the object store instead of etcd. Restore objects created prior to v.0.6.0 should be deleted, or a new bucket used, and the old restore objects deleted from Kubernetes (`kubectl -n heptio-ark delete restore --all`).
|
||||
|
||||
### All New Features
|
||||
* Add `ark plugin add` and `ark plugin remove` commands #217, @skriss
|
||||
* Add plugin support for block/object stores, backup/restore item actions #174 #188 #206 #213 #215 #223 #226, @skriss @ncdc
|
||||
* Improve Azure deployment instructions #216, @ncdc
|
||||
* Change default TTL for backups to 30 days #204, @nrb
|
||||
* Improve logging for backups and restores #199, @ncdc
|
||||
* Add `ark backup describe`, `ark schedule describe` #196, @ncdc
|
||||
* Add `ark restore describe` and move restore warnings/errors to object storage #173 #201 #202, @ncdc
|
||||
* Upgrade to client-go v5.0.1, kubernetes v1.8.2 #157, @ncdc
|
||||
* Add Travis CI support #165 #166, @ncdc
|
||||
|
||||
### Bug Fixes
|
||||
* Fix log location hook prefix stripping #222, @ncdc
|
||||
* When running `ark backup download`, remove file if there's an error #154, @ncdc
|
||||
* Update documentation for AWS KMS Key alias support #163, @lli-hiya
|
||||
* Remove clock from `volume_snapshot_action` #137, @athampy
|
||||
30
changelogs/CHANGELOG-0.7.md
Normal file
30
changelogs/CHANGELOG-0.7.md
Normal file
@@ -0,0 +1,30 @@
|
||||
- [v0.7.1](#v071)
|
||||
- [v0.7.0](#v070)
|
||||
|
||||
## v0.7.1
|
||||
#### 2018-02-22
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.7.1
|
||||
|
||||
### Bug Fixes:
|
||||
* Run the Ark server in its own namespace, separate from backups/schedules/restores/config (#322, @ncdc)
|
||||
|
||||
|
||||
## v0.7.0
|
||||
#### 2018-02-15
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.7.0
|
||||
|
||||
### New Features:
|
||||
* Run the Ark server in any namespace (#272, @ncdc)
|
||||
* Add ability to delete backups and their associated data (#252, @skriss)
|
||||
* Support both pre and post backup hooks (#243, @ncdc)
|
||||
|
||||
### Bug Fixes / Other Changes:
|
||||
* Switch from Update() to Patch() when updating Ark resources (#241, @skriss)
|
||||
* Don't fail the backup if a PVC is not bound to a PV (#256, @skriss)
|
||||
* Restore serviceaccounts prior to workload controllers (#258, @ncdc)
|
||||
* Stop removing annotations from PVs when restoring them (#263, @skriss)
|
||||
* Update GCP client libraries (#249, @skriss)
|
||||
* Clarify backup and restore creation messages (#270, @nrb)
|
||||
* Update S3 bucket creation docs for us-east-1 (#285, @lypht)
|
||||
100
changelogs/CHANGELOG-0.8.md
Normal file
100
changelogs/CHANGELOG-0.8.md
Normal file
@@ -0,0 +1,100 @@
|
||||
- [v0.8.3](#v083)
|
||||
- [v0.8.2](#v082)
|
||||
- [v0.8.1](#v081)
|
||||
- [v0.8.0](#v080)
|
||||
|
||||
## v0.8.3
|
||||
#### 2018-06-29
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.8.3
|
||||
|
||||
### Bug Fixes:
|
||||
* Don't restore backup and restore resources to avoid possible data corruption (#622, @ncdc)
|
||||
|
||||
|
||||
## v0.8.2
|
||||
#### 2018-06-01
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.8.2
|
||||
|
||||
### Bug Fixes:
|
||||
* Don't crash when a persistent volume claim is missing spec.volumeName (#520, @ncdc)
|
||||
|
||||
|
||||
## v0.8.1
|
||||
#### 2018-04-23
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.8.1
|
||||
|
||||
### Bug Fixes:
|
||||
* Azure: allow pre-v0.8.0 backups with disk snapshots to be restored and deleted (#446 #449, @skriss)
|
||||
|
||||
|
||||
## v0.8.0
|
||||
#### 2018-04-19
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.8.0
|
||||
|
||||
### Highlights:
|
||||
* Backup deletion has been completely revamped to make it simpler and less error-prone. As a user, you still use the `ark backup delete` command to request deletion of a backup and its associated cloud
|
||||
resources; behind the scenes, we've switched to using a new `DeleteBackupRequest` Custom Resource and associated controller for processing deletion requests.
|
||||
* We've reduced the number of required fields in the Ark config. For Azure, `location` is no longer required, and for GCP, `project` is not needed.
|
||||
* Ark now copies tags from volumes to snapshots during backup, and from snapshots to new volumes during restore.
|
||||
|
||||
### Breaking Changes:
|
||||
* Ark has moved back to a single namespace (`heptio-ark` by default) as part of #383.
|
||||
|
||||
### All New Features:
|
||||
* Add global `--kubecontext` flag to Ark CLI (#296, @blakebarnett)
|
||||
* Azure: support cross-resource group restores of volumes (#356 #378, @skriss)
|
||||
* AWS/Azure/GCP: copy tags from volumes to snapshots, and from snapshots to volumes (#341, @skriss)
|
||||
* Replace finalizer for backup deletion with `DeleteBackupRequest` custom resource & controller (#383 #431, @ncdc @nrb)
|
||||
* Don't log warnings during restore if an identical object already exists in the cluster (#405, @nrb)
|
||||
* Add bash & zsh completion support (#384, @containscafeine)
|
||||
|
||||
### Bug Fixes / Other Changes:
|
||||
* Error from the Ark CLI if attempting to restore a non-existent backup (#302, @ncdc)
|
||||
* Enable running the Ark server locally for development purposes (#334, @ncdc)
|
||||
* Add examples to `ark schedule create` documentation (#331, @lypht)
|
||||
* GCP: Remove `project` requirement from Ark config (#345, @skriss)
|
||||
* Add `--from-backup` flag to `ark restore create` and allow custom restore names (#342 #409, @skriss)
|
||||
* Azure: remove `location` requirement from Ark config (#344, @skriss)
|
||||
* Add documentation/examples for storing backups in IBM Cloud Object Storage (#321, @roytman)
|
||||
* Reduce verbosity of hooks logging (#362, @skriss)
|
||||
* AWS: Add minimal IAM policy to documentation (#363 #419, @hopkinsth)
|
||||
* Don't restore events (#374, @sanketjpatel)
|
||||
* Azure: reduce API polling interval from 60s to 5s (#359, @skriss)
|
||||
* Switch from hostPath to emptyDir volume type for minio example (#386, @containscafeine)
|
||||
* Add limit ranges as a prioritized resource for restores (#392, @containscafeine)
|
||||
* AWS: Add documentation on using Ark with kube2iam (#402, @domderen)
|
||||
* Azure: add node selector so Ark pod is scheduled on a linux node (#415, @ffd2subroutine)
|
||||
* Error from the Ark CLI if attempting to get logs for a non-existent restore (#391, @containscafeine)
|
||||
* GCP: Add minimal IAM policy to documentation (#429, @skriss @jody-frankowski)
|
||||
|
||||
### Upgrading from v0.7.1:
|
||||
Ark v0.7.1 moved the Ark server deployment into a separate namespace, `heptio-ark-server`. As of v0.8.0 we've
|
||||
returned to a single namespace, `heptio-ark`, for all Ark-related resources. If you're currently running v0.7.1,
|
||||
here are the steps you can take to upgrade:
|
||||
|
||||
1. Execute the steps from the **Credentials and configuration** section for your cloud:
|
||||
* [AWS](https://heptio.github.io/velero/v0.8.0/aws-config#credentials-and-configuration)
|
||||
* [Azure](https://heptio.github.io/velero/v0.8.0/azure-config#credentials-and-configuration)
|
||||
* [GCP](https://heptio.github.io/velero/v0.8.0/gcp-config#credentials-and-configuration)
|
||||
|
||||
When you get to the secret creation step, if you don't have your `credentials-ark` file handy,
|
||||
you can copy the existing secret from your `heptio-ark-server` namespace into the `heptio-ark` namespace:
|
||||
```bash
|
||||
kubectl get secret/cloud-credentials -n heptio-ark-server --export -o json | \
|
||||
jq '.metadata.namespace="heptio-ark"' | \
|
||||
kubectl apply -f -
|
||||
```
|
||||
|
||||
2. You can now safely delete the `heptio-ark-server` namespace:
|
||||
```bash
|
||||
kubectl delete namespace heptio-ark-server
|
||||
```
|
||||
|
||||
3. Execute the commands from the **Start the server** section for your cloud:
|
||||
* [AWS](https://heptio.github.io/velero/v0.8.0/aws-config#start-the-server)
|
||||
* [Azure](https://heptio.github.io/velero/v0.8.0/azure-config#start-the-server)
|
||||
* [GCP](https://heptio.github.io/velero/v0.8.0/gcp-config#start-the-server)
|
||||
181
changelogs/CHANGELOG-0.9.md
Normal file
181
changelogs/CHANGELOG-0.9.md
Normal file
@@ -0,0 +1,181 @@
|
||||
- [v0.9.11](#v0911)
|
||||
- [v0.9.10](#v0910)
|
||||
- [v0.9.9](#v099)
|
||||
- [v0.9.8](#v098)
|
||||
- [v0.9.7](#v097)
|
||||
- [v0.9.6](#v096)
|
||||
- [v0.9.5](#v095)
|
||||
- [v0.9.4](#v094)
|
||||
- [v0.9.3](#v093)
|
||||
- [v0.9.2](#v092)
|
||||
- [v0.9.1](#v091)
|
||||
- [v0.9.0](#v090)
|
||||
|
||||
## v0.9.11
|
||||
#### 2018-11-08
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.11
|
||||
|
||||
### Bug Fixes
|
||||
* Fix bug preventing PV snapshots from being restored (#1040, @ncdc)
|
||||
|
||||
|
||||
## v0.9.10
|
||||
#### 2018-11-01
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.10
|
||||
|
||||
### Bug Fixes
|
||||
* restore storageclasses before pvs and pvcs (#594, @shubheksha)
|
||||
* AWS: Ensure that the order returned by ListObjects is consistent (#999, @bashofmann)
|
||||
* Add CRDs to list of prioritized resources (#424, @domenicrosati)
|
||||
* Verify PV doesn't exist before creating new volume (#609, @nrb)
|
||||
* Update README.md - Grammar mistake corrected (#1018, @midhunbiju)
|
||||
|
||||
|
||||
## v0.9.9
|
||||
#### 2018-10-24
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.9
|
||||
|
||||
### Bug Fixes
|
||||
* Check if initContainers key exists before attempting to remove volume mounts. (#927, @skriss)
|
||||
|
||||
|
||||
## v0.9.8
|
||||
#### 2018-10-18
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.8
|
||||
|
||||
### Bug Fixes
|
||||
* Discard service account token volume mounts from init containers on restore (#910, @james-powis)
|
||||
* Support --include-cluster-resources flag when creating schedule (#942, @captjt)
|
||||
* Remove logic to get a GCP project (#926, @shubheksha)
|
||||
* Only try to back up PVCs linked PV if the PVC's phase is Bound (#920, @skriss)
|
||||
* Claim ownership of new AWS volumes on Kubernetes cluster being restored into (#801, @ljakimczuk)
|
||||
* Remove timeout check when taking snapshots (#928, @carlisia)
|
||||
|
||||
|
||||
## v0.9.7
|
||||
#### 2018-10-04
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.7
|
||||
|
||||
### Bug Fixes
|
||||
* Preserve explicitly-specified node ports during restore (#712, @timoreimann)
|
||||
* Enable restoring resources with ownerReference set (#837, @mwieczorek)
|
||||
* Fix error when restoring ExternalName services (#869, @shubheksha)
|
||||
* remove restore log helper for accurate line numbers (#891, @skriss)
|
||||
* Display backup StartTimestamp in `ark backup get` output (#894, @marctc)
|
||||
* Fix restic restores when using namespace mappings (#900, @skriss)
|
||||
|
||||
|
||||
## v0.9.6
|
||||
#### 2018-09-21
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.6
|
||||
|
||||
### Bug Fixes
|
||||
* Discard service account tokens from non-default service accounts on restore (#843, @james-powis)
|
||||
* Update Docker images to use `alpine:3.8` (#852, @nrb)
|
||||
|
||||
|
||||
## v0.9.5
|
||||
#### 2018-09-17
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.5
|
||||
|
||||
### Bug Fixes
|
||||
* Fix issue causing restic restores not to work (#834, @skriss)
|
||||
|
||||
|
||||
## v0.9.4
|
||||
#### 20180-09-05
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.4
|
||||
|
||||
### Bug Fixes
|
||||
* Terminate plugin clients to resolve memory leaks (#797, @skriss)
|
||||
* Fix nil map errors when merging annotations (#812, @nrb)
|
||||
|
||||
|
||||
## v0.9.3
|
||||
#### 2018-08-10
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.3
|
||||
### Bug Fixes
|
||||
* Initalize Prometheus metrics when creating a new schedule (#689, @lemaral)
|
||||
|
||||
|
||||
## v0.9.2
|
||||
#### 2018-07-26
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.2) - 2018-07-26
|
||||
|
||||
### Bug Fixes:
|
||||
* Fix issue where modifications made by backup item actions were not being saved to backup tarball (#704, @skriss)
|
||||
|
||||
|
||||
## v0.9.1
|
||||
#### 2018-07-23
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.1
|
||||
|
||||
### Bug Fixes:
|
||||
* Require namespace for Ark's CRDs to already exist at server startup (#676, @skriss)
|
||||
* Require all Ark CRDs to exist at server startup (#683, @skriss)
|
||||
* Fix `latest` tagging in Makefile (#690, @skriss)
|
||||
* Make Ark compatible with clusters that don't have the `rbac.authorization.k8s.io/v1` API group (#682, @nrb)
|
||||
* Don't consider missing snapshots an error during backup deletion, limit backup deletion requests per backup to 1 (#687, @skriss)
|
||||
|
||||
|
||||
## v0.9.0
|
||||
#### 2018-07-06
|
||||
### Download
|
||||
- https://github.com/heptio/ark/releases/tag/v0.9.0
|
||||
|
||||
### Highlights:
|
||||
* Ark now has support for backing up and restoring Kubernetes volumes using a free open-source backup tool called [restic](https://github.com/restic/restic).
|
||||
This provides users an out-of-the-box solution for backing up and restoring almost any type of Kubernetes volume, whether or not it has snapshot support
|
||||
integrated with Ark. For more information, see the [documentation](https://github.com/heptio/ark/blob/master/docs/restic.md).
|
||||
* Support for Prometheus metrics has been added! View total number of backup attempts (including success or failure), total backup size in bytes, and backup
|
||||
durations. More metrics coming in future releases!
|
||||
|
||||
### All New Features:
|
||||
* Add restic support (#508 #532 #533 #534 #535 #537 #540 #541 #545 #546 #547 #548 #555 #557 #561 #563 #569 #570 #571 #606 #608 #610 #621 #631 #636, @skriss)
|
||||
* Add prometheus metrics (#531 #551 #564, @ashish-amarnath @nrb)
|
||||
* When backing up a service account, include cluster roles/cluster role bindings that reference it (#470, @skriss)
|
||||
* When restoring service accounts, copy secrets/image pull secrets into the target cluster even if the service account already exists (#403, @nrb)
|
||||
|
||||
### Bug Fixes / Other Changes:
|
||||
* Upgrade to Kubernetes 1.10 dependencies (#417, @skriss)
|
||||
* Upgrade to go 1.10 and alpine 3.7 (#456, @skriss)
|
||||
* Display no excluded resources/namespaces as `<none>` rather than `*` (#453, @nrb)
|
||||
* Skip completed jobs and pods when restoring (#463, @nrb)
|
||||
* Set namespace correctly when syncing backups from object storage (#472, @skriss)
|
||||
* When building on macOS, bind-mount volumes with delegated config (#478, @skriss)
|
||||
* Add replica sets and daemonsets to cohabitating resources so they're not backed up twice (#482 #485, @skriss)
|
||||
* Shut down the Ark server gracefully on SIGINT/SIGTERM (#483, @skriss)
|
||||
* Only back up resources that support GET and DELETE in addition to LIST and CREATE (#486, @nrb)
|
||||
* Show a better error message when trying to get an incomplete restore's logs (#496, @nrb)
|
||||
* Stop processing when setting a backup deletion request's phase to `Deleting` fails (#500, @nrb)
|
||||
* Add library code to install Ark's server components (#437 #506, @marpaia)
|
||||
* Properly handle errors when backing up additional items (#512, @carlpett)
|
||||
* Run post hooks even if backup actions fail (#514, @carlpett)
|
||||
* GCP: fail backup if upload to object storage fails (#510, @nrb)
|
||||
* AWS: don't require `region` as part of backup storage provider config (#455, @skriss)
|
||||
* Ignore terminating resources while doing a backup (#526, @yastij)
|
||||
* Log to stdout instead of stderr (#553, @ncdc)
|
||||
* Move sample minio deployment's config to an emptyDir (#566, @runyontr)
|
||||
* Add `omitempty` tag to optional API fields (@580, @nikhita)
|
||||
* Don't restore PVs with a reclaim policy of `Delete` and no snapshot (#613, @ncdc)
|
||||
* Don't restore mirror pods (#619, @ncdc)
|
||||
|
||||
### Docs Contributors:
|
||||
* @gianrubio
|
||||
* @castrojo
|
||||
* @dhananjaysathe
|
||||
* @c-knowles
|
||||
* @mattkelly
|
||||
* @ae-v
|
||||
* @hamidzr
|
||||
139
changelogs/CHANGELOG-1.0.md
Normal file
139
changelogs/CHANGELOG-1.0.md
Normal file
@@ -0,0 +1,139 @@
|
||||
## v1.0.0
|
||||
#### 2019-05-20
|
||||
|
||||
### Highlights
|
||||
- We've added a new command, `velero install`, to make it easier to get up and running with Velero. This CLI command replaces the static YAML installation files that were previously part of release tarballs. See the updated [install instructions][3] for more information.
|
||||
- We've made a number of improvements to the plugin framework:
|
||||
- we've reorganized the relevant packages to minimize the import surface for plugin authors
|
||||
- all plugins are now wrapped in panic handlers that will report information on panics back to Velero
|
||||
- Velero's `--log-level` flag is now passed to plugin implementations
|
||||
- Errors logged within plugins are now annotated with the file/line of where the error occurred
|
||||
- Restore item actions can now optionally return a list of additional related items that should be restored
|
||||
- Restore item actions can now indicate that an item *should not* be restored
|
||||
- For Azure installation, the `cloud-credentials` secret can now be created from a file containing a list of environment variables. Note that `velero install` always uses this method of providing credentials for Azure. For more details, see [Run on Azure][0].
|
||||
- We've added a new phase, `PartiallyFailed`, for both backups and restores. This new phase is used for backups/restores that successfully process some but not all of their items.
|
||||
- We removed all legacy Ark references, including API types, prometheus metrics, restic & hook annotations, etc.
|
||||
- The restic integration remains a **beta feature**. Please continue to try it out and provide feedback, and we'll be working over the next couple of releases to bring it to GA.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
#### API
|
||||
* All legacy Ark data types and pre-1.0 compatibility code has been removed. Users should migrate any backups created pre-v0.11.0 with the `velero migrate-backups` command, available in [v0.11.1][2].
|
||||
|
||||
#### Image
|
||||
* The base container image has been switched to `ubuntu:bionic`
|
||||
|
||||
#### Labels/Annotations/Metrics
|
||||
* The "ark" annotations for specifying hooks are no longer supported, and have been replaced with "velero"-based equivalents.
|
||||
* The "ark" annotation for specifying restic backups is no longer supported, and has been replaced with a "velero"-based equivalent.
|
||||
* The "ark" prometheus metrics no longer exist, and have been replaced with "velero"-based equivalents.
|
||||
|
||||
#### Plugin Development
|
||||
* `BlockStore` plugins are now named `VolumeSnapshotter` plugins
|
||||
* Plugin APIs have moved to reduce the import surface:
|
||||
* Plugin gRPC servers live in `github.com/heptio/velero/pkg/plugin/framework`
|
||||
* Plugin interface types live in `github.com/heptio/velero/pkg/plugin/velero`
|
||||
* RestoreItemAction interface now takes the original item from the backup as a parameter
|
||||
* RestoreItemAction plugins can now return additional items to restore
|
||||
* RestoreItemAction plugins can now skip restoring an item
|
||||
* Plugins may now send stack traces with errors to the Velero server, so that the errors may be put into the server log
|
||||
* Plugins must now be "namespaced," using `example.domain.com/plugin-name` format
|
||||
* For external ObjectStore and VolumeSnapshotter plugins. this name will also be the provider name in BackupStorageLoction and VolumeSnapshotLocation objects
|
||||
* `--log-level` flag is now passed to all plugins
|
||||
|
||||
#### Validation
|
||||
* Configs for Azure, AWS, and GCP are now checked for invalid or extra keys, and the server is halted if any are found
|
||||
|
||||
### Download
|
||||
- https://github.com/heptio/velero/releases/tag/v1.0.0
|
||||
|
||||
### Container Image
|
||||
`gcr.io/heptio-images/velero:v1.0.0`
|
||||
|
||||
### Documentation
|
||||
https://velero.io/docs/v1.0.0/
|
||||
|
||||
### Upgrading
|
||||
To upgrade from a previous version of Velero, see our [upgrade instructions][1].
|
||||
|
||||
### All Changes
|
||||
* Change base images to ubuntu:bionic (#1488, @skriss)
|
||||
* Expose the timestamp of the last successful backup in a gauge (#1448, @fabito)
|
||||
* check backup existence before download (#1447, @fabito)
|
||||
* Use `latest` image tag if no version information is provided at build time (#1439, @nrb)
|
||||
* switch from `restic stats` to `restic snapshots` for checking restic repository existence (#1416, @skriss)
|
||||
* GCP: add optional 'project' config to volume snapshot location for if snapshots are in a different project than the IAM account (#1405, @skriss)
|
||||
* Disallow bucket names starting with '-' (#1407, @nrb)
|
||||
* Shorten label values when they're longer than 63 characters (#1392, @anshulc)
|
||||
* Fail backup if it already exists in object storage. (#1390, @ncdc,carlisia)
|
||||
* Add PartiallyFailed phase for backups, log + continue on errors during backup process (#1386, @skriss)
|
||||
* Remove deprecated "hooks" for backups (they've been replaced by "pre hooks") (#1384, @skriss)
|
||||
* Restic repo ensurer: return error if new repository does not become ready within a minute, and fix channel closing/deletion (#1367, @skriss)
|
||||
* Support non-namespaced names for built-in plugins (#1366, @nrb)
|
||||
* Change container base images to debian:stretch-slim and upgrade to go 1.12 (#1365, @skriss)
|
||||
* Azure: allow credentials to be provided in a .env file (path specified by $AZURE_CREDENTIALS_FILE), formatted like (#1364, @skriss):
|
||||
```
|
||||
AZURE_TENANT_ID=${AZURE_TENANT_ID}
|
||||
AZURE_SUBSCRIPTION_ID=${AZURE_SUBSCRIPTION_ID}
|
||||
AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
|
||||
AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
|
||||
AZURE_RESOURCE_GROUP=${AZURE_RESOURCE_GROUP}
|
||||
```
|
||||
* Instantiate the plugin manager with the per-restore logger so plugin logs are captured in the per-restore log (#1358, @skriss)
|
||||
* Add gauge metrics for number of existing backups and restores (#1353, @fabito)
|
||||
* Set default TTL for backups (#1352, @vorar)
|
||||
* Validate that there can't be any duplicate plugin name, and that the name format is `example.io/name`. (#1339, @carlisia)
|
||||
* AWS/Azure/GCP: fail fast if unsupported keys are provided in BackupStorageLocation/VolumeSnapshotLocation config (#1338, @skriss)
|
||||
* `velero backup logs` & `velero restore logs`: show helpful error message if backup/restore does not exist or is not finished processing (#1337, @skriss)
|
||||
* Add support for allowing a RestoreItemAction to skip item restore. (#1336, @sseago)
|
||||
* Improve error message around invalid S3 URLs, and gracefully handle trailing backslashes. (#1331, @skriss)
|
||||
* Set backup's start timestamp before patching it to InProgress so start times display in `velero backup get` while in progress (#1330, @skriss)
|
||||
* Added ability to dynamically disable controllers (#1326, @amanw)
|
||||
* Remove deprecated code in preparation for v1.0 release (#1323, @skriss):
|
||||
- remove ark.heptio.com API group
|
||||
- remove support for reading ark-backup.json files from object storage
|
||||
- remove Ark field from RestoreResult type
|
||||
- remove support for "hook.backup.ark.heptio.com/..." annotations for specifying hooks
|
||||
- remove support for $HOME/.config/ark/ client config directory
|
||||
- remove support for restoring Azure snapshots using short snapshot ID formats in backup metadata
|
||||
- stop applying "velero-restore" label to restored resources and remove it from the API pkg
|
||||
- remove code that strips the "gc.ark.heptio.com" finalizer from backups
|
||||
- remove support for "backup.ark.heptio.com/..." annotations for requesting restic backups
|
||||
- remove "ark"-prefixed prometheus metrics
|
||||
- remove VolumeBackups field and related code from Backup's status
|
||||
* Rename BlockStore plugin to VolumeSnapshotter (#1321, @skriss)
|
||||
* Bump plugin ProtocolVersion to version 2 (#1319, @carlisia)
|
||||
* Remove Warning field from restore item action output (#1318, @skriss)
|
||||
* Fix for #1312, use describe to determine if AWS EBS snapshot is encrypted and explicitly pass that value in EC2 CreateVolume call. (#1316, @mstump)
|
||||
* Allow restic restore helper image name to be optionally specified via ConfigMap (#1311, @skriss)
|
||||
* Compile only once to lower the initialization cost for regexp.MustCompile. (#1306, @pei0804)
|
||||
* Enable restore item actions to return additional related items to be restored; have pods return PVCs and PVCs return PVs (#1304, @skriss)
|
||||
* Log error locations from plugin logger, and don't overwrite them in the client logger if they exist already (#1301, @skriss)
|
||||
* Send stack traces from plugin errors to Velero via gRPC so error location info can be logged (#1300, @skriss)
|
||||
* Azure: restore volumes in the original region's zone (#1298, @sylr)
|
||||
* Check for and exclude hostPath-based persistent volumes from restic backup (#1297, @skriss)
|
||||
* Make resticrepositories non-restorable resources (#1296, @skriss)
|
||||
* Gracefully handle failed API groups from the discovery API (#1293, @fabito)
|
||||
* Add `velero install` command for basic use cases. (#1287, @nrb)
|
||||
* Collect 3 new metrics: backup_deletion_{attempt|failure|success}_total (#1280, @fabito)
|
||||
* Pass --log-level flag to internal/external plugins, matching Velero server's log level (#1278, @skriss)
|
||||
* AWS EBS Volume IDs now contain AZ (#1274, @tsturzl)
|
||||
* Add panic handlers to all server-side plugin methods (#1270, @skriss)
|
||||
* Move all the interfaces and associated types necessary to implement all of the Velero plugins to under the new package `velero`. (#1264, @carlisia)
|
||||
* Update `velero restore` to not open every single file open during extraction of the data (#1261, @asaf)
|
||||
* Remove restore code that waits for a PV to become Available (#1254, @skriss)
|
||||
* Improve `describe` output
|
||||
* Move Phase to right under Metadata(name/namespace/label/annotations)
|
||||
* Move Validation errors: section right after Phase: section and only show it if the item has a phase of FailedValidation
|
||||
* For restores move Warnings and Errors under Validation errors. Leave their display as is. (#1248, @DheerajSShetty)
|
||||
* Don't remove storage class from a persistent volume when restoring it (#1246, @skriss)
|
||||
* Need to defer closing the the ReadCloser in ObjectStoreGRPCServer.GetObject (#1236, @DheerajSShetty)
|
||||
* Update Kubernetes dependencies to match v1.12, and update Azure SDK to v19.0.0 (GA) (#1231, @skriss)
|
||||
* Remove pkg/util/collections/map_utils.go, replace with structured API types and apimachinery's unstructured helpers (#1146, @skriss)
|
||||
* Add original resource (from backup) to restore item action interface (#1123, @mwieczorek)
|
||||
|
||||
|
||||
[0]: https://velero.io/docs/v1.0.0/azure-config
|
||||
[1]: https://velero.io/docs/v1.0.0/upgrade-to-1.0
|
||||
[2]: https://github.com/heptio/velero/releases/tag/v0.11.1
|
||||
[3]: https://velero.io/docs/v1.0.0/install-overview
|
||||
100
changelogs/CHANGELOG-1.1.md
Normal file
100
changelogs/CHANGELOG-1.1.md
Normal file
@@ -0,0 +1,100 @@
|
||||
## v1.1.0
|
||||
#### 2019-08-22
|
||||
|
||||
### Download
|
||||
- https://github.com/heptio/velero/releases/tag/v1.1.0
|
||||
|
||||
### Container Image
|
||||
`gcr.io/heptio-images/velero:v1.1.0`
|
||||
|
||||
### Documentation
|
||||
https://velero.io/docs/v1.1.0/
|
||||
|
||||
### Upgrading
|
||||
|
||||
**If you are running Velero in a non-default namespace**, i.e. any namespace other than `velero`, manual intervention is required when upgrading to v1.1. See [upgrading to v1.1](https://velero.io/docs/v1.1.0/upgrade-to-1.1/) for details.
|
||||
|
||||
### Highlights
|
||||
|
||||
#### Improved Restic Support
|
||||
|
||||
A big focus of our work this cycle was continuing to improve support for restic. To that end, we’ve fixed the following bugs:
|
||||
|
||||
|
||||
- Prior to version 1.1, restic backups could be delayed or failed due to long-lived locks on the repository. Now, Velero removes stale locks from restic repositories every 5 minutes, ensuring they do not interrupt normal operations.
|
||||
- Previously, the PodVolumeBackup custom resources that represented a restic backup within a cluster were not synchronized between clusters, making it unclear what restic volumes were available to restore into a new cluster. In version 1.1, these resources are synced into clusters, so they are more visible to you when you are trying to restore volumes.
|
||||
- Originally, Velero would not validate the host path in which volumes were mounted on a given node. If a node did not expose the filesystem correctly, you wouldn’t know about it until a backup failed. Now, Velero’s restic server will validate that the directory structure is correct on startup, providing earlier feedback when it’s not.
|
||||
- Velero’s restic support is intended to work on a broad range of volume types. With the general release of the [Container Storage Interface API](https://kubernetes.io/blog/2019/01/15/container-storage-interface-ga/), Velero can now use restic to back up CSI volumes.
|
||||
|
||||
Along with our bug fixes, we’ve provided an easier way to move restic backups between storage providers. Different providers often have different StorageClasses, requiring user intervention to make restores successfully complete.
|
||||
|
||||
To make cross-provider moves simpler, we’ve introduced a StorageClass remapping plug-in. It allows you to automatically translate one StorageClass on PersistentVolumeClaims and PersistentVolumes to another. You can read more about it in our [documentation](https://velero.io/docs/v1.1.0/restore-reference/#changing-pv-pvc-storage-classes).
|
||||
|
||||
#### Quality-of-Life Improvements
|
||||
|
||||
We’ve also made several other enhancements to Velero that should benefit all users.
|
||||
|
||||
Users sometimes ask about recommendations for Velero’s resource allocation within their cluster. To help with this concern, we’ve added default resource requirements to the Velero Deployment and restic init containers, along with configurable requests and limits for the restic DaemonSet. All these values can be adjusted if your environment requires it.
|
||||
|
||||
We’ve also taken some time to improve Velero for the future by updating the Deployment and DaemonSet to use the apps/v1 API group, which will be the [default in Kubernetes 1.16](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.16.md#action-required-3). This change means that `velero install` and the `velero plugin` commands will require Kubernetes 1.9 or later to work. Existing Velero installs will continue to work without needing changes, however.
|
||||
|
||||
In order to help you better understand what resources have been backed up, we’ve added a list of resources in the `velero backup describe --details` command. This change makes it easier to inspect a backup without having to download and extract it.
|
||||
|
||||
In the same vein, we’ve added the ability to put custom tags on cloud-provider snapshots. This approach should provide a better way to keep track of the resources being created in your cloud account. To add a label to a snapshot at backup time, use the `--labels` argument in the `velero backup create` command.
|
||||
|
||||
Our final change for increasing visibility into your Velero installation is the `velero plugin get` command. This command will report all the plug-ins within the Velero deployment..
|
||||
|
||||
Velero has previously used a restore-only flag on the server to control whether a cluster could write backups to object storage. With Velero 1.1, we’ve now moved the restore-only behavior into read-only BackupStorageLocations. This move means that the Velero server can use a BackupStorageLocation as a source to restore from, but not for backups, while still retaining the ability to back up to other configured locations. In the future, the `--restore-only` flag will be removed in favor of configuring read-only BackupStorageLocations.
|
||||
|
||||
#### Community Contributions
|
||||
|
||||
We appreciate all community contributions, whether they be pull requests, bug reports, feature requests, or just questions. With this release, we wanted to draw attention to a few contributions in particular:
|
||||
|
||||
For users of node-based IAM authentication systems such as kube2iam, `velero install` now supports the `--pod-annotations` argument for applying necessary annotations at install time. This support should make `velero install` more flexible for scenarios that do not use Secrets for access to their cloud buckets and volumes. You can read more about how to use this new argument in our [AWS documentation](https://velero.io/docs/v1.1.0/aws-config/#alternative-setup-permissions-using-kube2iam). Huge thanks to [Traci Kamp](https://github.com/tlkamp) for this contribution.
|
||||
|
||||
Structured logging is important for any application, and Velero is no different. Starting with version 1.1, the Velero server can now output its logs in a JSON format, allowing easier parsing and ingestion. Thank you to [Donovan Carthew](https://github.com/carthewd) for this feature.
|
||||
|
||||
AWS supports multiple profiles for accessing object storage, but in the past Velero only used the default. With v.1.1, you can set the `profile` key on yourBackupStorageLocation to specify an alternate profile. If no profile is set, the default one is used, making this change backward compatible. Thanks [Pranav Gaikwad](https://github.com/pranavgaikwad) for this change.
|
||||
|
||||
Finally, thanks to testing by [Dylan Murray](https://github.com/dymurray) and [Scott Seago](https://github.com/sseago), an issue with running Velero in non-default namespaces was found in our beta version for this release. If you’re running Velero in a namespace other than `velero`, please follow the [upgrade instructions](https://velero.io/docs/v1.1.0/upgrade-to-1.1/).
|
||||
|
||||
### All Changes
|
||||
* Add the prefix to BSL config map so that object stores can use it when initializing (#1767, @betta1)
|
||||
* Use `VELERO_NAMESPACE` to determine what namespace Velero server is running in. For any v1.0 installations using a different namespace, the `VELERO_NAMESPACE` environment variable will need to be set to the correct namespace. (#1748, @nrb)
|
||||
* support setting CPU/memory requests with unbounded limits using velero install (#1745, @prydonius)
|
||||
* sort output of resource list in `velero backup describe --details` (#1741, @prydonius)
|
||||
* adds the ability to define custom tags to be added to snapshots by specifying custom labels on the Backup CR with the velero backup create --labels flag (#1729, @prydonius)
|
||||
* Restore restic volumes from PodVolumeBackups CRs (#1723, @carlisia)
|
||||
* properly restore PVs backed up with restic and a reclaim policy of "Retain" (#1713, @skriss)
|
||||
* Make `--secret-file` flag on `velero install` optional, add `--no-secret` flag for explicit confirmation (#1699, @nrb)
|
||||
* Add low cpu/memory limits to the restic init container. This allows for restoration into namespaces with quotas defined. (#1677, @nrb)
|
||||
* Adds configurable CPU/memory requests and limits to the restic DaemonSet generated by velero install. (#1710, @prydonius)
|
||||
* remove any stale locks from restic repositories every 5m (#1708, @skriss)
|
||||
* error if backup storage location's Bucket field also contains a prefix, and gracefully handle leading/trailing slashes on Bucket and Prefix fields. (#1694, @skriss)
|
||||
* enhancement: allow option to choose JSON log output (#1654, @carthewd)
|
||||
* Adds configurable CPU/memory requests and limits to the Velero Deployment generated by velero install. (#1678, @prydonius)
|
||||
* Store restic PodVolumeBackups in obj storage & use that as source of truth like regular backups. (#1577, @carlisia)
|
||||
* Update Velero Deployment to use apps/v1 API group. `velero install` and `velero plugin add/remove` commands will now require Kubernetes 1.9+ (#1673, @nrb)
|
||||
* Respect the --kubecontext and --kubeconfig arugments for `velero install`. (#1656, @nrb)
|
||||
* add plugin for updating PV & PVC storage classes on restore based on a config map (#1621, @skriss)
|
||||
* Add restic support for CSI volumes (#1615, @nrb)
|
||||
* bug fix: Fixed namespace usage with cli command 'version' (#1630, @jwmatthews)
|
||||
* enhancement: allow users to specify additional Velero/Restic pod annotations on the command line with the pod-annotations flag. (#1626, @tlkamp)
|
||||
* adds validation for pod volumes hostPath mount on restic server startup (#1616, @prydonius)
|
||||
* enable support for ppc64le architecture (#1605, @prajyot)
|
||||
* bug fix: only restore additional items returned from restore item actions if they match the restore's namespace/resource selectors (#1612, @skriss)
|
||||
* add startTimestamp and completionTimestamp to PodVolumeBackup and PodVolumeRestore status fields (#1609, @prydonius)
|
||||
* bug fix: respect namespace selector when determining which restore item actions to run (#1607, @skriss)
|
||||
* ensure correct backup item actions run with namespace selector (#1601, @prydonius)
|
||||
* allows excluding resources from backups with the `velero.io/exclude-from-backup=true` label (#1588, @prydonius)
|
||||
* ensures backup item action modifications to an item's namespace/name are saved in the file path in the tarball (#1587, @prydonius)
|
||||
* Hides `velero server` and `velero restic server` commands from the list of available commands as these are not intended for use by the velero CLI user. (#1561, @prydonius)
|
||||
* remove dependency on glog, update to klog (#1559, @skriss)
|
||||
* move issue-template-gen from docs/ to hack/ (#1558, @skriss)
|
||||
* fix panic when processing DeleteBackupRequest objects without labels (#1556, @prydonius)
|
||||
* support for multiple AWS profiles (#1548, @pranavgaikwad)
|
||||
* Add CLI command to list (get) all Velero plugins (#1535, @carlisia)
|
||||
* Added author as a tag on blog post. Should fix 404 error when trying to follow link as specified in issue #1522. (#1522, @coonsd)
|
||||
* Allow individual backup storage locations to be read-only (#1517, @skriss)
|
||||
* Stop returning an error when a restic volume is empty since it is a valid scenario. (#1480, @carlisia)
|
||||
* add ability to use wildcard in includes/excludes (#1428, @guilhem)
|
||||
0
changelogs/unreleased/.keep
Normal file
0
changelogs/unreleased/.keep
Normal file
77
cmd/velero-restic-restore-helper/main.go
Normal file
77
cmd/velero-restic-restore-helper/main.go
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Fprintln(os.Stderr, "ERROR: exactly one argument must be provided, the restore's UID")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
if done() {
|
||||
fmt.Println("All restic restores are done")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// done returns true if for each directory under /restores, a file exists
|
||||
// within the .velero/ subdirectory whose name is equal to os.Args[1], or
|
||||
// false otherwise
|
||||
func done() bool {
|
||||
children, err := ioutil.ReadDir("/restores")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "ERROR reading /restores directory: %s\n", err)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, child := range children {
|
||||
if !child.IsDir() {
|
||||
fmt.Printf("%s is not a directory, skipping.\n", child.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
doneFile := filepath.Join("/restores", child.Name(), ".velero", os.Args[1])
|
||||
|
||||
if _, err := os.Stat(doneFile); os.IsNotExist(err) {
|
||||
fmt.Printf("Not found: %s\n", doneFile)
|
||||
return false
|
||||
} else if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "ERROR looking for %s: %s\n", doneFile, err)
|
||||
return false
|
||||
}
|
||||
|
||||
fmt.Printf("Found %s", doneFile)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017, 2019 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -20,17 +20,17 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
"github.com/heptio/ark/pkg/cmd"
|
||||
"github.com/heptio/ark/pkg/cmd/ark"
|
||||
"github.com/heptio/velero/pkg/cmd"
|
||||
"github.com/heptio/velero/pkg/cmd/velero"
|
||||
)
|
||||
|
||||
func main() {
|
||||
defer glog.Flush()
|
||||
defer klog.Flush()
|
||||
|
||||
baseName := filepath.Base(os.Args[0])
|
||||
|
||||
err := ark.NewCommand(baseName).Execute()
|
||||
err := velero.NewCommand(baseName).Execute()
|
||||
cmd.CheckError(err)
|
||||
}
|
||||
48
design/_template.md
Normal file
48
design/_template.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Design proposal template (replace with your proposal's title)
|
||||
|
||||
Status: {Draft,Accepted,Declined}
|
||||
|
||||
One to two sentences that describes the goal of this proposal.
|
||||
The reader should be able to tell by the title, and the opening paragraph, if this document is relevant to them.
|
||||
|
||||
_Note_: The preferred style for design documents is one sentence per line.
|
||||
*Do not wrap lines*.
|
||||
This aids in review of the document as changes to a line are not obscured by the reflowing those changes caused and has a side effect of avoiding debate about one or two space after a period.
|
||||
|
||||
## Goals
|
||||
|
||||
- A short list of things which will be accomplished by implementing this proposal.
|
||||
- Two things is ok.
|
||||
- Three is pushing it.
|
||||
- More than three goals suggests that the proposal's scope is too large.
|
||||
|
||||
## Non Goals
|
||||
|
||||
- A short list of items which are:
|
||||
- a. out of scope
|
||||
- b. follow on items which are deliberately excluded from this proposal.
|
||||
|
||||
## Background
|
||||
|
||||
One to two paragraphs of exposition to set the context for this proposal.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
One to two paragraphs that describe the high level changes that will be made to implement this proposal.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
A detailed design describing how the changes to the product should be made.
|
||||
|
||||
The names of types, fields, interfaces, and methods should be agreed on here, not debated in code review.
|
||||
The same applies to changes in CRDs, YAML examples, and so on.
|
||||
|
||||
Ideally the changes should be made in sequence so that the work required to implement this design can be done incrementally, possibly in parallel.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
If there are alternative high level or detailed designs that were not pursued they should be called out here with a brief explanation of why they were not pursued.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
If this proposal has an impact to the security of the product, its users, or data stored or transmitted via the product, they must be addressed here.
|
||||
96
design/backup-resource-list.md
Normal file
96
design/backup-resource-list.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Expose list of backed up resources in backup details
|
||||
|
||||
Status: Accepted
|
||||
|
||||
To increase the visibility of what a backup might contain, this document proposes storing metadata about backed up resources in object storage and adding a new section to the detailed backup description output to list them.
|
||||
|
||||
## Goals
|
||||
|
||||
- Include a list of backed up resources as metadata in the bucket
|
||||
- Enable users to get a view of what resources are included in a backup using the Velero CLI
|
||||
|
||||
## Non Goals
|
||||
|
||||
- Expose the full manifests of the backed up resources
|
||||
|
||||
## Background
|
||||
|
||||
As reported in [#396](https://github.com/heptio/velero/issues/396), the information reported in a `velero backup describe <name> --details` command is fairly limited, and does not easily describe what resources a backup contains.
|
||||
In order to see what a backup might contain, a user would have to download the backup tarball and extract it.
|
||||
This makes it difficult to keep track of different backups in a cluster.
|
||||
|
||||
## High-Level Design
|
||||
|
||||
After performing a backup, a new file will be created that contains the list of the resources that have been included in the backup.
|
||||
This file will be persisted in object storage alongside the backup contents and existing metadata.
|
||||
|
||||
A section will be added to the output of `velero backup describe <name> --details` command to view this metadata.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
### Metadata file
|
||||
|
||||
This metadata will be in JSON (or YAML) format so that it can be easily inspected from the bucket outside of Velero tooling, and will contain the API resource and group, namespaces and names of the resources:
|
||||
|
||||
```
|
||||
apps/v1/Deployment:
|
||||
- default/database
|
||||
- default/wordpress
|
||||
v1/Service:
|
||||
- default/database
|
||||
- default/wordpress
|
||||
v1/Secret:
|
||||
- default/database-root-password
|
||||
- default/database-user-password
|
||||
v1/ConfigMap:
|
||||
- default/database
|
||||
v1/PersistentVolume:
|
||||
- my-pv
|
||||
```
|
||||
|
||||
The filename for this metadata will be `<backup name>-resource-list.json.gz`.
|
||||
The top-level key is the string form of the `schema.GroupResource` type that we currently keep track of in the backup controller code path.
|
||||
|
||||
### Changes in Backup controller
|
||||
|
||||
The Backupper currently initialises a map to track the `backedUpItems` (https://github.com/heptio/velero/blob/1594bdc8d0132f548e18ffcc1db8c4cd2b042726/pkg/backup/backup.go#L269), this is passed down through GroupBackupper, ResourceBackupper and ItemBackupper where ItemBackupper records each backed up item.
|
||||
This property will be moved to the [Backup request struct](https://github.com/heptio/velero/blob/16910a6215cbd8f0bde385dba9879629ebcbcc28/pkg/backup/request.go#L11), allowing the BackupController to access it after a successful backup.
|
||||
|
||||
`backedUpItems` currently uses the `schema.GroupResource` as a key for the resource.
|
||||
In order to record the API group, version and kind for the resource, this key will be constructed from the object's `schema.GroupVersionKind` in the format `{group}/{version}/{kind}` (e.g. `apps/v1/Deployment`).
|
||||
|
||||
The `backedUpItems` map is kept as a flat structure internally for quick lookup.
|
||||
When the backup is ready to upload, `backedUpItems` will be converted to a nested structure representing the metadata file above, grouped by `schema.GroupVersionKind`.
|
||||
After converting to the right format, it can be passed to the `persistBackup` function to persist the file in object storage.
|
||||
|
||||
### Changes to DownloadRequest CRD and processing
|
||||
|
||||
A new `DownloadTargetKind` "BackupResourceList" will be added to the DownloadRequest CR.
|
||||
|
||||
The `GetDownloadURL` function in the `persistence` package will be updated to handle this new DownloadTargetKind to enable the Velero client to fetch the metadata from the bucket.
|
||||
|
||||
### Changes to `velero backup describe <name> --details`
|
||||
|
||||
This command will need to be updated to fetch the metadata from the bucket using the `Stream` method used in other commands.
|
||||
The file will be read in memory and displayed in the output of the command.
|
||||
Depending on the format the metadata is stored in, it may need processing to print in a more human-readable format.
|
||||
If we choose to store the metadata in YAML, it can likely be directly printed out.
|
||||
|
||||
If the metadata file does not exist, this is an older backup and we cannot display the list of resources that were backed up.
|
||||
|
||||
## Open Questions
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
### Fetch backup contents archive and walkthrough to list contents
|
||||
|
||||
Instead of recording new metadata about what resources have been backed up, we could simply download the backup contents archive and walkthrough it to list the contents everytime `velero backup describe <name> --details` is run.
|
||||
|
||||
The advantage of this approach is that we don't need to change any backup procedures as we already have this content, and we will also be able to list resources for older backups.
|
||||
Additionally, if we wanted to expose more information about the backed up resources, we can do so without having to update what we store in the metadata.
|
||||
|
||||
The disadvantages are:
|
||||
- downloading the whole backup archive will be larger than just downloading a smaller file with metadata
|
||||
- reduces the metadata available in the bucket that users might want to inspect outside of Velero tooling (though this is not an explicit requirement)
|
||||
|
||||
## Security Considerations
|
||||
54
design/pv-cloning.md
Normal file
54
design/pv-cloning.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Cloning PVs While Remapping Namespaces
|
||||
|
||||
Status: Approved
|
||||
|
||||
Velero supports restoring resources into different namespaces than they were backed up from.
|
||||
This enables a user to, among other things, clone a namespace within a cluster.
|
||||
However, if the namespace being cloned uses persistent volume claims, Velero cannot currently create a second copy of the original persistent volume when restoring.
|
||||
This limitation is documented in detail in [issue #192](https://github.com/heptio/velero/issues/192).
|
||||
This document proposes a solution that allows new copies of persistent volumes to be created during a namespace clone.
|
||||
|
||||
## Goals
|
||||
|
||||
- Enable persistent volumes to be cloned when using `velero restore create --namespace-mappings ...` to create a second copy of a namespace within a cluster.
|
||||
|
||||
## Non Goals
|
||||
|
||||
- Cloning of persistent volumes in any scenario other than when using `velero restore create --namespace-mappings ...` flag.
|
||||
- [CSI-based cloning](https://kubernetes.io/docs/concepts/storage/volume-pvc-datasource/).
|
||||
|
||||
## Background
|
||||
|
||||
(Omitted, see introduction)
|
||||
|
||||
## High-Level Design
|
||||
|
||||
During a restore, Velero will detect that it needs to assign a new name to a persistent volume being restored if and only if both of the following conditions are met:
|
||||
- the persistent volume is claimed by a persistent volume claim in a namespace that's being remapped using `velero restore create --namespace-mappings ...`
|
||||
- a persistent volume already exists in the cluster with the original name
|
||||
|
||||
If these conditions exist, Velero will give the persistent volume a new arbitrary name before restoring it.
|
||||
It will also update the `spec.volumeName` of the related persistent volume claim.
|
||||
|
||||
## Detailed Design
|
||||
|
||||
In `pkg/restore/restore.go`, around [line 872](https://github.com/heptio/velero/blob/master/pkg/restore/restore.go#L872), Velero has special-case code for persistent volumes.
|
||||
This code will be updated to check for the two preconditions described in the previous section.
|
||||
If the preconditions are met, the object will be given a new name.
|
||||
The persistent volume will also be annotated with the original name, e.g. `velero.io/original-pv-name=NAME`.
|
||||
Importantly, the name change will occur **before** [line 890](https://github.com/heptio/velero/blob/master/pkg/restore/restore.go#L890), where Velero checks to see if it should restore the persistent volume.
|
||||
Additionally, the old and new persistent volume names will be recorded in a new field that will be added to the `context` struct, `renamedPVs map[string]string`.
|
||||
|
||||
In the special-case code for persistent volume claims starting on [line 987](https://github.com/heptio/velero/blob/master/pkg/restore/restore.go#L987), Velero will check to see if the claimed persistent volume has been renamed by looking in `ctx.renamedPVs`.
|
||||
If so, Velero will update the persistent volume claim's `spec.volumeName` to the new name.
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
One alternative approach is to add a new CLI flag and API field for restores, e.g. `--clone-pvs`, that a user could provide to indicate they want to create copies of persistent volumes.
|
||||
This approach would work fine, but it does require the user to be aware of this flag/field and to properly specify it when needed.
|
||||
It seems like a better UX to detect the typical conditions where this behavior is needed, and to automatically apply it.
|
||||
Additionally, the design proposed here does not preclude such a flag/field from being added later, if it becomes necessary to cover other use cases.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
N/A
|
||||
@@ -1,12 +1,11 @@
|
||||
# Examples
|
||||
|
||||
The YAML config files in this directory can be used to quickly deploy a containerized Ark deployment.
|
||||
This directory contains sample YAML config files that can be used for exploring Velero.
|
||||
|
||||
* `common/`: Contains manifests to set up Ark. Can be used across cloud provider platforms. (Note that Azure requires its own deployment file due to its unique way of loading credentials).
|
||||
* `minio/`: Used in the [Quickstart][0] to set up [Minio][1], a local S3-compatible object storage service. It provides a convenient way to test Velero without tying you to a specific cloud provider.
|
||||
|
||||
* `minio/`: Used in the [Quickstart][1] to set up [Minio][0], a local S3-compatible object storage service. It provides a convenient way to test Ark without tying you to a specific cloud provider.
|
||||
* `nginx-app/`: A sample nginx app that can be used to test backups and restores.
|
||||
|
||||
* `aws/`, `azure/`, `gcp/`, `ibm/`: Contains manifests specific to the given cloud provider's setup.
|
||||
|
||||
[0]: https://github.com/minio/minio
|
||||
[1]: /README.md#quickstart
|
||||
[0]: /docs/get-started.md
|
||||
[1]: https://github.com/minio/minio
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: ark.heptio.com/v1
|
||||
kind: Config
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: default
|
||||
persistentVolumeProvider:
|
||||
name: aws
|
||||
config:
|
||||
region: <YOUR_REGION>
|
||||
backupStorageProvider:
|
||||
name: aws
|
||||
bucket: <YOUR_BUCKET>
|
||||
config:
|
||||
region: <YOUR_REGION>
|
||||
backupSyncPeriod: 30m
|
||||
gcSyncPeriod: 30m
|
||||
scheduleSyncPeriod: 1m
|
||||
restoreOnlyMode: false
|
||||
@@ -1,44 +0,0 @@
|
||||
# Copyright 2018 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: ark
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
component: ark
|
||||
annotations:
|
||||
iam.amazonaws.com/role: arn:aws:iam::<AWS_ACCOUNT_ID>:role/<HEPTIO_ARK_ROLE_NAME>
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
serviceAccountName: ark
|
||||
containers:
|
||||
- name: ark
|
||||
image: gcr.io/heptio-images/ark:latest
|
||||
command:
|
||||
- /ark
|
||||
args:
|
||||
- server
|
||||
volumeMounts:
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
volumes:
|
||||
- name: plugins
|
||||
emptyDir: {}
|
||||
@@ -1,50 +0,0 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: ark
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
serviceAccountName: ark
|
||||
containers:
|
||||
- name: ark
|
||||
image: gcr.io/heptio-images/ark:latest
|
||||
command:
|
||||
- /ark
|
||||
args:
|
||||
- server
|
||||
volumeMounts:
|
||||
- name: cloud-credentials
|
||||
mountPath: /credentials
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
env:
|
||||
- name: AWS_SHARED_CREDENTIALS_FILE
|
||||
value: /credentials/cloud
|
||||
volumes:
|
||||
- name: cloud-credentials
|
||||
secret:
|
||||
secretName: cloud-credentials
|
||||
- name: plugins
|
||||
emptyDir: {}
|
||||
@@ -1,47 +0,0 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: ark
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
serviceAccountName: ark
|
||||
containers:
|
||||
- name: ark
|
||||
image: gcr.io/heptio-images/ark:latest
|
||||
command:
|
||||
- /ark
|
||||
args:
|
||||
- server
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: cloud-credentials
|
||||
volumeMounts:
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
volumes:
|
||||
- name: plugins
|
||||
emptyDir: {}
|
||||
nodeSelector:
|
||||
beta.kubernetes.io/os: linux
|
||||
@@ -1,134 +0,0 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: backups.ark.heptio.com
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
group: ark.heptio.com
|
||||
version: v1
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: backups
|
||||
kind: Backup
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: schedules.ark.heptio.com
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
group: ark.heptio.com
|
||||
version: v1
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: schedules
|
||||
kind: Schedule
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: restores.ark.heptio.com
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
group: ark.heptio.com
|
||||
version: v1
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: restores
|
||||
kind: Restore
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: configs.ark.heptio.com
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
group: ark.heptio.com
|
||||
version: v1
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: configs
|
||||
kind: Config
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: downloadrequests.ark.heptio.com
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
group: ark.heptio.com
|
||||
version: v1
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: downloadrequests
|
||||
kind: DownloadRequest
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: deletebackuprequests.ark.heptio.com
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
group: ark.heptio.com
|
||||
version: v1
|
||||
scope: Namespaced
|
||||
names:
|
||||
plural: deletebackuprequests
|
||||
kind: DeleteBackupRequest
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: heptio-ark
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: ark
|
||||
namespace: heptio-ark
|
||||
labels:
|
||||
component: ark
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: ark
|
||||
labels:
|
||||
component: ark
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
namespace: heptio-ark
|
||||
name: ark
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
@@ -1,10 +0,0 @@
|
||||
# File Structure
|
||||
|
||||
## 00-prereqs.yaml
|
||||
|
||||
This file contains the prerequisites necessary to run the Ark server:
|
||||
|
||||
- `heptio-ark` namespace
|
||||
- `ark` service account
|
||||
- RBAC rules to grant permissions to the `ark` service account
|
||||
- CRDs for the Ark-specific resources (Backup, Schedule, Restore, Config)
|
||||
@@ -1,50 +0,0 @@
|
||||
# Copyright 2018 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: ark
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
serviceAccountName: ark
|
||||
containers:
|
||||
- name: ark
|
||||
image: gcr.io/heptio-images/ark:latest
|
||||
command:
|
||||
- /ark
|
||||
args:
|
||||
- server
|
||||
volumeMounts:
|
||||
- name: cloud-credentials
|
||||
mountPath: /credentials
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
env:
|
||||
- name: GOOGLE_APPLICATION_CREDENTIALS
|
||||
value: /credentials/cloud
|
||||
volumes:
|
||||
- name: cloud-credentials
|
||||
secret:
|
||||
secretName: cloud-credentials
|
||||
- name: plugins
|
||||
emptyDir: {}
|
||||
@@ -1,50 +0,0 @@
|
||||
# Copyright 2018 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: ark
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
serviceAccountName: ark
|
||||
containers:
|
||||
- name: ark
|
||||
image: gcr.io/heptio-images/ark:latest
|
||||
command:
|
||||
- /ark
|
||||
args:
|
||||
- server
|
||||
volumeMounts:
|
||||
- name: cloud-credentials
|
||||
mountPath: /credentials
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
env:
|
||||
- name: AWS_SHARED_CREDENTIALS_FILE
|
||||
value: /credentials/cloud
|
||||
volumes:
|
||||
- name: cloud-credentials
|
||||
secret:
|
||||
secretName: cloud-credentials
|
||||
- name: plugins
|
||||
emptyDir: {}
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -13,16 +13,25 @@
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: velero
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
namespace: velero
|
||||
name: minio
|
||||
labels:
|
||||
component: minio
|
||||
spec:
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
component: minio
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
@@ -31,6 +40,8 @@ spec:
|
||||
volumes:
|
||||
- name: storage
|
||||
emptyDir: {}
|
||||
- name: config
|
||||
emptyDir: {}
|
||||
containers:
|
||||
- name: minio
|
||||
image: minio/minio:latest
|
||||
@@ -38,6 +49,7 @@ spec:
|
||||
args:
|
||||
- server
|
||||
- /storage
|
||||
- --config-dir=/config
|
||||
env:
|
||||
- name: MINIO_ACCESS_KEY
|
||||
value: "minio"
|
||||
@@ -48,16 +60,21 @@ spec:
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: "/storage"
|
||||
- name: config
|
||||
mountPath: "/config"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
namespace: velero
|
||||
name: minio
|
||||
labels:
|
||||
component: minio
|
||||
spec:
|
||||
# ClusterIP is recommended for production environments.
|
||||
# Change to NodePort if needed per documentation,
|
||||
# but only if you run Minio in a test/trial environment, for example with Minikube.
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 9000
|
||||
@@ -66,25 +83,11 @@ spec:
|
||||
selector:
|
||||
component: minio
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: cloud-credentials
|
||||
labels:
|
||||
component: minio
|
||||
stringData:
|
||||
cloud: |
|
||||
[default]
|
||||
aws_access_key_id = minio
|
||||
aws_secret_access_key = minio123
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
namespace: velero
|
||||
name: minio-setup
|
||||
labels:
|
||||
component: minio
|
||||
@@ -94,6 +97,9 @@ spec:
|
||||
name: minio-setup
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
volumes:
|
||||
- name: config
|
||||
emptyDir: {}
|
||||
containers:
|
||||
- name: mc
|
||||
image: minio/mc:latest
|
||||
@@ -101,4 +107,7 @@ spec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- "mc config host add ark http://minio:9000 minio minio123 && mc mb -p ark/ark"
|
||||
- "mc --config-dir=/config config host add velero http://minio:9000 minio minio123 && mc --config-dir=/config mb -p velero/velero"
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: "/config"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: ark.heptio.com/v1
|
||||
kind: Config
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: default
|
||||
backupStorageProvider:
|
||||
name: aws
|
||||
bucket: ark
|
||||
config:
|
||||
region: minio
|
||||
s3ForcePathStyle: "true"
|
||||
s3Url: http://minio.heptio-ark.svc:9000
|
||||
backupSyncPeriod: 1m
|
||||
gcSyncPeriod: 1m
|
||||
scheduleSyncPeriod: 1m
|
||||
restoreOnlyMode: false
|
||||
@@ -1,50 +0,0 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: heptio-ark
|
||||
name: ark
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
component: ark
|
||||
spec:
|
||||
restartPolicy: Always
|
||||
serviceAccountName: ark
|
||||
containers:
|
||||
- name: ark
|
||||
image: gcr.io/heptio-images/ark:latest
|
||||
command:
|
||||
- /ark
|
||||
args:
|
||||
- server
|
||||
volumeMounts:
|
||||
- name: cloud-credentials
|
||||
mountPath: /credentials
|
||||
- name: plugins
|
||||
mountPath: /plugins
|
||||
env:
|
||||
- name: AWS_SHARED_CREDENTIALS_FILE
|
||||
value: /credentials/cloud
|
||||
volumes:
|
||||
- name: cloud-credentials
|
||||
secret:
|
||||
secretName: cloud-credentials
|
||||
- name: plugins
|
||||
emptyDir: {}
|
||||
@@ -4,12 +4,12 @@ This directory contains manifests for two versions of a sample Nginx app under t
|
||||
|
||||
## `base.yaml`
|
||||
|
||||
This is the most basic version of the Nginx app, which can be used to test Ark's backup and restore functionality.
|
||||
This is the most basic version of the Nginx app, which can be used to test Velero's backup and restore functionality.
|
||||
|
||||
*This can be deployed as is.*
|
||||
|
||||
## `with-pv.yaml`
|
||||
|
||||
This sets up an Nginx app that logs to a persistent volume, so that Ark's PV snapshotting functionality can also be tested.
|
||||
This sets up an Nginx app that logs to a persistent volume, so that Velero's PV snapshotting functionality can also be tested.
|
||||
|
||||
*This requires you to first replace the placeholder value `<YOUR_STORAGE_CLASS_NAME>`.*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -21,13 +21,16 @@ metadata:
|
||||
app: nginx
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
namespace: nginx-example
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -29,7 +29,7 @@ metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
storageClassName: <YOUR_STORAGE_CLASS_NAME>
|
||||
# storageClassName: <YOUR_STORAGE_CLASS_NAME>
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
@@ -37,17 +37,25 @@ spec:
|
||||
storage: 50Mi
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta1
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
namespace: nginx-example
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
annotations:
|
||||
pre.hook.backup.velero.io/container: fsfreeze
|
||||
pre.hook.backup.velero.io/command: '["/sbin/fsfreeze", "--freeze", "/var/log/nginx"]'
|
||||
post.hook.backup.velero.io/container: fsfreeze
|
||||
post.hook.backup.velero.io/command: '["/sbin/fsfreeze", "--unfreeze", "/var/log/nginx"]'
|
||||
spec:
|
||||
volumes:
|
||||
- name: nginx-logs
|
||||
@@ -62,6 +70,14 @@ spec:
|
||||
- mountPath: "/var/log/nginx"
|
||||
name: nginx-logs
|
||||
readOnly: false
|
||||
- image: gcr.io/heptio-images/fsfreeze-pause:latest
|
||||
name: fsfreeze
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- mountPath: "/var/log/nginx"
|
||||
name: nginx-logs
|
||||
readOnly: false
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright YEAR the Heptio Ark contributors.
|
||||
Copyright the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2018 the Heptio Ark contributors.
|
||||
# Copyright 2018 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -12,10 +12,15 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM gcr.io/heptio-images/golang:1.9-alpine3.6
|
||||
FROM golang:1.12
|
||||
|
||||
RUN mkdir -p /go/src/k8s.io && \
|
||||
cd /go/src/k8s.io && \
|
||||
git clone -b kubernetes-1.9.0 https://github.com/kubernetes/code-generator && \
|
||||
git clone -b kubernetes-1.9.0 https://github.com/kubernetes/apimachinery && \
|
||||
git config --global advice.detachedHead false && \
|
||||
git clone -b kubernetes-1.14.0 https://github.com/kubernetes/code-generator && \
|
||||
git clone -b kubernetes-1.14.0 https://github.com/kubernetes/apimachinery && \
|
||||
go get golang.org/x/tools/cmd/goimports && \
|
||||
cd /go/src/golang.org/x/tools && \
|
||||
git checkout 40a48ad93fbe707101afb2099b738471f70594ec && \
|
||||
go install ./cmd/goimports && \
|
||||
echo chmod -R a+w /go
|
||||
|
||||
@@ -41,7 +41,7 @@ fi
|
||||
|
||||
export CGO_ENABLED=0
|
||||
|
||||
GIT_SHA=$(git describe --tags --always)
|
||||
GIT_SHA=$(git rev-parse HEAD)
|
||||
GIT_DIRTY=$(git status --porcelain 2> /dev/null)
|
||||
if [[ -z "${GIT_DIRTY}" ]]; then
|
||||
GIT_TREE_STATE=clean
|
||||
@@ -61,7 +61,7 @@ if [[ "${GOOS}" = "windows" ]]; then
|
||||
OUTPUT="${OUTPUT}.exe"
|
||||
fi
|
||||
|
||||
go build -i \
|
||||
go build \
|
||||
-o ${OUTPUT} \
|
||||
-installsuffix "static" \
|
||||
-ldflags "${LDFLAGS}" \
|
||||
|
||||
31
hack/changelog.sh
Executable file
31
hack/changelog.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
CHANGELOG_PATH='changelogs/unreleased'
|
||||
UNRELEASED=$(ls -t ${CHANGELOG_PATH})
|
||||
echo -e "Generating CHANGELOG markdown from ${CHANGELOG_PATH}\n"
|
||||
for entry in $UNRELEASED
|
||||
do
|
||||
IFS=$'-' read -ra pruser <<<"$entry"
|
||||
contents=$(cat ${CHANGELOG_PATH}/${entry})
|
||||
echo " * ${contents} (#${pruser[0]}, @${pruser[1]})"
|
||||
done
|
||||
echo -e "\nCopy and paste the list above in to the appropriate CHANGELOG file."
|
||||
echo "Be sure to run: git rm ${CHANGELOG_PATH}/*"
|
||||
17
hack/ci-check.sh
Executable file
17
hack/ci-check.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# If we're doing push build, as opposed to a PR, always run make ci
|
||||
if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
make ci
|
||||
# Exit script early, returning make ci's error
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# Only run `make ci` if files outside of the site directory changed in the branch
|
||||
# In a PR build, $TRAVIS_BRANCH is the destination branch.
|
||||
if [[ $(git diff --name-only $TRAVIS_BRANCH | grep --invert-match site/) ]]; then
|
||||
make ci
|
||||
else
|
||||
echo "Skipping make ci since nothing outside of site directory changed."
|
||||
exit 0
|
||||
fi
|
||||
108
hack/gen-docs.sh
Executable file
108
hack/gen-docs.sh
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# gen-docs.sh is used for the "make gen-docs" target. See additional
|
||||
# documentation in the Makefile.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
# don't run if there's already a directory for the target docs version
|
||||
if [[ -d site/docs/$NEW_DOCS_VERSION ]]; then
|
||||
echo "ERROR: site/docs/$NEW_DOCS_VERSION already exists"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# get the alphabetically last item in site/docs to use as PREVIOUS_DOCS_VERSION
|
||||
# if not explicitly specified by the user
|
||||
if [[ -z "${PREVIOUS_DOCS_VERSION:-}" ]]; then
|
||||
echo "PREVIOUS_DOCS_VERSION was not specified, getting the latest version"
|
||||
PREVIOUS_DOCS_VERSION=$(ls -1 site/docs/ | tail -n 1)
|
||||
fi
|
||||
|
||||
# make a copy of the previous versioned docs dir
|
||||
echo "Creating copy of docs directory site/docs/$PREVIOUS_DOCS_VERSION in site/docs/$NEW_DOCS_VERSION"
|
||||
cp -r site/docs/${PREVIOUS_DOCS_VERSION}/ site/docs/${NEW_DOCS_VERSION}/
|
||||
|
||||
# 'git add' the previous version's docs as-is so we get a useful diff when we copy the master docs in
|
||||
echo "Running 'git add' for previous version's doc contents to use as a base for diff"
|
||||
git add site/docs/${NEW_DOCS_VERSION}
|
||||
|
||||
# now copy the contents of site/docs/master into the same directory so we can get a nice
|
||||
# git diff of what changed since previous version
|
||||
echo "Copying site/docs/master/ to site/docs/${NEW_DOCS_VERSION}/"
|
||||
rm -rf site/docs/${NEW_DOCS_VERSION}/ && cp -r site/docs/master/ site/docs/${NEW_DOCS_VERSION}/
|
||||
|
||||
# make a copy of the previous versioned ToC
|
||||
NEW_DOCS_TOC="$(echo ${NEW_DOCS_VERSION} | tr . -)-toc"
|
||||
PREVIOUS_DOCS_TOC="$(echo ${PREVIOUS_DOCS_VERSION} | tr . -)-toc"
|
||||
|
||||
echo "Creating copy of site/_data/$PREVIOUS_DOCS_TOC.yml at site/_data/$NEW_DOCS_TOC.yml"
|
||||
cp site/_data/$PREVIOUS_DOCS_TOC.yml site/_data/$NEW_DOCS_TOC.yml
|
||||
|
||||
# 'git add' the previous version's ToC content as-is so we get a useful diff when we copy the master ToC in
|
||||
echo "Running 'git add' for previous version's ToC to use as a base for diff"
|
||||
git add site/_data/$NEW_DOCS_TOC.yml
|
||||
|
||||
# now copy the master ToC so we can get a nice git diff of what changed since previous version
|
||||
echo "Copying site/_data/master-toc.yml to site/_data/$NEW_DOCS_TOC.yml"
|
||||
rm site/_data/$NEW_DOCS_TOC.yml && cp site/_data/master-toc.yml site/_data/$NEW_DOCS_TOC.yml
|
||||
|
||||
# replace known version-specific links -- the sed syntax is slightly different in OS X and Linux,
|
||||
# so check which OS we're running on.
|
||||
if [[ $(uname) == "Darwin" ]]; then
|
||||
echo "[OS X] updating version-specific links"
|
||||
find site/docs/${NEW_DOCS_VERSION} -type f -name "*.md" | xargs sed -i '' "s|https://velero.io/docs/master|https://velero.io/docs/$NEW_DOCS_VERSION|g"
|
||||
find site/docs/${NEW_DOCS_VERSION} -type f -name "*.md" | xargs sed -i '' "s|https://github.com/heptio/velero/blob/master|https://github.com/heptio/velero/blob/$NEW_DOCS_VERSION|g"
|
||||
|
||||
echo "[OS X] Updating latest version in _config.yml"
|
||||
sed -i '' "s/latest: ${PREVIOUS_DOCS_VERSION}/latest: ${NEW_DOCS_VERSION}/" site/_config.yml
|
||||
|
||||
# newlines and lack of indentation are requirements for this sed syntax
|
||||
# which is doing an append
|
||||
echo "[OS X] Adding latest version to versions list in _config.yml"
|
||||
sed -i '' "/- master/a\\
|
||||
- ${NEW_DOCS_VERSION}
|
||||
" site/_config.yml
|
||||
|
||||
echo "[OS X] Adding ToC mapping entry"
|
||||
sed -i '' "/master: master-toc/a\\
|
||||
${NEW_DOCS_VERSION}: ${NEW_DOCS_TOC}
|
||||
" site/_data/toc-mapping.yml
|
||||
|
||||
else
|
||||
echo "[Linux] updating version-specific links"
|
||||
find site/docs/${NEW_DOCS_VERSION} -type f -name "*.md" | xargs sed -i'' "s|https://velero.io/docs/master|https://velero.io/docs/$NEW_DOCS_VERSION|g"
|
||||
find site/docs/${NEW_DOCS_VERSION} -type f -name "*.md" | xargs sed -i'' "s|https://github.com/heptio/velero/blob/master|https://github.com/heptio/velero/blob/$NEW_DOCS_VERSION|g"
|
||||
|
||||
echo "[Linux] Updating latest version in _config.yml"
|
||||
sed -i'' "s/latest: ${PREVIOUS_DOCS_VERSION}/latest: ${NEW_DOCS_VERSION}/" site/_config.yml
|
||||
|
||||
echo "[Linux] Adding latest version to versions list in _config.yml"
|
||||
sed -i'' "/- master/a - ${NEW_DOCS_VERSION}" site/_config.yml
|
||||
|
||||
echo "[Linux] Adding ToC mapping entry"
|
||||
sed -i'' "/master: master-toc/a ${NEW_DOCS_VERSION}: ${NEW_DOCS_TOC}" site/_data/toc-mapping.yml
|
||||
fi
|
||||
|
||||
echo "Success! site/docs/$NEW_DOCS_VERSION has been created."
|
||||
echo ""
|
||||
echo "The next steps are:"
|
||||
echo " 1. Consult site/README-JEKYLL.md for further manual steps required to finalize the new versioned docs generation."
|
||||
echo " 2. Run a 'git diff' to review all changes made to the docs since the previous version."
|
||||
echo " 3. Make any manual changes/corrections necessary."
|
||||
echo " 4. Run 'git add' to stage all unstaged changes, then 'git commit'."
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
50
hack/goreleaser.sh
Executable file
50
hack/goreleaser.sh
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2018 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
if [[ -z "${GITHUB_TOKEN}" ]]; then
|
||||
echo "GITHUB_TOKEN must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TODO derive this from the major+minor version
|
||||
if [ -z "${RELEASE_NOTES_FILE}" ]; then
|
||||
echo "RELEASE_NOTES_FILE must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GIT_DIRTY=$(git status --porcelain 2> /dev/null)
|
||||
if [[ -z "${GIT_DIRTY}" ]]; then
|
||||
export GIT_TREE_STATE=clean
|
||||
else
|
||||
export GIT_TREE_STATE=dirty
|
||||
fi
|
||||
|
||||
# $PUBLISH must explicitly be set to 'true' for goreleaser
|
||||
# to publish the release to GitHub.
|
||||
if [[ "${PUBLISH:-}" != "true" ]]; then
|
||||
goreleaser release \
|
||||
--rm-dist \
|
||||
--release-notes="${RELEASE_NOTES_FILE}" \
|
||||
--skip-publish
|
||||
else
|
||||
goreleaser release \
|
||||
--rm-dist \
|
||||
--release-notes="${RELEASE_NOTES_FILE}"
|
||||
fi
|
||||
45
hack/issue-template-gen/main.go
Normal file
45
hack/issue-template-gen/main.go
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This code renders the IssueTemplate string in pkg/cmd/cli/bug/bug.go to
|
||||
// .github/ISSUE_TEMPLATE/bug_report.md via the hack/update-generated-issue-template.sh script.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"text/template"
|
||||
|
||||
"github.com/heptio/velero/pkg/cmd/cli/bug"
|
||||
)
|
||||
|
||||
func main() {
|
||||
outTemplateFilename := os.Args[1]
|
||||
outFile, err := os.OpenFile(outTemplateFilename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer outFile.Close()
|
||||
tmpl, err := template.New("ghissue").Parse(bug.IssueTemplate)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = tmpl.Execute(outFile, bug.VeleroBugInfo{})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
19
hack/test.sh
19
hack/test.sh
@@ -20,9 +20,20 @@ set -o pipefail
|
||||
|
||||
export CGO_ENABLED=0
|
||||
|
||||
TARGETS=$(for d in "$@"; do echo ./$d/...; done)
|
||||
TARGETS=(
|
||||
./cmd/...
|
||||
./pkg/...
|
||||
)
|
||||
|
||||
echo "Running tests:"
|
||||
go test -i -installsuffix "static" ${TARGETS}
|
||||
go test -installsuffix "static" -timeout 60s ${TARGETS}
|
||||
if [[ ${#@} -ne 0 ]]; then
|
||||
TARGETS=("$@")
|
||||
fi
|
||||
|
||||
echo "Running tests:" "${TARGETS[@]}"
|
||||
|
||||
if [[ -n "${GOFLAGS:-}" ]]; then
|
||||
echo "GOFLAGS: ${GOFLAGS}"
|
||||
fi
|
||||
|
||||
go test -installsuffix "static" -timeout 60s "${TARGETS[@]}"
|
||||
echo "Success!"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -14,13 +14,54 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
HACK_DIR=$(dirname "${BASH_SOURCE}")
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
echo "Updating formatting"
|
||||
if [[ ${1:-} == '--verify' ]]; then
|
||||
# List file diffs that need formatting updates
|
||||
MODE='-d'
|
||||
ACTION='Verifying'
|
||||
else
|
||||
# Write formatting updates to files
|
||||
MODE='-w'
|
||||
ACTION='Updating'
|
||||
fi
|
||||
|
||||
gofmt -w -s $(find . -type f -name "*.go" -not -path "./vendor/*" -not -path "./pkg/generated/*" -not -name "zz_generated*")
|
||||
if ! command -v goimports > /dev/null; then
|
||||
echo 'goimports is missing - please run "go get golang.org/x/tools/cmd/goimports"'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command -v goimports > /dev/null || go get golang.org/x/tools/cmd/goimports
|
||||
goimports -w -d $(find . -type f -name "*.go" -not -path "./vendor/*" -not -path "./pkg/generated/*" -not -name "zz_generated*")
|
||||
files="$(find . -type f -name '*.go' -not -path './vendor/*' -not -path './site/*' -not -path './pkg/generated/*' -not -name 'zz_generated*')"
|
||||
echo "${ACTION} gofmt"
|
||||
for file in ${files}; do
|
||||
output=$(gofmt "${MODE}" -s "${file}")
|
||||
if [[ -n "${output}" ]]; then
|
||||
VERIFY_FMT_FAILED=1
|
||||
echo "${output}"
|
||||
fi
|
||||
done
|
||||
if [[ -n "${VERIFY_FMT_FAILED:-}" ]]; then
|
||||
echo "${ACTION} gofmt - failed! Please run 'make update'."
|
||||
else
|
||||
echo "${ACTION} gofmt - done!"
|
||||
fi
|
||||
|
||||
echo "Success!"
|
||||
echo "${ACTION} goimports"
|
||||
for file in ${files}; do
|
||||
output=$(goimports "${MODE}" -local github.com/heptio/velero "${file}")
|
||||
if [[ -n "${output}" ]]; then
|
||||
VERIFY_IMPORTS_FAILED=1
|
||||
echo "${output}"
|
||||
fi
|
||||
done
|
||||
if [[ -n "${VERIFY_IMPORTS_FAILED:-}" ]]; then
|
||||
echo "${ACTION} goimports - failed! Please run 'make update'."
|
||||
else
|
||||
echo "${ACTION} goimports - done!"
|
||||
fi
|
||||
|
||||
if [[ -n "${VERIFY_FMT_FAILED:-}" || -n "${VERIFY_IMPORTS_FAILED:-}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -32,8 +32,8 @@ cd ${GOPATH}/src/k8s.io/code-generator
|
||||
|
||||
./generate-groups.sh \
|
||||
all \
|
||||
github.com/heptio/ark/pkg/generated \
|
||||
github.com/heptio/ark/pkg/apis \
|
||||
ark:v1 \
|
||||
--go-header-file ${GOPATH}/src/github.com/heptio/ark/hack/boilerplate.go.txt \
|
||||
github.com/heptio/velero/pkg/generated \
|
||||
github.com/heptio/velero/pkg/apis \
|
||||
"velero:v1" \
|
||||
--go-header-file ${GOPATH}/src/github.com/heptio/velero/hack/boilerplate.go.txt \
|
||||
$@
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2018, 2019 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -14,24 +14,23 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARK_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
BIN=${ARK_ROOT}/_output/bin
|
||||
VELERO_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
BIN=${VELERO_ROOT}/_output/bin
|
||||
|
||||
mkdir -p ${BIN}
|
||||
|
||||
echo "Updating generated docs"
|
||||
|
||||
go build -o ${BIN}/docs-gen ./docs/generate/ark.go
|
||||
echo "Updating generated Github issue template"
|
||||
go build -o ${BIN}/issue-tmpl-gen ./hack/issue-template-gen/main.go
|
||||
|
||||
if [[ $# -gt 1 ]]; then
|
||||
echo "usage: ${BASH_SOURCE} [DIRECTORY]"
|
||||
echo "usage: ${BASH_SOURCE} [OUTPUT_FILE]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTPUT_DIR="$@"
|
||||
if [[ -z "${OUTPUT_DIR}" ]]; then
|
||||
OUTPUT_DIR=${ARK_ROOT}/docs/cli-reference
|
||||
OUTPUT_ISSUE_FILE="$1"
|
||||
if [[ -z "${OUTPUT_ISSUE_FILE}" ]]; then
|
||||
OUTPUT_ISSUE_FILE=${VELERO_ROOT}/.github/ISSUE_TEMPLATE/bug_report.md
|
||||
fi
|
||||
|
||||
${BIN}/docs-gen ark ${OUTPUT_DIR}
|
||||
|
||||
${BIN}/issue-tmpl-gen ${OUTPUT_ISSUE_FILE}
|
||||
echo "Success!"
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -14,19 +14,5 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
HACK_DIR=$(dirname "${BASH_SOURCE}")
|
||||
|
||||
echo "Verifying gofmt"
|
||||
files=$(gofmt -l -s $(find . -type f -name "*.go" -not -path "./vendor/*" -not -path "./pkg/generated/*" -not -name "zz_generated*"))
|
||||
if [[ -n "${files}" ]]; then
|
||||
echo "The following files need gofmt updating - please run 'make update'"
|
||||
echo "${files}"
|
||||
exit 1
|
||||
fi
|
||||
echo "Success!"
|
||||
|
||||
echo "Verifying goimports"
|
||||
command -v goimports > /dev/null || go get golang.org/x/tools/cmd/goimports
|
||||
goimports -l $(find . -type f -name "*.go" -not -path "./vendor/*" -not -path "./pkg/generated/*" -not -name "zz_generated*")
|
||||
echo "Success!"
|
||||
|
||||
HACK_DIR=$(dirname "${BASH_SOURCE[0]}")
|
||||
"${HACK_DIR}"/update-fmt.sh --verify
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2017 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash -e
|
||||
#
|
||||
# Copyright 2017 the Heptio Ark contributors.
|
||||
# Copyright 2018 the Velero contributors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -14,10 +14,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
ARK_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
VELERO_ROOT=$(dirname ${BASH_SOURCE})/..
|
||||
HACK_DIR=$(dirname "${BASH_SOURCE}")
|
||||
DOCS_DIR=${ARK_ROOT}/docs/cli-reference
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
ISSUE_TEMPLATE_FILE=${VELERO_ROOT}/.github/ISSUE_TEMPLATE/bug_report.md
|
||||
OUT_TMP_FILE="$(mktemp -d)"/bug_report.md
|
||||
|
||||
|
||||
trap cleanup INT TERM HUP EXIT
|
||||
|
||||
@@ -25,15 +26,12 @@ cleanup() {
|
||||
rm -rf ${TMP_DIR}
|
||||
}
|
||||
|
||||
echo "Verifying generated docs"
|
||||
|
||||
${HACK_DIR}/update-generated-docs.sh ${TMP_DIR} > /dev/null
|
||||
|
||||
exclude_file="README.md"
|
||||
output=$(echo "`diff -r ${DOCS_DIR} ${TMP_DIR}`" | sed "/${exclude_file}/d")
|
||||
echo "Verifying generated Github issue template"
|
||||
${HACK_DIR}/update-generated-issue-template.sh ${OUT_TMP_FILE} > /dev/null
|
||||
output=$(echo "`diff ${ISSUE_TEMPLATE_FILE} ${OUT_TMP_FILE}`")
|
||||
|
||||
if [[ -n "${output}" ]] ; then
|
||||
echo "FAILURE: verification of docs failed:"
|
||||
echo "FAILURE: verification of generated template failed:"
|
||||
echo "${output}"
|
||||
exit 1
|
||||
fi
|
||||
4
netlify.toml
Normal file
4
netlify.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[build]
|
||||
base = "site/"
|
||||
command = "jekyll build"
|
||||
publish = "site/_site"
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ConfigList is a list of Configs.
|
||||
type ConfigList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
|
||||
Items []Config `json:"items"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Config is an Ark resource that captures configuration information to be
|
||||
// used for running the Ark server.
|
||||
type Config struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
// PersistentVolumeProvider is the configuration information for the cloud where
|
||||
// the cluster is running and has PersistentVolumes to snapshot or restore. Optional.
|
||||
PersistentVolumeProvider *CloudProviderConfig `json:"persistentVolumeProvider"`
|
||||
|
||||
// BackupStorageProvider is the configuration information for the cloud where
|
||||
// Ark backups are stored in object storage. This may be a different cloud than
|
||||
// where the cluster is running.
|
||||
BackupStorageProvider ObjectStorageProviderConfig `json:"backupStorageProvider"`
|
||||
|
||||
// BackupSyncPeriod is how often the BackupSyncController runs to ensure all
|
||||
// Ark backups in object storage exist as Backup API objects in the cluster.
|
||||
BackupSyncPeriod metav1.Duration `json:"backupSyncPeriod"`
|
||||
|
||||
// GCSyncPeriod is how often the GCController runs to delete expired backup
|
||||
// API objects and corresponding backup files in object storage.
|
||||
GCSyncPeriod metav1.Duration `json:"gcSyncPeriod"`
|
||||
|
||||
// ScheduleSyncPeriod is how often the ScheduleController runs to check for
|
||||
// new backups that should be triggered based on schedules.
|
||||
ScheduleSyncPeriod metav1.Duration `json:"scheduleSyncPeriod"`
|
||||
|
||||
// ResourcePriorities is an ordered slice of resources specifying the desired
|
||||
// order of resource restores. Any resources not in the list will be restored
|
||||
// alphabetically after the prioritized resources.
|
||||
ResourcePriorities []string `json:"resourcePriorities"`
|
||||
|
||||
// RestoreOnlyMode is whether Ark should run in a mode where only restores
|
||||
// are allowed; backups, schedules, and garbage-collection are all disabled.
|
||||
RestoreOnlyMode bool `json:"restoreOnlyMode"`
|
||||
}
|
||||
|
||||
// CloudProviderConfig is configuration information about how to connect
|
||||
// to a particular cloud.
|
||||
type CloudProviderConfig struct {
|
||||
Name string `json:"name"`
|
||||
|
||||
Config map[string]string `json:"config"`
|
||||
}
|
||||
|
||||
// ObjectStorageProviderConfig is configuration information for connecting to
|
||||
// a particular bucket in object storage to access Ark backups.
|
||||
type ObjectStorageProviderConfig struct {
|
||||
// CloudProviderConfig is the configuration information for the cloud where
|
||||
// Ark backups are stored in object storage.
|
||||
CloudProviderConfig `json:",inline"`
|
||||
|
||||
// Bucket is the name of the bucket in object storage where Ark backups
|
||||
// are stored.
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017, 2019 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -16,9 +16,11 @@ limitations under the License.
|
||||
|
||||
package v1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// BackupSpec defines the specification for an Ark backup.
|
||||
// BackupSpec defines the specification for a Velero backup.
|
||||
type BackupSpec struct {
|
||||
// IncludedNamespaces is a slice of namespace names to include objects
|
||||
// from. If empty, all namespaces are included.
|
||||
@@ -44,7 +46,7 @@ type BackupSpec struct {
|
||||
// SnapshotVolumes specifies whether to take cloud snapshots
|
||||
// of any PV's referenced in the set of objects included
|
||||
// in the Backup.
|
||||
SnapshotVolumes *bool `json:"snapshotVolumes"`
|
||||
SnapshotVolumes *bool `json:"snapshotVolumes,omitempty"`
|
||||
|
||||
// TTL is a time.Duration-parseable string describing how long
|
||||
// the Backup should be retained for.
|
||||
@@ -56,6 +58,12 @@ type BackupSpec struct {
|
||||
|
||||
// Hooks represent custom behaviors that should be executed at different phases of the backup.
|
||||
Hooks BackupHooks `json:"hooks"`
|
||||
|
||||
// StorageLocation is a string containing the name of a BackupStorageLocation where the backup should be stored.
|
||||
StorageLocation string `json:"storageLocation"`
|
||||
|
||||
// VolumeSnapshotLocations is a list containing names of VolumeSnapshotLocations associated with this backup.
|
||||
VolumeSnapshotLocations []string `json:"volumeSnapshotLocations"`
|
||||
}
|
||||
|
||||
// BackupHooks contains custom behaviors that should be executed at different phases of the backup.
|
||||
@@ -80,9 +88,7 @@ type BackupResourceHookSpec struct {
|
||||
// ExcludedResources specifies the resources to which this hook spec does not apply.
|
||||
ExcludedResources []string `json:"excludedResources"`
|
||||
// LabelSelector, if specified, filters the resources to which this hook spec applies.
|
||||
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||
// Hooks is a list of BackupResourceHooks to execute. DEPRECATED. Replaced by PreHooks.
|
||||
Hooks []BackupResourceHook `json:"hooks"`
|
||||
LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"`
|
||||
// PreHooks is a list of BackupResourceHooks to execute prior to storing the item in the backup.
|
||||
// These are executed before any "additional items" from item actions are processed.
|
||||
PreHooks []BackupResourceHook `json:"pre,omitempty"`
|
||||
@@ -104,14 +110,14 @@ type ExecHook struct {
|
||||
Container string `json:"container"`
|
||||
// Command is the command and arguments to execute.
|
||||
Command []string `json:"command"`
|
||||
// OnError specifies how Ark should behave if it encounters an error executing this hook.
|
||||
// OnError specifies how Velero should behave if it encounters an error executing this hook.
|
||||
OnError HookErrorMode `json:"onError"`
|
||||
// Timeout defines the maximum amount of time Ark should wait for the hook to complete before
|
||||
// Timeout defines the maximum amount of time Velero should wait for the hook to complete before
|
||||
// considering the execution a failure.
|
||||
Timeout metav1.Duration `json:"timeout"`
|
||||
}
|
||||
|
||||
// HookErrorMode defines how Ark should treat an error from a hook.
|
||||
// HookErrorMode defines how Velero should treat an error from a hook.
|
||||
type HookErrorMode string
|
||||
|
||||
const (
|
||||
@@ -124,7 +130,7 @@ const (
|
||||
)
|
||||
|
||||
// BackupPhase is a string representation of the lifecycle phase
|
||||
// of an Ark backup.
|
||||
// of a Velero backup.
|
||||
type BackupPhase string
|
||||
|
||||
const (
|
||||
@@ -143,6 +149,10 @@ const (
|
||||
// errors.
|
||||
BackupPhaseCompleted BackupPhase = "Completed"
|
||||
|
||||
// BackupPhasePartiallyFailed means the backup has run to completion
|
||||
// but encountered 1+ errors backing up individual items.
|
||||
BackupPhasePartiallyFailed BackupPhase = "PartiallyFailed"
|
||||
|
||||
// BackupPhaseFailed means the backup ran but encountered an error that
|
||||
// prevented it from completing successfully.
|
||||
BackupPhaseFailed BackupPhase = "Failed"
|
||||
@@ -151,7 +161,7 @@ const (
|
||||
BackupPhaseDeleting BackupPhase = "Deleting"
|
||||
)
|
||||
|
||||
// BackupStatus captures the current status of an Ark backup.
|
||||
// BackupStatus captures the current status of a Velero backup.
|
||||
type BackupStatus struct {
|
||||
// Version is the backup format version.
|
||||
Version int `json:"version"`
|
||||
@@ -162,41 +172,45 @@ type BackupStatus struct {
|
||||
// Phase is the current state of the Backup.
|
||||
Phase BackupPhase `json:"phase"`
|
||||
|
||||
// VolumeBackups is a map of PersistentVolume names to
|
||||
// information about the backed-up volume in the cloud
|
||||
// provider API.
|
||||
VolumeBackups map[string]*VolumeBackupInfo `json:"volumeBackups"`
|
||||
|
||||
// ValidationErrors is a slice of all validation errors (if
|
||||
// applicable).
|
||||
ValidationErrors []string `json:"validationErrors"`
|
||||
}
|
||||
|
||||
// VolumeBackupInfo captures the required information about
|
||||
// a PersistentVolume at backup time to be able to restore
|
||||
// it later.
|
||||
type VolumeBackupInfo struct {
|
||||
// SnapshotID is the ID of the snapshot taken in the cloud
|
||||
// provider API of this volume.
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
// StartTimestamp records the time a backup was started.
|
||||
// Separate from CreationTimestamp, since that value changes
|
||||
// on restores.
|
||||
// The server's time is used for StartTimestamps
|
||||
StartTimestamp metav1.Time `json:"startTimestamp"`
|
||||
|
||||
// Type is the type of the disk/volume in the cloud provider
|
||||
// API.
|
||||
Type string `json:"type"`
|
||||
// CompletionTimestamp records the time a backup was completed.
|
||||
// Completion time is recorded even on failed backups.
|
||||
// Completion time is recorded before uploading the backup object.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
CompletionTimestamp metav1.Time `json:"completionTimestamp"`
|
||||
|
||||
// AvailabilityZone is the where the volume is provisioned
|
||||
// in the cloud provider.
|
||||
AvailabilityZone string `json:"availabilityZone,omitempty"`
|
||||
// VolumeSnapshotsAttempted is the total number of attempted
|
||||
// volume snapshots for this backup.
|
||||
VolumeSnapshotsAttempted int `json:"volumeSnapshotsAttempted"`
|
||||
|
||||
// Iops is the optional value of provisioned IOPS for the
|
||||
// disk/volume in the cloud provider API.
|
||||
Iops *int64 `json:"iops,omitempty"`
|
||||
// VolumeSnapshotsCompleted is the total number of successfully
|
||||
// completed volume snapshots for this backup.
|
||||
VolumeSnapshotsCompleted int `json:"volumeSnapshotsCompleted"`
|
||||
|
||||
// Warnings is a count of all warning messages that were generated during
|
||||
// execution of the backup. The actual warnings are in the backup's log
|
||||
// file in object storage.
|
||||
Warnings int `json:"warnings"`
|
||||
|
||||
// Errors is a count of all error messages that were generated during
|
||||
// execution of the backup. The actual errors are in the backup's log
|
||||
// file in object storage.
|
||||
Errors int `json:"errors"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Backup is an Ark resource that respresents the capture of Kubernetes
|
||||
// Backup is a Velero resource that respresents the capture of Kubernetes
|
||||
// cluster state at a point in time (API objects and associated volume state).
|
||||
type Backup struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
109
pkg/apis/velero/v1/backup_storage_location.go
Normal file
109
pkg/apis/velero/v1/backup_storage_location.go
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// BackupStorageLocation is a location where Velero stores backup objects.
|
||||
type BackupStorageLocation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
Spec BackupStorageLocationSpec `json:"spec"`
|
||||
Status BackupStorageLocationStatus `json:"status"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// BackupStorageLocationList is a list of BackupStorageLocations.
|
||||
type BackupStorageLocationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []BackupStorageLocation `json:"items"`
|
||||
}
|
||||
|
||||
// StorageType represents the type of storage that a backup location uses.
|
||||
// ObjectStorage must be non-nil, since it is currently the only supported StorageType.
|
||||
type StorageType struct {
|
||||
ObjectStorage *ObjectStorageLocation `json:"objectStorage,omitempty"`
|
||||
}
|
||||
|
||||
// ObjectStorageLocation specifies the settings necessary to connect to a provider's object storage.
|
||||
type ObjectStorageLocation struct {
|
||||
// Bucket is the bucket to use for object storage.
|
||||
Bucket string `json:"bucket"`
|
||||
|
||||
// Prefix is the path inside a bucket to use for Velero storage. Optional.
|
||||
Prefix string `json:"prefix"`
|
||||
}
|
||||
|
||||
// BackupStorageLocationSpec defines the specification for a Velero BackupStorageLocation.
|
||||
type BackupStorageLocationSpec struct {
|
||||
// Provider is the provider of the backup storage.
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// Config is for provider-specific configuration fields.
|
||||
Config map[string]string `json:"config"`
|
||||
|
||||
StorageType `json:",inline"`
|
||||
|
||||
// AccessMode defines the permissions for the backup storage location.
|
||||
AccessMode BackupStorageLocationAccessMode `json:"accessMode,omitempty"`
|
||||
}
|
||||
|
||||
// BackupStorageLocationPhase is the lifecyle phase of a Velero BackupStorageLocation.
|
||||
type BackupStorageLocationPhase string
|
||||
|
||||
const (
|
||||
// BackupStorageLocationPhaseAvailable means the location is available to read and write from.
|
||||
BackupStorageLocationPhaseAvailable BackupStorageLocationPhase = "Available"
|
||||
|
||||
// BackupStorageLocationPhaseUnavailable means the location is unavailable to read and write from.
|
||||
BackupStorageLocationPhaseUnavailable BackupStorageLocationPhase = "Unavailable"
|
||||
)
|
||||
|
||||
// BackupStorageLocationAccessMode represents the permissions for a BackupStorageLocation.
|
||||
type BackupStorageLocationAccessMode string
|
||||
|
||||
const (
|
||||
// BackupStorageLocationAccessModeReadOnly represents read-only access to a BackupStorageLocation.
|
||||
BackupStorageLocationAccessModeReadOnly BackupStorageLocationAccessMode = "ReadOnly"
|
||||
|
||||
// BackupStorageLocationAccessModeReadWrite represents read and write access to a BackupStorageLocation.
|
||||
BackupStorageLocationAccessModeReadWrite BackupStorageLocationAccessMode = "ReadWrite"
|
||||
)
|
||||
|
||||
// TODO(2.0): remove the AccessMode field from BackupStorageLocationStatus.
|
||||
|
||||
// BackupStorageLocationStatus describes the current status of a Velero BackupStorageLocation.
|
||||
type BackupStorageLocationStatus struct {
|
||||
Phase BackupStorageLocationPhase `json:"phase,omitempty"`
|
||||
LastSyncedRevision types.UID `json:"lastSyncedRevision,omitempty"`
|
||||
LastSyncedTime metav1.Time `json:"lastSyncedTime,omitempty"`
|
||||
|
||||
// AccessMode is an unused field.
|
||||
//
|
||||
// Deprecated: there is now an AccessMode field on the Spec and this field
|
||||
// will be removed entirely as of v2.0.
|
||||
AccessMode BackupStorageLocationAccessMode `json:"accessMode,omitempty"`
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,23 +18,22 @@ package v1
|
||||
|
||||
const (
|
||||
// DefaultNamespace is the Kubernetes namespace that is used by default for
|
||||
// the Ark server and API objects.
|
||||
DefaultNamespace = "heptio-ark"
|
||||
// the Velero server and API objects.
|
||||
DefaultNamespace = "velero"
|
||||
|
||||
// ResourcesDir is a top-level directory expected in backups which contains sub-directories
|
||||
// for each resource type in the backup.
|
||||
ResourcesDir = "resources"
|
||||
|
||||
// RestoreLabelKey is the label key that's applied to all resources that
|
||||
// are created during a restore. This is applied for ease of identification
|
||||
// of restored resources. The value will be the restore's name.
|
||||
RestoreLabelKey = "ark-restore"
|
||||
// MetadataDir is a top-level directory expected in backups which contains
|
||||
// files that store metadata about the backup, such as the backup version.
|
||||
MetadataDir = "metadata"
|
||||
|
||||
// ClusterScopedDir is the name of the directory containing cluster-scoped
|
||||
// resources within an Ark backup.
|
||||
// resources within a Velero backup.
|
||||
ClusterScopedDir = "cluster"
|
||||
|
||||
// NamespaceScopedDir is the name of the directory containing namespace-scoped
|
||||
// resource within an Ark backup.
|
||||
// resource within a Velero backup.
|
||||
NamespaceScopedDir = "namespaces"
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 the Heptio Ark contributors.
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -33,11 +33,6 @@ const (
|
||||
DeleteBackupRequestPhaseInProgress DeleteBackupRequestPhase = "InProgress"
|
||||
// DeleteBackupRequestPhaseProcessed means the DeleteBackupRequest has been processed.
|
||||
DeleteBackupRequestPhaseProcessed DeleteBackupRequestPhase = "Processed"
|
||||
|
||||
// BackupNameLabel is the label key used by a DeleteBackupRequest to identify its backup by name.
|
||||
BackupNameLabel = "ark.heptio.com/backup-name"
|
||||
// BackupUIDLabel is the label key used by a DeleteBackupRequest to identify its backup by uid.
|
||||
BackupUIDLabel = "ark.heptio.com/backup-uid"
|
||||
)
|
||||
|
||||
// DeleteBackupRequestStatus is the current status of a DeleteBackupRequest.
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,5 +17,5 @@ limitations under the License.
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package v1 is the v1 version of the API.
|
||||
// +groupName=ark.heptio.com
|
||||
// +groupName=velero.io
|
||||
package v1
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -28,10 +28,12 @@ type DownloadRequestSpec struct {
|
||||
type DownloadTargetKind string
|
||||
|
||||
const (
|
||||
DownloadTargetKindBackupLog DownloadTargetKind = "BackupLog"
|
||||
DownloadTargetKindBackupContents DownloadTargetKind = "BackupContents"
|
||||
DownloadTargetKindRestoreLog DownloadTargetKind = "RestoreLog"
|
||||
DownloadTargetKindRestoreResults DownloadTargetKind = "RestoreResults"
|
||||
DownloadTargetKindBackupLog DownloadTargetKind = "BackupLog"
|
||||
DownloadTargetKindBackupContents DownloadTargetKind = "BackupContents"
|
||||
DownloadTargetKindBackupVolumeSnapshots DownloadTargetKind = "BackupVolumeSnapshots"
|
||||
DownloadTargetKindBackupResourceList DownloadTargetKind = "BackupResourceList"
|
||||
DownloadTargetKindRestoreLog DownloadTargetKind = "RestoreLog"
|
||||
DownloadTargetKindRestoreResults DownloadTargetKind = "RestoreResults"
|
||||
)
|
||||
|
||||
// DownloadTarget is the specification for what kind of file to download, and the name of the
|
||||
50
pkg/apis/velero/v1/labels_annotations.go
Normal file
50
pkg/apis/velero/v1/labels_annotations.go
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
const (
|
||||
// BackupNameLabel is the label key used to identify a backup by name.
|
||||
BackupNameLabel = "velero.io/backup-name"
|
||||
|
||||
// BackupUIDLabel is the label key used to identify a backup by uid.
|
||||
BackupUIDLabel = "velero.io/backup-uid"
|
||||
|
||||
// RestoreNameLabel is the label key used to identify a restore by name.
|
||||
RestoreNameLabel = "velero.io/restore-name"
|
||||
|
||||
// ScheduleNameLabel is the label key used to identify a schedule by name.
|
||||
ScheduleNameLabel = "velero.io/schedule-name"
|
||||
|
||||
// RestoreUIDLabel is the label key used to identify a restore by uid.
|
||||
RestoreUIDLabel = "velero.io/restore-uid"
|
||||
|
||||
// PodUIDLabel is the label key used to identify a pod by uid.
|
||||
PodUIDLabel = "velero.io/pod-uid"
|
||||
|
||||
// PodVolumeOperationTimeoutAnnotation is the annotation key used to apply
|
||||
// a backup/restore-specific timeout value for pod volume operations (i.e.
|
||||
// restic backups/restores).
|
||||
PodVolumeOperationTimeoutAnnotation = "velero.io/pod-volume-timeout"
|
||||
|
||||
// StorageLocationLabel is the label key used to identify the storage
|
||||
// location of a backup.
|
||||
StorageLocationLabel = "velero.io/storage-location"
|
||||
|
||||
// ResticVolumeNamespaceLabel is the label key used to identify which
|
||||
// namespace a restic repository stores pod volume backups for.
|
||||
ResticVolumeNamespaceLabel = "velero.io/volume-namespace"
|
||||
)
|
||||
103
pkg/apis/velero/v1/pod_volume_backup.go
Normal file
103
pkg/apis/velero/v1/pod_volume_backup.go
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// PodVolumeBackupSpec is the specification for a PodVolumeBackup.
|
||||
type PodVolumeBackupSpec struct {
|
||||
// Node is the name of the node that the Pod is running on.
|
||||
Node string `json:"node"`
|
||||
|
||||
// Pod is a reference to the pod containing the volume to be backed up.
|
||||
Pod corev1api.ObjectReference `json:"pod"`
|
||||
|
||||
// Volume is the name of the volume within the Pod to be backed
|
||||
// up.
|
||||
Volume string `json:"volume"`
|
||||
|
||||
// BackupStorageLocation is the name of the backup storage location
|
||||
// where the restic repository is stored.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// RepoIdentifier is the restic repository identifier.
|
||||
RepoIdentifier string `json:"repoIdentifier"`
|
||||
|
||||
// Tags are a map of key-value pairs that should be applied to the
|
||||
// volume backup as tags.
|
||||
Tags map[string]string `json:"tags"`
|
||||
}
|
||||
|
||||
// PodVolumeBackupPhase represents the lifecycle phase of a PodVolumeBackup.
|
||||
type PodVolumeBackupPhase string
|
||||
|
||||
const (
|
||||
PodVolumeBackupPhaseNew PodVolumeBackupPhase = "New"
|
||||
PodVolumeBackupPhaseInProgress PodVolumeBackupPhase = "InProgress"
|
||||
PodVolumeBackupPhaseCompleted PodVolumeBackupPhase = "Completed"
|
||||
PodVolumeBackupPhaseFailed PodVolumeBackupPhase = "Failed"
|
||||
)
|
||||
|
||||
// PodVolumeBackupStatus is the current status of a PodVolumeBackup.
|
||||
type PodVolumeBackupStatus struct {
|
||||
// Phase is the current state of the PodVolumeBackup.
|
||||
Phase PodVolumeBackupPhase `json:"phase"`
|
||||
|
||||
// Path is the full path within the controller pod being backed up.
|
||||
Path string `json:"path"`
|
||||
|
||||
// SnapshotID is the identifier for the snapshot of the pod volume.
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
|
||||
// Message is a message about the pod volume backup's status.
|
||||
Message string `json:"message"`
|
||||
|
||||
// StartTimestamp records the time a backup was started.
|
||||
// Separate from CreationTimestamp, since that value changes
|
||||
// on restores.
|
||||
// The server's time is used for StartTimestamps
|
||||
StartTimestamp metav1.Time `json:"startTimestamp"`
|
||||
|
||||
// CompletionTimestamp records the time a backup was completed.
|
||||
// Completion time is recorded even on failed backups.
|
||||
// Completion time is recorded before uploading the backup object.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
CompletionTimestamp metav1.Time `json:"completionTimestamp"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type PodVolumeBackup struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
Spec PodVolumeBackupSpec `json:"spec"`
|
||||
Status PodVolumeBackupStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PodVolumeBackupList is a list of PodVolumeBackups.
|
||||
type PodVolumeBackupList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []PodVolumeBackup `json:"items"`
|
||||
}
|
||||
89
pkg/apis/velero/v1/pod_volume_restore.go
Normal file
89
pkg/apis/velero/v1/pod_volume_restore.go
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// PodVolumeRestoreSpec is the specification for a PodVolumeRestore.
|
||||
type PodVolumeRestoreSpec struct {
|
||||
// Pod is a reference to the pod containing the volume to be restored.
|
||||
Pod corev1api.ObjectReference `json:"pod"`
|
||||
|
||||
// Volume is the name of the volume within the Pod to be restored.
|
||||
Volume string `json:"volume"`
|
||||
|
||||
// BackupStorageLocation is the name of the backup storage location
|
||||
// where the restic repository is stored.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// RepoIdentifier is the restic repository identifier.
|
||||
RepoIdentifier string `json:"repoIdentifier"`
|
||||
|
||||
// SnapshotID is the ID of the volume snapshot to be restored.
|
||||
SnapshotID string `json:"snapshotID"`
|
||||
}
|
||||
|
||||
// PodVolumeRestorePhase represents the lifecycle phase of a PodVolumeRestore.
|
||||
type PodVolumeRestorePhase string
|
||||
|
||||
const (
|
||||
PodVolumeRestorePhaseNew PodVolumeRestorePhase = "New"
|
||||
PodVolumeRestorePhaseInProgress PodVolumeRestorePhase = "InProgress"
|
||||
PodVolumeRestorePhaseCompleted PodVolumeRestorePhase = "Completed"
|
||||
PodVolumeRestorePhaseFailed PodVolumeRestorePhase = "Failed"
|
||||
)
|
||||
|
||||
// PodVolumeRestoreStatus is the current status of a PodVolumeRestore.
|
||||
type PodVolumeRestoreStatus struct {
|
||||
// Phase is the current state of the PodVolumeRestore.
|
||||
Phase PodVolumeRestorePhase `json:"phase"`
|
||||
|
||||
// Message is a message about the pod volume restore's status.
|
||||
Message string `json:"message"`
|
||||
|
||||
// StartTimestamp records the time a restore was started.
|
||||
// The server's time is used for StartTimestamps
|
||||
StartTimestamp metav1.Time `json:"startTimestamp"`
|
||||
|
||||
// CompletionTimestamp records the time a restore was completed.
|
||||
// Completion time is recorded even on failed restores.
|
||||
// The server's time is used for CompletionTimestamps
|
||||
CompletionTimestamp metav1.Time `json:"completionTimestamp"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type PodVolumeRestore struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
Spec PodVolumeRestoreSpec `json:"spec"`
|
||||
Status PodVolumeRestoreStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// PodVolumeRestoreList is a list of PodVolumeRestores.
|
||||
type PodVolumeRestoreList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []PodVolumeRestore `json:"items"`
|
||||
}
|
||||
83
pkg/apis/velero/v1/register.go
Normal file
83
pkg/apis/velero/v1/register.go
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
var (
|
||||
// SchemeBuilder collects the scheme builder functions for the Velero API
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
|
||||
// AddToScheme applies the SchemeBuilder functions to a specified scheme
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// GroupName is the group name for the Velero API
|
||||
const GroupName = "velero.io"
|
||||
|
||||
// SchemeGroupVersion is the GroupVersion for the Velero API
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"}
|
||||
|
||||
// Resource gets a Velero GroupResource for a specified resource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
type typeInfo struct {
|
||||
PluralName string
|
||||
ItemType runtime.Object
|
||||
ItemListType runtime.Object
|
||||
}
|
||||
|
||||
func newTypeInfo(pluralName string, itemType, itemListType runtime.Object) typeInfo {
|
||||
return typeInfo{
|
||||
PluralName: pluralName,
|
||||
ItemType: itemType,
|
||||
ItemListType: itemListType,
|
||||
}
|
||||
}
|
||||
|
||||
// CustomResources returns a map of all custom resources within the Velero
|
||||
// API group, keyed on Kind.
|
||||
func CustomResources() map[string]typeInfo {
|
||||
return map[string]typeInfo{
|
||||
"Backup": newTypeInfo("backups", &Backup{}, &BackupList{}),
|
||||
"Restore": newTypeInfo("restores", &Restore{}, &RestoreList{}),
|
||||
"Schedule": newTypeInfo("schedules", &Schedule{}, &ScheduleList{}),
|
||||
"DownloadRequest": newTypeInfo("downloadrequests", &DownloadRequest{}, &DownloadRequestList{}),
|
||||
"DeleteBackupRequest": newTypeInfo("deletebackuprequests", &DeleteBackupRequest{}, &DeleteBackupRequestList{}),
|
||||
"PodVolumeBackup": newTypeInfo("podvolumebackups", &PodVolumeBackup{}, &PodVolumeBackupList{}),
|
||||
"PodVolumeRestore": newTypeInfo("podvolumerestores", &PodVolumeRestore{}, &PodVolumeRestoreList{}),
|
||||
"ResticRepository": newTypeInfo("resticrepositories", &ResticRepository{}, &ResticRepositoryList{}),
|
||||
"BackupStorageLocation": newTypeInfo("backupstoragelocations", &BackupStorageLocation{}, &BackupStorageLocationList{}),
|
||||
"VolumeSnapshotLocation": newTypeInfo("volumesnapshotlocations", &VolumeSnapshotLocation{}, &VolumeSnapshotLocationList{}),
|
||||
"ServerStatusRequest": newTypeInfo("serverstatusrequests", &ServerStatusRequest{}, &ServerStatusRequestList{}),
|
||||
}
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
for _, typeInfo := range CustomResources() {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion, typeInfo.ItemType, typeInfo.ItemListType)
|
||||
}
|
||||
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
80
pkg/apis/velero/v1/restic_repository.go
Normal file
80
pkg/apis/velero/v1/restic_repository.go
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ResticRepositorySpec is the specification for a ResticRepository.
|
||||
type ResticRepositorySpec struct {
|
||||
// VolumeNamespace is the namespace this restic repository contains
|
||||
// pod volume backups for.
|
||||
VolumeNamespace string `json:"volumeNamespace"`
|
||||
|
||||
// BackupStorageLocation is the name of the BackupStorageLocation
|
||||
// that should contain this repository.
|
||||
BackupStorageLocation string `json:"backupStorageLocation"`
|
||||
|
||||
// ResticIdentifier is the full restic-compatible string for identifying
|
||||
// this repository.
|
||||
ResticIdentifier string `json:"resticIdentifier"`
|
||||
|
||||
// MaintenanceFrequency is how often maintenance should be run.
|
||||
MaintenanceFrequency metav1.Duration `json:"maintenanceFrequency"`
|
||||
}
|
||||
|
||||
// ResticRepositoryPhase represents the lifecycle phase of a ResticRepository.
|
||||
type ResticRepositoryPhase string
|
||||
|
||||
const (
|
||||
ResticRepositoryPhaseNew ResticRepositoryPhase = "New"
|
||||
ResticRepositoryPhaseReady ResticRepositoryPhase = "Ready"
|
||||
ResticRepositoryPhaseNotReady ResticRepositoryPhase = "NotReady"
|
||||
)
|
||||
|
||||
// ResticRepositoryStatus is the current status of a ResticRepository.
|
||||
type ResticRepositoryStatus struct {
|
||||
// Phase is the current state of the ResticRepository.
|
||||
Phase ResticRepositoryPhase `json:"phase"`
|
||||
|
||||
// Message is a message about the current status of the ResticRepository.
|
||||
Message string `json:"message"`
|
||||
|
||||
// LastMaintenanceTime is the last time maintenance was run.
|
||||
LastMaintenanceTime metav1.Time `json:"lastMaintenanceTime"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
type ResticRepository struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
Spec ResticRepositorySpec `json:"spec"`
|
||||
Status ResticRepositoryStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ResticRepositoryList is a list of ResticRepositories.
|
||||
type ResticRepositoryList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []ResticRepository `json:"items"`
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017, 2019 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,12 +18,17 @@ package v1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// RestoreSpec defines the specification for an Ark restore.
|
||||
// RestoreSpec defines the specification for a Velero restore.
|
||||
type RestoreSpec struct {
|
||||
// BackupName is the unique name of the Ark backup to restore
|
||||
// BackupName is the unique name of the Velero backup to restore
|
||||
// from.
|
||||
BackupName string `json:"backupName"`
|
||||
|
||||
// ScheduleName is the unique name of the Velero schedule to restore
|
||||
// from. If specified, and BackupName is empty, Velero will restore
|
||||
// from the most recent successful backup created from this schedule.
|
||||
ScheduleName string `json:"scheduleName,omitempty"`
|
||||
|
||||
// IncludedNamespaces is a slice of namespace names to include objects
|
||||
// from. If empty, all namespaces are included.
|
||||
IncludedNamespaces []string `json:"includedNamespaces"`
|
||||
@@ -49,20 +54,20 @@ type RestoreSpec struct {
|
||||
// LabelSelector is a metav1.LabelSelector to filter with
|
||||
// when restoring individual objects from the backup. If empty
|
||||
// or nil, all objects are included. Optional.
|
||||
LabelSelector *metav1.LabelSelector `json:"labelSelector"`
|
||||
LabelSelector *metav1.LabelSelector `json:"labelSelector,omitempty"`
|
||||
|
||||
// RestorePVs specifies whether to restore all included
|
||||
// PVs from snapshot (via the cloudprovider).
|
||||
RestorePVs *bool `json:"restorePVs"`
|
||||
RestorePVs *bool `json:"restorePVs,omitempty"`
|
||||
|
||||
// IncludeClusterResources specifies whether cluster-scoped resources
|
||||
// should be included for consideration in the restore. If null, defaults
|
||||
// to true.
|
||||
IncludeClusterResources *bool `json:"includeClusterResources"`
|
||||
IncludeClusterResources *bool `json:"includeClusterResources,omitempty"`
|
||||
}
|
||||
|
||||
// RestorePhase is a string representation of the lifecycle phase
|
||||
// of an Ark restore
|
||||
// of a Velero restore
|
||||
type RestorePhase string
|
||||
|
||||
const (
|
||||
@@ -77,12 +82,20 @@ const (
|
||||
// RestorePhaseInProgress means the restore is currently executing.
|
||||
RestorePhaseInProgress RestorePhase = "InProgress"
|
||||
|
||||
// RestorePhaseCompleted means the restore has finished executing.
|
||||
// Any relevant warnings or errors will be captured in the Status.
|
||||
// RestorePhaseCompleted means the restore has run successfully
|
||||
// without errors.
|
||||
RestorePhaseCompleted RestorePhase = "Completed"
|
||||
|
||||
// RestorePhasePartiallyFailed means the restore has run to completion
|
||||
// but encountered 1+ errors restoring individual items.
|
||||
RestorePhasePartiallyFailed RestorePhase = "PartiallyFailed"
|
||||
|
||||
// RestorePhaseFailed means the restore was unable to execute.
|
||||
// The failing error is recorded in status.FailureReason.
|
||||
RestorePhaseFailed RestorePhase = "Failed"
|
||||
)
|
||||
|
||||
// RestoreStatus captures the current status of an Ark restore
|
||||
// RestoreStatus captures the current status of a Velero restore
|
||||
type RestoreStatus struct {
|
||||
// Phase is the current state of the Restore
|
||||
Phase RestorePhase `json:"phase"`
|
||||
@@ -98,31 +111,16 @@ type RestoreStatus struct {
|
||||
// Errors is a count of all error messages that were generated during
|
||||
// execution of the restore. The actual errors are stored in object storage.
|
||||
Errors int `json:"errors"`
|
||||
}
|
||||
|
||||
// RestoreResult is a collection of messages that were generated
|
||||
// during execution of a restore. This will typically store either
|
||||
// warning or error messages.
|
||||
type RestoreResult struct {
|
||||
// Ark is a slice of messages related to the operation of Ark
|
||||
// itself (for example, messages related to connecting to the
|
||||
// cloud, reading a backup file, etc.)
|
||||
Ark []string `json:"ark"`
|
||||
|
||||
// Cluster is a slice of messages related to restoring cluster-
|
||||
// scoped resources.
|
||||
Cluster []string `json:"cluster"`
|
||||
|
||||
// Namespaces is a map of namespace name to slice of messages
|
||||
// related to restoring namespace-scoped resources.
|
||||
Namespaces map[string][]string `json:"namespaces"`
|
||||
// FailureReason is an error that caused the entire restore to fail.
|
||||
FailureReason string `json:"failureReason"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Restore is an Ark resource that represents the application of
|
||||
// resources from an Ark backup to a target Kubernetes cluster.
|
||||
// Restore is a Velero resource that represents the application of
|
||||
// resources from a Velero backup to a target Kubernetes cluster.
|
||||
type Restore struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,7 @@ package v1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// ScheduleSpec defines the specification for an Ark schedule
|
||||
// ScheduleSpec defines the specification for a Velero schedule
|
||||
type ScheduleSpec struct {
|
||||
// Template is the definition of the Backup to be run
|
||||
// on the provided schedule
|
||||
@@ -30,7 +30,7 @@ type ScheduleSpec struct {
|
||||
}
|
||||
|
||||
// SchedulePhase is a string representation of the lifecycle phase
|
||||
// of an Ark schedule
|
||||
// of a Velero schedule
|
||||
type SchedulePhase string
|
||||
|
||||
const (
|
||||
@@ -47,7 +47,7 @@ const (
|
||||
SchedulePhaseFailedValidation SchedulePhase = "FailedValidation"
|
||||
)
|
||||
|
||||
// ScheduleStatus captures the current state of an Ark schedule
|
||||
// ScheduleStatus captures the current state of a Velero schedule
|
||||
type ScheduleStatus struct {
|
||||
// Phase is the current phase of the Schedule
|
||||
Phase SchedulePhase `json:"phase"`
|
||||
@@ -64,7 +64,7 @@ type ScheduleStatus struct {
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Schedule is an Ark resource that represents a pre-scheduled or
|
||||
// Schedule is a Velero resource that represents a pre-scheduled or
|
||||
// periodic Backup that should be run.
|
||||
type Schedule struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
79
pkg/apis/velero/v1/server_status_request.go
Normal file
79
pkg/apis/velero/v1/server_status_request.go
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ServerStatusRequest is a request to access current status information about
|
||||
// the Velero server.
|
||||
type ServerStatusRequest struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
Spec ServerStatusRequestSpec `json:"spec"`
|
||||
Status ServerStatusRequestStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// ServerStatusRequestSpec is the specification for a ServerStatusRequest.
|
||||
type ServerStatusRequestSpec struct {
|
||||
}
|
||||
|
||||
// ServerStatusRequestPhase represents the lifecycle phase of a ServerStatusRequest.
|
||||
type ServerStatusRequestPhase string
|
||||
|
||||
const (
|
||||
// ServerStatusRequestPhaseNew means the ServerStatusRequest has not been processed yet.
|
||||
ServerStatusRequestPhaseNew ServerStatusRequestPhase = "New"
|
||||
// ServerStatusRequestPhaseProcessed means the ServerStatusRequest has been processed.
|
||||
ServerStatusRequestPhaseProcessed ServerStatusRequestPhase = "Processed"
|
||||
)
|
||||
|
||||
// PluginInfo contains attributes of a Velero plugin
|
||||
type PluginInfo struct {
|
||||
Name string `json:"name"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
// ServerStatusRequestStatus is the current status of a ServerStatusRequest.
|
||||
type ServerStatusRequestStatus struct {
|
||||
// Phase is the current lifecycle phase of the ServerStatusRequest.
|
||||
Phase ServerStatusRequestPhase `json:"phase"`
|
||||
|
||||
// ProcessedTimestamp is when the ServerStatusRequest was processed
|
||||
// by the ServerStatusRequestController.
|
||||
ProcessedTimestamp metav1.Time `json:"processedTimestamp"`
|
||||
|
||||
// ServerVersion is the Velero server version.
|
||||
ServerVersion string `json:"serverVersion"`
|
||||
|
||||
// Plugins list information about the plugins running on the Velero server
|
||||
Plugins []PluginInfo `json:"plugins"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// ServerStatusRequestList is a list of ServerStatusRequests.
|
||||
type ServerStatusRequestList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []ServerStatusRequest `json:"items"`
|
||||
}
|
||||
65
pkg/apis/velero/v1/volume_snapshot_location.go
Normal file
65
pkg/apis/velero/v1/volume_snapshot_location.go
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VolumeSnapshotLocation is a location where Velero stores volume snapshots.
|
||||
type VolumeSnapshotLocation struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
Spec VolumeSnapshotLocationSpec `json:"spec"`
|
||||
Status VolumeSnapshotLocationStatus `json:"status"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VolumeSnapshotLocationList is a list of VolumeSnapshotLocations.
|
||||
type VolumeSnapshotLocationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata"`
|
||||
Items []VolumeSnapshotLocation `json:"items"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotLocationSpec defines the specification for a Velero VolumeSnapshotLocation.
|
||||
type VolumeSnapshotLocationSpec struct {
|
||||
// Provider is the provider of the volume storage.
|
||||
Provider string `json:"provider"`
|
||||
|
||||
// Config is for provider-specific configuration fields.
|
||||
Config map[string]string `json:"config"`
|
||||
}
|
||||
|
||||
// VolumeSnapshotLocationPhase is the lifecyle phase of a Velero VolumeSnapshotLocation.
|
||||
type VolumeSnapshotLocationPhase string
|
||||
|
||||
const (
|
||||
// VolumeSnapshotLocationPhaseAvailable means the location is available to read and write from.
|
||||
VolumeSnapshotLocationPhaseAvailable VolumeSnapshotLocationPhase = "Available"
|
||||
|
||||
// VolumeSnapshotLocationPhaseUnavailable means the location is unavailable to read and write from.
|
||||
VolumeSnapshotLocationPhaseUnavailable VolumeSnapshotLocationPhase = "Unavailable"
|
||||
)
|
||||
|
||||
// VolumeSnapshotLocationStatus describes the current status of a Velero VolumeSnapshotLocation.
|
||||
type VolumeSnapshotLocationStatus struct {
|
||||
Phase VolumeSnapshotLocationPhase `json:"phase,omitempty"`
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -19,50 +19,49 @@ package backup
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
kuberrs "k8s.io/apimachinery/pkg/util/errors"
|
||||
|
||||
api "github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/client"
|
||||
"github.com/heptio/ark/pkg/cloudprovider"
|
||||
"github.com/heptio/ark/pkg/discovery"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
kubeutil "github.com/heptio/ark/pkg/util/kube"
|
||||
"github.com/heptio/ark/pkg/util/logging"
|
||||
api "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/client"
|
||||
"github.com/heptio/velero/pkg/discovery"
|
||||
"github.com/heptio/velero/pkg/plugin/velero"
|
||||
"github.com/heptio/velero/pkg/podexec"
|
||||
"github.com/heptio/velero/pkg/restic"
|
||||
"github.com/heptio/velero/pkg/util/collections"
|
||||
)
|
||||
|
||||
// BackupVersion is the current backup version for Velero.
|
||||
const BackupVersion = 1
|
||||
|
||||
// Backupper performs backups.
|
||||
type Backupper interface {
|
||||
// Backup takes a backup using the specification in the api.Backup and writes backup and log data
|
||||
// to the given writers.
|
||||
Backup(backup *api.Backup, backupFile, logFile io.Writer, actions []ItemAction) error
|
||||
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []velero.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
|
||||
}
|
||||
|
||||
// kubernetesBackupper implements Backupper.
|
||||
type kubernetesBackupper struct {
|
||||
dynamicFactory client.DynamicFactory
|
||||
discoveryHelper discovery.Helper
|
||||
podCommandExecutor podCommandExecutor
|
||||
groupBackupperFactory groupBackupperFactory
|
||||
snapshotService cloudprovider.SnapshotService
|
||||
}
|
||||
|
||||
type itemKey struct {
|
||||
resource string
|
||||
namespace string
|
||||
name string
|
||||
dynamicFactory client.DynamicFactory
|
||||
discoveryHelper discovery.Helper
|
||||
podCommandExecutor podexec.PodCommandExecutor
|
||||
groupBackupperFactory groupBackupperFactory
|
||||
resticBackupperFactory restic.BackupperFactory
|
||||
resticTimeout time.Duration
|
||||
}
|
||||
|
||||
type resolvedAction struct {
|
||||
ItemAction
|
||||
velero.BackupItemAction
|
||||
|
||||
resourceIncludesExcludes *collections.IncludesExcludes
|
||||
namespaceIncludesExcludes *collections.IncludesExcludes
|
||||
@@ -73,23 +72,35 @@ func (i *itemKey) String() string {
|
||||
return fmt.Sprintf("resource=%s,namespace=%s,name=%s", i.resource, i.namespace, i.name)
|
||||
}
|
||||
|
||||
func cohabitatingResources() map[string]*cohabitatingResource {
|
||||
return map[string]*cohabitatingResource{
|
||||
"deployments": newCohabitatingResource("deployments", "extensions", "apps"),
|
||||
"daemonsets": newCohabitatingResource("daemonsets", "extensions", "apps"),
|
||||
"replicasets": newCohabitatingResource("replicasets", "extensions", "apps"),
|
||||
"networkpolicies": newCohabitatingResource("networkpolicies", "extensions", "networking.k8s.io"),
|
||||
"events": newCohabitatingResource("events", "", "events.k8s.io"),
|
||||
}
|
||||
}
|
||||
|
||||
// NewKubernetesBackupper creates a new kubernetesBackupper.
|
||||
func NewKubernetesBackupper(
|
||||
discoveryHelper discovery.Helper,
|
||||
dynamicFactory client.DynamicFactory,
|
||||
podCommandExecutor podCommandExecutor,
|
||||
snapshotService cloudprovider.SnapshotService,
|
||||
podCommandExecutor podexec.PodCommandExecutor,
|
||||
resticBackupperFactory restic.BackupperFactory,
|
||||
resticTimeout time.Duration,
|
||||
) (Backupper, error) {
|
||||
return &kubernetesBackupper{
|
||||
discoveryHelper: discoveryHelper,
|
||||
dynamicFactory: dynamicFactory,
|
||||
podCommandExecutor: podCommandExecutor,
|
||||
groupBackupperFactory: &defaultGroupBackupperFactory{},
|
||||
snapshotService: snapshotService,
|
||||
discoveryHelper: discoveryHelper,
|
||||
dynamicFactory: dynamicFactory,
|
||||
podCommandExecutor: podCommandExecutor,
|
||||
groupBackupperFactory: &defaultGroupBackupperFactory{},
|
||||
resticBackupperFactory: resticBackupperFactory,
|
||||
resticTimeout: resticTimeout,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func resolveActions(actions []ItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
||||
func resolveActions(actions []velero.BackupItemAction, helper discovery.Helper) ([]resolvedAction, error) {
|
||||
var resolved []resolvedAction
|
||||
|
||||
for _, action := range actions {
|
||||
@@ -109,7 +120,7 @@ func resolveActions(actions []ItemAction, helper discovery.Helper) ([]resolvedAc
|
||||
}
|
||||
|
||||
res := resolvedAction{
|
||||
ItemAction: action,
|
||||
BackupItemAction: action,
|
||||
resourceIncludesExcludes: resources,
|
||||
namespaceIncludesExcludes: namespaces,
|
||||
selector: selector,
|
||||
@@ -164,18 +175,11 @@ func getResourceHooks(hookSpecs []api.BackupResourceHookSpec, discoveryHelper di
|
||||
}
|
||||
|
||||
func getResourceHook(hookSpec api.BackupResourceHookSpec, discoveryHelper discovery.Helper) (resourceHook, error) {
|
||||
// Use newer PreHooks if it's set
|
||||
preHooks := hookSpec.PreHooks
|
||||
if len(preHooks) == 0 {
|
||||
// Fall back to Hooks otherwise (DEPRECATED)
|
||||
preHooks = hookSpec.Hooks
|
||||
}
|
||||
|
||||
h := resourceHook{
|
||||
name: hookSpec.Name,
|
||||
namespaces: collections.NewIncludesExcludes().Includes(hookSpec.IncludedNamespaces...).Excludes(hookSpec.ExcludedNamespaces...),
|
||||
resources: getResourceIncludesExcludes(discoveryHelper, hookSpec.IncludedResources, hookSpec.ExcludedResources),
|
||||
pre: preHooks,
|
||||
pre: hookSpec.PreHooks,
|
||||
post: hookSpec.PostHooks,
|
||||
}
|
||||
|
||||
@@ -190,88 +194,109 @@ func getResourceHook(hookSpec api.BackupResourceHookSpec, discoveryHelper discov
|
||||
return h, nil
|
||||
}
|
||||
|
||||
type VolumeSnapshotterGetter interface {
|
||||
GetVolumeSnapshotter(name string) (velero.VolumeSnapshotter, error)
|
||||
}
|
||||
|
||||
// Backup backs up the items specified in the Backup, placing them in a gzip-compressed tar file
|
||||
// written to backupFile. The finalized api.Backup is written to metadata.
|
||||
func (kb *kubernetesBackupper) Backup(backup *api.Backup, backupFile, logFile io.Writer, actions []ItemAction) error {
|
||||
// written to backupFile. The finalized api.Backup is written to metadata. Any error that represents
|
||||
// a complete backup failure is returned. Errors that constitute partial failures (i.e. failures to
|
||||
// back up individual resources that don't prevent the backup from continuing to be processed) are logged
|
||||
// to the backup log.
|
||||
func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer, actions []velero.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
|
||||
gzippedData := gzip.NewWriter(backupFile)
|
||||
defer gzippedData.Close()
|
||||
|
||||
tw := tar.NewWriter(gzippedData)
|
||||
defer tw.Close()
|
||||
|
||||
gzippedLog := gzip.NewWriter(logFile)
|
||||
defer gzippedLog.Close()
|
||||
log.Info("Writing backup version file")
|
||||
if err := kb.writeBackupVersion(tw); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
logger := logrus.New()
|
||||
logger.Out = gzippedLog
|
||||
logger.Hooks.Add(&logging.ErrorLocationHook{})
|
||||
logger.Hooks.Add(&logging.LogLocationHook{})
|
||||
log := logger.WithField("backup", kubeutil.NamespaceAndName(backup))
|
||||
log.Info("Starting backup")
|
||||
backupRequest.NamespaceIncludesExcludes = getNamespaceIncludesExcludes(backupRequest.Backup)
|
||||
log.Infof("Including namespaces: %s", backupRequest.NamespaceIncludesExcludes.IncludesString())
|
||||
log.Infof("Excluding namespaces: %s", backupRequest.NamespaceIncludesExcludes.ExcludesString())
|
||||
|
||||
namespaceIncludesExcludes := getNamespaceIncludesExcludes(backup)
|
||||
log.Infof("Including namespaces: %s", namespaceIncludesExcludes.IncludesString())
|
||||
log.Infof("Excluding namespaces: %s", namespaceIncludesExcludes.ExcludesString())
|
||||
backupRequest.ResourceIncludesExcludes = getResourceIncludesExcludes(kb.discoveryHelper, backupRequest.Spec.IncludedResources, backupRequest.Spec.ExcludedResources)
|
||||
log.Infof("Including resources: %s", backupRequest.ResourceIncludesExcludes.IncludesString())
|
||||
log.Infof("Excluding resources: %s", backupRequest.ResourceIncludesExcludes.ExcludesString())
|
||||
|
||||
resourceIncludesExcludes := getResourceIncludesExcludes(kb.discoveryHelper, backup.Spec.IncludedResources, backup.Spec.ExcludedResources)
|
||||
log.Infof("Including resources: %s", resourceIncludesExcludes.IncludesString())
|
||||
log.Infof("Excluding resources: %s", resourceIncludesExcludes.ExcludesString())
|
||||
|
||||
resourceHooks, err := getResourceHooks(backup.Spec.Hooks.Resources, kb.discoveryHelper)
|
||||
var err error
|
||||
backupRequest.ResourceHooks, err = getResourceHooks(backupRequest.Spec.Hooks.Resources, kb.discoveryHelper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var labelSelector string
|
||||
if backup.Spec.LabelSelector != nil {
|
||||
labelSelector = metav1.FormatLabelSelector(backup.Spec.LabelSelector)
|
||||
}
|
||||
|
||||
backedUpItems := make(map[itemKey]struct{})
|
||||
var errs []error
|
||||
|
||||
cohabitatingResources := map[string]*cohabitatingResource{
|
||||
"deployments": newCohabitatingResource("deployments", "extensions", "apps"),
|
||||
"networkpolicies": newCohabitatingResource("networkpolicies", "extensions", "networking.k8s.io"),
|
||||
"events": newCohabitatingResource("events", "", "events.k8s.io"),
|
||||
}
|
||||
|
||||
resolvedActions, err := resolveActions(actions, kb.discoveryHelper)
|
||||
backupRequest.ResolvedActions, err = resolveActions(actions, kb.discoveryHelper)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
backupRequest.BackedUpItems = map[itemKey]struct{}{}
|
||||
|
||||
podVolumeTimeout := kb.resticTimeout
|
||||
if val := backupRequest.Annotations[api.PodVolumeOperationTimeoutAnnotation]; val != "" {
|
||||
parsed, err := time.ParseDuration(val)
|
||||
if err != nil {
|
||||
log.WithError(errors.WithStack(err)).Errorf("Unable to parse pod volume timeout annotation %s, using server value.", val)
|
||||
} else {
|
||||
podVolumeTimeout = parsed
|
||||
}
|
||||
}
|
||||
|
||||
ctx, cancelFunc := context.WithTimeout(context.Background(), podVolumeTimeout)
|
||||
defer cancelFunc()
|
||||
|
||||
var resticBackupper restic.Backupper
|
||||
if kb.resticBackupperFactory != nil {
|
||||
resticBackupper, err = kb.resticBackupperFactory.NewBackupper(ctx, backupRequest.Backup)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
gb := kb.groupBackupperFactory.newGroupBackupper(
|
||||
log,
|
||||
backup,
|
||||
namespaceIncludesExcludes,
|
||||
resourceIncludesExcludes,
|
||||
labelSelector,
|
||||
backupRequest,
|
||||
kb.dynamicFactory,
|
||||
kb.discoveryHelper,
|
||||
backedUpItems,
|
||||
cohabitatingResources,
|
||||
resolvedActions,
|
||||
cohabitatingResources(),
|
||||
kb.podCommandExecutor,
|
||||
tw,
|
||||
resourceHooks,
|
||||
kb.snapshotService,
|
||||
resticBackupper,
|
||||
newPVCSnapshotTracker(),
|
||||
volumeSnapshotterGetter,
|
||||
)
|
||||
|
||||
for _, group := range kb.discoveryHelper.Resources() {
|
||||
if err := gb.backupGroup(group); err != nil {
|
||||
errs = append(errs, err)
|
||||
log.WithError(err).WithField("apiGroup", group.String()).Error("Error backing up API group")
|
||||
}
|
||||
}
|
||||
|
||||
err = kuberrs.Flatten(kuberrs.NewAggregate(errs))
|
||||
if err == nil {
|
||||
log.Infof("Backup completed successfully")
|
||||
} else {
|
||||
log.Infof("Backup completed with errors: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
func (kb *kubernetesBackupper) writeBackupVersion(tw *tar.Writer) error {
|
||||
versionFile := filepath.Join(api.MetadataDir, "version")
|
||||
versionString := fmt.Sprintf("%d\n", BackupVersion)
|
||||
|
||||
hdr := &tar.Header{
|
||||
Name: versionFile,
|
||||
Size: int64(len(versionString)),
|
||||
Typeflag: tar.TypeReg,
|
||||
Mode: 0755,
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
if _, err := tw.Write([]byte(versionString)); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type tarWriter interface {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,55 +17,49 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/kuberesource"
|
||||
"github.com/heptio/velero/pkg/plugin/velero"
|
||||
)
|
||||
|
||||
// backupPVAction inspects a PersistentVolumeClaim for the PersistentVolume
|
||||
// PVCAction inspects a PersistentVolumeClaim for the PersistentVolume
|
||||
// that it references and backs it up
|
||||
type backupPVAction struct {
|
||||
type PVCAction struct {
|
||||
log logrus.FieldLogger
|
||||
}
|
||||
|
||||
func NewBackupPVAction(log logrus.FieldLogger) ItemAction {
|
||||
return &backupPVAction{log: log}
|
||||
func NewPVCAction(logger logrus.FieldLogger) *PVCAction {
|
||||
return &PVCAction{log: logger}
|
||||
}
|
||||
|
||||
var pvGroupResource = schema.GroupResource{Group: "", Resource: "persistentvolumes"}
|
||||
|
||||
func (a *backupPVAction) AppliesTo() (ResourceSelector, error) {
|
||||
return ResourceSelector{
|
||||
func (a *PVCAction) AppliesTo() (velero.ResourceSelector, error) {
|
||||
return velero.ResourceSelector{
|
||||
IncludedResources: []string{"persistentvolumeclaims"},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Execute finds the PersistentVolume bound by the provided
|
||||
// PersistentVolumeClaim, if any, and backs it up
|
||||
func (a *backupPVAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []ResourceIdentifier, error) {
|
||||
a.log.Info("Executing backupPVAction")
|
||||
func (a *PVCAction) Execute(item runtime.Unstructured, backup *v1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
|
||||
a.log.Info("Executing PVCAction")
|
||||
|
||||
var additionalItems []ResourceIdentifier
|
||||
|
||||
pvc := item.UnstructuredContent()
|
||||
|
||||
volumeName, err := collections.GetString(pvc, "spec.volumeName")
|
||||
// if there's no volume name, it's not an error, since it's possible
|
||||
// for the PVC not be bound; don't return an additional PV item to
|
||||
// back up.
|
||||
if err != nil || volumeName == "" {
|
||||
a.log.Info("No spec.volumeName found for PersistentVolumeClaim")
|
||||
return nil, nil, nil
|
||||
var pvc corev1api.PersistentVolumeClaim
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(item.UnstructuredContent(), &pvc); err != nil {
|
||||
return nil, nil, errors.Wrap(err, "unable to convert unstructured item to persistent volume claim")
|
||||
}
|
||||
|
||||
additionalItems = append(additionalItems, ResourceIdentifier{
|
||||
GroupResource: pvGroupResource,
|
||||
Name: volumeName,
|
||||
})
|
||||
if pvc.Status.Phase != corev1api.ClaimBound || pvc.Spec.VolumeName == "" {
|
||||
return item, nil, nil
|
||||
}
|
||||
|
||||
return item, additionalItems, nil
|
||||
pv := velero.ResourceIdentifier{
|
||||
GroupResource: kuberesource.PersistentVolumes,
|
||||
Name: pvc.Spec.VolumeName,
|
||||
}
|
||||
return item, []velero.ResourceIdentifier{pv}, nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -19,23 +19,28 @@ package backup
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
arktest "github.com/heptio/ark/pkg/util/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
|
||||
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/kuberesource"
|
||||
"github.com/heptio/velero/pkg/plugin/velero"
|
||||
velerotest "github.com/heptio/velero/pkg/test"
|
||||
)
|
||||
|
||||
func TestBackupPVAction(t *testing.T) {
|
||||
pvc := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"spec": map[string]interface{}{},
|
||||
"spec": map[string]interface{}{},
|
||||
"status": map[string]interface{}{},
|
||||
},
|
||||
}
|
||||
|
||||
backup := &v1.Backup{}
|
||||
|
||||
a := NewBackupPVAction(arktest.NewLogger())
|
||||
a := NewPVCAction(velerotest.NewLogger())
|
||||
|
||||
// no spec.volumeName should result in no error
|
||||
// and no additional items
|
||||
@@ -50,11 +55,39 @@ func TestBackupPVAction(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, additional, 0)
|
||||
|
||||
// non-empty spec.volumeName should result in
|
||||
// no error and an additional item for the PV
|
||||
// non-empty spec.volumeName when status.phase is empty
|
||||
// should result in no error and no additional items
|
||||
pvc.Object["spec"].(map[string]interface{})["volumeName"] = "myVolume"
|
||||
_, additional, err = a.Execute(pvc, backup)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, additional, 0)
|
||||
|
||||
// non-empty spec.volumeName when status.phase is 'Pending'
|
||||
// should result in no error and no additional items
|
||||
pvc.Object["status"].(map[string]interface{})["phase"] = corev1api.ClaimPending
|
||||
_, additional, err = a.Execute(pvc, backup)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, additional, 0)
|
||||
|
||||
// non-empty spec.volumeName when status.phase is 'Lost'
|
||||
// should result in no error and no additional items
|
||||
pvc.Object["status"].(map[string]interface{})["phase"] = corev1api.ClaimLost
|
||||
_, additional, err = a.Execute(pvc, backup)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, additional, 0)
|
||||
|
||||
// non-empty spec.volumeName when status.phase is 'Bound'
|
||||
// should result in no error and one additional item for the PV
|
||||
pvc.Object["status"].(map[string]interface{})["phase"] = corev1api.ClaimBound
|
||||
_, additional, err = a.Execute(pvc, backup)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, additional, 1)
|
||||
assert.Equal(t, ResourceIdentifier{GroupResource: pvGroupResource, Name: "myVolume"}, additional[0])
|
||||
assert.Equal(t, velero.ResourceIdentifier{GroupResource: kuberesource.PersistentVolumes, Name: "myVolume"}, additional[0])
|
||||
|
||||
// empty spec.volumeName when status.phase is 'Bound' should
|
||||
// result in no error and no additional items
|
||||
pvc.Object["spec"].(map[string]interface{})["volumeName"] = ""
|
||||
_, additional, err = a.Execute(pvc, backup)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, additional, 0)
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 the Heptio Ark contributors.
|
||||
Copyright 2018 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -19,8 +19,10 @@ package backup
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/label"
|
||||
)
|
||||
|
||||
// NewDeleteBackupRequest creates a DeleteBackupRequest for the backup identified by name and uid.
|
||||
@@ -29,7 +31,7 @@ func NewDeleteBackupRequest(name string, uid string) *v1.DeleteBackupRequest {
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: name + "-",
|
||||
Labels: map[string]string{
|
||||
v1.BackupNameLabel: name,
|
||||
v1.BackupNameLabel: label.GetValidName(name),
|
||||
v1.BackupUIDLabel: uid,
|
||||
},
|
||||
},
|
||||
@@ -43,6 +45,6 @@ func NewDeleteBackupRequest(name string, uid string) *v1.DeleteBackupRequest {
|
||||
// find DeleteBackupRequests for the backup identified by name and uid.
|
||||
func NewDeleteBackupRequestListOptions(name, uid string) metav1.ListOptions {
|
||||
return metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s,%s=%s", v1.BackupNameLabel, name, v1.BackupUIDLabel, uid),
|
||||
LabelSelector: fmt.Sprintf("%s=%s,%s=%s", v1.BackupNameLabel, label.GetValidName(name), v1.BackupUIDLabel, uid),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -22,33 +22,27 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
kuberrs "k8s.io/apimachinery/pkg/util/errors"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/client"
|
||||
"github.com/heptio/ark/pkg/cloudprovider"
|
||||
"github.com/heptio/ark/pkg/discovery"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
"github.com/heptio/velero/pkg/client"
|
||||
"github.com/heptio/velero/pkg/discovery"
|
||||
"github.com/heptio/velero/pkg/podexec"
|
||||
"github.com/heptio/velero/pkg/restic"
|
||||
)
|
||||
|
||||
type groupBackupperFactory interface {
|
||||
newGroupBackupper(
|
||||
log logrus.FieldLogger,
|
||||
backup *v1.Backup,
|
||||
namespaces, resources *collections.IncludesExcludes,
|
||||
labelSelector string,
|
||||
backupRequest *Request,
|
||||
dynamicFactory client.DynamicFactory,
|
||||
discoveryHelper discovery.Helper,
|
||||
backedUpItems map[itemKey]struct{},
|
||||
cohabitatingResources map[string]*cohabitatingResource,
|
||||
actions []resolvedAction,
|
||||
podCommandExecutor podCommandExecutor,
|
||||
podCommandExecutor podexec.PodCommandExecutor,
|
||||
tarWriter tarWriter,
|
||||
resourceHooks []resourceHook,
|
||||
snapshotService cloudprovider.SnapshotService,
|
||||
resticBackupper restic.Backupper,
|
||||
resticSnapshotTracker *pvcSnapshotTracker,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||
) groupBackupper
|
||||
}
|
||||
|
||||
@@ -56,34 +50,28 @@ type defaultGroupBackupperFactory struct{}
|
||||
|
||||
func (f *defaultGroupBackupperFactory) newGroupBackupper(
|
||||
log logrus.FieldLogger,
|
||||
backup *v1.Backup,
|
||||
namespaces, resources *collections.IncludesExcludes,
|
||||
labelSelector string,
|
||||
backupRequest *Request,
|
||||
dynamicFactory client.DynamicFactory,
|
||||
discoveryHelper discovery.Helper,
|
||||
backedUpItems map[itemKey]struct{},
|
||||
cohabitatingResources map[string]*cohabitatingResource,
|
||||
actions []resolvedAction,
|
||||
podCommandExecutor podCommandExecutor,
|
||||
podCommandExecutor podexec.PodCommandExecutor,
|
||||
tarWriter tarWriter,
|
||||
resourceHooks []resourceHook,
|
||||
snapshotService cloudprovider.SnapshotService,
|
||||
resticBackupper restic.Backupper,
|
||||
resticSnapshotTracker *pvcSnapshotTracker,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||
) groupBackupper {
|
||||
return &defaultGroupBackupper{
|
||||
log: log,
|
||||
backup: backup,
|
||||
namespaces: namespaces,
|
||||
resources: resources,
|
||||
labelSelector: labelSelector,
|
||||
dynamicFactory: dynamicFactory,
|
||||
discoveryHelper: discoveryHelper,
|
||||
backedUpItems: backedUpItems,
|
||||
cohabitatingResources: cohabitatingResources,
|
||||
actions: actions,
|
||||
podCommandExecutor: podCommandExecutor,
|
||||
tarWriter: tarWriter,
|
||||
resourceHooks: resourceHooks,
|
||||
snapshotService: snapshotService,
|
||||
log: log,
|
||||
backupRequest: backupRequest,
|
||||
dynamicFactory: dynamicFactory,
|
||||
discoveryHelper: discoveryHelper,
|
||||
cohabitatingResources: cohabitatingResources,
|
||||
podCommandExecutor: podCommandExecutor,
|
||||
tarWriter: tarWriter,
|
||||
resticBackupper: resticBackupper,
|
||||
resticSnapshotTracker: resticSnapshotTracker,
|
||||
volumeSnapshotterGetter: volumeSnapshotterGetter,
|
||||
|
||||
resourceBackupperFactory: &defaultResourceBackupperFactory{},
|
||||
}
|
||||
}
|
||||
@@ -94,43 +82,21 @@ type groupBackupper interface {
|
||||
|
||||
type defaultGroupBackupper struct {
|
||||
log logrus.FieldLogger
|
||||
backup *v1.Backup
|
||||
namespaces, resources *collections.IncludesExcludes
|
||||
labelSelector string
|
||||
backupRequest *Request
|
||||
dynamicFactory client.DynamicFactory
|
||||
discoveryHelper discovery.Helper
|
||||
backedUpItems map[itemKey]struct{}
|
||||
cohabitatingResources map[string]*cohabitatingResource
|
||||
actions []resolvedAction
|
||||
podCommandExecutor podCommandExecutor
|
||||
podCommandExecutor podexec.PodCommandExecutor
|
||||
tarWriter tarWriter
|
||||
resourceHooks []resourceHook
|
||||
snapshotService cloudprovider.SnapshotService
|
||||
resticBackupper restic.Backupper
|
||||
resticSnapshotTracker *pvcSnapshotTracker
|
||||
resourceBackupperFactory resourceBackupperFactory
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter
|
||||
}
|
||||
|
||||
// backupGroup backs up a single API group.
|
||||
func (gb *defaultGroupBackupper) backupGroup(group *metav1.APIResourceList) error {
|
||||
var (
|
||||
errs []error
|
||||
log = gb.log.WithField("group", group.GroupVersion)
|
||||
rb = gb.resourceBackupperFactory.newResourceBackupper(
|
||||
log,
|
||||
gb.backup,
|
||||
gb.namespaces,
|
||||
gb.resources,
|
||||
gb.labelSelector,
|
||||
gb.dynamicFactory,
|
||||
gb.discoveryHelper,
|
||||
gb.backedUpItems,
|
||||
gb.cohabitatingResources,
|
||||
gb.actions,
|
||||
gb.podCommandExecutor,
|
||||
gb.tarWriter,
|
||||
gb.resourceHooks,
|
||||
gb.snapshotService,
|
||||
)
|
||||
)
|
||||
log := gb.log.WithField("group", group.GroupVersion)
|
||||
|
||||
log.Infof("Backing up group")
|
||||
|
||||
@@ -145,13 +111,26 @@ func (gb *defaultGroupBackupper) backupGroup(group *metav1.APIResourceList) erro
|
||||
sortCoreGroup(group)
|
||||
}
|
||||
|
||||
rb := gb.resourceBackupperFactory.newResourceBackupper(
|
||||
log,
|
||||
gb.backupRequest,
|
||||
gb.dynamicFactory,
|
||||
gb.discoveryHelper,
|
||||
gb.cohabitatingResources,
|
||||
gb.podCommandExecutor,
|
||||
gb.tarWriter,
|
||||
gb.resticBackupper,
|
||||
gb.resticSnapshotTracker,
|
||||
gb.volumeSnapshotterGetter,
|
||||
)
|
||||
|
||||
for _, resource := range group.APIResources {
|
||||
if err := rb.backupResource(group, resource); err != nil {
|
||||
errs = append(errs, err)
|
||||
log.WithError(err).WithField("resource", resource.String()).Error("Error backing up API resource")
|
||||
}
|
||||
}
|
||||
|
||||
return kuberrs.NewAggregate(errs)
|
||||
return nil
|
||||
}
|
||||
|
||||
// sortCoreGroup sorts group as a coreGroup.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017, 2019 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -19,176 +19,10 @@ package backup
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/client"
|
||||
"github.com/heptio/ark/pkg/cloudprovider"
|
||||
"github.com/heptio/ark/pkg/discovery"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
arktest "github.com/heptio/ark/pkg/util/test"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func TestBackupGroup(t *testing.T) {
|
||||
backup := &v1.Backup{}
|
||||
|
||||
namespaces := collections.NewIncludesExcludes().Includes("a")
|
||||
resources := collections.NewIncludesExcludes().Includes("b")
|
||||
labelSelector := "foo=bar"
|
||||
|
||||
dynamicFactory := &arktest.FakeDynamicFactory{}
|
||||
defer dynamicFactory.AssertExpectations(t)
|
||||
|
||||
discoveryHelper := arktest.NewFakeDiscoveryHelper(true, nil)
|
||||
|
||||
backedUpItems := map[itemKey]struct{}{
|
||||
{resource: "a", namespace: "b", name: "c"}: {},
|
||||
}
|
||||
|
||||
cohabitatingResources := map[string]*cohabitatingResource{
|
||||
"a": {
|
||||
resource: "a",
|
||||
groupResource1: schema.GroupResource{Group: "g1", Resource: "a"},
|
||||
groupResource2: schema.GroupResource{Group: "g2", Resource: "a"},
|
||||
},
|
||||
}
|
||||
|
||||
actions := []resolvedAction{
|
||||
{
|
||||
ItemAction: newFakeAction("pods"),
|
||||
resourceIncludesExcludes: collections.NewIncludesExcludes().Includes("pods"),
|
||||
},
|
||||
}
|
||||
|
||||
podCommandExecutor := &mockPodCommandExecutor{}
|
||||
defer podCommandExecutor.AssertExpectations(t)
|
||||
|
||||
tarWriter := &fakeTarWriter{}
|
||||
|
||||
resourceHooks := []resourceHook{
|
||||
{name: "myhook"},
|
||||
}
|
||||
|
||||
gb := (&defaultGroupBackupperFactory{}).newGroupBackupper(
|
||||
arktest.NewLogger(),
|
||||
backup,
|
||||
namespaces,
|
||||
resources,
|
||||
labelSelector,
|
||||
dynamicFactory,
|
||||
discoveryHelper,
|
||||
backedUpItems,
|
||||
cohabitatingResources,
|
||||
actions,
|
||||
podCommandExecutor,
|
||||
tarWriter,
|
||||
resourceHooks,
|
||||
nil,
|
||||
).(*defaultGroupBackupper)
|
||||
|
||||
resourceBackupperFactory := &mockResourceBackupperFactory{}
|
||||
defer resourceBackupperFactory.AssertExpectations(t)
|
||||
gb.resourceBackupperFactory = resourceBackupperFactory
|
||||
|
||||
resourceBackupper := &mockResourceBackupper{}
|
||||
defer resourceBackupper.AssertExpectations(t)
|
||||
|
||||
resourceBackupperFactory.On("newResourceBackupper",
|
||||
mock.Anything,
|
||||
backup,
|
||||
namespaces,
|
||||
resources,
|
||||
labelSelector,
|
||||
dynamicFactory,
|
||||
discoveryHelper,
|
||||
backedUpItems,
|
||||
cohabitatingResources,
|
||||
actions,
|
||||
podCommandExecutor,
|
||||
tarWriter,
|
||||
resourceHooks,
|
||||
nil,
|
||||
).Return(resourceBackupper)
|
||||
|
||||
group := &metav1.APIResourceList{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "persistentvolumes"},
|
||||
{Name: "pods"},
|
||||
{Name: "persistentvolumeclaims"},
|
||||
},
|
||||
}
|
||||
|
||||
expectedOrder := []string{"pods", "persistentvolumeclaims", "persistentvolumes"}
|
||||
var actualOrder []string
|
||||
|
||||
runFunc := func(args mock.Arguments) {
|
||||
actualOrder = append(actualOrder, args.Get(1).(metav1.APIResource).Name)
|
||||
}
|
||||
|
||||
resourceBackupper.On("backupResource", group, metav1.APIResource{Name: "pods"}).Return(nil).Run(runFunc)
|
||||
resourceBackupper.On("backupResource", group, metav1.APIResource{Name: "persistentvolumeclaims"}).Return(nil).Run(runFunc)
|
||||
resourceBackupper.On("backupResource", group, metav1.APIResource{Name: "persistentvolumes"}).Return(nil).Run(runFunc)
|
||||
|
||||
err := gb.backupGroup(group)
|
||||
require.NoError(t, err)
|
||||
|
||||
// make sure PVs were last
|
||||
assert.Equal(t, expectedOrder, actualOrder)
|
||||
}
|
||||
|
||||
type mockResourceBackupperFactory struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (rbf *mockResourceBackupperFactory) newResourceBackupper(
|
||||
log logrus.FieldLogger,
|
||||
backup *v1.Backup,
|
||||
namespaces *collections.IncludesExcludes,
|
||||
resources *collections.IncludesExcludes,
|
||||
labelSelector string,
|
||||
dynamicFactory client.DynamicFactory,
|
||||
discoveryHelper discovery.Helper,
|
||||
backedUpItems map[itemKey]struct{},
|
||||
cohabitatingResources map[string]*cohabitatingResource,
|
||||
actions []resolvedAction,
|
||||
podCommandExecutor podCommandExecutor,
|
||||
tarWriter tarWriter,
|
||||
resourceHooks []resourceHook,
|
||||
snapshotService cloudprovider.SnapshotService,
|
||||
) resourceBackupper {
|
||||
args := rbf.Called(
|
||||
log,
|
||||
backup,
|
||||
namespaces,
|
||||
resources,
|
||||
labelSelector,
|
||||
dynamicFactory,
|
||||
discoveryHelper,
|
||||
backedUpItems,
|
||||
cohabitatingResources,
|
||||
actions,
|
||||
podCommandExecutor,
|
||||
tarWriter,
|
||||
resourceHooks,
|
||||
snapshotService,
|
||||
)
|
||||
return args.Get(0).(resourceBackupper)
|
||||
}
|
||||
|
||||
type mockResourceBackupper struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (rb *mockResourceBackupper) backupResource(group *metav1.APIResourceList, resource metav1.APIResource) error {
|
||||
args := rb.Called(group, resource)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func TestSortCoreGroup(t *testing.T) {
|
||||
group := &metav1.APIResourceList{
|
||||
GroupVersion: "v1",
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package backup
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
api "github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
)
|
||||
|
||||
// ItemAction is an actor that performs an operation on an individual item being backed up.
|
||||
type ItemAction interface {
|
||||
// AppliesTo returns information about which resources this action should be invoked for.
|
||||
// An ItemAction's Execute function will only be invoked on items that match the returned
|
||||
// selector. A zero-valued ResourceSelector matches all resources.
|
||||
AppliesTo() (ResourceSelector, error)
|
||||
|
||||
// Execute allows the ItemAction to perform arbitrary logic with the item being backed up,
|
||||
// including mutating the item itself prior to backup. The item (unmodified or modified)
|
||||
// should be returned, along with an optional slice of ResourceIdentifiers specifying
|
||||
// additional related items that should be backed up.
|
||||
Execute(item runtime.Unstructured, backup *api.Backup) (runtime.Unstructured, []ResourceIdentifier, error)
|
||||
}
|
||||
|
||||
// ResourceIdentifier describes a single item by its group, resource, namespace, and name.
|
||||
type ResourceIdentifier struct {
|
||||
schema.GroupResource
|
||||
Namespace string
|
||||
Name string
|
||||
}
|
||||
|
||||
// ResourceSelector is a collection of included/excluded namespaces,
|
||||
// included/excluded resources, and a label-selector that can be used
|
||||
// to match a set of items from a cluster.
|
||||
type ResourceSelector struct {
|
||||
// IncludedNamespaces is a slice of namespace names to match. All
|
||||
// namespaces in this slice, except those in ExcludedNamespaces,
|
||||
// will be matched. A nil/empty slice matches all namespaces.
|
||||
IncludedNamespaces []string
|
||||
// ExcludedNamespaces is a slice of namespace names to exclude.
|
||||
// All namespaces in IncludedNamespaces, *except* those in
|
||||
// this slice, will be matched.
|
||||
ExcludedNamespaces []string
|
||||
// IncludedResources is a slice of resources to match. Resources
|
||||
// may be specified as full names (e.g. "services") or abbreviations
|
||||
// (e.g. "svc"). All resources in this slice, except those in
|
||||
// ExcludedResources, will be matched. A nil/empty slice matches
|
||||
// all resources.
|
||||
IncludedResources []string
|
||||
// ExcludedResources is a slice of resources to exclude.
|
||||
// Resources may be specified as full names (e.g. "services") or
|
||||
// abbreviations (e.g. "svc"). All resources in IncludedResources,
|
||||
// *except* those in this slice, will be matched.
|
||||
ExcludedResources []string
|
||||
// LabelSelector is a string representation of a selector to apply
|
||||
// when matching resources. See "k8s.io/apimachinery/pkg/labels".Parse()
|
||||
// for details on syntax.
|
||||
LabelSelector string
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -19,66 +19,65 @@ package backup
|
||||
import (
|
||||
"archive/tar"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
|
||||
|
||||
api "github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/client"
|
||||
"github.com/heptio/ark/pkg/cloudprovider"
|
||||
"github.com/heptio/ark/pkg/discovery"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
"github.com/heptio/ark/pkg/util/logging"
|
||||
api "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
velerov1api "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/client"
|
||||
"github.com/heptio/velero/pkg/discovery"
|
||||
"github.com/heptio/velero/pkg/kuberesource"
|
||||
"github.com/heptio/velero/pkg/plugin/velero"
|
||||
"github.com/heptio/velero/pkg/podexec"
|
||||
"github.com/heptio/velero/pkg/restic"
|
||||
"github.com/heptio/velero/pkg/volume"
|
||||
)
|
||||
|
||||
type itemBackupperFactory interface {
|
||||
newItemBackupper(
|
||||
backup *api.Backup,
|
||||
namespaces, resources *collections.IncludesExcludes,
|
||||
backedUpItems map[itemKey]struct{},
|
||||
actions []resolvedAction,
|
||||
podCommandExecutor podCommandExecutor,
|
||||
backup *Request,
|
||||
podCommandExecutor podexec.PodCommandExecutor,
|
||||
tarWriter tarWriter,
|
||||
resourceHooks []resourceHook,
|
||||
dynamicFactory client.DynamicFactory,
|
||||
discoveryHelper discovery.Helper,
|
||||
snapshotService cloudprovider.SnapshotService,
|
||||
resticBackupper restic.Backupper,
|
||||
resticSnapshotTracker *pvcSnapshotTracker,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||
) ItemBackupper
|
||||
}
|
||||
|
||||
type defaultItemBackupperFactory struct{}
|
||||
|
||||
func (f *defaultItemBackupperFactory) newItemBackupper(
|
||||
backup *api.Backup,
|
||||
namespaces, resources *collections.IncludesExcludes,
|
||||
backedUpItems map[itemKey]struct{},
|
||||
actions []resolvedAction,
|
||||
podCommandExecutor podCommandExecutor,
|
||||
backupRequest *Request,
|
||||
podCommandExecutor podexec.PodCommandExecutor,
|
||||
tarWriter tarWriter,
|
||||
resourceHooks []resourceHook,
|
||||
dynamicFactory client.DynamicFactory,
|
||||
discoveryHelper discovery.Helper,
|
||||
snapshotService cloudprovider.SnapshotService,
|
||||
resticBackupper restic.Backupper,
|
||||
resticSnapshotTracker *pvcSnapshotTracker,
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter,
|
||||
) ItemBackupper {
|
||||
ib := &defaultItemBackupper{
|
||||
backup: backup,
|
||||
namespaces: namespaces,
|
||||
resources: resources,
|
||||
backedUpItems: backedUpItems,
|
||||
actions: actions,
|
||||
tarWriter: tarWriter,
|
||||
resourceHooks: resourceHooks,
|
||||
dynamicFactory: dynamicFactory,
|
||||
discoveryHelper: discoveryHelper,
|
||||
snapshotService: snapshotService,
|
||||
backupRequest: backupRequest,
|
||||
tarWriter: tarWriter,
|
||||
dynamicFactory: dynamicFactory,
|
||||
discoveryHelper: discoveryHelper,
|
||||
resticBackupper: resticBackupper,
|
||||
resticSnapshotTracker: resticSnapshotTracker,
|
||||
volumeSnapshotterGetter: volumeSnapshotterGetter,
|
||||
|
||||
itemHookHandler: &defaultItemHookHandler{
|
||||
podCommandExecutor: podCommandExecutor,
|
||||
},
|
||||
@@ -95,24 +94,19 @@ type ItemBackupper interface {
|
||||
}
|
||||
|
||||
type defaultItemBackupper struct {
|
||||
backup *api.Backup
|
||||
namespaces *collections.IncludesExcludes
|
||||
resources *collections.IncludesExcludes
|
||||
backedUpItems map[itemKey]struct{}
|
||||
actions []resolvedAction
|
||||
tarWriter tarWriter
|
||||
resourceHooks []resourceHook
|
||||
dynamicFactory client.DynamicFactory
|
||||
discoveryHelper discovery.Helper
|
||||
snapshotService cloudprovider.SnapshotService
|
||||
backupRequest *Request
|
||||
tarWriter tarWriter
|
||||
dynamicFactory client.DynamicFactory
|
||||
discoveryHelper discovery.Helper
|
||||
resticBackupper restic.Backupper
|
||||
resticSnapshotTracker *pvcSnapshotTracker
|
||||
volumeSnapshotterGetter VolumeSnapshotterGetter
|
||||
|
||||
itemHookHandler itemHookHandler
|
||||
additionalItemBackupper ItemBackupper
|
||||
itemHookHandler itemHookHandler
|
||||
additionalItemBackupper ItemBackupper
|
||||
snapshotLocationVolumeSnapshotters map[string]velero.VolumeSnapshotter
|
||||
}
|
||||
|
||||
var podsGroupResource = schema.GroupResource{Group: "", Resource: "pods"}
|
||||
var namespacesGroupResource = schema.GroupResource{Group: "", Resource: "namespaces"}
|
||||
|
||||
// backupItem backs up an individual item to tarWriter. The item may be excluded based on the
|
||||
// namespaces IncludesExcludes list.
|
||||
func (ib *defaultItemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstructured, groupResource schema.GroupResource) error {
|
||||
@@ -131,111 +125,112 @@ func (ib *defaultItemBackupper) backupItem(logger logrus.FieldLogger, obj runtim
|
||||
|
||||
// NOTE: we have to re-check namespace & resource includes/excludes because it's possible that
|
||||
// backupItem can be invoked by a custom action.
|
||||
if namespace != "" && !ib.namespaces.ShouldInclude(namespace) {
|
||||
if namespace != "" && !ib.backupRequest.NamespaceIncludesExcludes.ShouldInclude(namespace) {
|
||||
log.Info("Excluding item because namespace is excluded")
|
||||
return nil
|
||||
}
|
||||
|
||||
// NOTE: we specifically allow namespaces to be backed up even if IncludeClusterResources is
|
||||
// false.
|
||||
if namespace == "" && groupResource != namespacesGroupResource && ib.backup.Spec.IncludeClusterResources != nil && !*ib.backup.Spec.IncludeClusterResources {
|
||||
if namespace == "" && groupResource != kuberesource.Namespaces && ib.backupRequest.Spec.IncludeClusterResources != nil && !*ib.backupRequest.Spec.IncludeClusterResources {
|
||||
log.Info("Excluding item because resource is cluster-scoped and backup.spec.includeClusterResources is false")
|
||||
return nil
|
||||
}
|
||||
|
||||
if !ib.resources.ShouldInclude(groupResource.String()) {
|
||||
if !ib.backupRequest.ResourceIncludesExcludes.ShouldInclude(groupResource.String()) {
|
||||
log.Info("Excluding item because resource is excluded")
|
||||
return nil
|
||||
}
|
||||
|
||||
if metadata.GetDeletionTimestamp() != nil {
|
||||
log.Info("Skipping item because it's being deleted.")
|
||||
return nil
|
||||
}
|
||||
|
||||
key := itemKey{
|
||||
resource: groupResource.String(),
|
||||
resource: resourceKey(obj),
|
||||
namespace: namespace,
|
||||
name: name,
|
||||
}
|
||||
|
||||
if _, exists := ib.backedUpItems[key]; exists {
|
||||
if _, exists := ib.backupRequest.BackedUpItems[key]; exists {
|
||||
log.Info("Skipping item because it's already been backed up.")
|
||||
return nil
|
||||
}
|
||||
ib.backedUpItems[key] = struct{}{}
|
||||
ib.backupRequest.BackedUpItems[key] = struct{}{}
|
||||
|
||||
log.Info("Backing up resource")
|
||||
|
||||
// Never save status
|
||||
delete(obj.UnstructuredContent(), "status")
|
||||
log.Info("Backing up item")
|
||||
|
||||
log.Debug("Executing pre hooks")
|
||||
if err := ib.itemHookHandler.handleHooks(log, groupResource, obj, ib.resourceHooks, hookPhasePre); err != nil {
|
||||
if err := ib.itemHookHandler.handleHooks(log, groupResource, obj, ib.backupRequest.ResourceHooks, hookPhasePre); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, action := range ib.actions {
|
||||
if !action.resourceIncludesExcludes.ShouldInclude(groupResource.String()) {
|
||||
log.Debug("Skipping action because it does not apply to this resource")
|
||||
continue
|
||||
}
|
||||
var (
|
||||
backupErrs []error
|
||||
pod *corev1api.Pod
|
||||
resticVolumesToBackup []string
|
||||
)
|
||||
|
||||
if namespace != "" && !action.namespaceIncludesExcludes.ShouldInclude(namespace) {
|
||||
log.Debug("Skipping action because it does not apply to this namespace")
|
||||
continue
|
||||
}
|
||||
|
||||
if !action.selector.Matches(labels.Set(metadata.GetLabels())) {
|
||||
log.Debug("Skipping action because label selector does not match")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info("Executing custom action")
|
||||
|
||||
if logSetter, ok := action.ItemAction.(logging.LogSetter); ok {
|
||||
logSetter.SetLog(log)
|
||||
}
|
||||
|
||||
if updatedItem, additionalItemIdentifiers, err := action.Execute(obj, ib.backup); err == nil {
|
||||
obj = updatedItem
|
||||
|
||||
for _, additionalItem := range additionalItemIdentifiers {
|
||||
gvr, resource, err := ib.discoveryHelper.ResourceFor(additionalItem.GroupResource.WithVersion(""))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := ib.dynamicFactory.ClientForGroupVersionResource(gvr.GroupVersion(), resource, additionalItem.Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
additionalItem, err := client.Get(additionalItem.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ib.additionalItemBackupper.backupItem(log, additionalItem, gvr.GroupResource())
|
||||
}
|
||||
if groupResource == kuberesource.Pods {
|
||||
// pod needs to be initialized for the unstructured converter
|
||||
pod = new(corev1api.Pod)
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), pod); err != nil {
|
||||
backupErrs = append(backupErrs, errors.WithStack(err))
|
||||
// nil it on error since it's not valid
|
||||
pod = nil
|
||||
} else {
|
||||
// We want this to show up in the log file at the place where the error occurs. When we return
|
||||
// the error, it get aggregated with all the other ones at the end of the backup, making it
|
||||
// harder to tell when it happened.
|
||||
log.WithError(err).Error("error executing custom action")
|
||||
// get the volumes to backup using restic, and add any of them that are PVCs to the pvc snapshot
|
||||
// tracker, so that when we backup PVCs/PVs via an item action in the next step, we don't snapshot
|
||||
// PVs that will have their data backed up with restic.
|
||||
resticVolumesToBackup = restic.GetVolumesToBackup(pod)
|
||||
|
||||
return errors.Wrapf(err, "error executing custom action (groupResource=%s, namespace=%s, name=%s)", groupResource.String(), namespace, name)
|
||||
ib.resticSnapshotTracker.Track(pod, resticVolumesToBackup)
|
||||
}
|
||||
}
|
||||
|
||||
if groupResource == pvGroupResource {
|
||||
if ib.snapshotService == nil {
|
||||
log.Debug("Skipping Persistent Volume snapshot because they're not enabled.")
|
||||
} else {
|
||||
if err := ib.takePVSnapshot(obj, ib.backup, log); err != nil {
|
||||
return err
|
||||
}
|
||||
updatedObj, err := ib.executeActions(log, obj, groupResource, name, namespace, metadata)
|
||||
if err != nil {
|
||||
backupErrs = append(backupErrs, err)
|
||||
|
||||
// if there was an error running actions, execute post hooks and return
|
||||
log.Debug("Executing post hooks")
|
||||
if err := ib.itemHookHandler.handleHooks(log, groupResource, obj, ib.backupRequest.ResourceHooks, hookPhasePost); err != nil {
|
||||
backupErrs = append(backupErrs, err)
|
||||
}
|
||||
|
||||
return kubeerrs.NewAggregate(backupErrs)
|
||||
}
|
||||
obj = updatedObj
|
||||
if metadata, err = meta.Accessor(obj); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
// update name and namespace in case they were modified in an action
|
||||
name = metadata.GetName()
|
||||
namespace = metadata.GetNamespace()
|
||||
|
||||
if groupResource == kuberesource.PersistentVolumes {
|
||||
if err := ib.takePVSnapshot(obj, log); err != nil {
|
||||
backupErrs = append(backupErrs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if groupResource == kuberesource.Pods && pod != nil {
|
||||
// this function will return partial results, so process podVolumeBackups
|
||||
// even if there are errors.
|
||||
podVolumeBackups, errs := ib.backupPodVolumes(log, pod, resticVolumesToBackup)
|
||||
|
||||
ib.backupRequest.PodVolumeBackups = append(ib.backupRequest.PodVolumeBackups, podVolumeBackups...)
|
||||
backupErrs = append(backupErrs, errs...)
|
||||
}
|
||||
|
||||
log.Debug("Executing post hooks")
|
||||
if err := ib.itemHookHandler.handleHooks(log, groupResource, obj, ib.resourceHooks, hookPhasePost); err != nil {
|
||||
return err
|
||||
if err := ib.itemHookHandler.handleHooks(log, groupResource, obj, ib.backupRequest.ResourceHooks, hookPhasePost); err != nil {
|
||||
backupErrs = append(backupErrs, err)
|
||||
}
|
||||
|
||||
if len(backupErrs) != 0 {
|
||||
return kubeerrs.NewAggregate(backupErrs)
|
||||
}
|
||||
|
||||
var filePath string
|
||||
@@ -269,6 +264,106 @@ func (ib *defaultItemBackupper) backupItem(logger logrus.FieldLogger, obj runtim
|
||||
return nil
|
||||
}
|
||||
|
||||
// backupPodVolumes triggers restic backups of the specified pod volumes, and returns a list of PodVolumeBackups
|
||||
// for volumes that were successfully backed up, and a slice of any errors that were encountered.
|
||||
func (ib *defaultItemBackupper) backupPodVolumes(log logrus.FieldLogger, pod *corev1api.Pod, volumes []string) ([]*velerov1api.PodVolumeBackup, []error) {
|
||||
if len(volumes) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if ib.resticBackupper == nil {
|
||||
log.Warn("No restic backupper, not backing up pod's volumes")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return ib.resticBackupper.BackupPodVolumes(ib.backupRequest.Backup, pod, log)
|
||||
}
|
||||
|
||||
func (ib *defaultItemBackupper) executeActions(
|
||||
log logrus.FieldLogger,
|
||||
obj runtime.Unstructured,
|
||||
groupResource schema.GroupResource,
|
||||
name, namespace string,
|
||||
metadata metav1.Object,
|
||||
) (runtime.Unstructured, error) {
|
||||
for _, action := range ib.backupRequest.ResolvedActions {
|
||||
if !action.resourceIncludesExcludes.ShouldInclude(groupResource.String()) {
|
||||
log.Debug("Skipping action because it does not apply to this resource")
|
||||
continue
|
||||
}
|
||||
|
||||
if namespace != "" && !action.namespaceIncludesExcludes.ShouldInclude(namespace) {
|
||||
log.Debug("Skipping action because it does not apply to this namespace")
|
||||
continue
|
||||
}
|
||||
|
||||
if namespace == "" && !action.namespaceIncludesExcludes.IncludeEverything() {
|
||||
log.Debug("Skipping action because resource is cluster-scoped and action only applies to specific namespaces")
|
||||
continue
|
||||
}
|
||||
|
||||
if !action.selector.Matches(labels.Set(metadata.GetLabels())) {
|
||||
log.Debug("Skipping action because label selector does not match")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info("Executing custom action")
|
||||
|
||||
updatedItem, additionalItemIdentifiers, err := action.Execute(obj, ib.backupRequest.Backup)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error executing custom action (groupResource=%s, namespace=%s, name=%s)", groupResource.String(), namespace, name)
|
||||
}
|
||||
obj = updatedItem
|
||||
|
||||
for _, additionalItem := range additionalItemIdentifiers {
|
||||
gvr, resource, err := ib.discoveryHelper.ResourceFor(additionalItem.GroupResource.WithVersion(""))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := ib.dynamicFactory.ClientForGroupVersionResource(gvr.GroupVersion(), resource, additionalItem.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
additionalItem, err := client.Get(additionalItem.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
if err = ib.additionalItemBackupper.backupItem(log, additionalItem, gvr.GroupResource()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
// volumeSnapshotter instantiates and initializes a VolumeSnapshotter given a VolumeSnapshotLocation,
|
||||
// or returns an existing one if one's already been initialized for the location.
|
||||
func (ib *defaultItemBackupper) volumeSnapshotter(snapshotLocation *api.VolumeSnapshotLocation) (velero.VolumeSnapshotter, error) {
|
||||
if bs, ok := ib.snapshotLocationVolumeSnapshotters[snapshotLocation.Name]; ok {
|
||||
return bs, nil
|
||||
}
|
||||
|
||||
bs, err := ib.volumeSnapshotterGetter.GetVolumeSnapshotter(snapshotLocation.Spec.Provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := bs.Init(snapshotLocation.Spec.Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ib.snapshotLocationVolumeSnapshotters == nil {
|
||||
ib.snapshotLocationVolumeSnapshotters = make(map[string]velero.VolumeSnapshotter)
|
||||
}
|
||||
ib.snapshotLocationVolumeSnapshotters[snapshotLocation.Name] = bs
|
||||
|
||||
return bs, nil
|
||||
}
|
||||
|
||||
// zoneLabel is the label that stores availability-zone info
|
||||
// on PVs
|
||||
const zoneLabel = "failure-domain.beta.kubernetes.io/zone"
|
||||
@@ -276,69 +371,123 @@ const zoneLabel = "failure-domain.beta.kubernetes.io/zone"
|
||||
// takePVSnapshot triggers a snapshot for the volume/disk underlying a PersistentVolume if the provided
|
||||
// backup has volume snapshots enabled and the PV is of a compatible type. Also records cloud
|
||||
// disk type and IOPS (if applicable) to be able to restore to current state later.
|
||||
func (ib *defaultItemBackupper) takePVSnapshot(pv runtime.Unstructured, backup *api.Backup, log logrus.FieldLogger) error {
|
||||
func (ib *defaultItemBackupper) takePVSnapshot(obj runtime.Unstructured, log logrus.FieldLogger) error {
|
||||
log.Info("Executing takePVSnapshot")
|
||||
|
||||
if backup.Spec.SnapshotVolumes != nil && !*backup.Spec.SnapshotVolumes {
|
||||
if ib.backupRequest.Spec.SnapshotVolumes != nil && !*ib.backupRequest.Spec.SnapshotVolumes {
|
||||
log.Info("Backup has volume snapshots disabled; skipping volume snapshot action.")
|
||||
return nil
|
||||
}
|
||||
|
||||
metadata, err := meta.Accessor(pv)
|
||||
if err != nil {
|
||||
pv := new(corev1api.PersistentVolume)
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), pv); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
name := metadata.GetName()
|
||||
var pvFailureDomainZone string
|
||||
labels := metadata.GetLabels()
|
||||
log = log.WithField("persistentVolume", pv.Name)
|
||||
|
||||
if labels[zoneLabel] != "" {
|
||||
pvFailureDomainZone = labels[zoneLabel]
|
||||
} else {
|
||||
// If this PV is claimed, see if we've already taken a (restic) snapshot of the contents
|
||||
// of this PV. If so, don't take a snapshot.
|
||||
if pv.Spec.ClaimRef != nil {
|
||||
if ib.resticSnapshotTracker.Has(pv.Spec.ClaimRef.Namespace, pv.Spec.ClaimRef.Name) {
|
||||
log.Info("Skipping persistent volume snapshot because volume has already been backed up with restic.")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
pvFailureDomainZone := pv.Labels[zoneLabel]
|
||||
if pvFailureDomainZone == "" {
|
||||
log.Infof("label %q is not present on PersistentVolume", zoneLabel)
|
||||
}
|
||||
|
||||
volumeID, err := ib.snapshotService.GetVolumeID(pv)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error getting volume ID for PersistentVolume")
|
||||
var (
|
||||
volumeID, location string
|
||||
volumeSnapshotter velero.VolumeSnapshotter
|
||||
)
|
||||
|
||||
for _, snapshotLocation := range ib.backupRequest.SnapshotLocations {
|
||||
log := log.WithField("volumeSnapshotLocation", snapshotLocation.Name)
|
||||
|
||||
bs, err := ib.volumeSnapshotter(snapshotLocation)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("Error getting volume snapshotter for volume snapshot location")
|
||||
continue
|
||||
}
|
||||
|
||||
if volumeID, err = bs.GetVolumeID(obj); err != nil {
|
||||
log.WithError(err).Errorf("Error attempting to get volume ID for persistent volume")
|
||||
continue
|
||||
}
|
||||
if volumeID == "" {
|
||||
log.Infof("No volume ID returned by volume snapshotter for persistent volume")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("Got volume ID for persistent volume")
|
||||
volumeSnapshotter = bs
|
||||
location = snapshotLocation.Name
|
||||
break
|
||||
}
|
||||
if volumeID == "" {
|
||||
log.Info("PersistentVolume is not a supported volume type for snapshots, skipping.")
|
||||
|
||||
if volumeSnapshotter == nil {
|
||||
log.Info("Persistent volume is not a supported volume type for snapshots, skipping.")
|
||||
return nil
|
||||
}
|
||||
|
||||
log = log.WithField("volumeID", volumeID)
|
||||
|
||||
tags := map[string]string{
|
||||
"ark.heptio.com/backup": backup.Name,
|
||||
"ark.heptio.com/pv": metadata.GetName(),
|
||||
tags := ib.backupRequest.GetLabels()
|
||||
if tags == nil {
|
||||
tags = map[string]string{}
|
||||
}
|
||||
tags["velero.io/backup"] = ib.backupRequest.Name
|
||||
tags["velero.io/pv"] = pv.Name
|
||||
|
||||
log.Info("Snapshotting PersistentVolume")
|
||||
snapshotID, err := ib.snapshotService.CreateSnapshot(volumeID, pvFailureDomainZone, tags)
|
||||
log.Info("Getting volume information")
|
||||
volumeType, iops, err := volumeSnapshotter.GetVolumeInfo(volumeID, pvFailureDomainZone)
|
||||
if err != nil {
|
||||
// log+error on purpose - log goes to the per-backup log file, error goes to the backup
|
||||
log.WithError(err).Error("error creating snapshot")
|
||||
return errors.WithMessage(err, "error creating snapshot")
|
||||
}
|
||||
|
||||
volumeType, iops, err := ib.snapshotService.GetVolumeInfo(volumeID, pvFailureDomainZone)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("error getting volume info")
|
||||
return errors.WithMessage(err, "error getting volume info")
|
||||
}
|
||||
|
||||
if backup.Status.VolumeBackups == nil {
|
||||
backup.Status.VolumeBackups = make(map[string]*api.VolumeBackupInfo)
|
||||
}
|
||||
log.Info("Snapshotting persistent volume")
|
||||
snapshot := volumeSnapshot(ib.backupRequest.Backup, pv.Name, volumeID, volumeType, pvFailureDomainZone, location, iops)
|
||||
|
||||
backup.Status.VolumeBackups[name] = &api.VolumeBackupInfo{
|
||||
SnapshotID: snapshotID,
|
||||
Type: volumeType,
|
||||
Iops: iops,
|
||||
AvailabilityZone: pvFailureDomainZone,
|
||||
var errs []error
|
||||
snapshotID, err := volumeSnapshotter.CreateSnapshot(snapshot.Spec.ProviderVolumeID, snapshot.Spec.VolumeAZ, tags)
|
||||
if err != nil {
|
||||
errs = append(errs, errors.Wrap(err, "error taking snapshot of volume"))
|
||||
snapshot.Status.Phase = volume.SnapshotPhaseFailed
|
||||
} else {
|
||||
snapshot.Status.Phase = volume.SnapshotPhaseCompleted
|
||||
snapshot.Status.ProviderSnapshotID = snapshotID
|
||||
}
|
||||
ib.backupRequest.VolumeSnapshots = append(ib.backupRequest.VolumeSnapshots, snapshot)
|
||||
|
||||
return nil
|
||||
// nil errors are automatically removed
|
||||
return kubeerrs.NewAggregate(errs)
|
||||
}
|
||||
|
||||
func volumeSnapshot(backup *api.Backup, volumeName, volumeID, volumeType, az, location string, iops *int64) *volume.Snapshot {
|
||||
return &volume.Snapshot{
|
||||
Spec: volume.SnapshotSpec{
|
||||
BackupName: backup.Name,
|
||||
BackupUID: string(backup.UID),
|
||||
Location: location,
|
||||
PersistentVolumeName: volumeName,
|
||||
ProviderVolumeID: volumeID,
|
||||
VolumeType: volumeType,
|
||||
VolumeAZ: az,
|
||||
VolumeIOPS: iops,
|
||||
},
|
||||
Status: volume.SnapshotStatus{
|
||||
Phase: volume.SnapshotPhaseNew,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// resourceKey returns a string representing the object's GroupVersionKind (e.g.
|
||||
// apps/v1/Deployment).
|
||||
func resourceKey(obj runtime.Unstructured) string {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
return fmt.Sprintf("%s/%s", gvk.GroupVersion().String(), gvk.Kind)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2019 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,602 +17,31 @@ limitations under the License.
|
||||
package backup
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
api "github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
arktest "github.com/heptio/ark/pkg/util/test"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/heptio/velero/pkg/builder"
|
||||
)
|
||||
|
||||
func TestBackupItemSkips(t *testing.T) {
|
||||
func Test_resourceKey(t *testing.T) {
|
||||
tests := []struct {
|
||||
testName string
|
||||
namespace string
|
||||
name string
|
||||
namespaces *collections.IncludesExcludes
|
||||
groupResource schema.GroupResource
|
||||
resources *collections.IncludesExcludes
|
||||
backedUpItems map[itemKey]struct{}
|
||||
resource metav1.Object
|
||||
want string
|
||||
}{
|
||||
{
|
||||
testName: "namespace not in includes list",
|
||||
namespace: "ns",
|
||||
name: "foo",
|
||||
namespaces: collections.NewIncludesExcludes().Includes("a"),
|
||||
},
|
||||
{
|
||||
testName: "namespace in excludes list",
|
||||
namespace: "ns",
|
||||
name: "foo",
|
||||
namespaces: collections.NewIncludesExcludes().Excludes("ns"),
|
||||
},
|
||||
{
|
||||
testName: "resource not in includes list",
|
||||
namespace: "ns",
|
||||
name: "foo",
|
||||
groupResource: schema.GroupResource{Group: "foo", Resource: "bar"},
|
||||
namespaces: collections.NewIncludesExcludes(),
|
||||
resources: collections.NewIncludesExcludes().Includes("a.b"),
|
||||
},
|
||||
{
|
||||
testName: "resource in excludes list",
|
||||
namespace: "ns",
|
||||
name: "foo",
|
||||
groupResource: schema.GroupResource{Group: "foo", Resource: "bar"},
|
||||
namespaces: collections.NewIncludesExcludes(),
|
||||
resources: collections.NewIncludesExcludes().Excludes("bar.foo"),
|
||||
},
|
||||
{
|
||||
testName: "resource already backed up",
|
||||
namespace: "ns",
|
||||
name: "foo",
|
||||
groupResource: schema.GroupResource{Group: "foo", Resource: "bar"},
|
||||
namespaces: collections.NewIncludesExcludes(),
|
||||
resources: collections.NewIncludesExcludes(),
|
||||
backedUpItems: map[itemKey]struct{}{
|
||||
{resource: "bar.foo", namespace: "ns", name: "foo"}: {},
|
||||
},
|
||||
},
|
||||
{resource: builder.ForPod("default", "test").Result(), want: "v1/Pod"},
|
||||
{resource: builder.ForDeployment("default", "test").Result(), want: "apps/v1/Deployment"},
|
||||
{resource: builder.ForPersistentVolume("test").Result(), want: "v1/PersistentVolume"},
|
||||
{resource: builder.ForRole("default", "test").Result(), want: "rbac.authorization.k8s.io/v1/Role"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.testName, func(t *testing.T) {
|
||||
ib := &defaultItemBackupper{
|
||||
namespaces: test.namespaces,
|
||||
resources: test.resources,
|
||||
backedUpItems: test.backedUpItems,
|
||||
}
|
||||
|
||||
u := unstructuredOrDie(fmt.Sprintf(`{"apiVersion":"v1","kind":"Pod","metadata":{"namespace":"%s","name":"%s"}}`, test.namespace, test.name))
|
||||
err := ib.backupItem(arktest.NewLogger(), u, test.groupResource)
|
||||
assert.NoError(t, err)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.want, func(t *testing.T) {
|
||||
content, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(tt.resource)
|
||||
unstructured := &unstructured.Unstructured{Object: content}
|
||||
assert.Equal(t, tt.want, resourceKey(unstructured))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackupItemSkipsClusterScopedResourceWhenIncludeClusterResourcesFalse(t *testing.T) {
|
||||
f := false
|
||||
ib := &defaultItemBackupper{
|
||||
backup: &v1.Backup{
|
||||
Spec: v1.BackupSpec{
|
||||
IncludeClusterResources: &f,
|
||||
},
|
||||
},
|
||||
namespaces: collections.NewIncludesExcludes(),
|
||||
resources: collections.NewIncludesExcludes(),
|
||||
}
|
||||
|
||||
u := unstructuredOrDie(`{"apiVersion":"v1","kind":"Foo","metadata":{"name":"bar"}}`)
|
||||
err := ib.backupItem(arktest.NewLogger(), u, schema.GroupResource{Group: "foo", Resource: "bar"})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestBackupItemNoSkips(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
item string
|
||||
namespaceIncludesExcludes *collections.IncludesExcludes
|
||||
expectError bool
|
||||
expectExcluded bool
|
||||
expectedTarHeaderName string
|
||||
tarWriteError bool
|
||||
tarHeaderWriteError bool
|
||||
customAction bool
|
||||
expectedActionID string
|
||||
customActionAdditionalItemIdentifiers []ResourceIdentifier
|
||||
customActionAdditionalItems []runtime.Unstructured
|
||||
groupResource string
|
||||
snapshottableVolumes map[string]api.VolumeBackupInfo
|
||||
}{
|
||||
{
|
||||
name: "explicit namespace include",
|
||||
item: `{"metadata":{"namespace":"foo","name":"bar"}}`,
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes().Includes("foo"),
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/resource.group/namespaces/foo/bar.json",
|
||||
},
|
||||
{
|
||||
name: "* namespace include",
|
||||
item: `{"metadata":{"namespace":"foo","name":"bar"}}`,
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes().Includes("*"),
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/resource.group/namespaces/foo/bar.json",
|
||||
},
|
||||
{
|
||||
name: "cluster-scoped",
|
||||
item: `{"metadata":{"name":"bar"}}`,
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/resource.group/cluster/bar.json",
|
||||
},
|
||||
{
|
||||
name: "make sure status is deleted",
|
||||
item: `{"metadata":{"name":"bar"},"spec":{"color":"green"},"status":{"foo":"bar"}}`,
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/resource.group/cluster/bar.json",
|
||||
},
|
||||
{
|
||||
name: "tar header write error",
|
||||
item: `{"metadata":{"name":"bar"},"spec":{"color":"green"},"status":{"foo":"bar"}}`,
|
||||
expectError: true,
|
||||
tarHeaderWriteError: true,
|
||||
},
|
||||
{
|
||||
name: "tar write error",
|
||||
item: `{"metadata":{"name":"bar"},"spec":{"color":"green"},"status":{"foo":"bar"}}`,
|
||||
expectError: true,
|
||||
tarWriteError: true,
|
||||
},
|
||||
{
|
||||
name: "action invoked - cluster-scoped",
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes().Includes("*"),
|
||||
item: `{"metadata":{"name":"bar"}}`,
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/resource.group/cluster/bar.json",
|
||||
customAction: true,
|
||||
expectedActionID: "bar",
|
||||
},
|
||||
{
|
||||
name: "action invoked - namespaced",
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes().Includes("*"),
|
||||
item: `{"metadata":{"namespace": "myns", "name":"bar"}}`,
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/resource.group/namespaces/myns/bar.json",
|
||||
customAction: true,
|
||||
expectedActionID: "myns/bar",
|
||||
},
|
||||
{
|
||||
name: "action invoked - additional items",
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes().Includes("*"),
|
||||
item: `{"metadata":{"namespace": "myns", "name":"bar"}}`,
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/resource.group/namespaces/myns/bar.json",
|
||||
customAction: true,
|
||||
expectedActionID: "myns/bar",
|
||||
customActionAdditionalItemIdentifiers: []ResourceIdentifier{
|
||||
{
|
||||
GroupResource: schema.GroupResource{Group: "g1", Resource: "r1"},
|
||||
Namespace: "ns1",
|
||||
Name: "n1",
|
||||
},
|
||||
{
|
||||
GroupResource: schema.GroupResource{Group: "g2", Resource: "r2"},
|
||||
Namespace: "ns2",
|
||||
Name: "n2",
|
||||
},
|
||||
},
|
||||
customActionAdditionalItems: []runtime.Unstructured{
|
||||
unstructuredOrDie(`{"apiVersion":"g1/v1","kind":"r1","metadata":{"namespace":"ns1","name":"n1"}}`),
|
||||
unstructuredOrDie(`{"apiVersion":"g2/v1","kind":"r1","metadata":{"namespace":"ns2","name":"n2"}}`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "takePVSnapshot is not invoked for PVs when snapshotService == nil",
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes().Includes("*"),
|
||||
item: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv", "labels": {"failure-domain.beta.kubernetes.io/zone": "us-east-1c"}}, "spec": {"awsElasticBlockStore": {"volumeID": "aws://us-east-1c/vol-abc123"}}}`,
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/persistentvolumes/cluster/mypv.json",
|
||||
groupResource: "persistentvolumes",
|
||||
},
|
||||
{
|
||||
name: "takePVSnapshot is invoked for PVs when snapshotService != nil",
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes().Includes("*"),
|
||||
item: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv", "labels": {"failure-domain.beta.kubernetes.io/zone": "us-east-1c"}}, "spec": {"awsElasticBlockStore": {"volumeID": "aws://us-east-1c/vol-abc123"}}}`,
|
||||
expectError: false,
|
||||
expectExcluded: false,
|
||||
expectedTarHeaderName: "resources/persistentvolumes/cluster/mypv.json",
|
||||
groupResource: "persistentvolumes",
|
||||
snapshottableVolumes: map[string]api.VolumeBackupInfo{
|
||||
"vol-abc123": {SnapshotID: "snapshot-1", AvailabilityZone: "us-east-1c"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
var (
|
||||
actions []resolvedAction
|
||||
action *fakeAction
|
||||
backup = &v1.Backup{}
|
||||
groupResource = schema.ParseGroupResource("resource.group")
|
||||
backedUpItems = make(map[itemKey]struct{})
|
||||
resources = collections.NewIncludesExcludes()
|
||||
w = &fakeTarWriter{}
|
||||
)
|
||||
|
||||
if test.groupResource != "" {
|
||||
groupResource = schema.ParseGroupResource(test.groupResource)
|
||||
}
|
||||
|
||||
item, err := getAsMap(test.item)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
namespaces := test.namespaceIncludesExcludes
|
||||
if namespaces == nil {
|
||||
namespaces = collections.NewIncludesExcludes()
|
||||
}
|
||||
|
||||
if test.tarHeaderWriteError {
|
||||
w.writeHeaderError = errors.New("error")
|
||||
}
|
||||
if test.tarWriteError {
|
||||
w.writeError = errors.New("error")
|
||||
}
|
||||
|
||||
if test.customAction {
|
||||
action = &fakeAction{
|
||||
additionalItems: test.customActionAdditionalItemIdentifiers,
|
||||
}
|
||||
actions = []resolvedAction{
|
||||
{
|
||||
ItemAction: action,
|
||||
namespaceIncludesExcludes: collections.NewIncludesExcludes(),
|
||||
resourceIncludesExcludes: collections.NewIncludesExcludes().Includes(groupResource.String()),
|
||||
selector: labels.Everything(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
resourceHooks := []resourceHook{}
|
||||
|
||||
podCommandExecutor := &mockPodCommandExecutor{}
|
||||
defer podCommandExecutor.AssertExpectations(t)
|
||||
|
||||
dynamicFactory := &arktest.FakeDynamicFactory{}
|
||||
defer dynamicFactory.AssertExpectations(t)
|
||||
|
||||
discoveryHelper := arktest.NewFakeDiscoveryHelper(true, nil)
|
||||
|
||||
b := (&defaultItemBackupperFactory{}).newItemBackupper(
|
||||
backup,
|
||||
namespaces,
|
||||
resources,
|
||||
backedUpItems,
|
||||
actions,
|
||||
podCommandExecutor,
|
||||
w,
|
||||
resourceHooks,
|
||||
dynamicFactory,
|
||||
discoveryHelper,
|
||||
nil,
|
||||
).(*defaultItemBackupper)
|
||||
|
||||
var snapshotService *arktest.FakeSnapshotService
|
||||
if test.snapshottableVolumes != nil {
|
||||
snapshotService = &arktest.FakeSnapshotService{
|
||||
SnapshottableVolumes: test.snapshottableVolumes,
|
||||
VolumeID: "vol-abc123",
|
||||
}
|
||||
b.snapshotService = snapshotService
|
||||
}
|
||||
|
||||
// make sure the podCommandExecutor was set correctly in the real hook handler
|
||||
assert.Equal(t, podCommandExecutor, b.itemHookHandler.(*defaultItemHookHandler).podCommandExecutor)
|
||||
|
||||
itemHookHandler := &mockItemHookHandler{}
|
||||
defer itemHookHandler.AssertExpectations(t)
|
||||
b.itemHookHandler = itemHookHandler
|
||||
|
||||
additionalItemBackupper := &mockItemBackupper{}
|
||||
defer additionalItemBackupper.AssertExpectations(t)
|
||||
b.additionalItemBackupper = additionalItemBackupper
|
||||
|
||||
obj := &unstructured.Unstructured{Object: item}
|
||||
itemHookHandler.On("handleHooks", mock.Anything, groupResource, obj, resourceHooks, hookPhasePre).Return(nil)
|
||||
itemHookHandler.On("handleHooks", mock.Anything, groupResource, obj, resourceHooks, hookPhasePost).Return(nil)
|
||||
|
||||
for i, item := range test.customActionAdditionalItemIdentifiers {
|
||||
itemClient := &arktest.FakeDynamicClient{}
|
||||
defer itemClient.AssertExpectations(t)
|
||||
|
||||
dynamicFactory.On("ClientForGroupVersionResource", item.GroupResource.WithVersion("").GroupVersion(), metav1.APIResource{Name: item.Resource}, item.Namespace).Return(itemClient, nil)
|
||||
|
||||
itemClient.On("Get", item.Name, metav1.GetOptions{}).Return(test.customActionAdditionalItems[i], nil)
|
||||
|
||||
additionalItemBackupper.On("backupItem", mock.AnythingOfType("*logrus.Entry"), test.customActionAdditionalItems[i], item.GroupResource).Return(nil)
|
||||
}
|
||||
|
||||
err = b.backupItem(arktest.NewLogger(), obj, groupResource)
|
||||
gotError := err != nil
|
||||
if e, a := test.expectError, gotError; e != a {
|
||||
t.Fatalf("error: expected %t, got %t: %v", e, a, err)
|
||||
}
|
||||
if test.expectError {
|
||||
return
|
||||
}
|
||||
|
||||
if test.expectExcluded {
|
||||
if len(w.headers) > 0 {
|
||||
t.Errorf("unexpected header write")
|
||||
}
|
||||
if len(w.data) > 0 {
|
||||
t.Errorf("unexpected data write")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// we have to delete status as that's what backupItem does,
|
||||
// and this ensures that we're verifying the right data
|
||||
delete(item, "status")
|
||||
itemWithoutStatus, err := json.Marshal(&item)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
require.Equal(t, 1, len(w.headers), "headers")
|
||||
assert.Equal(t, test.expectedTarHeaderName, w.headers[0].Name, "header.name")
|
||||
assert.Equal(t, int64(len(itemWithoutStatus)), w.headers[0].Size, "header.size")
|
||||
assert.Equal(t, byte(tar.TypeReg), w.headers[0].Typeflag, "header.typeflag")
|
||||
assert.Equal(t, int64(0755), w.headers[0].Mode, "header.mode")
|
||||
assert.False(t, w.headers[0].ModTime.IsZero(), "header.modTime set")
|
||||
assert.Equal(t, 1, len(w.data), "# of data")
|
||||
|
||||
actual, err := getAsMap(string(w.data[0]))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if e, a := item, actual; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("data: expected %s, got %s", e, a)
|
||||
}
|
||||
|
||||
if test.customAction {
|
||||
if len(action.ids) != 1 {
|
||||
t.Errorf("unexpected custom action ids: %v", action.ids)
|
||||
} else if e, a := test.expectedActionID, action.ids[0]; e != a {
|
||||
t.Errorf("action.ids[0]: expected %s, got %s", e, a)
|
||||
}
|
||||
|
||||
require.Equal(t, 1, len(action.backups), "unexpected custom action backups: %#v", action.backups)
|
||||
assert.Equal(t, backup, &(action.backups[0]), "backup")
|
||||
}
|
||||
|
||||
if test.snapshottableVolumes != nil {
|
||||
require.Equal(t, 1, len(snapshotService.SnapshotsTaken))
|
||||
|
||||
var expectedBackups []api.VolumeBackupInfo
|
||||
for _, vbi := range test.snapshottableVolumes {
|
||||
expectedBackups = append(expectedBackups, vbi)
|
||||
}
|
||||
|
||||
var actualBackups []api.VolumeBackupInfo
|
||||
for _, vbi := range backup.Status.VolumeBackups {
|
||||
actualBackups = append(actualBackups, *vbi)
|
||||
}
|
||||
|
||||
assert.Equal(t, expectedBackups, actualBackups)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTakePVSnapshot(t *testing.T) {
|
||||
iops := int64(1000)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
snapshotEnabled bool
|
||||
pv string
|
||||
ttl time.Duration
|
||||
expectError bool
|
||||
expectedVolumeID string
|
||||
expectedSnapshotsTaken int
|
||||
existingVolumeBackups map[string]*v1.VolumeBackupInfo
|
||||
volumeInfo map[string]v1.VolumeBackupInfo
|
||||
}{
|
||||
{
|
||||
name: "snapshot disabled",
|
||||
pv: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv"}}`,
|
||||
snapshotEnabled: false,
|
||||
},
|
||||
{
|
||||
name: "unsupported PV source type",
|
||||
snapshotEnabled: true,
|
||||
pv: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv"}, "spec": {"unsupportedPVSource": {}}}`,
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "without iops",
|
||||
snapshotEnabled: true,
|
||||
pv: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv", "labels": {"failure-domain.beta.kubernetes.io/zone": "us-east-1c"}}, "spec": {"awsElasticBlockStore": {"volumeID": "aws://us-east-1c/vol-abc123"}}}`,
|
||||
expectError: false,
|
||||
expectedSnapshotsTaken: 1,
|
||||
expectedVolumeID: "vol-abc123",
|
||||
ttl: 5 * time.Minute,
|
||||
volumeInfo: map[string]v1.VolumeBackupInfo{
|
||||
"vol-abc123": {Type: "gp", SnapshotID: "snap-1", AvailabilityZone: "us-east-1c"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with iops",
|
||||
snapshotEnabled: true,
|
||||
pv: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv", "labels": {"failure-domain.beta.kubernetes.io/zone": "us-east-1c"}}, "spec": {"awsElasticBlockStore": {"volumeID": "aws://us-east-1c/vol-abc123"}}}`,
|
||||
expectError: false,
|
||||
expectedSnapshotsTaken: 1,
|
||||
expectedVolumeID: "vol-abc123",
|
||||
ttl: 5 * time.Minute,
|
||||
volumeInfo: map[string]v1.VolumeBackupInfo{
|
||||
"vol-abc123": {Type: "io1", Iops: &iops, SnapshotID: "snap-1", AvailabilityZone: "us-east-1c"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "preexisting volume backup info in backup status",
|
||||
snapshotEnabled: true,
|
||||
pv: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv"}, "spec": {"gcePersistentDisk": {"pdName": "pd-abc123"}}}`,
|
||||
expectError: false,
|
||||
expectedSnapshotsTaken: 1,
|
||||
expectedVolumeID: "pd-abc123",
|
||||
ttl: 5 * time.Minute,
|
||||
existingVolumeBackups: map[string]*v1.VolumeBackupInfo{
|
||||
"anotherpv": {SnapshotID: "anothersnap"},
|
||||
},
|
||||
volumeInfo: map[string]v1.VolumeBackupInfo{
|
||||
"pd-abc123": {Type: "gp", SnapshotID: "snap-1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "create snapshot error",
|
||||
snapshotEnabled: true,
|
||||
pv: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv"}, "spec": {"gcePersistentDisk": {"pdName": "pd-abc123"}}}`,
|
||||
expectedVolumeID: "pd-abc123",
|
||||
expectError: true,
|
||||
},
|
||||
{
|
||||
name: "PV with label metadata but no failureDomainZone",
|
||||
snapshotEnabled: true,
|
||||
pv: `{"apiVersion": "v1", "kind": "PersistentVolume", "metadata": {"name": "mypv", "labels": {"failure-domain.beta.kubernetes.io/region": "us-east-1"}}, "spec": {"awsElasticBlockStore": {"volumeID": "aws://us-east-1c/vol-abc123"}}}`,
|
||||
expectError: false,
|
||||
expectedSnapshotsTaken: 1,
|
||||
expectedVolumeID: "vol-abc123",
|
||||
ttl: 5 * time.Minute,
|
||||
volumeInfo: map[string]v1.VolumeBackupInfo{
|
||||
"vol-abc123": {Type: "gp", SnapshotID: "snap-1"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
backup := &v1.Backup{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: v1.DefaultNamespace,
|
||||
Name: "mybackup",
|
||||
},
|
||||
Spec: v1.BackupSpec{
|
||||
SnapshotVolumes: &test.snapshotEnabled,
|
||||
TTL: metav1.Duration{Duration: test.ttl},
|
||||
},
|
||||
Status: v1.BackupStatus{
|
||||
VolumeBackups: test.existingVolumeBackups,
|
||||
},
|
||||
}
|
||||
|
||||
snapshotService := &arktest.FakeSnapshotService{
|
||||
SnapshottableVolumes: test.volumeInfo,
|
||||
VolumeID: test.expectedVolumeID,
|
||||
}
|
||||
|
||||
ib := &defaultItemBackupper{snapshotService: snapshotService}
|
||||
|
||||
pv, err := getAsMap(test.pv)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// method under test
|
||||
err = ib.takePVSnapshot(&unstructured.Unstructured{Object: pv}, backup, arktest.NewLogger())
|
||||
|
||||
gotErr := err != nil
|
||||
|
||||
if e, a := test.expectError, gotErr; e != a {
|
||||
t.Errorf("error: expected %v, got %v", e, a)
|
||||
}
|
||||
if test.expectError {
|
||||
return
|
||||
}
|
||||
|
||||
if !test.snapshotEnabled {
|
||||
// don't need to check anything else if snapshots are disabled
|
||||
return
|
||||
}
|
||||
|
||||
expectedVolumeBackups := test.existingVolumeBackups
|
||||
if expectedVolumeBackups == nil {
|
||||
expectedVolumeBackups = make(map[string]*v1.VolumeBackupInfo)
|
||||
}
|
||||
|
||||
// we should have one snapshot taken exactly
|
||||
require.Equal(t, test.expectedSnapshotsTaken, snapshotService.SnapshotsTaken.Len())
|
||||
|
||||
if test.expectedSnapshotsTaken > 0 {
|
||||
// the snapshotID should be the one in the entry in snapshotService.SnapshottableVolumes
|
||||
// for the volume we ran the test for
|
||||
snapshotID, _ := snapshotService.SnapshotsTaken.PopAny()
|
||||
|
||||
expectedVolumeBackups["mypv"] = &v1.VolumeBackupInfo{
|
||||
SnapshotID: snapshotID,
|
||||
Type: test.volumeInfo[test.expectedVolumeID].Type,
|
||||
Iops: test.volumeInfo[test.expectedVolumeID].Iops,
|
||||
AvailabilityZone: test.volumeInfo[test.expectedVolumeID].AvailabilityZone,
|
||||
}
|
||||
|
||||
if e, a := expectedVolumeBackups, backup.Status.VolumeBackups; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("backup.status.VolumeBackups: expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeTarWriter struct {
|
||||
closeCalled bool
|
||||
headers []*tar.Header
|
||||
data [][]byte
|
||||
writeHeaderError error
|
||||
writeError error
|
||||
}
|
||||
|
||||
func (w *fakeTarWriter) Close() error { return nil }
|
||||
|
||||
func (w *fakeTarWriter) Write(data []byte) (int, error) {
|
||||
w.data = append(w.data, data)
|
||||
return 0, w.writeError
|
||||
}
|
||||
|
||||
func (w *fakeTarWriter) WriteHeader(header *tar.Header) error {
|
||||
w.headers = append(w.headers, header)
|
||||
return w.writeHeaderError
|
||||
}
|
||||
|
||||
type mockItemBackupper struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (ib *mockItemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstructured, groupResource schema.GroupResource) error {
|
||||
args := ib.Called(logger, obj, groupResource)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -21,8 +21,6 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
api "github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
@@ -30,6 +28,11 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
api "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
"github.com/heptio/velero/pkg/kuberesource"
|
||||
"github.com/heptio/velero/pkg/podexec"
|
||||
"github.com/heptio/velero/pkg/util/collections"
|
||||
)
|
||||
|
||||
type hookPhase string
|
||||
@@ -56,7 +59,7 @@ type itemHookHandler interface {
|
||||
|
||||
// defaultItemHookHandler is the default itemHookHandler.
|
||||
type defaultItemHookHandler struct {
|
||||
podCommandExecutor podCommandExecutor
|
||||
podCommandExecutor podexec.PodCommandExecutor
|
||||
}
|
||||
|
||||
func (h *defaultItemHookHandler) handleHooks(
|
||||
@@ -67,7 +70,7 @@ func (h *defaultItemHookHandler) handleHooks(
|
||||
phase hookPhase,
|
||||
) error {
|
||||
// We only support hooks on pods right now
|
||||
if groupResource != podsGroupResource {
|
||||
if groupResource != kuberesource.Pods {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -93,7 +96,7 @@ func (h *defaultItemHookHandler) handleHooks(
|
||||
"hookPhase": phase,
|
||||
},
|
||||
)
|
||||
if err := h.podCommandExecutor.executePodCommand(hookLog, obj.UnstructuredContent(), namespace, name, "<from-annotation>", hookFromAnnotations); err != nil {
|
||||
if err := h.podCommandExecutor.ExecutePodCommand(hookLog, obj.UnstructuredContent(), namespace, name, "<from-annotation>", hookFromAnnotations); err != nil {
|
||||
hookLog.WithError(err).Error("Error executing hook")
|
||||
if hookFromAnnotations.OnError == api.HookErrorModeFail {
|
||||
return err
|
||||
@@ -117,7 +120,7 @@ func (h *defaultItemHookHandler) handleHooks(
|
||||
hooks = resourceHook.post
|
||||
}
|
||||
for _, hook := range hooks {
|
||||
if groupResource == podsGroupResource {
|
||||
if groupResource == kuberesource.Pods {
|
||||
if hook.Exec != nil {
|
||||
hookLog := log.WithFields(
|
||||
logrus.Fields{
|
||||
@@ -126,7 +129,7 @@ func (h *defaultItemHookHandler) handleHooks(
|
||||
"hookPhase": phase,
|
||||
},
|
||||
)
|
||||
err := h.podCommandExecutor.executePodCommand(hookLog, obj.UnstructuredContent(), namespace, name, resourceHook.name, hook.Exec)
|
||||
err := h.podCommandExecutor.ExecutePodCommand(hookLog, obj.UnstructuredContent(), namespace, name, resourceHook.name, hook.Exec)
|
||||
if err != nil {
|
||||
hookLog.WithError(err).Error("Error executing hook")
|
||||
if hook.Exec.OnError == api.HookErrorModeFail {
|
||||
@@ -142,12 +145,10 @@ func (h *defaultItemHookHandler) handleHooks(
|
||||
}
|
||||
|
||||
const (
|
||||
podBackupHookContainerAnnotationKey = "hook.backup.ark.heptio.com/container"
|
||||
podBackupHookCommandAnnotationKey = "hook.backup.ark.heptio.com/command"
|
||||
podBackupHookOnErrorAnnotationKey = "hook.backup.ark.heptio.com/on-error"
|
||||
podBackupHookTimeoutAnnotationKey = "hook.backup.ark.heptio.com/timeout"
|
||||
defaultHookOnError = api.HookErrorModeFail
|
||||
defaultHookTimeout = 30 * time.Second
|
||||
podBackupHookContainerAnnotationKey = "hook.backup.velero.io/container"
|
||||
podBackupHookCommandAnnotationKey = "hook.backup.velero.io/command"
|
||||
podBackupHookOnErrorAnnotationKey = "hook.backup.velero.io/on-error"
|
||||
podBackupHookTimeoutAnnotationKey = "hook.backup.velero.io/timeout"
|
||||
)
|
||||
|
||||
func phasedKey(phase hookPhase, key string) string {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2017 the Heptio Ark contributors.
|
||||
Copyright 2017 the Velero contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/heptio/ark/pkg/apis/ark/v1"
|
||||
"github.com/heptio/ark/pkg/util/collections"
|
||||
arktest "github.com/heptio/ark/pkg/util/test"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -33,6 +30,10 @@ import (
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
v1 "github.com/heptio/velero/pkg/apis/velero/v1"
|
||||
velerotest "github.com/heptio/velero/pkg/test"
|
||||
"github.com/heptio/velero/pkg/util/collections"
|
||||
)
|
||||
|
||||
type mockItemHookHandler struct {
|
||||
@@ -57,7 +58,7 @@ func TestHandleHooksSkips(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "pod without annotation / no spec hooks",
|
||||
item: unstructuredOrDie(
|
||||
item: velerotest.UnstructuredOrDie(
|
||||
`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
@@ -73,7 +74,7 @@ func TestHandleHooksSkips(t *testing.T) {
|
||||
{
|
||||
name: "spec hooks not applicable",
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(
|
||||
item: velerotest.UnstructuredOrDie(
|
||||
`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
@@ -114,7 +115,7 @@ func TestHandleHooksSkips(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
podCommandExecutor := &mockPodCommandExecutor{}
|
||||
podCommandExecutor := &velerotest.MockPodCommandExecutor{}
|
||||
defer podCommandExecutor.AssertExpectations(t)
|
||||
|
||||
h := &defaultItemHookHandler{
|
||||
@@ -122,7 +123,7 @@ func TestHandleHooksSkips(t *testing.T) {
|
||||
}
|
||||
|
||||
groupResource := schema.ParseGroupResource(test.groupResource)
|
||||
err := h.handleHooks(arktest.NewLogger(), groupResource, test.item, test.hooks, hookPhasePre)
|
||||
err := h.handleHooks(velerotest.NewLogger(), groupResource, test.item, test.hooks, hookPhasePre)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
@@ -144,7 +145,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, no annotation, spec (multiple pre hooks) = run spec",
|
||||
phase: hookPhasePre,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -194,7 +195,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, no annotation, spec (multiple post hooks) = run spec",
|
||||
phase: hookPhasePost,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -244,7 +245,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, annotation (legacy), no spec = run annotation",
|
||||
phase: hookPhasePre,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -252,8 +253,8 @@ func TestHandleHooks(t *testing.T) {
|
||||
"namespace": "ns",
|
||||
"name": "name",
|
||||
"annotations": {
|
||||
"hook.backup.ark.heptio.com/container": "c",
|
||||
"hook.backup.ark.heptio.com/command": "/bin/ls"
|
||||
"hook.backup.velero.io/container": "c",
|
||||
"hook.backup.velero.io/command": "/bin/ls"
|
||||
}
|
||||
}
|
||||
}`),
|
||||
@@ -266,7 +267,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, annotation (pre), no spec = run annotation",
|
||||
phase: hookPhasePre,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -274,8 +275,8 @@ func TestHandleHooks(t *testing.T) {
|
||||
"namespace": "ns",
|
||||
"name": "name",
|
||||
"annotations": {
|
||||
"pre.hook.backup.ark.heptio.com/container": "c",
|
||||
"pre.hook.backup.ark.heptio.com/command": "/bin/ls"
|
||||
"pre.hook.backup.velero.io/container": "c",
|
||||
"pre.hook.backup.velero.io/command": "/bin/ls"
|
||||
}
|
||||
}
|
||||
}`),
|
||||
@@ -288,7 +289,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, annotation (post), no spec = run annotation",
|
||||
phase: hookPhasePost,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -296,8 +297,8 @@ func TestHandleHooks(t *testing.T) {
|
||||
"namespace": "ns",
|
||||
"name": "name",
|
||||
"annotations": {
|
||||
"post.hook.backup.ark.heptio.com/container": "c",
|
||||
"post.hook.backup.ark.heptio.com/command": "/bin/ls"
|
||||
"post.hook.backup.velero.io/container": "c",
|
||||
"post.hook.backup.velero.io/command": "/bin/ls"
|
||||
}
|
||||
}
|
||||
}`),
|
||||
@@ -310,7 +311,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, annotation & spec = run annotation",
|
||||
phase: hookPhasePre,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -318,8 +319,8 @@ func TestHandleHooks(t *testing.T) {
|
||||
"namespace": "ns",
|
||||
"name": "name",
|
||||
"annotations": {
|
||||
"hook.backup.ark.heptio.com/container": "c",
|
||||
"hook.backup.ark.heptio.com/command": "/bin/ls"
|
||||
"hook.backup.velero.io/container": "c",
|
||||
"hook.backup.velero.io/command": "/bin/ls"
|
||||
}
|
||||
}
|
||||
}`),
|
||||
@@ -345,7 +346,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, annotation, onError=fail = return error",
|
||||
phase: hookPhasePre,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -353,9 +354,9 @@ func TestHandleHooks(t *testing.T) {
|
||||
"namespace": "ns",
|
||||
"name": "name",
|
||||
"annotations": {
|
||||
"hook.backup.ark.heptio.com/container": "c",
|
||||
"hook.backup.ark.heptio.com/command": "/bin/ls",
|
||||
"hook.backup.ark.heptio.com/on-error": "Fail"
|
||||
"hook.backup.velero.io/container": "c",
|
||||
"hook.backup.velero.io/command": "/bin/ls",
|
||||
"hook.backup.velero.io/on-error": "Fail"
|
||||
}
|
||||
}
|
||||
}`),
|
||||
@@ -371,7 +372,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, annotation, onError=continue = return nil",
|
||||
phase: hookPhasePre,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -379,9 +380,9 @@ func TestHandleHooks(t *testing.T) {
|
||||
"namespace": "ns",
|
||||
"name": "name",
|
||||
"annotations": {
|
||||
"hook.backup.ark.heptio.com/container": "c",
|
||||
"hook.backup.ark.heptio.com/command": "/bin/ls",
|
||||
"hook.backup.ark.heptio.com/on-error": "Continue"
|
||||
"hook.backup.velero.io/container": "c",
|
||||
"hook.backup.velero.io/command": "/bin/ls",
|
||||
"hook.backup.velero.io/on-error": "Continue"
|
||||
}
|
||||
}
|
||||
}`),
|
||||
@@ -397,7 +398,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
name: "pod, spec, onError=fail = don't run other hooks",
|
||||
phase: hookPhasePre,
|
||||
groupResource: "pods",
|
||||
item: unstructuredOrDie(`
|
||||
item: velerotest.UnstructuredOrDie(`
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Pod",
|
||||
@@ -459,7 +460,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
podCommandExecutor := &mockPodCommandExecutor{}
|
||||
podCommandExecutor := &velerotest.MockPodCommandExecutor{}
|
||||
defer podCommandExecutor.AssertExpectations(t)
|
||||
|
||||
h := &defaultItemHookHandler{
|
||||
@@ -467,20 +468,20 @@ func TestHandleHooks(t *testing.T) {
|
||||
}
|
||||
|
||||
if test.expectedPodHook != nil {
|
||||
podCommandExecutor.On("executePodCommand", mock.Anything, test.item.UnstructuredContent(), "ns", "name", "<from-annotation>", test.expectedPodHook).Return(test.expectedPodHookError)
|
||||
podCommandExecutor.On("ExecutePodCommand", mock.Anything, test.item.UnstructuredContent(), "ns", "name", "<from-annotation>", test.expectedPodHook).Return(test.expectedPodHookError)
|
||||
} else {
|
||||
hookLoop:
|
||||
for _, resourceHook := range test.hooks {
|
||||
for _, hook := range resourceHook.pre {
|
||||
hookError := test.hookErrorsByContainer[hook.Exec.Container]
|
||||
podCommandExecutor.On("executePodCommand", mock.Anything, test.item.UnstructuredContent(), "ns", "name", resourceHook.name, hook.Exec).Return(hookError)
|
||||
podCommandExecutor.On("ExecutePodCommand", mock.Anything, test.item.UnstructuredContent(), "ns", "name", resourceHook.name, hook.Exec).Return(hookError)
|
||||
if hookError != nil && hook.Exec.OnError == v1.HookErrorModeFail {
|
||||
break hookLoop
|
||||
}
|
||||
}
|
||||
for _, hook := range resourceHook.post {
|
||||
hookError := test.hookErrorsByContainer[hook.Exec.Container]
|
||||
podCommandExecutor.On("executePodCommand", mock.Anything, test.item.UnstructuredContent(), "ns", "name", resourceHook.name, hook.Exec).Return(hookError)
|
||||
podCommandExecutor.On("ExecutePodCommand", mock.Anything, test.item.UnstructuredContent(), "ns", "name", resourceHook.name, hook.Exec).Return(hookError)
|
||||
if hookError != nil && hook.Exec.OnError == v1.HookErrorModeFail {
|
||||
break hookLoop
|
||||
}
|
||||
@@ -489,7 +490,7 @@ func TestHandleHooks(t *testing.T) {
|
||||
}
|
||||
|
||||
groupResource := schema.ParseGroupResource(test.groupResource)
|
||||
err := h.handleHooks(arktest.NewLogger(), groupResource, test.item, test.hooks, test.phase)
|
||||
err := h.handleHooks(velerotest.NewLogger(), groupResource, test.item, test.hooks, test.phase)
|
||||
|
||||
if test.expectedError != nil {
|
||||
assert.EqualError(t, err, test.expectedError.Error())
|
||||
@@ -693,3 +694,11 @@ func TestResourceHookApplicableTo(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func parseLabelSelectorOrDie(s string) labels.Selector {
|
||||
ret, err := labels.Parse(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user