diff --git a/changelogs/unreleased/8987-kaovilai b/changelogs/unreleased/8987-kaovilai new file mode 100644 index 0000000000..26771dc16c --- /dev/null +++ b/changelogs/unreleased/8987-kaovilai @@ -0,0 +1 @@ +Make ResticIdentifier optional for kopia BackupRepositories diff --git a/config/crd/v1/bases/velero.io_backuprepositories.yaml b/config/crd/v1/bases/velero.io_backuprepositories.yaml index 2ac737063e..19e4ce0dc3 100644 --- a/config/crd/v1/bases/velero.io_backuprepositories.yaml +++ b/config/crd/v1/bases/velero.io_backuprepositories.yaml @@ -71,7 +71,7 @@ spec: resticIdentifier: description: |- ResticIdentifier is the full restic-compatible string for identifying - this repository. + this repository. This field is only used when RepositoryType is "restic". type: string volumeNamespace: description: |- @@ -81,7 +81,6 @@ spec: required: - backupStorageLocation - maintenanceFrequency - - resticIdentifier - volumeNamespace type: object status: diff --git a/config/crd/v1/crds/crds.go b/config/crd/v1/crds/crds.go index 60c18e9eb9..51bf72fcfc 100644 --- a/config/crd/v1/crds/crds.go +++ b/config/crd/v1/crds/crds.go @@ -29,7 +29,7 @@ import ( ) var rawCRDs = [][]byte{ - []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xccXO\xaf\xdb6\f\xbf\xe7S\x10\xdduNV\f\x1b\x86\xdc\xdal\x05\x8a\xb5\xc5CR\xbc\xbbbӉ\xfadI\x93\xa8tٟ\xef>P\xb2\x13\xc7V\xe2\x977`\x98n\x96H\x8a\xe4\x8f\xfcQIQ\x143a\xe5#:/\x8d^\x82\xb0\x12\x7f'\xd4\xfc\xe5\xe7O?\xf9\xb94\x8b\xc3\xebٓ\xd4\xd5\x12V\xc1\x93i\xd6\xe8Mp%\xfe\x8c\xb5Ԓ\xa4ѳ\x06IT\x82\xc4r\x06 \xb46$x\xdb\xf3'@i49\xa3\x14\xbab\x87z\xfe\x14\xb6\xb8\rRU\xe8\xa2\xf1\xee\xea\xc3w\xf3\xd7?\xce\x7f\x98\x01h\xd1\xe0\x12\xb6\xa2|\n֡5^\x92q\x12\xfd\xfc\x80\n\x9d\x99K3\xf3\x16K\xb6\xbes&\xd8%\x9c\x0f\x92v{s\xf2\xfam4\xb4\xee\f\x1d㑒\x9e~\xcd\x1e\x7f\x90\x9e\xa2\x88U\xc1\t\x95s$\x1e{\xa9wA\t7\x12\xe0\v|i,.\xe1\x13\xfbbE\x89\xd5\f\xa0\x8d4\xfaV\x80\xa8\xaa\x98;\xa1\x1e\x9cԄneTh\xba\x9c\x15\xf0\xc5\x1b\xfd h\xbf\x84y\x97\xddy\xe90&\xf6\xb3lГhl\x94\xed\x12\xf6f\x87\xed7\x1d\xf9\xf2J\x10\x8e\x8dq\xe6\xe6g_?\x1f-^X9'\x02zgɢ''\xf5nv\x16>\xbcN\xa9(\xf7؈e+k,\xea7\x0f\xef\x1f\xbf\xdf\\l\x03Xg,:\x92\x1d\x10\xbdA\xc7b\xc0\xefMP\x15\xa7\xef\x01\x1d\x81\xc3\xd2\xec\xb4\xfc\xe3$\xdb\x03\x99\xa8T\tBO\x10Q\xd4B\xc1A\xa8\x80\xff\a\xa1\xab\x81\xe4F\x1c\xc1!넠{\xf2\"\x83\x1f\xda\xf1\xc98\x04\xa9k\xb3\x84=\x91\xf5\xcb\xc5b'\xa9+\xca\xd24MВ\x8e\x8bX_r\x1b\xc88\xbf\xa8\xf0\x80j\xe1\xe5\xae\x10\xae\xdcK\u0092\x82Å\xb0\xb2\x88\x8e\xe8X\x98\xf3\xa6\xfa\x9fk\xcb\xd8_\xa8\x1d\x01\x9dN\xac\xa4;\xe0\xe1\xd2\x02\xe9A\xb4\xa2\x92\x8bg\x14\xf8\x8aC\xb7\xfee\xf3\x04\x9d%\t\xa9\x04ʙt\x14\x97\x0e\x1f\x8e\xa6\xd45\xba\xc4W;\xd3D\x99\xa8+k\xa4\xa6\xf8Q*\x89\x9a\xc0\x87m#\x89\xd3ව\x9e\x18\xba\xa1\xd8Ul\\\xb0E\b\x96K\xa7\x1a\x12|а\x12\r\xaa\x95\xf0\xf8/cŨ\xf8\x82Ax\x11Z\xfdv<$N\xe1\xed=t\xad\xf4\n\xb4\xc3\xf6\xb8\xb1X2\xb2\x1c\\f\x95\xb5,SM\xd5Ɓ\x18\xd1_F*\xdf\x02\xf8\xa4&\xba!\xe3\xc4\x0e?\x9a$sH4\x95v|\xde\xe5\x04u\x16s\xdbJ=\x01\xf3\x84\x19\x81\xb4\x17\xd4k\x06$\xa4>\xf5\x94\xac\x937\x90\x89\xe8\b\xee\x14Z\xe8\x12\xdf\xc7|\xd4\xe5q\xc2\xd1O\x19\x16vio\xbe\x81\xa9\tu_hkkƓ-\x82\v\xfa.c\xcf>\xae\x8c\xae\xe5nlh\x7f\x90]\x03wB\xc9\xc0\xdb\xf5@'{\xca\xc9u\xb6\xa5\xe82\x8f\x01\xa9\xe5.\xb8k\xe0\xd5\x12U5j!\x00:(%\xb6\n\x97@.\xe0\x95\x88\x8cj\xe52\"<\x1f'\x80[_\x10\x83\xd4\x15WK;\xacXI\x97\x8c\x9c\xfe\xa8+p\x97kJ\xff\xa0\x0e\xcdX]\x01\xcf\xc6J\x91\xb9w\xe8I\x96\x99\x87\x87\x87\xfb2\x80\xc5|\xa8\xb8\x1d\xd5\x12\xddkjr=\x90ѕc\x1d\x94j\x15\x14\xa5i\xac \xb9U\xd8\xcd\f\xc6\\&\x9ec.i`T\x86\xf0\x14'\x01c\xce*\x8cVG\b\x1e+\xf8\xb6G=\x02\xc3\xc3C\xd2\xfdpWI\x1cxQ\xc3\xd3j\xf7\x9ax|\xb9\x14\xd1\xefN\xe9\":\x96ZbϿ\xae\xfd\xf8\x8cHk\xaaֲ\x96/\xd6\xcc\x1d\x8eq_\x91\x0e\ac\xbe\xc87\xe6\x01M\xae\xa5\rH\x06Q{\xd1d\"A\xc1\xdf3\x9b\"C\x17\xcd28\x17g\x7f\xba\xe5\x95\xef\xd5\xd3I\tO\xbd&\xcc\v\xf8\x04\xee\x1f\xc7\x1c\x9da,\f\x88/\x18\xda~\xf02\xb8\xfaP\x96\x88\xd5x\x1d\x01Ʒ\x11\x94\x16\xfd\x82彮\xcb\xe5\x87\x14z/vSN~JTi\xd3kY@lM\xa0+\b\xd0>\xe7\xe3mT&,\xb5{\xe1\xa7\xec|d\x9a\\^\f\x96\x81[&\\k\xbf\x9f\xf1[\xe6v\x8d\xa2\x1a\xb7\xf0\x02>\x1b\xca?\xdd\xec\xc0%\xea~2M\x0e\x9d\x01={~\x81A+r\x94\x7fc\xaf%a\x93\x1d\xe7\xd7k%\x1dn\xe7\n\tO\xbfU\xf3d\x03\xd3WC\xae\x13h\xe9\x81W\xb9X9Ws\xa9\vٔc\xe9L\x97P:\x13\x85\x94\xce\xcd\r\an\x15U&\x12\xf7\x96\xd6\xd5P$\xb8_\x16\x8eI\x0f\x1c\xfa\xa0\xe8E\x0e\xac#i\x87_b<\xa7\xdf\xcb\xec\xc9\xd7\\:\x05l\xba\xd6x\x95⽐\xea\xea\U000e4cde\x84\xa3\xfb\xf2ws\xc1r\xfa\x9dķ\xfd\xbc\xfdO\xe6獝\xb7{\x14Ή\xe3\xf4\xe8\x1e]z\xfe\xc9^\xf5\x8c\xf3i\x9d\xe8߄\xed\xe9\x1f\x89%\xfc\xf9\xf7\xec\x9f\x00\x00\x00\xff\xff\x18\xd9g\x90\x9b\x14\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xec=]s\xdb8\x92\xef\xf9\x15(\xdf\xc3\xecnI\xf6\xa6\ue8ee\xfc\x96q\x92\x1b\xd5\xce$\xaeؓ}\x86Ȗ\x841\bp\x01P\xb6\xf6\xee\xfe\xfb\x15\x1a\x00?D\x90\x04eٓ\xdd\v_\x12\x8b`\x03\xe8n\xf47\x80\xe5r\xf9\x86\x96\xec+(ͤ\xb8&\xb4d\xf0d@ؿ\xf4\xe5\xc3\x7f\xeaK&\xaf\xf6o\xdf<0\x91_\x93\x9bJ\x1bY|\x01-+\x95\xc1{\xd80\xc1\f\x93\xe2M\x01\x86\xe6\xd4\xd0\xeb7\x84P!\xa4\xa1\xf6gm\xff$$\x93\xc2(\xc99\xa8\xe5\x16\xc4\xe5C\xb5\x86u\xc5x\x0e\n\x81\x87\xae\xf7\x7f\xbe|\xfb\x1f\x97\xff\xfe\x86\x10A\v\xb8&k\x9a=T\xa5\xbe\xdc\x03\a%/\x99|\xa3K\xc8,ȭ\x92UyM\x9a\x17\xee\x13ߝ\x1b\xea\x8f\xf85\xfe\xc0\x996\x7fi\xfd\xf83\xd3\x06_\x94\xbcR\x94\xd7=\xe1o\x9a\x89mũ\n\xbf\xbe!Dg\xb2\x84k\xf2\xc9vQ\xd2\f\xf27\x84\xf8Qc\x97K?\xe0\xfd[\a!\xdbAA\xddX\b\x91%\x88w\xb7\xab\xaf\xffz\xd7\xf9\x99\x90\x1ct\xa6Xip\xee\xff\xb3\xac\x7f'~\x94\x84iB\xc9W\x9c#Q\x1e\xe5\xc4\xec\xa8!\nJ\x05\x1a\x84\xd1\xc4\xec\x80d\xb44\x95\x02\"7\xe4/\xd5\x1a\x94\x00\x03\xba\x05/\xe3\x956\xa0\x886\xd4\x00\xa1\x86PRJ&\fa\x82\x18V\x00\xf9û\xdb\x15\x91\xeb\xdf 3\x9aP\x91\x13\xaa\xb5\xcc\x185\x90\x93\xbd\xe4U\x01\xee\xdb?^\xd6PK%KP\x86\x05\xa4\xbb\xa7\xc5I\xad_\xc7\xe6j\x1f\x8b\x1e\xf7\x15\xc9-K\x81\x9b\x96G1\xe4\x1e\xa3v~f\xc7t3}d2\xfb3\x15~\xf8\x97G\xa0\xef@Y0D\xefd\xc5sˉ{P\x16\x81\x99\xdc\n\xf6\xf7\x1a\xb6&Fb\xa7\x9c\x1a\xd0\x163\x06\x94\xa0\x9c\xec)\xaf`a\x91r\x04\xb9\xa0\a\xa2\xc0\xf6I*т\x87\x1f\xe8\xe3q\xfc\"\x15\x10&6\xf2\x9a\xec\x8c)\xf5\xf5\xd5Ֆ\x99\xb0\xbe2Y\x14\x95`\xe6p\x85K\x85\xad+#\x95\xbe\xcaa\x0f\xfcJ\xb3풪l\xc7\fd\x96\xccW\xb4dK\x9c\x88\xc05vY\xe4\xff\x12\xd8Cw\xba5\a˶\xda(&\xb6\xad\x17\xb8>f\x90\xc7.\x1dnj\x0e\x94\x9bbC\x05\xfb\x93Eݗ\x0fw\xf7mFe\xda\x13\xa5ůC\xf4\xb1\xd8db\x03\xca}\xb7Q\xb2@\x98 rǪ\xc8省0DW\xeb\x82\x19\xcb\x06\x7f\xab@\xdb5 \x8f\xc1ޠ\f\"k U\x99[6>n\xb0\x12\xe4\x86\x16\xc0o\xa8\x86W\xa6\x95\xa5\x8a^Z\"$Q\xab-Y\x8f\x1b;\xf4\xb6^\x04\x019@Z'X\xeeJ\xc8:\v\xcd~\xc56,s\xcbi#U#w\x9c\f\xecb(\xbe\xf4\xed\x93iv'h\xa9w\xd2ܳ\x02de\x8e[L\xf1\x1a\x12\xefnu\x04%\x8cЏ\x17eV\xa5!\xb7\x8b\xf6\x912\x83c\xbe\xb9[\x91\xaf(\xac\xc2\xd7(\xb4*ML\xa5\x84\xe5\x92H__\x80\xe6\x87{\xf9\xab\x06\x92W\xc8ܙ\x02\xc4Â\xacac9A\x81\xfd\u07be\x02\xa5,n4\x0e@V=ac\x9f\xfb\x1dX\xdcҊ\x1b\xbfN\x98&o\xffL\n&*\xd3c\xb5A\xaa#\xa6\xa8\xa1\x85܃:\x05\x89視\xbf؏\x8fpg\x81\x12\x84j\x91\xb7\xf6x\\\x1f\xf0e\x8c\xda\xeeYmZ\x10\x99&\x17\x17D*r\xe14\xf0\xc5\xc2}]1n\x96L\xb4\xfbxd\x9c\x87^\xe6M\xde\xe1\xd0\x11T\xdfˏ\xda1\xefI\xb8\x18\x80\xd5B\xcd\xe3\x0e\xcc\x0e\x14)e\xad\xf16\x8c\x03\xd1\am\xa0\xf0\x88\tZ\xc4\xcf'\xd2\x13\xae\x1d\xce=\bm\xf1\xea'ҟ\xbc\xa88\xa7k\x0e\xd7Ĩ\n\x06p\xb3\x96\x92\x03\x15\x13\xc8\xf9\x02ڰ\xec\x1c\xa8q\x90\"\x88Q\xfeE\a\x03\xa84\xe9\x03\x10\x1a\x01\xedqf\xb53\xe7-\xc4v\xb1\x12\x1dS\xa9 \xb3R\xfb\xdak\x03\x06\x1c5\x90\x90\x84K\xb1\x05\xe5z\xb7\x96J`0\x05\x96\xe1rb\x05\xad\x02n\xb5\t\xd9TV\x06_\x12\xbb\xba\ay\x80\tm\x80F\x98\xf3\x19\U001019ccW9\xe47\xce\xf0\xba\xb3\xf6c\x1e\xac\xe6\x9e\xd4L\xa1ӇQ\x88^;s\x96\xa1\x11\xe8\xed\xbd%ڭ16m\x94\xf4\xa1\x04g:[R\xfaa7\xdawT\x1eh0\xf6\xa3\x8b?],\x90\xc2\xdd^\xbb}hB\x15\xd4hI\x96\x9bP\x94\xe6\xd0o\xcd\f\x14\x11,\x8eʓDzR\xa5\xe8a\x80\x9a\xb5\xfd\x7fFz\x0e\xc1<\xa2\xa8\b\xcd^\x99\xa6\xc7\xfd\xfe3S\xf5o\u00877h\x03\xd5\x0e\x90K\x85,\b%\x0fpp\xa6\v\x15\xc4҇\x86\xc6\t\xdd+\xc0\x9c\f\xf2\xd9\x03\x1c\x10L<\xc9\xd2\x7fR\xb9\xc1=\x0fpHiv\x84C;&\xa6}\xf2\xc8\xe2\xc9\xfe\x80\x88\xc0\xd8z*\x1b\xb8\xc7/\x85HJ#\xfe$ʒ\xf0\x04ܟ0\xcd$Vi\xf7\xd1\xceR\"\a\xfc\xa0\x1d-\xed\x8aٱ\x12\xc5*F\x1c\xe4&\x99\xa0\xee\xf9J9\xcb\xeb\x8e\xdc\x1aY\x89\x05\xf9$\x8d\xfd\xe7\xc3\x13\xd3>\x91\xf9^\x82\xfe$\r\xfe\xf2\"\x18u\x03\x7fI|\xba\x1ep\xa1\t'\xe5-\xc2ک8\xa7\xd3,\xb7ոg\x9a\xac\x84uW\x1cJ\x12\xbb¬\xab\xeb\xceuTT\x1a\xb3hB\x8a\xa5\v\xdb\xc4z\xf2\xf8\x96\xaa\x83\xeegw\xea;\xbc\xb7\xca½q\xb9_N3\xc8C\xba\x06\x93\x92\xd4\xc0\x96e\x89\xfd\x15\xa0\xb6@J+\xc2\xd38\"Q\xb0\xfa\xd9\xccc\x9f4\xed\xdd~\x9e\x96\x0fu\x8e\x7fiU\xce\xd2C0\xb2H\xc0\x81\x97\xdd\xf9\xf4|\x96v\xcd&\xb4\n\x9c0\xd9t g9\xdc4\x05)\xcf@\ajq4q&\xa9K\xf3\x1c\xeb\\(\xbf\x9d\xa1Qf\xf0\xc2\\\xd1\xd0\x1a\xbbS\xc1\x05\xc5T\xcb\x7f[M\x8b\xab\xe9\x7fII\x99җ\xe4\x1d\x96\xb4p\xe8\xbc\xf3A\xb3\x16\x98\x84.\xb1$\xc5\xf2Ϟr\xab\xfb\xad\x00\x17\x04\xb8\xb3\x04\xe4\xa6g\x17-\xc8\xe3Nj\xa7\xb6\xeb$\xce\xc5\x03\x1c\\\xc6p\xb2˶\x90\xb9X\x89\vgC\xf4\x04FmpH\xc1\x0f\xe4\x02\xdf]<ǔJ\xe4\xd4\xc4f\x1d\x16-h\x99ơXR\x94j\xa8[\x875\x18!\xf6úT\xc6\x1a\xd9c\xb3Mb\xd1R\xeaH\"\x7f`(\x13\xcc{+\xb5q\xf1\xb2\x8e\xcd\x1c\r\xa8\xc9\x10D#t\xe3ꗤ\n\xc5&V(O\x85~\xdb\xcf\xfd\x0e4\xf8|\x85\x0f\xcc9\xa0ֳ\xbbhַ\x93\xf6\x17._\x82\x9d\xd0\f-\x16\xfc\xb6T2\x03\x1d\xcde7O\x82\xbe\x88Te\xb4\xe7^\xc7\x1c\xa9\xf3\x92\\I\xc6x\b4<\xe9&\xafE\xc4L\x7f\xe1\xc3S+ j\u05fe\xfd{\x8a\xc7掋`\xc9`Q\xd0\xe32\xa5\xa4!\u07b8/\xc3j\xf0\x80\x9c\xf3\xa1\xb6\x15J\x82T]^3\xe0\xb7`(\x14L\xac\xb0\x03\xf2\xf6\x05\f\v/Cc\xc5&\xb1\xe74S\xf6&t\xd2P\xa7\xfe\xc1-\xe5Rb\xaa@A\x87x\xfd\xa8:ڡB\x9aV@b\x86\xb9Y\xca\xfc\aM6Li\xd3\x1e\x82\x1e(S\x89\x82\x99\xe9x\x89\x0fJ\x9d\xe4w}v_\xb6\xc2];\xf9\x18ʳ\x1cb\x12g\x8e\xf9% lC\x98! 2Y\t\f\xe0\xd8u\x8c]8\xe4:\t\xcbR\x17I\xda\xea\xb7\x0f\x88\xaaHC\xc0\x129\x85\x89\xd1HO\xbb\xf9G\xca\xf8K\x90\xcd\fU\xb1Ş\xd3\xd6D(qk\x17\xe4\x15\xf4\x89\x15UAhai\x84ʜ\x15\xd0%zS\xf8f\xbf@5a\xa4]1%\a\x03\xbex-q\f\x99\x14\x9a\xe5P+W\xcf\bR\x10J6\x94\xf1J%J\xc0Y\xe8\x9d\xe3\x8axIp>\x1f#\xad\xf3%\xa2\"!\x9a\x9bh+\x8eK\xe3R\xa5[|Sf\x96\x82\xf9VV\xa9\x98IJ\xc03\x1bZ\xbe\x90\x92\x8a\xc3wK+u\xa8\xdf-\xad\xb1绥5\xf1|\xb7\xb4\xbe[Z)-\xbf[Z\xdf-\xad\xf6\xf3\xff\xc2Қ\x1a\x91\xdb\xcf7\xf0rr\x14\t\xa9\xea\xb1!\x8e\xc0\xf7\xc5\x15\xbe\x06\xfcY\xb5\x98\xab8\xa8H\xe1\xff@YwLh5ʣ.δ\xab&\xf0\xbc\xdb^4aJ>\xa3\xea>tz\xbe\xaa\xfb\xd5(\xc43U\xdd\xfbaO\xdb\xd8'\xd5\xdc\a\xa4̫\xce^\xf8B\x8d\x02h\b\xab\xbb4|l^C\x1c2\xd1\xff+\x17\xe6\xf6\xaa\xc6\xce\xc8\x1f/^ş\xcc#Q\x92^\xfc\xe9\xe2\xdbC\xffy\x10>\x88\xe2>\xee\xfc\xfe\xe6\bT끶\xcbºUx\xdf&\x1b\x9f\x85oS+\xf1k$F`uY\xf2\b\x8bߪ,0P|.\xbdFz\xc6N\xd5U\x04N\xd2^U\xaa\x0f\"\xdb))d\xa5}T\xc2\xc2z\x97\xb9\r\xed\x01d\x8cY\xa3+\xfc\xdf\xc8NV\x91J\xf0\x11\xf4MT\x04NO\xbeS\x1c\xe8\x93\xd0`\xe8\xfe\xede\xf7\x8d\x91\xbeT\x90<2\xb3\x8b\x00z܁\xc0\f\xbbض7\x00\x84\xf3\b\xfc\xc6\xfcc\x06\x8b\x00\x92\x8a\b\xc6\x1d\xe7է\x19\xb4\xf9\x8e|.]\xeci\xb6\xdd1\x1eSI+&<\xb9\x84\xb0[\"8`\x97\xce\xcdv\x9fe\xcb\xc4\xefR\x1a8\xbf 0%\"6Q\xfcwB\xc9_bm\xf1\xb3\xd3\xf3)E}s<\xe6\x17+\xe0;\x7f\xd9^\x12~\xa6K\xf4\xe6`\xe7\xc5\xcb\xf1^\xb1\b\xefuJ\xef\x12\v\xee\xceW9\x9f\x16\x8f=\xa9rl:t0\\47Y*7\x19Z\x98\x9a\xd8\xec)M\x96\xc0\xcd)|\x9b\xa4N\xda2{\xb5ҶW+h{\xdd2\xb6Q.\x1a}9\xa7P-~,\r\x99T\xb6\xfc\xb5\x98\xedT4H\xd51_O\xf2\xaf>\x1f\xc1\xb0\x84\x0f\xa6\xdd+\xd9\xc8E\xc5\r+9&R\xf7,\x8f\x06\x1b\xcc\x0e\x0e\xf5\x01\x1a\xbfI\xdcz\xeaO\x82\xf9\xfc\xa5\xe6\xda\xcb#K\x9fj\xf2\b\x9c\x13\x1a[W\xbd\x99g\xee$\xa6L.\xc1\xea#\xbb:\xfd\xc1 \xfe\xf8\xa6\x85cw\xdc]\x8bZ\xad\x88\x85\x98\xa8\x18>EfPq\xa4ț\x9e\x05\xeb\xecp\xfc\xedo\x15\xa8\x03\xc1slj;\xa7\xd9\x04\xe6\x17\xa6\xb6\x8eX\x10\x15^l\r\xc5\xcf{F\x7f\xb3\x94\xc9;\xe1\xb4\xee\xf1x\xf0\x1b+#\x1a\xa7\xc6\n>\xeb\xafD\xfb\x18\xf8\\\xc8\xfa\xeb\xc8gS\x06r\xean\xa9\x97uq\xe6;9\x93VE\xba\xe5\xf7;\xed\x82:e\xf7SZ\x01\xc0\xe4n\xa7\x97ry\xa6\x9c\x9ed;/m7Ӽd\xe1\v\xee^z\x89]K\x89\x98J٥4\x0fO\xaf\xb0+\xe9Uw#\xbd\xd6.\xa4\xe4\xddGI%.\xc9Y\xe0\xd4\x12\x95\x13\xb7\xd3L\xe7x\xc7w\x13%\xec\"J\xc8\xfeNO\xf2\x84\xe9%\xec\x12\x9a\xb7;(\x81f\xa9K\xf1\x15w\x01\xbd\xe2\xee\x9f\xd7\xde\xf53\xc1Y\x13\xaf\xe7\xed\xee99e!U\x0ej4\xed\x93ʅ\xa3\xfc\x97\xe2\xdbt\ar\x94\xef\b\xa7\xfe\xd9V\x1d{\x19Ճ?h\x14\x8f\x94\x1dJ_ZNkY\x1b\x9d\\Tc\xfet\x8dI\x7fάKWi(\xa9³\x8b\xd7\aW\xce\x12U\xcd\x1fh\xb6;\x82\xbe\xa3\x9al\xa4*\xa8!\x17u\x02\xf0\xca\x01\xb7\x7f_\\\x12\xf2Q\xd65\x11\xedsy4+J~\xb0\x1e\n\xb9h\x7fp\x1a\aD\xb9-\xf4v+9\xcb\"\xb6[\xf4l&\u05f8wX\x06\x9e\x18\x95\xb5K\x06J\xdb0n\xba\xa1\x99\xd7=\x02s#9\x97\x8f3}\x7fZ\xb2\xff\u0093\xbb\x9f\x11\x1dzw\xbbB\x18\x81=\xf0(\xf0\xba8\xab\x9e\xcd\x1a\xacZn\xe69\xb4\xf6W\x9b\x0e\xc4n\x9dc\xfbp\\\xc8\xdd9\xc8\xc1,\xf0\xa23\x93V\xbaܮ\xdc8\x86z\xb1%\x8e\xbeƿj\x99\x95\xad\x95\xe6\xecJ\xb9\x89\f|\bN\xeb\x06\x8dGf\xfc\x91W\xe7=\xa3t\xc8Y\x18\xba\x1b\x00\x0fß\xbe\x1d\xc0\x9d\x99\xef\xef\x14\xf1\x8c\\)<`ԟ\xa7\x8f\ar\x9etA\xc0\xba.u\xaa˦\xf4;c\xa0(MLKO\v\x92\x1f\xc7\x00\xd6\x16\x8e4\x94\xb7\xf8\x99\x86\x061\x1bU\x1fD6V\x92\xe5\xd7\xf1\b5\xc789\x86\x80\x1b\xbf\x93\xe0l\b\xa8\x01\x0e!@WY\x06Zo*\xce\x0f\xf5F\x86o\x04\x1b\x1f)\xe3\xe7C\x85\x836\xc8\bvz\xa3\x90&'\xec\v\xa5A\xe4a\xa5\x87M>\xf3P\xe1\xa9\xe0\xeb\b\xb5\xa1\xc5IW\x1d\xdc\xf4\xc1\xe0e7*o\x95#\xd2z\xecT7䏉\xe5\x06\x9c\xfb\x12\xdd\x13\v\rr\x02{\x10\xc4\xea5\x87\xe2p[\xd3L(~o\xa8\xd3\rAS\x84 B\xf4J\x1f\xe2\xe3\x04\x1a\xaf\x8e\xf9A\xd70\xb1\xca\x12o\x02\xe9#\xa1o6:?\xff\xda\xdaͰ\xb4 N\xb3\xf7\xa2\xb29Ӭ\xab\x17\x9e'\xe4n\xeeVC\xe0N\x11q\xfd\x8bR\x9e\xb9\x8c\xfb\xd3}\x96H\xebOw\x96@\x8b@\xacy\xfc\xfcsǥ~\xdaq\xe8\xf8\xa538\xb2\xb0\xfb\x8cr\xee\xb7\b\x16\xa05݆s\xd0\x1f\xadѾ\x05\x01.\xb0\xe5\xd2\x0e\x11\xa0\xcd~\xb2\xee)\xe0n\xc9\xd0\xccT\xd4w\x10Jc[\xad~Є\xcb\x18T\xbc\n\x85\x85;\xb6\x8273\x13QO%S)\xdeχ\xba\xa1\xc5\rڐH\x9d\xe6V4\xe0lˬ\x97`)\xb7\xa5jM\xb7\xb0\xcc$\xe7\x80Һ?\xae\x97\\\xeb~\xd7\xde\x17\xa0zrj\x1f\xdbm}\xee\xccQۥ\x8c\xa9+\x14\xc7{\xaf\fS\xd0\\A\xd7\x1b\x90Ďg96\x0e\v\xd1\xfb\xd9\xfa#m\xb7\r\xab\u038be\x1f!\xf5׳-\xbcG\x1d\xe7ǂ\xfe&Ղ\x14L\xd8\x7f\xa8\xc8]\xea+|*\nK\x8f\xd7S\xec\x8e@\x93)\xd9X\xdb\x04\x8dM\x11\xba\xbd$\x9fdt\x81\xfb\x82 օiM+\xd0f\t\x9b\x8dT\xc6\xe5k\x97K\xc26!\x88`e\aF\x8e\xdcm\x8d\x84\xc5\x12\xadu\xa9E\xa3\x860\xec\xabP\x9b\xe2a\xee\x05=\xb8\xdc\fͲ\xcaZJW\xdaP\x1e1T\x9e%\xc01Zc\x17\x11\xe4\xbf>+\x97\xb5j\x03\xea\x87ݰ\x1f\x87R\x93\xc0\f8\\\x9a=\x90\xaa\\\xf8\xabk\xfd\xcd\xc4W\xfe\x16\x90\xe5F\xc9b\xe9\xfb\xc5\x02\xba\x85\xcfe+&\xad\x05bvQ\xac\x13g}\xfb\x83\xf6\x91\x13\xca\x12\x04\xa1\xda\xf7\x9cpV\xd2\xc9\xeaF\x1b\xaa̳\xc2\x11w\x1d\b\x13\x91\b\xec.>\x89;\x9f\xd2w\x87E\xdd\xf8+:k\xc0\v\xa2\x99\b\x97#\xbb\xf2\x00\xc7\x1f\xd1l\x91\xc0\xcb\f\xa5\x8aW썇\x16\xba\x13zݨ¾ֵ\x1fNv:\xbf\x1e\xc18\xda\xf8\x8bwW\xd6M\x82\xa3\xf8\a\x16\x8b|c\xa9gf\xa7\xf2\xc7\xdf}C\xef>ɩ\x89cd\xcc\xc7A\xf7e\xd8Y\xe9\xdeUy\xcb\xc1\x9a^\x1a\xa0\xeb>\xcdr\x93\xf7g\x8c\x1b\x9d3h\x14\xae\x01?O\xd4d\x7f\xc6pыŊ\xce;\xe5G\x8a\x97\b\x9f\xb4j\xff꿍\x04\x8b<\xd8s\x87\x8bZѢ0\xf0W\x8d\x17E\xb5R\xefG\x94\xd3yKZ\xf8\x9e\xfc/\xff\x17\x00\x00\xff\xff\xa5\x85lq\x8aؕ*\xdec͂\xf2]Q\xc9J\xaa\xeb\x97\xd7b\xb5\xc8\xe7\"\x9d\xba\xba\xf1\xfd\xd5\\\xbauc\x8cB\x96\xa8\xa4]\x87\xb7\xc9\v\xf9\x0e\x1b\xb6̛M\x8b\xfa\xe1\xe9\xc3\xcbo\xd7W\xd30\xe6H\xbd\xa0 ñ\x8emvh\x11^b\xfc%\xbb\xb9,ڙ&\x80\xd9\xfc\x8c\xdc_\x8c\xd8ZӢ\xf5\xb2\x04K\x1a\x1d,\xea\xcc\xf6x\xfaWu\xb5\x06@b\xa4S \b\x940\xf9U\x8e\x1f\x14Yr05\xf8\x9dt`\xb1\xb5\xe8P'\x98\xa2i\xa63\x83\xf3\x1e\xe95Z\"C\xb1\x1d\x94 ,;\xa0\xf5`\x91\x9b\xad\x96\xff8\xd3v\xe0Mvf\x8f\xceC\x8cP\xcd\x149k\xc0\x1f\x81iѣܰ\x13X\xa4;!\xe8\x0e\xbdx\xc0\xf5\xf9\xf8H\xd1 um\x96\xb0\xf3\xbeu\xcb\xc5b+}Ahn\x9a&h\xe9O\x8b\b\xb6r\x13\xbc\xb1n!\xf0\x80j\xe1\xe4\xb6b\x96\xef\xa4G\xee\x83\xc5\x05ke\x15\x05\xd1\tR\x1b\xf1\xbd͘\uebae\x1d\x84t\x1a\x11R_a\x1e\x82\xd7\xe42\x89T\x12\xf1b\x05\x9a\"\xd5}\xfe\xe3\xfa\x19\n'\xc9R\xc9(\x97\xad\x03\xbd\x14\xfb\x906\xa5\xaeѦs\xb55M\xa4\x89Z\xb4Fj\x1f\x7fp%Q{pa\xd3HOn\xf0\xf7\x80Γ\xe9\xfadW1\x8b\xc1\x06!\xb4\x11$\xfa\x1b>hX\xb1\x06Պ9\xfc\x85mEVq\x15\x19\xe1.kuss\x7fsRog\xa1\xe4\xd4\tӎ\xa2\xc1\xbaE~\x15w\x02\x9d\xb4\x14\x19\x9ey\x8c\xd1\xd5SP\x86\x8a\xe9\xa4\\\xc68H\xd0`\x9c\xa3s\x1f\x8d\xc0\xfeJ\x8f\xe5\x87\xf3\xc6+\x1e[\xb4\x8dt1\xbdBml?\xf3\xb03\x92wGA\xbc\xbe\xc1\x01P\x87f\xc8H\x05\x9f\x91\x89OZ\x9d&\x96\xfef\xa5\x1f^4aH\x1a\x89\xc5\xf5I\xf3'\xb4҈\x1b¿\xebm?\xab`g\x8ePG\xff\xd7^\x9d\b\xbb\xdcI\xf3!j\x97\xf1\xf0\xf4\xa1 x\x8a\xad\x1c\x98YWsx\xc8Amjx\x03B:*$\\$:T\x96\x0e*\x16\x1aK\xf06\xbcJ|nt-\xb7C\xa1\xbb\xb5є\xc7\xdc \xdd\xd3\xdc*\xdeD\xa8E\xde\xd1Zs\x90\x02mE\xf1!k\xc93'\xc1\xa6\fRKTb\x80M\x93Q\x16E\xb1((\xa8\x99\xbaa\xc3\xd5yc\xac\xa4\x99\xd4Ƀ/\x04\"\xd6\xd8&\xa7f\xedQ\v\xecg\x9bȍ\x89\x80\xe6P\xc0Q\xfa]BJ5\x16w\xf0\xd5أ\xb1\xc7\xd3\xd8t\x8f\xf7\xe7\x1d\xd2Δx\x11\x1cr\x8b>z\x1b*r\x1fr\xa59\xc0\xc7\xe0\"\xd6\xf6q\xa2\x8cX\xf0\x95\xd3{<\r\x15\r\xb7\x8c\x9bK\xa1\t\x96c\x11\xb5\x84ᄏ-\xd2 \xbb\x95A\xa5{\x11\xd4b\x8d\x16\xf5\xa0\x9a(\xe39\xe6(r\x1a\xf20\xack\xe4^\x1eP\x9dbN\"\xf0\xfc\x116\xc1\x83\b\x18\xad\xc6\xf8\xfeȬp\xc0M\xd32/7RI\x7f\x02\xe9&\xe83\xa5\xcc\x11E\xb686\xad?\xcd\xe1\x83v\x9ei\x8e\xee\\\a\x91ƒ+0\x9dv\xe5(\x8e\x05\x1d\xb3c\x18\x98\xc87\xc6y\xe0h\xc9\x1d\xd5\t\x8e\xd6\xe8픰#\xe9\x90z@\xab\xd1c̈\xc2pGɐc\xeb\xdd\xc2\x1c\xd0\x1e$\x1e\x17Gc\xf7Ro+b\xb0\xcaೈ\x9d\xdd\xe2\xfb\xf8\xe7[\xbc\xc0\xb4\t'\xeep\xdeu\x8c\xf5\x13\x95\xb7~\x87)E\xac\x93\x0f\x1a\vT@\x90k7\xd9w\x13\xb2\x8e\x85\xddX]\xde\x1d\xc5\xe4c\xf9c\x8f\xc3\xd4\xf1\x15P\x01\xf8R]t[5\xac\xad\xd2n\xe6M#\xf9\xac/m\xf2\xfb\xaf\xe3OiV\xa4\x16\x92Sq{\x8d\x1b\xa5\x89\x13W=͈\x1a\xfa]\xce\x14Z\x8e\xab)\x89\x9bk\x85\x1b\x1c\x7f\xea\uef74\xbe\t\xbas\xfew\xe8\xa9\xeet\xa0\x91\xea\x03f\x87z\x8e\x80ɍքT\xde\x00;\xa7\x81\x1f\\?\xff\xbd\x12=7\x81\xefqD\xf1\x03Q\xdeōE\xc7\xe9\x18\xf1\x12\x1c\xc6\xc4t\x8b\r\xb8\x1d\x11\x9c\xad\xd0\xde\xc3\xcb\xea\x816\x9eK\b\x06\xab\a\xd8\x04-\x14\x16\x8e\x8e;\xd4\xd4u\xc9\xfa4~\x17\x8d\xe7\xc7u\xd1j\xac\xber\xdfTt;.C\xcaoK\u061cF\xea\xa5;\x84l-\xd6\xf2\xcb\x1dB>ōE\xe1-\xf3;\x90\xdaI\x81\xc0Fԟ\n\xd9\tAϵѧ\x8c9\xdf`\x9e\xafaCb\xe75\xf0Pt|#~\x9e\xf2\xb6\xb3\x16\xca\xef\x9cݮ\xeb\xe4\xa98\x1e\x95\xe8p~\x94\xf9S\xaa>\xf9H\x19q\xc5\xcc\xcb\xf0\xc4W\xaa\xd8\xf244\x16\xccT3\x19kѵF\v\xea9\xef\xaba/,\xff\xef*\xd9q\xb3V\xd7(\xd7[+V\xb8\xab\x8d\x8b\xcf`\xafn\xe4\xd2\xe3`\xb7M2\x1bG\r\xf6\xa5\x97\xeb\xc9\xf8\x8b\xb4p\xa3%W\xa7\xaf\x93\x8eꗠce\x1b\xab\xaa\xf9l\xe4\xc4{l-R\x06\x13K\x92\xcdƃ\xda\x1c\xe9p\x87Z*ˌN\xf9\x9ez[\xa6E~U\xa0\xa5\x11\xcaG\xa9\x14\xd5\x00\x16\x1bCʢ\xb2\xdcR5\xc7b\xadu\xf8\xcd\xfc\xcd\xff\xafeT\xccy\xea\x00Q|ƃ\x1c>\xadݧ\xee\xc7\x01\x95\x82\x0e瘡\x1f?\x95׆\x85\xcd\xdb~\x82Z*\xaa\xff:\xd0qGu0\xf20\xfcn\xfd\xf8\x83\x8b=\x10j\xef\xe0H\x16t\x91%jzL~\xe1\t\xceS\x12\xb9i\xffn\x01\xae\r(\xa3\xb7h\xcbk\x0f\x15xɛ\x8c\x05\x81\x9er\x95\xde\x02\xdf1\xbd\xa5\xc8\x18\x83\xfc\xc8p\xe6\xbe\xcb'yϤ\x83H=\xe1\x1dw\x19\xf4Y\x8e\xb54\xaf1\xe6\xf43\xfc\x99\xffl\xd9\xcbkoO\xefSP[,\xd1_,\xa9\x9c\x14]\xf9\xcb\xd3\xfce|\xfb\xfb\xc0\xf0\xdd\xff[\xd5\xf3_}\xa9\x18|\xa1\xf8U(\xa7\xa1:\xf7f\xf1\xfc1\xedJ\xef\xb5\xf9\b\xb0\x8d\t~$\xf7w\x1c~4\xa6\xe3ǘ\xd7\xf0\x18?1\xdd*OhO\xb1\b\x0f\xd6\xc67\xdd\xf2\xd6\x18\x91b,+ݏ\xc0\x0f\xbd/aݵ\xe1w\xb2;\xe4\x1a\xcd҃ɔi;v\xcdJ\xee΄\xcd\xf9\xa5~\t\xff\xfc\xf7\xec?\x01\x00\x00\xff\xff\x03f\x86Y\xc0\x1d\x00\x00"), []byte("\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xbcVMo\x1b7\x10\xbd\xebW\f\xd0kwU\xa3hQ\xec\xadqr0\xda\x06\x82\x1d\xe4N\x91#-c.\xc9\xce\f\xe5\xba\x1f\xff\xbd \xb9+K\xab\x95\x93\\\xb27\x91Ù\xc7\xf7f\x1e\xd54\xcdJE\xfb\x11\x89m\xf0\x1d\xa8h\xf1/A\x9f\x7fq\xfb\xf8\v\xb76\xac\x0f7\xabG\xebM\a\xb7\x89%\f\xf7\xc8!\x91Ʒ\xb8\xb3ފ\r~5\xa0(\xa3Du+\x00\xe5}\x10\x95\x979\xff\x04\xd0\xc1\v\x05琚=\xfa\xf61mq\x9b\xac3H%\xf9T\xfa\xf0C{\xf3s\xfb\xd3\n\xc0\xab\x01;0\xe8Pp\xab\xf4c\x8a\x84\x7f&d\xe1\xf6\x80\x0e)\xb46\xac8\xa2\xce\xf9\xf7\x14R\xec\xe0e\xa3\x9e\x1fkW\xdcoK\xaa7%\xd5}MUv\x9de\xf9\xedZ\xc4\xefv\x8c\x8a.\x91rˀJ\x00[\xbfON\xd1b\xc8\n\x80u\x88\xd8\xc1\xfb\f+*\x8df\x050^\xbb\xc0l@\x19S\x88TnC\xd6\v\xd2mpi\x98\bl\xc0 k\xb2Q\nQ\x1fz,W\x84\xb0\x03\xe9\x11j9\x90\x00[\x1c\x11\x98r\x0e\xe0\x13\a\xbfQ\xd2w\xd0f\xbe\xda\x1a\x9a\x81\x8c\x01\x95\xea7\xf3ey\u0380Y\xc8\xfa\xfd5\b,J\x12O J]\x1b<\xd0\t\xbf\xe7\x00J|\x1b{\xc5\xe7\xd5\x1f\xcaƵ\xca5\xe6pS\x99\xd6=\x0e\xaa\x1bcCD\xff\xeb\xe6\xee\xe3\x8f\x0fg\xcbp\x8euAZ\xb0\fjB\x9a\x89\xab\xacA\xf0\b\x81`\b4\xb1\xca\xed1i\xa4\x10\x91\xc4N\xadU\xbf\x93\xe19Y\x9dA\xf8\xb79\xdb\x03Ȩ\xeb)0y\x8a\x90\v\x89cS\xa0\x19/Zɵ\f\x84\x91\x90\xd1\u05f9\xca\xcb\xcaC\xd8~B-\xed,\xf5\x03RN\x03܇\xe4L\x1e\xbe\x03\x92\x00\xa1\x0e{o\xff>\xe6\xe6|\xef\\\xd4))\x94\xe4\xb6\xf3\xca\xc1A\xb9\x84߃\xf2f\x96yP\xcf@\x98kB\xf2'\xf9\xca\x01\x9e\xe3\xf8#\x93h\xfd.tЋD\xee\xd6뽕\xc9Rt\x18\x86\xe4\xad<\xaf\x8b;\xd8m\x92@\xbc6x@\xb7f\xbbo\x14\xe9\xde\njI\x84k\x15mS.⋭\xb4\x83\xf9\x8eF\x13Ⳳ\x17\xddS\xbf\xe2\x02_!O\xf6\x84\xda#5U\xbd\xe2\x8b\ny)Sw\xff\xee\xe1\x03LH\xaaRU\x94\x97\xd0\v^&}2\x9b\xd6\xef\x90\xea\xb9\x1d\x85\xa1\xe4Dob\xb0^\xca\x0f\xed,z\x01N\xdb\xc1\nO\x1d\x9b\xa5\x9b\xa7\xbd-\xb6\x9b\x1d E\xa3\x04\xcd<\xe0\xceí\x1a\xd0\xdd*\xc6o\xacUV\x85\x9b,\xc2\x17\xa9u\xfa\x98̃+\xbd'\x1b\xd33pEڅ\xe1\x7f\x88\xa8\xb3\xb8\x99\xdf|\xda\ueb2ec\xb5\v\x04O\xbd\xd5\xfd4\xfc3\x9a\x8eFq\xce߲1\xe4\xef\xc5n\xe7;W/\x0fEdK8k\xd8\x06.\xbc\xfbu^\x8a\xa9~%3\xd5\xd1Gnt\"*\xcdw\xf4y\xb5t\xe8K\xb9@\xa2@\x17\xab3P\xefJP\xf9Ǡ\xacgP\xfey<\b\xd2+\x81'\xa4\r\x97\x95\x1ax\x8fO\v\xabw~CaO\xc8\xf3\x96ϛ\x9b\xca\x1e\xce߃WXZlʋE\xceVhNXd\t\xa4\xf6\xa7\xbcr\xda\x1e\x9d\xbe\x83\x7f\xfe[\xfd\x1f\x00\x00\xff\xff\xbeM\x1a\xea\xb1\n\x00\x00"), diff --git a/pkg/apis/velero/v1/backup_repository_types.go b/pkg/apis/velero/v1/backup_repository_types.go index fd30b04527..621ffcfcca 100644 --- a/pkg/apis/velero/v1/backup_repository_types.go +++ b/pkg/apis/velero/v1/backup_repository_types.go @@ -36,8 +36,9 @@ type BackupRepositorySpec struct { RepositoryType string `json:"repositoryType"` // ResticIdentifier is the full restic-compatible string for identifying - // this repository. - ResticIdentifier string `json:"resticIdentifier"` + // this repository. This field is only used when RepositoryType is "restic". + // +optional + ResticIdentifier string `json:"resticIdentifier,omitempty"` // MaintenanceFrequency is how often maintenance should be run. MaintenanceFrequency metav1.Duration `json:"maintenanceFrequency"` diff --git a/pkg/controller/backup_repository_controller.go b/pkg/controller/backup_repository_controller.go index b52282e213..d95ec95dfe 100644 --- a/pkg/controller/backup_repository_controller.go +++ b/pkg/controller/backup_repository_controller.go @@ -283,17 +283,21 @@ func (r *BackupRepoReconciler) getIdentifierByBSL(bsl *velerov1api.BackupStorage func (r *BackupRepoReconciler) initializeRepo(ctx context.Context, req *velerov1api.BackupRepository, bsl *velerov1api.BackupStorageLocation, log logrus.FieldLogger) error { log.WithField("repoConfig", r.backupRepoConfig).Info("Initializing backup repository") - // confirm the repo's BackupStorageLocation is valid - repoIdentifier, err := r.getIdentifierByBSL(bsl, req) - if err != nil { - return r.patchBackupRepository(ctx, req, func(rr *velerov1api.BackupRepository) { - rr.Status.Message = err.Error() - rr.Status.Phase = velerov1api.BackupRepositoryPhaseNotReady - - if rr.Spec.MaintenanceFrequency.Duration <= 0 { - rr.Spec.MaintenanceFrequency = metav1.Duration{Duration: r.getRepositoryMaintenanceFrequency(req)} - } - }) + var repoIdentifier string + // Only get restic identifier for restic repositories + if req.Spec.RepositoryType == "" || req.Spec.RepositoryType == velerov1api.BackupRepositoryTypeRestic { + var err error + repoIdentifier, err = r.getIdentifierByBSL(bsl, req) + if err != nil { + return r.patchBackupRepository(ctx, req, func(rr *velerov1api.BackupRepository) { + rr.Status.Message = err.Error() + rr.Status.Phase = velerov1api.BackupRepositoryPhaseNotReady + + if rr.Spec.MaintenanceFrequency.Duration <= 0 { + rr.Spec.MaintenanceFrequency = metav1.Duration{Duration: r.getRepositoryMaintenanceFrequency(req)} + } + }) + } } config, err := getBackupRepositoryConfig(ctx, r, r.backupRepoConfig, r.namespace, req.Name, req.Spec.RepositoryType, log) @@ -305,7 +309,10 @@ func (r *BackupRepoReconciler) initializeRepo(ctx context.Context, req *velerov1 // defaulting - if the patch fails, return an error so the item is returned to the queue if err := r.patchBackupRepository(ctx, req, func(rr *velerov1api.BackupRepository) { - rr.Spec.ResticIdentifier = repoIdentifier + // Only set ResticIdentifier for restic repositories + if rr.Spec.RepositoryType == "" || rr.Spec.RepositoryType == velerov1api.BackupRepositoryTypeRestic { + rr.Spec.ResticIdentifier = repoIdentifier + } if rr.Spec.MaintenanceFrequency.Duration <= 0 { rr.Spec.MaintenanceFrequency = metav1.Duration{Duration: r.getRepositoryMaintenanceFrequency(req)} @@ -503,16 +510,19 @@ func dueForMaintenance(req *velerov1api.BackupRepository, now time.Time) bool { func (r *BackupRepoReconciler) checkNotReadyRepo(ctx context.Context, req *velerov1api.BackupRepository, bsl *velerov1api.BackupStorageLocation, log logrus.FieldLogger) (bool, error) { log.Info("Checking backup repository for readiness") - repoIdentifier, err := r.getIdentifierByBSL(bsl, req) - if err != nil { - return false, r.patchBackupRepository(ctx, req, repoNotReady(err.Error())) - } + // Only check and update restic identifier for restic repositories + if req.Spec.RepositoryType == "" || req.Spec.RepositoryType == velerov1api.BackupRepositoryTypeRestic { + repoIdentifier, err := r.getIdentifierByBSL(bsl, req) + if err != nil { + return false, r.patchBackupRepository(ctx, req, repoNotReady(err.Error())) + } - if repoIdentifier != req.Spec.ResticIdentifier { - if err := r.patchBackupRepository(ctx, req, func(rr *velerov1api.BackupRepository) { - rr.Spec.ResticIdentifier = repoIdentifier - }); err != nil { - return false, err + if repoIdentifier != req.Spec.ResticIdentifier { + if err := r.patchBackupRepository(ctx, req, func(rr *velerov1api.BackupRepository) { + rr.Spec.ResticIdentifier = repoIdentifier + }); err != nil { + return false, err + } } } @@ -521,7 +531,7 @@ func (r *BackupRepoReconciler) checkNotReadyRepo(ctx context.Context, req *veler if err := ensureRepo(req, r.repositoryManager); err != nil { return false, r.patchBackupRepository(ctx, req, repoNotReady(err.Error())) } - err = r.patchBackupRepository(ctx, req, repoReady()) + err := r.patchBackupRepository(ctx, req, repoReady()) if err != nil { return false, err } diff --git a/pkg/controller/backup_repository_controller_test.go b/pkg/controller/backup_repository_controller_test.go index 75aa16589b..98988f7a73 100644 --- a/pkg/controller/backup_repository_controller_test.go +++ b/pkg/controller/backup_repository_controller_test.go @@ -93,27 +93,83 @@ func TestPatchBackupRepository(t *testing.T) { } func TestCheckNotReadyRepo(t *testing.T) { - rr := mockBackupRepositoryCR() - rr.Spec.BackupStorageLocation = "default" - rr.Spec.ResticIdentifier = "fake-identifier" - rr.Spec.VolumeNamespace = "volume-ns-1" - reconciler := mockBackupRepoReconciler(t, "PrepareRepo", rr, nil) - err := reconciler.Client.Create(context.TODO(), rr) - assert.NoError(t, err) - location := velerov1api.BackupStorageLocation{ - Spec: velerov1api.BackupStorageLocationSpec{ - Config: map[string]string{"resticRepoPrefix": "s3:test.amazonaws.com/bucket/restic"}, - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: velerov1api.DefaultNamespace, - Name: rr.Spec.BackupStorageLocation, - }, - } + // Test for restic repository + t.Run("restic repository", func(t *testing.T) { + rr := mockBackupRepositoryCR() + rr.Spec.BackupStorageLocation = "default" + rr.Spec.ResticIdentifier = "fake-identifier" + rr.Spec.VolumeNamespace = "volume-ns-1" + rr.Spec.RepositoryType = velerov1api.BackupRepositoryTypeRestic + reconciler := mockBackupRepoReconciler(t, "PrepareRepo", rr, nil) + err := reconciler.Client.Create(context.TODO(), rr) + assert.NoError(t, err) + location := velerov1api.BackupStorageLocation{ + Spec: velerov1api.BackupStorageLocationSpec{ + Config: map[string]string{"resticRepoPrefix": "s3:test.amazonaws.com/bucket/restic"}, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: rr.Spec.BackupStorageLocation, + }, + } + + _, err = reconciler.checkNotReadyRepo(context.TODO(), rr, &location, reconciler.logger) + assert.NoError(t, err) + assert.Equal(t, velerov1api.BackupRepositoryPhaseReady, rr.Status.Phase) + assert.Equal(t, "s3:test.amazonaws.com/bucket/restic/volume-ns-1", rr.Spec.ResticIdentifier) + }) + + // Test for kopia repository + t.Run("kopia repository", func(t *testing.T) { + rr := mockBackupRepositoryCR() + rr.Spec.BackupStorageLocation = "default" + rr.Spec.VolumeNamespace = "volume-ns-1" + rr.Spec.RepositoryType = velerov1api.BackupRepositoryTypeKopia + reconciler := mockBackupRepoReconciler(t, "PrepareRepo", rr, nil) + err := reconciler.Client.Create(context.TODO(), rr) + assert.NoError(t, err) + location := velerov1api.BackupStorageLocation{ + Spec: velerov1api.BackupStorageLocationSpec{ + Config: map[string]string{"resticRepoPrefix": "s3:test.amazonaws.com/bucket/restic"}, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: rr.Spec.BackupStorageLocation, + }, + } + + _, err = reconciler.checkNotReadyRepo(context.TODO(), rr, &location, reconciler.logger) + assert.NoError(t, err) + assert.Equal(t, velerov1api.BackupRepositoryPhaseReady, rr.Status.Phase) + // ResticIdentifier should remain empty for kopia + assert.Empty(t, rr.Spec.ResticIdentifier) + }) + + // Test for empty repository type (defaults to restic) + t.Run("empty repository type", func(t *testing.T) { + rr := mockBackupRepositoryCR() + rr.Spec.BackupStorageLocation = "default" + rr.Spec.ResticIdentifier = "fake-identifier" + rr.Spec.VolumeNamespace = "volume-ns-1" + // Deliberately leave RepositoryType empty + reconciler := mockBackupRepoReconciler(t, "PrepareRepo", rr, nil) + err := reconciler.Client.Create(context.TODO(), rr) + assert.NoError(t, err) + location := velerov1api.BackupStorageLocation{ + Spec: velerov1api.BackupStorageLocationSpec{ + Config: map[string]string{"resticRepoPrefix": "s3:test.amazonaws.com/bucket/restic"}, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: rr.Spec.BackupStorageLocation, + }, + } - _, err = reconciler.checkNotReadyRepo(context.TODO(), rr, &location, reconciler.logger) - assert.NoError(t, err) - assert.Equal(t, velerov1api.BackupRepositoryPhaseReady, rr.Status.Phase) - assert.Equal(t, "s3:test.amazonaws.com/bucket/restic/volume-ns-1", rr.Spec.ResticIdentifier) + _, err = reconciler.checkNotReadyRepo(context.TODO(), rr, &location, reconciler.logger) + assert.NoError(t, err) + assert.Equal(t, velerov1api.BackupRepositoryPhaseReady, rr.Status.Phase) + assert.Equal(t, "s3:test.amazonaws.com/bucket/restic/volume-ns-1", rr.Spec.ResticIdentifier) + }) } func startMaintenanceJobFail(client.Client, context.Context, *velerov1api.BackupRepository, string, kube.PodResources, logrus.Level, *logging.FormatFlag, logrus.FieldLogger) (string, error) { @@ -1413,3 +1469,167 @@ func TestGetLastMaintenanceTimeFromHistory(t *testing.T) { }) } } + +func TestInitializeRepoWithRepositoryTypes(t *testing.T) { + scheme := runtime.NewScheme() + corev1api.AddToScheme(scheme) + velerov1api.AddToScheme(scheme) + + // Test for restic repository + t.Run("restic repository", func(t *testing.T) { + rr := mockBackupRepositoryCR() + rr.Spec.BackupStorageLocation = "default" + rr.Spec.VolumeNamespace = "volume-ns-1" + rr.Spec.RepositoryType = velerov1api.BackupRepositoryTypeRestic + + location := &velerov1api.BackupStorageLocation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: "default", + }, + Spec: velerov1api.BackupStorageLocationSpec{ + Provider: "aws", + StorageType: velerov1api.StorageType{ + ObjectStorage: &velerov1api.ObjectStorageLocation{ + Bucket: "test-bucket", + Prefix: "test-prefix", + }, + }, + Config: map[string]string{ + "region": "us-east-1", + }, + }, + } + + fakeClient := clientFake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(rr, location).Build() + mgr := &repomokes.Manager{} + mgr.On("PrepareRepo", rr).Return(nil) + + reconciler := NewBackupRepoReconciler( + velerov1api.DefaultNamespace, + velerotest.NewLogger(), + fakeClient, + mgr, + testMaintenanceFrequency, + "", + 3, + "", + kube.PodResources{}, + logrus.InfoLevel, + nil, + ) + + err := reconciler.initializeRepo(context.TODO(), rr, location, reconciler.logger) + assert.NoError(t, err) + + // Verify ResticIdentifier is set for restic + assert.NotEmpty(t, rr.Spec.ResticIdentifier) + assert.Contains(t, rr.Spec.ResticIdentifier, "volume-ns-1") + assert.Equal(t, velerov1api.BackupRepositoryPhaseReady, rr.Status.Phase) + }) + + // Test for kopia repository + t.Run("kopia repository", func(t *testing.T) { + rr := mockBackupRepositoryCR() + rr.Spec.BackupStorageLocation = "default" + rr.Spec.VolumeNamespace = "volume-ns-1" + rr.Spec.RepositoryType = velerov1api.BackupRepositoryTypeKopia + + location := &velerov1api.BackupStorageLocation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: "default", + }, + Spec: velerov1api.BackupStorageLocationSpec{ + Provider: "aws", + StorageType: velerov1api.StorageType{ + ObjectStorage: &velerov1api.ObjectStorageLocation{ + Bucket: "test-bucket", + Prefix: "test-prefix", + }, + }, + Config: map[string]string{ + "region": "us-east-1", + }, + }, + } + + fakeClient := clientFake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(rr, location).Build() + mgr := &repomokes.Manager{} + mgr.On("PrepareRepo", rr).Return(nil) + + reconciler := NewBackupRepoReconciler( + velerov1api.DefaultNamespace, + velerotest.NewLogger(), + fakeClient, + mgr, + testMaintenanceFrequency, + "", + 3, + "", + kube.PodResources{}, + logrus.InfoLevel, + nil, + ) + + err := reconciler.initializeRepo(context.TODO(), rr, location, reconciler.logger) + assert.NoError(t, err) + + // Verify ResticIdentifier is NOT set for kopia + assert.Empty(t, rr.Spec.ResticIdentifier) + assert.Equal(t, velerov1api.BackupRepositoryPhaseReady, rr.Status.Phase) + }) + + // Test for empty repository type (defaults to restic) + t.Run("empty repository type", func(t *testing.T) { + rr := mockBackupRepositoryCR() + rr.Spec.BackupStorageLocation = "default" + rr.Spec.VolumeNamespace = "volume-ns-1" + // Leave RepositoryType empty + + location := &velerov1api.BackupStorageLocation{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: velerov1api.DefaultNamespace, + Name: "default", + }, + Spec: velerov1api.BackupStorageLocationSpec{ + Provider: "aws", + StorageType: velerov1api.StorageType{ + ObjectStorage: &velerov1api.ObjectStorageLocation{ + Bucket: "test-bucket", + Prefix: "test-prefix", + }, + }, + Config: map[string]string{ + "region": "us-east-1", + }, + }, + } + + fakeClient := clientFake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(rr, location).Build() + mgr := &repomokes.Manager{} + mgr.On("PrepareRepo", rr).Return(nil) + + reconciler := NewBackupRepoReconciler( + velerov1api.DefaultNamespace, + velerotest.NewLogger(), + fakeClient, + mgr, + testMaintenanceFrequency, + "", + 3, + "", + kube.PodResources{}, + logrus.InfoLevel, + nil, + ) + + err := reconciler.initializeRepo(context.TODO(), rr, location, reconciler.logger) + assert.NoError(t, err) + + // Verify ResticIdentifier is set when type is empty (defaults to restic) + assert.NotEmpty(t, rr.Spec.ResticIdentifier) + assert.Contains(t, rr.Spec.ResticIdentifier, "volume-ns-1") + assert.Equal(t, velerov1api.BackupRepositoryPhaseReady, rr.Status.Phase) + }) +}