elfmz / far2l

Linux port of FAR v2
GNU General Public License v2.0
1.79k stars 173 forks source link

rclone support in netrocks (via FTP) #1816

Closed unxed closed 1 year ago

unxed commented 1 year ago

Users continue to suffer without cloud services support in far2l's netrocks. And suddenly I saw this: https://rclone.org/commands/rclone_serve_ftp/

It turns out that rclone itself can work as FTP server, giving "proxy" access to a remote host.

It would be great to add to netrocks the ability to automatically launch rclone with the necessary parameters, and only then connect via FTP. So that everything is configured in one place — in netrocks itself.

phanex commented 1 year ago

It could be super! I see it in the following way: The user opens netrocks and adds a remote. In the drop-down, he chooses rclone. In the connection address, he enters the existing remote name + optionally a path. ... Magic!

elfmz commented 1 year ago

There is similar option for 'file' protocol. It can be extended to all protocols, is it looks ok?

elfmz commented 1 year ago

May try out on branch nr-improvements. In connection settings - press Extra settings and you may setup arbitrary command to be executed on connection opening

phanex commented 1 year ago

So did I understand right? It will be possible to do following:

  1. I choose ftp.
  2. I have an option to execute command in the protocol settings.
  3. I write my connection data such as remote name and if needed working directory.
  4. In the protocol settings, I am using variables like $HOST and so on. And then everything works.
phanex commented 1 year ago

It would be also great if there were another command in protocol options, like "execute on closing a connection". To stop rclone server afterwards.

elfmz commented 1 year ago

Note that there can be multiple far2l having same connection opened, also even single far2l may have multiple times opened same connection (background copying or browsing same connection on both panels) so connect/disconnect scripts must then have some kind of reference counting.. (that ideally would be good to be resilient to abnormal process termination..)

atolismesh commented 1 year ago

May try out on branch nr-improvements.

Can't compile this branch -

far2l/NetRocks/src/Protocol/ProtocolInitCommand.cpp:47:37: error: ‘time’ was not declared in this scope

  47 |                 time_t time_limit = time(NULL) + std::max(3, protocol_options.GetInt("CommandTimeLimit", 30));
     |                                     ^~~~
elfmz commented 1 year ago

Can't compile this branch -

fixed, try now

atolismesh commented 1 year ago

Now it compiles successfully. Exploring new features Try to integrate with rclone serve sftp remote: --user $USER --pass $PASSWORD &

elfmz commented 1 year ago

i think i will also make 'deinit' command with possibility to distinguish first init / last deinit so it will be possible to properly start/shutdown rclone

atolismesh commented 1 year ago

It'll be great! As I know, rclone serve can be deinited only by kill

atolismesh commented 1 year ago

rclone serve sftp remote: --user $USER --pass $PASS & works great, as expected

atolismesh commented 1 year ago

Stable errors: ╔═══════════════════════════════════════ Operation failed ════════════════════════════════════════╗ ║ Timeout - <5>NOTICE: Loaded 1 authorized keys from "/home/user/.ssh/authorized_keys"◙<5>NOTICE ║ ║ SFTP server listening on 127.0.0.1:2022◙ (110) ║ ╟─────────────────────────────────────────────────────────────────────────────────────────────────╢ ║ { Ok } ║ ╚═════════════════════════════════════════════════════════════════════════════════════════════════╝

rclone correctly started sftp server. But netrocks do not try to connect it.

atolismesh commented 1 year ago

May be it is waiting for the rclone process exit?

elfmz commented 1 year ago

Yes, command is expected to (quickly) exit.

atolismesh commented 1 year ago

Run a script, not rclone directly - it was my first idea. But it didn't work. Adding redirects to the script made a trick:

#!/bin/bash
rclone -vv serve sftp gdrive: --user $USER --pass $PASSWORD  >/dev/null 2>&1 &

Now it seems to work as expected.

elfmz commented 1 year ago

Its cuz other end of stdout is being closed just on exit of command, but rclone wants to write it smthng and gets SIGPIPE then..

elfmz commented 1 year ago

Added support for 'deinit' command and added way to do shared init/deinit across different NetRocks connection instances: just do if [ "$SINGULAR" = 1 ]; then ... in your init/deinit scripts

atolismesh commented 1 year ago

Do you have any idea how to 'deinit' right rclone process?

elfmz commented 1 year ago

if you can identify it by command line, then ps aux | awk ' { if (...) { system("kill "$2); }; }'

atolismesh commented 1 year ago

Может лучше сохранять в NetRocks PID запущенного rclone? А сам PID получать как exitcode запущенного 'init' скрипта? Тогда точно не промахнемся с kill. Т.е. в скрипте использовать следующую конструкцию:

#!/bin/bash
rclone  serve sftp gdrive: --user $USER --pass $PASSWORD  >/dev/null 2>&1 &
exit $! 
atolismesh commented 1 year ago

Или так - отлавливать в NetRocks последнюю выведенную в скрипте строку и сохранять ее в $NRPID, а затем в deinit скрипте делать kill $NRPID:

#!/bin/bash
rclone  serve sftp gdrive: --user $USER --pass $PASSWORD  >/dev/null 2>&1 &
echo $!
exit  
unxed commented 1 year ago

Я не понял, можно, наконец, через фар в облака ходить, не выкачивая содержимое целиком?

atolismesh commented 1 year ago

Да, конечно! rclone не выкачивает ничего - только отображает в виде виртуальной файловой системы

unxed commented 1 year ago

А как там какой-нибудь Яндекс.Диск цепануть теперь? Вместо gdrive что-то другое писать?

elfmz commented 1 year ago

Добавил переменную $STORAGE которая указывает на уникальный для данного конекшена путь в который можно положить PID а потом в deinit вычитать его. И удалить, чтож мусор не оставялть. И вмержил все в мастер

unxed commented 1 year ago

А можно, пожалуйста, сделать какой-нибудь Wizard, куда просто логин и пароль от Яндекса/ДругихСервисов говоришь, и он всё настраивает и прописывает? Это ж не сложно должно быть, давайте пожалеем пользователей :)

elfmz commented 1 year ago

Так rclone сам по себе такой визард. Просто консольный image

unxed commented 1 year ago

| Extra environment variables available for command process: | | $HOST $PORT $USER $PASSWORD $DIRECTORY |

— забыта $STORAGE

unxed commented 1 year ago

Так rclone сам по себе такой визард. Просто консольный

ну блин, требовать от пользователя писать скрипт запуска rclone (ещё и несколько) просто чтоб стянуть файл из облака? то есть конечно оч классно что оно появилось для тех, кто в состоянии разобраться)) теперь для всех остальных бы

unxed commented 1 year ago

может, можно сделать штатные шаблоны этих скриптов хотя бы для яндекса и гугла? там же только логин и пароль меняется, я правильно понимаю?

atolismesh commented 1 year ago

Добавил переменную $STORAGE

So, init script for sftp + rclone now looks like:

#!/bin/bash
rclone  serve sftp remote: --user $USER --pass $PASSWORD  >/dev/null 2>&1 &
echo $! >$STORAGE

Simple deinit script looks like:

#!/bin/bash
if [ "$SINGULAR" = 1 ] && [ -r $STORAGE ]; then kill $(< $STORAGE) ; fi  

Right?

elfmz commented 1 year ago

1 need to check for if [ "$SINGULAR" = 1 ] also in init otherwise second subsequent opens of connection will launch another rclone 2 also to unlink $STORAGE in deinit to not leave uneeded files

unxed commented 1 year ago

Why sftp? Is encryption really needed within localhost? Also FTP is built in far2l without any additional dependencies.

atolismesh commented 1 year ago

Why sftp?

  1. It just an example
  2. ubuntu 23.04 repository has rclone 1.6.0-dev package missing ftp serve support
  3. current rclone 1.6.3 from rclone.org has bug in ftp serve server - ftp dir/ls command do not output year in dates
elfmz commented 1 year ago

I'd also add that ftp has poor symlinks support, so if some cloud supports them, this support would be lost in such translation

atolismesh commented 1 year ago

1 need to check for if [ "$SINGULAR" = 1 ] a

init script for sftp + rclone now looks like:

#!/bin/bash
if [ "$SINGULAR" = 1 ] ; then 
    rclone  serve sftp remote: --user "$USER" --pass "$PASSWORD"  >/dev/null 2>&1 &
    echo $! >"$STORAGE"
fi

Simple deinit script looks like:

#!/bin/bash
if [ "$SINGULAR" = 1 ] && [ -r "$STORAGE" ]; then 
    kill $(< "$STORAGE") 
    unlink "$STORAGE"
fi  
elfmz commented 1 year ago

almost ok, but better to take $STORAGE into quotes everywhere as theoretically home directory (where $STORAGE usually located in) may contain spaces Same for $USER $PASSWORD

atolismesh commented 1 year ago

better to take $STORAGE into quotes

Thanks! II remembered this but forgot to fix it Fixed in script above

elfmz commented 1 year ago

BTW does it really needs /bin/bash ? from first look should work with /bin/sh

atolismesh commented 1 year ago

BTW does it really needs /bin/bash

As I remember, sh do not support $(<
So:

Init script for sftp + rclone for sh looks like:

#!/bin/sh
if [ "$SINGULAR" = 1 ] ; then 
    rclone  serve sftp remote: --user "$USER" --pass "$PASSWORD"  >/dev/null 2>&1 &
    echo $! >"$STORAGE"
fi

Simple deinit script for sh looks like:

#!/bin/sh
if [ "$SINGULAR" = 1 ] && [ -r "$STORAGE" ]; then 
    kill $(cat "$STORAGE") 
    unlink "$STORAGE"
fi  
unxed commented 1 year ago

Has it been tested?

unxed commented 1 year ago

Can we close an issue now?

spvkgn commented 1 year ago

Еще можно просто к systemd прикрутить: ~/.config/systemd/user/rclone-serve@.service

[Unit]
Description=rclone: serve the remote %i over SFTP
After=network-online.target
Wants=network-online.target

[Service]
ExecStart= \
  %h/.local/bin/rclone serve sftp %i: \
    --no-auth \
    --config %h/.config/rclone/rclone.conf \
    --log-level INFO \
    --log-file /tmp/rclone-serve-%i.log \
    --umask 022

[Install]
WantedBy=default.target

Cтарт/стоп systemctl --user enable/disable --now rclone-serve@gdrive

Раньше так вручную запускал, вроде проблем не было.

phanex commented 1 year ago

atolismesh, может лучше так:

rclone serve sftp $HOST: --user $USER --pass $PASSWORD >/dev/null 2>&1 & Ну, чтобы делать строку универсальной, а название ремоты писать прямо в параметрах соединения? Или я сильно туплю?

atolismesh commented 1 year ago

@phanex $HOST здесь не подходит, так как это адрес хоста, на котором запускается rclone serve. В большинстве случаев это localhost, и во всех случаях это локальный адрес хоста, никак не связанный с облаком, к которому соединяется rclone.

Я для универсальности использую $EXTRA

rclone serve sftp "$EXTRA": --user "$USER" --pass "$PASSWORD" --addr :"$PORT" >/dev/null 2>&1 &

unxed commented 1 year ago

native implementation to be discussed in #1861

LihacheFF commented 6 months ago

Привет. Как подключить облачное хранилище Terabox (terabox.com) в far2l? Спасибо

unxed commented 6 months ago

Как подключить облачное хранилище Terabox (terabox.com) в far2l?

Надо сначала чтоб в rclone поддержку этого хранилища добавили. Если чаще лайкать и писать что нужна такая поддержка по ссылочкам, вероятность что сделают может стать выше (а может и не стать, но и лайкнуть же не трудно!).

We first need to add support for this storage provider to rclone. If you like more often and write that such support is needed via links, the likelihood that they will do so may become higher (or it may not be, but it’s not difficult to like!).

https://github.com/rclone/rclone/issues/7496

https://forum.rclone.org/t/degoo-terabox-jiocloud-mediafire-support-rclone/35974/2 https://forum.rclone.org/t/can-rclone-add-support-for-terabox/29807/4

unxed commented 3 months ago

Пошаговая инструкция по использованию в NetRocks примерно любого протокола (Amazon S3, etc):

  1. Устанавливаем rclone:
    sudo apt install rclone
  2. Настраиваем подключение, запоминаем его имя (name):
    rclone config
  3. Создаем в домашней папке два скрипта:

nr_rclone_up.sh

#!/bin/sh
if [ "$SINGULAR" = 1 ] ; then 
    rclone serve sftp "$EXTRA": --user "$USER" --pass "$PASSWORD" --addr :"$PORT" >/dev/null 2>&1 &
    sleep 3
    echo $! >"$STORAGE"
fi

nr_rclone_down.sh

#!/bin/sh
if [ "$SINGULAR" = 1 ] && [ -r "$STORAGE" ]; then 
    kill $(cat "$STORAGE") 
    unlink "$STORAGE"
fi
  1. Ставим им право на выполнение:
    chmod +x nr_rclone*
  2. Создаем новое соединение в NetRocks. Протокол: sftp Хост: localhost Порт: 2022 Режим входа: сохраненный пароль (saved password) Имя пользователя: 1111 (любое не пустое, на самом деле) Пароль: 1111 (любой не пустой, на самом деле) Идём в Extra options Command to execute on connect: ~/nr_rclone_up.sh Command to execute on disconnect: ~/nr_rclone_down.sh Extra string passed to command: имя (name) вашего соединения rclone с шага 2

Сохраняем всё. Подключаемся. Пользуемся.

Для каждого дополнительного соединения rclone указываем другой свободный порт: 2022, 2023 и т.д. Это позволяет запускать несколько облачных источников одновременно. И копировать между ними, если открыты в разных панелях.

PS: Для быстрых соединений sleep 3 можно заменить на 2 или 1. Для медленных — увеличить.