Restic: Menggunakan rclone sebagai backend

Dibuat pada 17 Jan 2018  ·  63Komentar  ·  Sumber: restic/restic

Masalah ini ada untuk membahas implementasi prototipe yang memungkinkan restic menggunakan rclone sebagai backend. Ini sangat masuk akal karena rclone sudah menerapkan semua backend cloud (termasuk konfigurasi pengguna dan sebagainya). Saya telah melakukan diskusi yang sangat produktif dengan @ncw , yang merupakan penulis rclone, tentang cara menggunakan restic use rclone untuk mengakses data, dan kami telah memutuskan untuk melanjutkan diskusi kami dalam masalah publik di sini di GitHub.

Ide saya adalah menambahkan backend baru ke restic yang berbicara dengan proses kedua melalui stdin/stdout, menggunakan protokol yang masih harus ditentukan. Saya membaca hal-hal baik tentang https://github.com/hashicorp/yamux , yang memungkinkan pencampuran beberapa aliran secara paralel melalui satu "koneksi" (sangat mirip dengan apa yang dilakukan HTTP2). Kita perlu mendefinisikan protokol untuk mengakses file di atas itu, hanya dengan operasi dasar yang dibutuhkan restic.

Backend ini kemudian dapat diimplementasikan di rclone, sehingga restic baru saja memulai rclone serve restic-backend (atau baris perintah apa pun yang kita butuhkan), berbicara dengan rclone, dan rclone menangani penyimpanan/pemuatan/penghapusan file di suatu tempat.

Mengambil langkah ini lebih jauh, kami juga dapat mengimplementasikan sisi server untuk backend ini dalam restic itu sendiri, yang kemudian dapat dimulai misalnya melalui SSH pada server jarak jauh, jadi restic menjalankan ssh user<strong i="11">@host</strong> restic serve backend , dan menggunakan koneksi itu, yang akan menjadi jauh lebih efisien daripada sftp. Jika kami membuat protokol dapat diperpanjang, kami juga dapat menambahkan fitur seperti pengemasan ulang jarak jauh (jika didukung oleh "server"), sehingga data yang dikemas ulang selama pemangkasan tidak perlu diunduh dan diunggah ulang.

Protokol tersebut kemudian dapat juga diimplementasikan pada program lain, sehingga kita dapat menggunakannya sebagai "plugin" untuk mengakses data yang disimpan di mana saja.

Pendekatan yang sedikit berbeda adalah berbicara HTTP2 melalui stdin/stdout dengan proses seperti rclone, atau menggunakan sesuatu seperti https://github.com/hashicorp/go-plugin dan mengimplementasikan backend di Go sebagai plugin.

Jadi, masalah ini adalah untuk memajukan diskusi lebih lanjut dan bermain dengan beberapa contoh implementasi, sehingga kita bisa merasakan apa yang terbaik.

Komentar yang paling membantu

Saya sudah bermain-main dengannya, sudah terlihat bagus!

Saya telah menambahkan dua komit di sini: https://github.com/fd0/rclone/tree/serve-restic , yang kedua menambahkan mode http2/server di stdin/stdout. Ini dapat digunakan dengan cabang saya https://github.com/restic/restic/tree/rclone-backend seperti ini:

$ ./restic -r rclone:b2:restic-dev-an/path/to/repo snapshots

Ini akan secara otomatis memulai rclone dalam mode http2/server dengan --stdin , Anda juga dapat melewati baris perintah sebagai opsi:

$ ./restic \
  -r rclone:b2:restic-dev-an/path/to/repo \
  -o rclone.command="rclone serve restic --stdin --bwlimit 1M --verbose b2:restic-test-an/foo" \
  backup .

Secara internal, saya menggunakan backend REST dan hanya menambahkan sedikit lem untuk memulai proses rclone dan merobeknya dengan benar.

Omong-omong, ini dapat dimulai dengan mudah melalui ssh pada host jarak jauh, cukup setel -o rclone.command='ssh user<strong i="18">@host</strong> rclone serve restic --stdin b2:restic-test-an/foo' .

Tolong beritahu saya bagaimana menurut anda!

Semua 63 komentar

Apa yang dikatakan tentang redundansi yang akan muncul dengan backend yang ada, misalnya S3, Swift, dll?

Belum ada keputusan. Saya tidak melihat gunanya menduplikasi semua pekerjaan dan mendukung ribuan layanan cloud, tetapi untuk backend yang ada, saya juga tidak melihat ada gunanya menghapusnya. Backend yang ada memiliki properti bagus yang tidak memerlukan pengaturan alat pihak ketiga, Anda bisa lolos dengan restic saja, yang juga diinginkan.

Untuk saat ini ini hanya percobaan, kita akan lihat bagaimana kelanjutannya.

Saya membuat sedikit percobaan di cabang serve-restic untuk rclone. Saya mengambil repo restic/rest-server dan menumbuknya menjadi rclone dengan kekuatan besar dan sedikit kehalusan ;-)

Jalankan rclone serve restic remote: mana remote: dapat berupa remote rclone, atau direktori lokal.

Saya sudah mengujinya dan sepertinya berhasil - saya mencoba beberapa operasi. Itu tidak memiliki tes. Catatan saya juga tidak menjual dependensi.

Ini tidak ideal karena kami memiliki masalah soket mendengarkan secara keseluruhan, yaitu tidak aman dari aplikasi lain. Akan relatif mudah untuk melewati kata sandi di lingkungan ketika dimulai dan membutuhkan itu. Memilih port acak mungkin juga diperlukan.

Pikiran?

Saya baru saja mencobanya: Perlu dipoles;)

Saya baru saja mendorong beberapa komit ke cabang ext-rest-backend-test , yang memungkinkan Anda menjalankan pengujian backend kami terhadap server REST yang ditentukan dalam variabel lingkungan, seperti ini:

$ RESTIC_TEST_REST_REPOSITORY=rest:http://localhost:8000/foo go test ./internal/backend/rest

Tampaknya ada masalah dengan daftar file:

FAIL |         --- FAIL: TestBackendRESTExternalServer/TestList/max-11 (1.48s)
     |          tests.go:294: loaded 39 IDs from backend
     |          tests.go:297: lists are not equal, list1 38 entries, list2 39 entries

Dan dengan rentang byte:

FAIL |     --- FAIL: TestBackendRESTExternalServer/TestLoad (81.05s)
     |      tests.go:28: rand initialized with seed 1516439868654186529
     |      tests.go:142: saved 13138440 bytes as <data/39caa259bf>
     |      tests.go:206: Load, l 2668197, o 8157054, len(d) 2668197, getlen 2668197
     |      tests.go:207: Load(2668197, 8157054) wrong number of bytes read: want 2668197, got 13138440

Dari percakapan kami melalui email:

  • Kita dapat dengan mudah mengatur Content-Length header, restic upload file temp (sehingga dapat mencoba lagi) dan mengetahui ukurannya terlebih dahulu
  • Saya lebih suka jika rclone tidak akan mencoba lagi unggahan atau buffer di memori, itu sudah dilakukan oleh restic

Saya baru saja mencobanya: Perlu dipoles;)

Hehe!

Terima kasih telah memberikan petunjuk tentang cara menjalankan tes.

Tampaknya ada masalah dengan daftar file:

Tidak yakin tentang apa itu. Saya yakin itu akan menjadi jelas!

Dan dengan rentang byte:

Saya tidak menerapkan rentang byte karena saya pikir itu tidak diperlukan. Sebuah kesalahan yang sekarang saya lihat!

Kita dapat dengan mudah mengatur header Content-Length, restic upload file temp (sehingga dapat mencoba lagi) dan mengetahui ukurannya terlebih dahulu

Saya pikir itu mungkin ide yang bagus. Sebagian besar dukungan rclone backend perlu mengetahui panjang file sebelum diunggah, sehingga akan membuat hidup rclone lebih mudah. Ini juga akan mengubah format POST dari penyandian transfer chunked menjadi POST lurus ke depan (yang mungkin tidak ada bedanya). Ini akan memungkinkan rclone untuk memeriksa bahwa jumlah data yang tepat tiba di POST yang bagus.

Saya lebih suka jika rclone tidak akan mencoba lagi unggahan atau buffer di memori, itu sudah dilakukan oleh restic

Saya akan bertanya tentang itu - apakah restic melakukan percobaan ulang atau tidak. rclone masih akan melakukan percobaan ulang tingkat rendah ketika mencoba membuka objek untuk dibaca, melakukan daftar, dll, tetapi saya akan membuatnya sehingga tidak buffer atau coba lagi data.

Ada satu hal lain yang saya pikirkan... Saya ingin menyimpan daftar yang dilakukan restic. Rclone memiliki lapisan vfs yang akan melakukan ini - itu akan membuat daftar direktori, mengambil objek jauh lebih efisien karena rclone tidak perlu mencari setiap objek lagi. Biaya adalah sejumlah kecil memori. Lapisan VFS akan membuat permintaan Rentang implementasi menjadi sepele juga.

Jika di masa depan restic menggunakan backend rclone secara langsung maka saya berharap restic menyimpan daftar itu sendiri dan kita bisa berhenti menggunakan lapisan VFS.

Saya akan mencoba dan membuat v2 dalam satu atau dua hari berikutnya dan saya akan memposting pembaruan di sini.

Sudahkah Anda mempertimbangkan untuk menyematkan rclone sebagai perpustakaan ke dalam restic?

Sebagai pengguna rumahan, saya tidak mungkin mendapat manfaat dari server rclone tetapi apakah akan lebih sulit bagi saya untuk menginstal, mengkonfigurasi, dan memelihara dua perangkat lunak. Saya mengerti bagaimana server rclone yang terpisah dapat menarik di lingkungan perusahaan, jadi tebak itu sangat tergantung pada siapa audiens target Anda.

@ifedorenko menulis:

Sudahkah Anda mempertimbangkan untuk menyematkan rclone sebagai perpustakaan ke dalam restic?

Saya yakin kita akan sampai ke titik itu pada akhirnya - kita hanya bereksperimen saat ini :-)

Sudahkah Anda mempertimbangkan untuk menyematkan rclone sebagai perpustakaan ke dalam restic?
Sebagai pengguna rumahan, saya tidak mungkin mendapat manfaat dari server rclone tetapi apakah akan lebih sulit bagi saya untuk menginstal, mengkonfigurasi, dan memelihara dua perangkat lunak.

Ya, tetapi saat ini, restic tidak mendukung semua layanan rclone, yang bahkan memiliki sistem dialog yang bagus untuk konfigurasi.

Dari sudut pandang saya, ini juga tentang menggunakan sumber daya (terutama waktu pengembang) dengan bijak, menggunakan rclone untuk mengakses layanan yang tidak kami dukung dan menyediakan cara konfigurasi yang bagus itu bagus, bahkan jika itu datang dengan pekerjaan tambahan karena harus menginstal rclone. :)

@fd0 menulis

Saya baru saja mendorong beberapa komit ke cabang ext-rest-backend-test

Saya tidak dapat menemukan cabang itu di repo restic? Apakah saya mencari di tempat yang salah?

Oh, maaf, saya sudah menggabungkan tambalan menjadi master di #1569, jadi Anda bisa menggunakan cabang master.

Saya melihat apa yang terjadi dengan pengujian saya sebelumnya... Saya menjalankan perintah yang Anda berikan yang mencoba untuk memulai rest-server pada port yang sama dengan yang dijalankan rclone sehingga menyebabkan kebingungan!

Saya telah menetapkan ini sebagai tes rutin

Jalankan ini dalam satu jendela terminal

rclone -vv serve restic /tmp/restic-test

Dan jalankan ini untuk menguji

RESTIC_TEST_REST_REPOSITORY=rest:http://localhost:8000/ go test ./internal/backend/rest -run TestBackendRESTExternalServer

Apakah itu tampak masuk akal?

Saya akan mencoba untuk membuat lulus!

Saya lebih suka jika rclone tidak akan mencoba lagi unggahan atau buffer di memori, itu sudah dilakukan oleh restic

Saya menyadari bahwa saya akan membutuhkan restic untuk menyediakan header Content-Length untuk menghapus buffering sepenuhnya.

Saya telah memperbarui cabang dengan beberapa kode yang sekarang melewati semua tes :-)

Saya juga telah mengirim PR yang akan menghemat banyak waktu jika sudah ada!

Luar biasa, saya baru saja melihat sekilas dan itu bekerja dengan sangat baik! Terima kasih!

Jadi, apa langkah selanjutnya? Dari sudut pandang saya, akan lebih baik untuk mencoba perpustakaan go-plugin oleh hashicorp, jadi memulai/menghentikan rclone dapat diintegrasikan ke dalam restic. Pikiran?

Atau mungkin go-plugin bukan pilihan yang tepat, tidak dirancang untuk bekerja, misalnya ssh . Hm. Mungkin membangun sesuatu sendiri?

Saya telah bermain-main dengan gRPC melalui yamux hari ini, bekerja dengan cukup baik. Pro adalah:

  • Spesifikasi antarmuka yang dapat dibaca mesin
  • Pembuatan kode untuk sebagian besar bahasa, termasuk Go
  • Dapat diucapkan melalui stdin/stdout (hanya dengan stream muxer seperti yamux)

Kontra:

  • Tergantung pada yamux, yang merupakan protokol yang telah teruji pertempuran tetapi tidak umum
  • Mengirim data dalam jumlah besar memerlukan pengiriman data dalam potongan, yang perlu diakui dari sisi lain, sehingga sangat bergantung pada latensi. Menjenuhkan tautan latensi tinggi membutuhkan potongan besar atau paralelisme besar.

Kita dapat membuang yamux dan menggunakan HTTP2 (tanpa TLS), kemudian kita dapat menggunakan HTTP secara langsung atau menggunakan gRPC lagi. Saya ingin tahu apakah ada solusi yang lebih sederhana. Hm. Tidak terlalu memuaskan.

Dari apa yang saya pahami, Yamux terinspirasi oleh SPDY (pendahulu HTTP2, IIRC) tetapi tidak kompatibel dengannya. Apa keuntungan menggunakan protokol kustom dibandingkan protokol standar?

Sepertinya saya HTTP2 akan banyak keuntungan dalam hal interoperabilitas, desain, portabilitas dan keamanan (mengapa tidak ada TLS?). Bisakah Anda menjelaskan mengapa Anda ragu-ragu menggunakannya?

Mengenai latensi, Google sedang mengerjakan QUIC untuk menyelesaikan masalah tersebut (LWN memiliki seri yang bagus tentang itu , meskipun APNIC juga memiliki peringatan ), jadi ada cara standar di luar sana juga.

Saya telah bermain-main dengan gRPC melalui HTTP2 melalui stdin/stdout (tanpa TLS) hari ini, juga berfungsi dengan baik. Meskipun saya harus sedikit mengutak-atiknya agar HTTP2 over stdin/stdout berfungsi, tetapi itu sudah selesai sekarang. Itu membutuhkan golang.org/x/net/http2 , tapi kami tetap menjualnya. Itu membuat implementasi backend lebih fleksibel: Kita dapat memiliki backend melalui HTTP2 melalui stdin/stdout (misalnya proses rclone , atau menjalankan proses melalui ssh ) atau bahkan menggunakan backend HTTP2 secara langsung . Rapi.

Juga, menjenuhkan tautan latensi tinggi lebih baik saat menggunakan HTTP2 (dibandingkan dengan yamux)

@ncw apakah Anda memiliki preferensi atau pengalaman sehubungan dengan RPC atau kerangka muxing streaming?

Saya telah bekerja untuk mengintegrasikan server REST API ke rclone dan sekarang saya mendapatkan sesuatu yang saya senangi! Saya harus membuat lapisan penyajian HTTP umum untuk dua server http yang ada di rclone (!) sebelum saya menambahkan yang lain! Saya akhirnya menulis ulang server http restic hampir dari awal.

Anda dapat menemukan kode di serve-restic repo di rclone repo . Ini melewati tes backend restic dan sedikit pengujian manual ringan - umpan balik akan dihargai :-)

Jika Anda punya waktu, saya akan menghargai beberapa umpan balik tentang:

Saya menulis ulang mux dari prinsip pertama dan berhasil membuatnya hampir bebas kebijakan. Satu-satunya kebijakan di sini di mana objek konfigurasi dapat ditimpa tetapi tidak ada yang bisa. Itu mungkin bisa diganti dengan parameter allow_overwrite ...

REST API untuk restic tampaknya melakukan pekerjaan dengan baik. Satu-satunya hal yang akan membuat hidup rclone lebih mudah adalah memiliki Content-Length pada POST panggilan objek baru. Saya melihat patching restic untuk menambahkan itu, tetapi kesimpulan saya adalah bahwa itu lebih sulit daripada yang saya pikir pertama kali karena panggilan Save() backend tidak tahu panjang objek yang di-POSTing. Sebuah petunjuk di sini akan sangat membantu :-)

Konsekuensi dari rclone tidak mengetahui panjang benda yang disimpan adalah bahwa pada beberapa remote ( apa pun yang tidak mendukung unggahan streaming ), rclone harus menggulungnya ke memori/disk sebelum mengunggahnya.

Saya sangat ingin menggabungkan cabang serve-restic menjadi master sehingga pengguna kami memiliki versi 1.0 untuk dimainkan - bagaimana menurut Anda?

@fd0 menulis

Saya telah bermain-main dengan gRPC melalui HTTP2 melalui stdin/stdout (tanpa TLS) hari ini, juga berfungsi dengan baik. Meskipun saya harus sedikit mengutak-atiknya agar HTTP2 over stdin/stdout berfungsi, tetapi itu sudah selesai sekarang. Itu membutuhkan golang.org/x/net/http2, tapi kami tetap menjualnya. Itu membuat implementasi backend lebih fleksibel: Kita dapat memiliki backend melalui HTTP2 melalui stdin/stdout (misalnya proses rclone lokal, atau menjalankan proses melalui ssh) atau bahkan menggunakan backend HTTP2 secara langsung. Rapi.

Melayani HTTP2 melalui stdin/stdout terdengar sangat menarik... Apakah Anda memiliki beberapa kode yang dapat saya lihat sehingga saya dapat mengimplementasikannya di rclone? Evolusi berikutnya untuk rclone serve restic mungkin membuatnya melayani melalui HTTP2 dan melalui stdin/stdout. Itu kemudian akan membiarkan restic memulai dan menghentikan rclone.

Saya tidak memiliki pendapat yang kuat tentang gRPC karena tidak menggunakannya dengan sungguh-sungguh. Jelas terlihat kekuatan industri :-) Yang mengatakan, apakah kita membutuhkannya jika HTTP2 melakukan pekerjaan untuk kita? Seperti yang saya pahami, HTTP2 akan menggandakan koneksi melalui satu soket jadi saya pikir itu akan bekerja dengan baik tanpa gRPC dan kita bisa mendapatkan backend REST yang ada untuk menggunakannya?

@ncw Saya juga tidak terlalu akrab dengan gRPC, tetapi dari apa yang saya kumpulkan, itu pada dasarnya HTTP2 + protobufs + saus ajaib (wikipedia secara khusus mengatakan "otentikasi, streaming dua arah dan kontrol aliran, pengikatan pemblokiran atau nonblocking, dan pembatalan dan batas waktu") ... "REST" tidak banyak bicara: apa format serialisasi yang sebenarnya? JSON? XML-RPC? bagaimana panggilan RPC sebenarnya dilakukan?

gRPC memiliki keuntungan menstandarisasi semua ini dengan protobuf dan cara pemanggilan fungsi yang telah ditentukan sebelumnya dan sebagainya.

kerja yang baik!

Hei Nick, itu berita bagus! Aku akan melihat sekarang. Bisakah Anda membuka Permintaan Tarik di repo rclone sehingga kami dapat melampirkan komentar ke kode dan mengulanginya (jika perlu)? Atau apa cara komunikasi pilihan Anda di sini? Haruskah saya mengirimi Anda tambalan? ;)

Masalah acak yang saya lihat saat menggulir kode:

  • Mungkin kita harus menambahkan tautan ke https://restic.net di bantuan? Sehingga pengguna dapat menemukan tentang apa ini semua?
  • Apakah otentikasi untuk server HTTP didukung? Jika demikian, haruskah kita memaksanya untuk mendengarkan sesuatu selain localhost (akhirnya)?
  • Versi restic minimal yang dibutuhkan mungkin 0.8.0, bahkan dapat bekerja dengan versi sebelumnya. Atau adakah alasan khusus mengapa bantuan mengatakan 0.8.2 diperlukan?
  • Apa alasan URL yang diteruskan ke restic harus diakhiri dengan garis miring? Apakah itu batasan yang dimiliki restic (kita harus memperbaikinya...)?
  • Kami telah melonggarkan persyaratan untuk file baru, mengembalikan kesalahan saat menulis file yang ada tidak diperlukan lagi, lihat https://github.com/restic/restic/pull/1623
  • Tes integrasi terdengar bagus sejauh ini, meskipun saya tidak dapat menjamin bahwa nama file dan jalur tetap seperti itu :)
  • Saya akan membantu menambahkan header Content-Length jangka pendek, kita perlu sedikit mengerjakan ulang antarmuka backend secara restic. Saya punya rencana untuk itu, tetapi belum ada kode. Luar biasa bahwa kode di rclone sudah menangani kedua kasus, kerja bagus!

Selama pengembangan restic, kami memiliki beberapa tata letak repositori yang berbeda, yang dijelaskan di sini: https://restic.readthedocs.io/en/latest/100_references.html#repository -layout Sekarang kami telah menetapkan tata letak default, yang berarti file di data/ disimpan di subdir, misalnya data/21/2159dd48f8a24f33c307b750592773f8b71ff8d11452132a7b2e2a6a01611be1 . Tetapi file ini diakses melalui REST sebagai http://localhost:8080/repo/path/data/2159dd48f8a24f33c307b750592773f8b71ff8d11452132a7b2e2a6a01611be1 .

Saat ini, rclone akan memasukkan file-file tersebut ke data/ secara langsung. Yang masih didukung secara transparan seharusnya restic pernah mengakses direktori secara langsung, tetapi akan menimbulkan masalah ketika repo dibuat di s3 atau b2 melalui rclone, dan kemudian diakses dengan restic langsung di layanan.

Ini adalah salah satu alasan saya tidak terlalu suka mengimplementasikan backend REST di rclone, melainkan membangun sesuatu yang lain, misalnya berdasarkan gRPC (lihat di bawah). Tapi sekarang kita memilikinya, kita harus memperbaikinya dan membuatnya bekerja. Ini adalah satu-satunya masalah kritis yang bisa saya lihat. Saya ingin pindah menggunakan tata letak repo default di mana-mana, itulah satu-satunya cara yang masuk akal IMHO.

Apa yang perlu terjadi dari sudut pandang saya adalah bahwa rclone perlu mengimplementasikan (atau menyalin) apa yang disebut DefaultLayout , yang memberikan jalur ke nama file yang diakses melalui HTTP: https://github.com/ restic/restic/blob/master/internal/backend/layout_default.go Dir perantara perlu dibuat sesuai permintaan, jika tidak ada.

Saat kami menambahkan backend yang menggunakan mis. gRPC via HTTP2 via stdin/stdout, ada masalah desain antarmuka pengguna yang perlu dipertimbangkan. Bagaimana backend baru akan dipanggil? Bagaimana pengguna menentukan perintah mana yang akan dijalankan (seperti ssh user<strong i="30">@host</strong> restic serve-backend atau rclone serve restic-http2-grpc )? Kemudian backend baru juga tidak akan mempedulikan path file apa pun, jadi restic akan menangani subdir data/ dan menyediakan backend dengan path lengkap (misalnya save data to file /foo/bar/restic-repo/data/21/21123123123[...] ). Ini tidak mungkin untuk backend REST, karena kami telah mendefinisikan protokol dan ada implementasi yang digunakan di alam liar...

sekian untuk saat ini :)

@fd0 maaf atas penundaan lama lainnya - bertukar buruk saat ini ;-)

Hei Nick, itu berita bagus! Aku akan melihat sekarang. Bisakah Anda membuka Permintaan Tarik di repo rclone sehingga kami dapat melampirkan komentar ke kode dan mengulanginya (jika perlu)? Atau apa cara komunikasi pilihan Anda di sini? Haruskah saya mengirimi Anda tambalan? ;)

Tambalan - betapa anehnya! Saya akan membuka PR dengan iterasi berikutnya dan kita bisa melihat cara kerjanya! Anda juga dapat mengirim PR ke cabang (walaupun jika Anda ingin melakukannya, saya harus berhenti me-rebasing cabang!)

Mungkin kita harus menambahkan tautan ke https://restic.net di bantuan? Sehingga pengguna dapat menemukan tentang apa ini semua?

Saya sudah melakukannya :-)

Apakah otentikasi untuk server HTTP didukung? Jika demikian, haruskah kita memaksanya untuk mendengarkan sesuatu selain localhost (akhirnya)?

Ya, Anda dapat mengatur banyak hal keluar untuk server! Tidak ingin memaksa pengguna untuk mengatur kata sandi, tetapi menyarankan dengan kuat di dokumen adalah ide yang bagus! Saya telah membuat catatan di dokumen tentang itu.

Flags:
      --addr string                     IPaddress:Port or :Port to bind server to. (default "localhost:8080")
      --cert string                     SSL PEM key (concatenation of certificate and CA certificate)
      --client-ca string                Client certificate authority to verify clients with
      --htpasswd string                 htpasswd file - if not provided no authentication is done
      --key string                      SSL PEM Private key
      --max-header-bytes int            Maximum size of request header (default 4096)
      --pass string                     Password for authentication.
      --realm string                    realm for authentication (default "rclone")
      --server-read-timeout duration    Timeout for server reading data (default 1h0m0s)
      --server-write-timeout duration   Timeout for server writing data (default 1h0m0s)
      --user string                     User name for authentication.

Versi restic minimal yang dibutuhkan mungkin 0.8.0, bahkan dapat bekerja dengan versi sebelumnya. Atau adakah alasan khusus mengapa bantuan mengatakan 0.8.2 diperlukan?

Err, saya menggunakan v2 REST API 7e6bfdae7909da7a1f9da76e1be063001c8b34c3 yang menurut saya hanya dirilis di v0.8.2.

Apa alasan URL yang diteruskan ke restic harus diakhiri dengan garis miring? Apakah itu batasan yang dimiliki restic (kita harus memperbaikinya...)?

Ini lebih merupakan batasan backend rclone. Ini memberitahu file dan direktori terpisah apakah mereka berakhir dengan / atau tidak.

Kami telah melonggarkan persyaratan untuk file baru, mengembalikan kesalahan saat menulis file yang ada tidak diperlukan lagi, lihat #1623

Selesai!

Tes integrasi terdengar bagus sejauh ini, meskipun saya tidak dapat menjamin bahwa nama file dan jalur tetap seperti itu :)

Tentu! Senang menyesuaikannya saat rusak!

Saya akan membantu menambahkan header Content-Length jangka pendek, kita perlu sedikit mengerjakan ulang antarmuka backend secara restic. Saya punya rencana untuk itu, tetapi belum ada kode. Luar biasa bahwa kode di rclone sudah menangani kedua kasus, kerja bagus!

:-)

Saat ini, rclone akan memasukkan file-file itu ke dalam data/ ...

Ah. Saya melewatkan sedikit itu ... Mudah untuk memperbaikinya

Dir perantara perlu dibuat sesuai permintaan, jika tidak ada.

rclone akan membuat direktori perantara seiring berjalannya

Idealnya saya ingin menggabungkan ini tepat waktu untuk rilis rclone berikutnya yang seharusnya dalam beberapa minggu ...

Saya meletakkan versi berikutnya di cabang serve-restic dan saya membuat permintaan tarik kali ini untuk komentar yang lebih mudah: https://github.com/ncw/rclone/pull/2116

Keren, saya akan lihat! Btw, dengan perubahan terbaru di #1639, sekarang backend restic akan mengatur header content-length . :)

Err, saya menggunakan v2 REST API 7e6bfda yang hanya dirilis di v0.8.2 saya rasa.

Oke. Apakah kode mengembalikan kesalahan saat protokol REST lama digunakan? Itu akan menjadi hal yang baik untuk dimiliki, sehingga orang tidak mengalami masalah, kami menghabiskan waktu untuk men-debug ini, dan ternyata hanya versi restic...

Ini lebih merupakan batasan backend rclone. Ini memberitahu file dan direktori terpisah apakah mereka berakhir dengan / atau tidak.

Hm, kita bisa melakukan ini di restic, rest-server kompatibel dengannya, jadi pengguna tidak perlu peduli tentang itu. Pikiran?

Idealnya saya ingin menggabungkan ini tepat waktu untuk rilis rclone berikutnya yang seharusnya dalam beberapa minggu ...

Baik dengan saya, saya akan bekerja dengan Anda untuk menggabungkannya!

Saya meletakkan versi berikutnya di cabang serve-restic dan saya membuat permintaan tarik kali ini untuk komentar yang lebih mudah: ncw/rclone#2116

Saya akan mengeceknya!

Bisakah kita menambahkan kode untuk menjalankan server di stdin/stdout dengan HTTP2? Saya sudah menyiapkan kode untuk itu, seharusnya tidak sulit dilakukan. Dengan cara ini, kita bisa memulai rclone dari restic, dan merobohkannya dengan benar, tanpa TCP...

Saya akan memasang beberapa kode sampel.

Bersulang!

  • Alex

Saya sudah bermain-main dengannya, sudah terlihat bagus!

Saya telah menambahkan dua komit di sini: https://github.com/fd0/rclone/tree/serve-restic , yang kedua menambahkan mode http2/server di stdin/stdout. Ini dapat digunakan dengan cabang saya https://github.com/restic/restic/tree/rclone-backend seperti ini:

$ ./restic -r rclone:b2:restic-dev-an/path/to/repo snapshots

Ini akan secara otomatis memulai rclone dalam mode http2/server dengan --stdin , Anda juga dapat melewati baris perintah sebagai opsi:

$ ./restic \
  -r rclone:b2:restic-dev-an/path/to/repo \
  -o rclone.command="rclone serve restic --stdin --bwlimit 1M --verbose b2:restic-test-an/foo" \
  backup .

Secara internal, saya menggunakan backend REST dan hanya menambahkan sedikit lem untuk memulai proses rclone dan merobeknya dengan benar.

Omong-omong, ini dapat dimulai dengan mudah melalui ssh pada host jarak jauh, cukup setel -o rclone.command='ssh user<strong i="18">@host</strong> rclone serve restic --stdin b2:restic-test-an/foo' .

Tolong beritahu saya bagaimana menurut anda!

Oke. Apakah kode mengembalikan kesalahan saat protokol REST lama digunakan? Itu akan menjadi hal yang baik untuk dimiliki, sehingga orang tidak mengalami masalah, kami menghabiskan waktu untuk men-debug ini, dan ternyata hanya versi restic...

Saya pikir satu-satunya perbedaan adalah format apa yang dikembalikan oleh perintah daftar. Saya dapat dengan mudah mengembalikan format lama juga - saya baru saja menyipitkan mata pada sumber server lainnya dan menggunakan header Terima untuk melakukan itu. Apakah layak melakukan itu menurut Anda atau hanya mengembalikan kesalahan jika format lama terdeteksi?

Hm, kita bisa melakukan ini di restic, rest-server kompatibel dengannya, jadi pengguna tidak perlu peduli tentang itu. Pikiran?

Jika Anda ingin memperbaikinya dalam restic (dan saya kira spesifikasi API) maka saya dapat mengambil kalimat itu dari dokumen yang mungkin lebih rapi.

Saya telah menambahkan dua komit di sini: https://github.com/fd0/rclone/tree/serve-restic , yang kedua menambahkan mode http2/server di stdin/stdout. Ini dapat digunakan dengan cabang saya https://github.com/restic/restic/tree/rclone-backend seperti ini:

Indah :-) Saya akan segera menggabungkan ini ke cabang saya dan mencobanya!

Saya mungkin pada suatu saat memindahkan penyajian http2 dan stdin ke cmd/serve/httplib tetapi saya pikir membiarkannya di tempat Anda meletakkannya untuk saat ini adalah ide yang bagus.

Saya pikir satu-satunya perbedaan adalah format apa yang dikembalikan oleh perintah daftar. Saya dapat dengan mudah mengembalikan format lama juga - saya baru saja menyipitkan mata pada sumber server lainnya dan menggunakan header Terima untuk melakukan itu. Apakah layak melakukan itu menurut Anda atau hanya mengembalikan kesalahan jika format lama terdeteksi?

Ah, hm. Saya pikir lebih baik mengembalikan kesalahan, kami tidak menginginkan format lama. Ini membutuhkan lebih banyak perjalanan pulang pergi HTTP (itulah sebabnya kami memperkenalkan yang baru).

Saya mungkin pada suatu saat memindahkan penyajian http2 dan stdin ke cmd/serve/httplib tapi saya pikir membiarkannya di tempat Anda meletakkannya untuk saat ini adalah ide yang bagus.

Tentu, tolong pindahkan ke tempat yang tepat. Itu hanya percobaan. Saya senang Anda menyukainya. Anehnya, itu sangat mudah diterapkan setelah saya memiliki StdioConn hal di tempat.

Jika Anda ingin memperbaikinya dalam restic (dan saya kira spesifikasi API) maka saya dapat mengambil kalimat itu dari dokumen yang mungkin lebih rapi.

Kedengarannya seperti rencana yang bagus, saya ingin melakukan itu. Apa yang perlu kita lakukan? Tentukan bahwa URL dasar untuk repo selalu diakhiri dengan garis miring?

Kita dapat menulis ini ke dalam protokol REST, dan restic secara otomatis menambahkan garis miring jika tidak ada. Ada lagi yang tidak saya pikirkan?

Saya telah bermain-main dengan server stdin HTTP2, dan saya sangat suka itu bekerja dengan sangat baik. Apa yang saya tidak suka adalah bagaimana canggung rasanya memulainya. Apakah Anda memiliki ide yang lebih baik tentang apa yang harus dilakukan daripada --stdin ? Saya berpikir untuk mengatur variabel lingkungan untuk mengaktifkan mode stdin/stdout, tetapi itu tidak mudah ditransmisikan melalui SSH, meh.

Untuk proses rclone lokal, ini tidak terlalu buruk:

$ restic \
  -r rclone:b2:restic-dev-an/path/to/repo \
  backup .

Memulai proses rclone jarak jauh di sisi lain benar-benar canggung, saya tidak suka UI sama sekali:

$ restic \
  -r rclone:b2:restic-dev-an/path/to/repo \
  -o rclone.command="rclone serve restic --stdin --bwlimit 1M --verbose b2:restic-test-an/foo" \
  backup .

Spesifikasi jarak jauh yang diberikan dalam spesifikasi repo ( rclone:b2:restic-dev-an/path/to/repo ) sebenarnya tidak diteruskan ke rclone karena baris perintah ditimpa oleh -o rclone.command . Hm. Saya tidak punya ide yang lebih baik tentang bagaimana menyelesaikan ini sekarang.

Saya telah membuka PR #1657 untuk diskusi, ia menambahkan backend rclone dan juga tes yang tepat.

Satu masalah aneh yang saya temui saat menjalankan tes integrasi adalah yang ini:

$ go test -v -run /TestLoad
=== RUN   TestParseConfig
--- PASS: TestParseConfig (0.00s)
=== RUN   TestBackendRclone
2018/03/07 22:57:49 Server.Close()
=== RUN   TestBackendRclone/TestLoad
2018/03/07 22:57:49 ERROR : data/90/900a687bc2669f36e960c860f1e506daeb5753dd960b062b99b5716e2354d19c: Didn't finish writing GET request: http2: stream closed
2018/03/07 22:57:49 Server.Close()
--- PASS: TestBackendRclone (0.46s)
    backend_test.go:18: create new backend at /tmp/restic-test-822204889
    --- PASS: TestBackendRclone/TestLoad (0.45s)
        tests.go:27: rand initialized with seed 1520459869531256925
        tests.go:142: saved 12335322 bytes as <data/900a687bc2>
    backend_test.go:39: cleanup dir /tmp/restic-test-822204889
PASS
ok      github.com/restic/restic/internal/backend/rclone    0.462s

Pada pengujian pertama Load() di test suite ( di sini ), rclone mengeluh bahwa aliran untuk permintaan HTTP GET ditutup sebelum data selesai. Itu sangat aneh, saya tidak tahu mengapa itu terjadi. Untuk permintaan berikutnya dalam fungsi yang sama berhasil.

Juga sedikit mengganggu adalah output kesalahan dari rclone, hancur dengan output restic biasa ...

Ah, hm. Saya pikir lebih baik mengembalikan kesalahan, kami tidak menginginkan format lama. Ini membutuhkan lebih banyak perjalanan pulang pergi HTTP (itulah sebabnya kami memperkenalkan yang baru).

Oke saya sudah melakukannya. Saya mengembalikan HTTP errror 400. Saya menemukan bug kecil di restic melakukan ini - lihat #1660

Kedengarannya seperti rencana yang bagus, saya ingin melakukan itu. Apa yang perlu kita lakukan? Tentukan bahwa URL dasar untuk repo selalu diakhiri dengan garis miring?
Kita dapat menulis ini ke dalam protokol REST, dan restic secara otomatis menambahkan garis miring jika tidak ada. Ada lagi yang tidak saya pikirkan?

Saya pikir itu akan sempurna!

Saya telah bermain-main dengan server stdin HTTP2, dan saya sangat suka itu bekerja dengan sangat baik. Apa yang saya tidak suka adalah bagaimana canggung rasanya memulainya. Apakah Anda memiliki ide yang lebih baik tentang apa yang harus dilakukan daripada --stdin? Saya berpikir untuk mengatur variabel lingkungan untuk mengaktifkan mode stdin/stdout, tetapi itu tidak mudah ditransmisikan melalui SSH, meh.

Anda dapat mengatur params baris perintah rclone dengan variabel lingkungan , tetapi saya mengambil poin Anda tentang ssh.

Saya baik-baik saja dengan opsi --stdin - Saya pikir ini mengatakan persis apa yang kami coba lakukan di sini!

Memulai proses rclone jarak jauh di sisi lain benar-benar canggung, saya tidak suka UI sama sekali:

Saya mengerti maksud Anda... Seberapa mudahkah memproses baris perintah untuk menambahkan remote:path di ujungnya sehingga Anda tidak perlu menentukannya dua kali?

Keren, saya akan lihat! Btw, dengan perubahan terbaru di #1639, sekarang backend restic akan mengatur header panjang konten. :)

Saya tidak melihat itu di rclone... Jika Anda menghapus komentar debug di fungsi postObject sepertinya selalu -1, yaitu tidak ditentukan

Satu masalah aneh yang saya temui saat menjalankan tes integrasi adalah yang ini:

Saya akan menyelidikinya sebentar lagi!

Hm, panjang konten tidak diatur, Anda benar. Tapi saya mengaturnya dalam kode: https://github.com/restic/restic/blob/master/internal/backend/rest/rest.go#L122

Dan saya baru saja memverifikasi bahwa itu benar-benar sesuatu > 0. Apakah Anda tahu apa yang terjadi?

Ha, mengerti, lihat #1661 :)

Ya, itu dia! Saya telah membuat kesalahan itu sebelumnya :-)

Saya telah mengerjakan ulang backend dan sekarang UI jauh lebih baik. Ada dua opsi sekarang, rclone.command , yang berisi perintah yang digunakan untuk menjalankan proses rclone itu sendiri, dan rclone.args , yang secara default adalah serve restic --stdio . Perintah dan argumen dibangun dengan terlebih dahulu memisahkan rclone.command dan rclone.args menjadi "kata-kata shell" (menghormati kutipan), dan kemudian menggabungkan semuanya, dan menambahkan nama jarak jauh dari spesifikasi repositori.

Contoh lokal:

$ restic \
  -r rclone:b2:restic-dev-an/path/to/repo \
  -o rclone.args="serve restic --stdin --bwlimit 1M --verbose" \
  backup .

Menjalankan rclone melalui SSH:

$ restic \
  -r rclone:b2:restic-dev-an/path/to/repo \
  -o rclone.command="ssh user<strong i="15">@foo</strong> '/path/with spaces/rclone'" \
  -o rclone.args="serve restic --stdin --bwlimit 1M --verbose" \
  backup .

Itu IMHO jauh lebih baik.

Apakah Anda menemukan sesuatu tentang pesan kesalahan aneh selama pengujian?

Yang menurut saya agak aneh adalah rclone mencetak pesan selama teardown yang bahkan tidak dinonaktifkan dengan -q :

2018/03/13 22:39:03 Server.Close()

Pada 13-03-2018 21:44:20, Alexander Neumann menulis:

Saya telah mengerjakan ulang backend dan sekarang UI jauh lebih baik. Ada dua opsi sekarang, rclone.command , yang berisi perintah yang digunakan untuk menjalankan proses rclone itu sendiri, dan rclone.args , yang secara default adalah serve restic --stdio . Perintah dan argumen dibangun dengan terlebih dahulu memisahkan rclone.command dan rclone.args menjadi "kata-kata shell" (menghormati kutipan), dan kemudian menggabungkan semuanya, dan menambahkan nama jarak jauh dari spesifikasi repositori.

[...]

Menjalankan rclone melalui SSH:

$ restic \
  -r rclone:b2:restic-dev-an/path/to/repo \
  -o rclone.command="ssh user<strong i="16">@foo</strong> rclone" \
  -o rclone.args="serve restic --stdin --bwlimit 1M --verbose" \
  backup .

Berhati-hatilah saat meneruskan argumen string panjang yang dikutip Shell ke SSH. saya sudah
selalu terkejut dengan apa yang terjadi di sisi lain.. Misalnya,
alih-alih hanya memberikan argumen ke execve(2) seperti yang mungkin dilakukan golang
lakukan jika hanya memanggil "rclone serve restic --stdin --bwlimit 1M --verbose"
secara lokal, Anda sebenarnya akan memanggil sh -c di ujung lain dari ssh
pipa, yang berarti karakter shell Anda perlu dikutip lagi.

Saya tidak yakin apa dampaknya, tetapi "rclone" dan "ssh foo
rclone" tidak sama, kecuali jika Anda memanggil "rclone" (dan bukan "ssh foo
rclone") dengan "sh -c rclone".

Bingung belum? :)

Ah, terima kasih sudah diingatkan. Kode tidak meneruskan string panjang ke ssh sebagai argumen tunggal, melainkan menguraikannya dengan benar dan meneruskannya ke ssh sebagai argumen terpisah.

Jadi, untuk perintah

$ restic \
    -r rclone:b2:restic-dev-an/path/to/repo \
    -o rclone.command="ssh [email protected] '/path/with spaces/to/rclone'" \
    -o rclone.args="serve restic --stdin --bwlimit 1M --verbose" \
    backup .

restic akan memanggil (dalam kode semu):

exec("ssh", "[email protected]", "/path/with spaces/to/rclone", "serve", "restic", "--stdin", "--bwlimit", "1M", "--verbose", "b2:restic-dev-an/path/to/repo")

dari pada:

exec("ssh [email protected] '/path/with spaces/to/rclone'", [...])

Melewati string sebagai argumen terpisah ke ssh telah membantu saya dengan sangat baik di proyek lain, jadi ssh menangani meneruskannya dengan benar ke sisi lain.

Ada beberapa tes yang menunjukkan bahwa kode tersebut juga menangani, misalnya, pembatas string yang lolos dengan benar, misalnya:
https://github.com/restic/restic/blob/0279fd72123adc52686156332ed7c00a3a07d6e9/internal/backend/sftp/split_test.go#L39 -L44

menarik ... saya selalu berjuang dengan ini seperti orang gila, saya kira itu karena saya memanggil ssh pada baris perintah shell ... tidak apa-apa, Anda tampaknya memiliki hal-hal yang teratur. :)

Saya dapat mengaitkannya dengan itu, penanganan string menjadi jauh lebih rumit ketika shell terlibat, jadi saya berusaha keras untuk tidak memasukkan shell apa pun jika tidak benar-benar diperlukan;)

@fd0 menulis:

Saya telah mengerjakan ulang backend dan sekarang UI jauh lebih baik.

Sangat bagus :-)

Apakah Anda menemukan sesuatu tentang pesan kesalahan aneh selama pengujian?

Apa yang terlihat adalah bahwa rclone sedang melayani permintaan GET ketika restic menutup koneksi. Saya menambahkan sedikit lebih banyak debugging untuk melihat seberapa jauh hasilnya.

Saya juga menjalankan ini dengan rclone statis (tidak dimulai dengan tes rclone) dan melihat hal yang sama.

2018/03/14 15:10:04 ERROR : data/39/39bb8b2bacd307fab053ef721278630aa1c94ce716ce4236cbbab4c225998ec9: Tidak selesai menulis GET request (menulis 32768/13575812 byte): write tcp 127.0.0.1:80:56214: write:80:56214: write. pipa rusak

Sepertinya restic menutup koneksi tanpa membaca semua data

Setelah sedikit eksperimen, saya menemukan bahwa jika saya mengomentari kode ini, kesalahannya hilang. Saya tidak yakin bagaimana cara memperbaikinya, atau bahkan jika itu dapat diperbaiki, tetapi penyebabnya adalah restic tidak membaca seluruh respons.

diff --git a/internal/backend/test/tests.go b/internal/backend/test/tests.go
index caf0a9ac..643f4d1a 100644
--- a/internal/backend/test/tests.go
+++ b/internal/backend/test/tests.go
@@ -146,15 +146,15 @@ func (s *Suite) TestLoad(t *testing.T) {
        t.Fatalf("Load() returned no error for negative offset!")
    }

-   err = b.Load(context.TODO(), handle, 0, 0, func(rd io.Reader) error {
-       return errors.Errorf("deliberate error")
-   })
-   if err == nil {
-       t.Fatalf("Load() did not propagate consumer error!")
-   }
-   if err.Error() != "deliberate error" {
-       t.Fatalf("Load() did not correctly propagate consumer error!")
-   }
+   // err = b.Load(context.TODO(), handle, 0, 0, func(rd io.Reader) error {
+   //  return errors.Errorf("deliberate error")
+   // })
+   // if err == nil {
+   //  t.Fatalf("Load() did not propagate consumer error!")
+   // }
+   // if err.Error() != "deliberate error" {
+   //  t.Fatalf("Load() did not correctly propagate consumer error!")
+   // }

    loadTests := 50
    if s.MinimalData {

Saya pikir ini adalah bug di backend.DefaultLoad , itu tidak sepenuhnya menguras rd io.Reader jika terjadi kesalahan. Perlu menambahkan io.Copy(ioutil.Discard, rd) sana sesuai https://stackoverflow.com/questions/17948827/reusing-http-connections-in-golang.

@ifedorenko menulis:

Saya pikir ini adalah bug di backend.DefaultLoad, itu tidak sepenuhnya menguras rd io.Reader jika terjadi kesalahan. Perlu menambahkan io.Copy(ioutil.Discard, rd) di sana sesuai https://stackoverflow.com/questions/17948827/reusing-http-connections-in-golang.

Hmm, mungkin meskipun menguras pembaca non HTTP (misalnya file disk) tidak masuk akal.

Saya tidak berpikir ini akan terjadi dalam operasi normal dan jika rclone mencetak kesalahan dan kami harus membuat ulang koneksi http yang persisten yang seharusnya tidak menjadi masalah besar.

Saya pikir ini lebih merupakan masalah kosmetik untuk tes.

Ya, sedang memikirkan hal ini juga. Backend berbasis HTTP individual harus mengembalikan pembaca yang mengalirkan aliran saat ditutup.

Juga, saya baru menyadari backend rclone menggunakan http2, yang mendukung pembatalan aliran yang sedang berlangsung melalui frame RST_STREAM. Bertanya-tanya apakah implementasi klien/server Go http2 benar-benar memanfaatkannya.

Saya pikir ini adalah bug di backend.DefaultLoad, itu tidak sepenuhnya menguras rd io.Reader jika terjadi kesalahan.

Ah, saya dulu berpikir bahwa ini adalah cara yang benar, tetapi sekarang saya pikir kita harus membiarkan ini dan tidak menguras pembaca sepenuhnya di DefaultLoader . Kode net/http memiliki sesuatu yang mencoba membaca hingga 2KiB sehingga koneksi dapat digunakan kembali, tetapi jika lebih banyak data dapat dibaca, koneksi akan dibuang:

https://github.com/golang/go/blob/aff222cd185d10400b9177fe26ec06eb647b092d/src/net/http/client.go#L590 -L598

// Close the previous response's body. But
// read at least some of the body so if it's
// small the underlying TCP connection will be
// re-used. No need to check for errors: if it
// fails, the Transport won't reuse it anyway.
const maxBodySlurpSize = 2 << 10
if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
    io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize)
}

Di HTTP 1.1, menutup koneksi adalah satu-satunya cara yang dapat diandalkan untuk memberi tahu server untuk berhenti mengirim data, jadi tergantung pada jumlah data, seringkali lebih efisien untuk menutup koneksi dan membuat yang baru daripada memuat megabyte data hanya untuk dapat menggunakan kembali koneksi.

Jadi, saya telah memperbaiki tes untuk menguras pembaca terlebih dahulu dan kemudian mengembalikan kesalahan khusus, itu sangat mudah. Dalam retrospeksi juga mudah untuk melihat apa yang terjadi ;)

--- a/internal/backend/test/tests.go
+++ b/internal/backend/test/tests.go
@@ -147,6 +147,10 @@ func (s *Suite) TestLoad(t *testing.T) {
    }

    err = b.Load(context.TODO(), handle, 0, 0, func(rd io.Reader) error {
+       _, err := io.Copy(ioutil.Discard, rd)
+       if err != nil {
+           t.Fatal(err)
+       }
        return errors.Errorf("deliberate error")
    })
    if err == nil {

Saya menemukan penyebab pesan aneh yang tercetak di server tutup, saya meninggalkan panggilan ke log.Printf() dalam kode StdioConn :)

https://github.com/ncw/rclone/pull/2139

Terima kasih atas perbaikannya :-) Saya telah mencoba perbaikan pengeringan Anda dan itu juga berfungsi dengan baik :-)

Saya hanya akan memiliki jagoan cepat melalui cabang rclone-backend dan mengomentari apa pun yang saya lihat di sana.

Jadi, kode pada dasarnya sudah selesai, hanya perlu beberapa dokumen. Saya dapat menggunakan bantuan untuk menguji backend (di cabang rclone-backend ) :)

Juga, saya telah mengubah protokol REST dan backend REST, sehingga URL dasar selalu diakhiri dengan garis miring.

Dokumen selesai, silakan coba! Ping @mholt

Hai @fd0! terima kasih banyak telah melakukan pekerjaan untuk mengintegrasikan rclone .

Saya memiliki masalah dengan repositori restic di Google Drive. Membuat repositori baru berfungsi dengan baik, tetapi ketika saya mencoba mengakses repositori yang ada (dengan sekitar 7 TiB data), restic gagal dengan kesalahan:

./restic backup -o rclone.program="path/to/rclone" -r rclone:gdrive:restic/test --tag initial /path/to/data
Fatal: unable to open repo at rclone:gdrive:restic/test: error talking HTTP to rclone: Get http://localhost/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)

Ini adalah repositori lokal yang telah disinkronkan ke Google Drive. Menggunakan build restic khusus, saya dapat mengakses repositori dengan baik.

@fd0 Terima kasih atas pingnya! Saya telah menerima email tentang ini dan saya _super_ bersemangat untuk mencobanya! Baru saja datang pada saat yang buruk bagi saya karena saya benar-benar sibuk menyelesaikan dukungan ACMEv2 + wildcard di Caddy sekarang. Tapi saya akan kembali ke ini ASAP karena saya ingin melihat bagaimana menggunakannya, terutama proxy untuk menghindari memberikan kredensial cloud ke klien cadangan, seperti yang kita bicarakan di edisi lain. Pertahankan pekerjaan hebat!

@mathiasnagler

Anda bisa mendapatkan rclone untuk mencatat lebih banyak hal untuk debugging

export RCLONE_VERBOSE=2

sebelum istirahat berjalan.

Mungkin batas waktu dalam restic untuk backend lainnya terlalu pendek - bagaimana menurut Anda @ fd0?

Perhatikan juga bahwa drive bisa sangat lambat! Sudahkah Anda mendapatkan kredensial Anda sendiri atau apakah Anda menggunakan rclone's. Jika yang terakhir maka saya sarankan membuat sendiri .

Ah, itu batas waktu khusus: restic memulai rclone di grup proses latar depan (sehingga hal-hal seperti permintaan kata sandi berfungsi), dan di latar belakang ia mencoba membuat koneksi HTTP2. Setelah selesai, restic memindahkan rclone ke latar belakang. Saat ini, batas waktu untuk permintaan HTTP pertama yang harus diselesaikan cukup rendah (5 detik), saya akan memperbarui ini menjadi 60 detik. Setelah 60-an, proses seharusnya sudah boot.

Mungkin batas waktu dalam restic untuk backend lainnya terlalu pendek - bagaimana menurut Anda @ fd0?

Mungkin, tapi bukan yang ini: Yang ini adalah batas waktu internal restic ;)

Saya akan menambahkan petunjuk untuk men-debug rclone ke dokumen. Mampu mengonfigurasi rclone secara tidak langsung melalui variabel lingkungan yang diwarisi itu luar biasa :)

@mathiasnagler bisa tolong coba lagi?

Terima kasih atas tanggapan Anda!

@ncw Saya menggunakan kredensial saya sendiri. Menggunakan build dari komit yang saya tautkan di atas, restic dapat sepenuhnya memenuhi bandwidth unggahan saya dengan kredensial tersebut (sekitar 40Mbit/dtk).

@ fd0 Akan dilakukan secepatnya.

Memperbarui:

Sayangnya, bahkan dengan 60 detik masalah yang sama terjadi. Saya pikir ini disebabkan oleh ukuran repositori/jumlah file dalam repositori. Saya bahkan meningkatkan batas waktu menjadi 180 detik, tetapi masih belum berhasil.

Apa yang sebenarnya terjadi selama periode boot? rclone debug output menyarankan, bahwa a ls dijalankan:

rclone: 2018/03/18 14:14:49 DEBUG : : list request

Bisakah saya memeriksa secara manual berapa lama waktu yang dibutuhkan dengan menjalankan rclone ls gdrive:restic/test ?

Memperbarui:

Saya meningkatkan batas waktu menjadi 1800 detik (30 menit) untuk melihat berapa lama waktu yang dibutuhkan. Setelah 7 menit, restic diminta untuk memasukkan kata sandi repositori. Dari sana, daftar snapshot berfungsi seperti yang diharapkan.

@mathiasnagler

Bisakah saya memeriksa secara manual berapa lama waktu yang dibutuhkan dengan menjalankan rclone ls gdrive:restic/test?

Ya itu harus melakukannya. Perhatikan bahwa daftar di drive relatif mahal :-(

Saya tertarik untuk menguji (menggunakan Google Drive sebagai backend), tetapi saya memerlukan edisi win64 yang telah dikompilasi dari restic dan rclone untuk melakukannya..

Saat ini saya mendapatkan batas waktu acak pada pemeriksaan restic --read-data berjalan dengan beberapa repositori menggunakan klien Drive FS (sebagai pengguna yang membayar untuk GSuite for Business)

rclone ls gdrive:restic/test membutuhkan waktu antara 4 dan 7 menit untuk saya selesaikan. Ukuran repositori sekitar 7 TiB, jadi ini mungkin bukan norma.
Masih saya merasa restic tidak harus gagal di sini. Saya baik-baik saja dengan itu membutuhkan waktu.

Oh, itu salahku. Saya pikir itu akan menjadi ide yang baik (sebagai ujian ketika rclone siap menerima permintaan HTTP) untuk mengeluarkan permintaan HTTP GET / . Yang, seperti yang baru saja saya temukan, menghasilkan daftar semua file di remote. Itulah alasan mengapa startup membutuhkan waktu begitu lama. Saya akan mengubahnya, silakan coba lagi!

Saya telah mengubah kodenya sehingga akan mencoba meminta nama file acak, yang tidak ada. Kami hanya ingin memastikan rclone siap untuk menanggapi permintaan HTTP.

Startup cepat sekarang. Terima kasih atas pembaruannya!

Saya memulai pencadangan baru untuk menguji lagi.

@ fd0 Setelah pemeriksaan lebih lanjut, saya memiliki masalah lain. Untuk menguji fitur baru, saya membuat repositori baru di gdrive (Google Drive). Membuat repositori berfungsi seperti yang diharapkan dan saya dapat melihat file dan folder menggunakan antarmuka web gdrive.
Saya kemudian memulai pencadangan pertama saya ke repositori baru:

restic -o rclone.program="/path/to/rclone" -r rclone:gdrive:test backup --tag initial /path/to/data

restic melaporkan bahwa pencadangan sedang berjalan dan tampaknya telah mencadangkan sejumlah data:

[4:00] 0.12%  99.099 MiB / 82.369 GiB  49 / 13646 items  0 errors  ETA 56:40:29 

Masalahnya adalah bahwa pencadangan tidak akan pernah benar-benar berlanjut. Saya dapat mengamati bahwa tidak ada data yang keluar dari mesin. Tidak ada lalu lintas keluar sama sekali. Menggunakan export RCLONE_VERBOSE=2 Saya melihat beberapa kesalahan:

rclone: 2018/03/19 17:59:39 ERROR : locks: error listing: directory not found
rclone: 2018/03/19 17:59:39 DEBUG : Google drive root 'test': POST /locks/a23337ca935c44307b36f1f7146da9e152dbc3d919f5a254c78921fa986fae1a
rclone: 2018/03/19 17:59:42 DEBUG : Google drive root 'test': GET /locks/
rclone: 2018/03/19 17:59:42 DEBUG : locks: list request
rclone: 2018/03/19 17:59:42 DEBUG : Google drive root 'test': GET /index/
rclone: 2018/03/19 17:59:42 DEBUG : index: list request
rclone: 2018/03/19 17:59:42 ERROR : index: error listing: directory not found
rclone: 2018/03/19 17:59:42 DEBUG : Google drive root 'test': GET /snapshots/
rclone: 2018/03/19 17:59:42 DEBUG : snapshots: list request
rclone: 2018/03/19 17:59:42 ERROR : snapshots: error listing: directory not found

Saya pikir itu baik-baik saja karena folder akan dibuat ketika pencadangan pertama terjadi dan bukan selama pembuatan repo, tetapi saya tidak sepenuhnya yakin.
Terlepas dari 3 kesalahan itu, tidak ada yang terlihat salah di output rclone. Juga, rclone tampaknya dapat berbicara dengan google drive karena struktur repo dasar telah dibuat dengan baik:

rclone ls gdrive:test
      155 config
      452 keys/452257875003e39aed0b95f7f75ead868dcc2dc0c14577dd24fd144d6895e2ce

Apakah ada orang lain yang dapat mereproduksi ini?

@ fd0 Adakah kesempatan untuk restic beta dengan dukungan rclone, jadi saya bisa melakukan beberapa pengujian?

Komentar lain - tidak terkait langsung dengan restic (tetapi mungkin menarik) dan mungkin dapat menyebabkan masalah/dukungan:

Karena saya menggunakan G Suite untuk bisnis, saya menggunakan akun layanan dengan rclone, dan dalam hal itu sangat penting untuk diingat untuk menggunakan opsi rclones --drive-impersonate jika Anda ingin dapat melihat file yang restic/rclone upload melalui web-UI normal di browser.

Ini dijelaskan secara detail di sini: https://rclone.org/drive/#use -case-google-apps-g-suite-account-and-individual-drive

Tanpa menggunakan --drive-impersonateopsi dengan rclone, semua file tidak terlihat oleh pengguna biasa saya - namun ini mungkin dianggap sebagai peningkatan keamanan karena tidak memungkinkan untuk merusak atau menghapus repo restic melalui cara lain

@mathiasnagler saya akan lihat

@naffit Saya dapat mengunggah build nanti hari ini, tetapi sangat mudah bagi Anda untuk membuat restic sendiri setelah Anda menginstal Go >= 1.8:

git clone https://github.com/restic/restic
cd restic
git checkout rclone-backend
go run build.go

Kemudian Anda memiliki biner restic yang berfungsi di direktori saat ini.

@fd0 Maaf jika saya buta, tapi di mana dokumennya? Saya siap untuk mencoba ini. Mendapat kloning dan segalanya.

Ada dokumentasi di manual di doc/030_preparing_a_new_repo.rst , di bagian tentang rclone:
https://github.com/restic/restic/blob/2d756ce7278cdd598ff08fc696cabded5f1630bf/doc/030_preparing_a_new_repo.rst#other -services-via-rclone

Ini membantu Anda memulai dengan rclone seperti yang dijalankan oleh restic. Anda juga dapat memanggil rclone serve restic dan kemudian menggunakan backend REST restic untuk mengakses server, seperti restic -r rest:http://localhost:8080/foo init

Atau apakah Anda mengharapkan sesuatu yang lain?

Itu sempurna, terima kasih!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat