Хочу рассказать о своей попытке создать простой однострочный клиент Dropbox под Linux, используя только бесплатные компоненты с открытым исходным кодом, в том числе rclone, entr и systemd.

Контекст


Недавно проприетарный клиент Dropbox под Linux отказался от поддержки всех файловых систем Linux, кроме незашифрованной ext4. А мой домашний каталог, «к сожалению», зашифрован.

В начале декабря проприетарный клиент перестал работать. Он вышел из системы и предложил выбрать другую папку синхронизации в «поддерживаемой файловой системе».

Кстати, я запускаю Ubuntu Bionic на двухлетнем Thinkpad t460s.

Зачем мне Dropbox


Я активно использую Org mode: делаю заметки обычным текстом, а Dropbox непрерывно создаёт резервные копии заметок во время набора.

Если вы тоже работаете в области инфраструктуры хранения данных, мой вариант использования очень похож на «асинхронную репликацию single-master», то есть с одним мастером. Все записи проходят через мой Thinkpad, это и есть мастер. Удалённая папка Dropbox — просто реплика только для чтения, которой я иногда «выдаю запросы только для чтения» или использую в качестве резервной копии для создания нового мастера, когда текущий терпит неудачу или украден.

Тем не менее, такая настройка репликации несколько раз спасала мне жизнь. У меня до сих пор перед глазами, как Thinkpad отказался загружаться во время сессии на втором курсе. Поскольку я постоянно реплицировал все заметки в Dropbox, то не потерял никаких данных и смог просмотреть последние заметки на Macbook моей мамы. Спасибо, мам!

Неудачные попытки


Когда клиент Dropbox перестал работать, я сосредоточился на поиске другого аналогичного многофункционального удалённого клиента под Linux. В принципе, я не против перейти и на другой сервис, такой как Google Drive или AWS S3. Некоторые из возможных вариантов — overGrive и insync.

Однако я пришёл к выводу, что эти решения излишне функциональны и не очень подходят для моего случая.

Например, клиенты пытаются подключить удалённую файловую систему к вашему ПК. Они очень стараются абстрагировать удалённые файловые системы, делая их похожими на локальные. Как правило, они реализуют двустороннюю синхронизацию, автоматическое сопоставление удалённых типов файлов с типами файлов Linux и т. д.

Мне не нужен такой уровень абстракции. Требуется что-то простое, позволяющее постоянно создавать резервные копии заметок в облаке, пока я набираю текст. Кроме того, абстракции затрудняют настройку и отладку. Не говоря уже о том, что большинство этих многофункциональных клиентов проприетарные.

rclone


Мне попалась утилита rclone, и я сразу понял: это именно то, что я искал. Простая, но мощная программа. Очень похожа на инструмент rsync, только для облачного хранилища.

Например, rclone заботится об отказоустойчивости (проверка целостности), имеет эффективные алгоритмы синхронизации и так далее, при этом предоставляет простой CRUD-интерфейс для взаимодействия с популярными сервисами облачного хранения, включая Amazon S3, Google Drive и Dropbox.

Следующая команда синхронизирует удалённый каталог org с локальным каталогом /home/lpan/org.

ORG_DIR=/home/lpan/org
REMOTE=dropbox

rclone sync $ORG_DIR $REMOTE:org

entr


Утилита для выполнения команд entr использует API inotify. По сути, она запускает команды при изменении файлов без опроса файловой системы.

Один из распространённых способов использования — пересборка проекта, если изменился какой-то из исходных файлов.

entr берёт список абсолютных путей из stdin, а затем выполняет команду, переданную в качестве аргумента, если изменился любой из наблюдаемых файлов.

WORKDIR=/path/to/myproject
find $WORKDIR | grep "\.cpp$" | entr make

Однострочный скрипт


Теперь у нас есть rclone и entr. Итоговый скрипт получился очень простым. Напомню, что мой вариант использования Dropbox очень простой: требуется лишь постоянно реплицировать локальные файлы Org при их изменении. Поэтому можно использовать entr для мониторинга файлов и rclone для «синхронизации» с удалённым хранилищем.

Итоговый скрипт (/home/lpan/sync_dropbox.sh) выглядит следующим образом:

#!/bin/bash

ORG_DIR=/home/lpan/org
REMOTE=dropbox

find $ORG_DIR | entr -r rclone sync -v $ORG_DIR $REMOTE:org

Запускаем демон


Демон — это просто компьютерная программа, которая работает в фоновом режиме. Сделаем наш скрипт фоновым процессом, чтобы он постоянно синхронизировал с удалённой файловой системой локальные изменения файлов в фоновом режиме.

systemd обеспечивает интерфейс для управления процессами демона.

Я создал Dropbox Service в ~/.config/systemd/user/dropbox.service.

[Unit]
Description=Dropbox Daemon

[Service]
ExecStart=/home/lpan/sync_dropbox.sh
Restart=always

[Install]
WantedBy=default.target

Затем можно управлять демоном с помощью следующих команд:

# reload the service file
systemctl --user daemon-reload

# start the daemon
systemctl --user start dropbox.service

# start the daemon on login
systemctl --user enable dropbox.service

# inspect the status of the daemon
systemctl --user status dropbox.service

Вывод


В этой статье мы обсудили, как применить философию UNIX и использовать набор бесплатных инструментов с открытым исходным кодом для замены проприетарного и устаревшего клиента Dropbox. Мы применили rclone и entr. Я также показал, как сделать этот процесс демоном и управлять им с помощью systemd.

Хочу напомнить, что ключевая идея — простота. Мы хотим простые решения для простых задач. Мой вариант использования Dropbox очень простой. И вот почему однострочный скрипт лучше, чем использование излишне функционального и проприетарного облачного клиента.

Большое спасибо за чтение! Очень надеюсь, что вам понравится этот пост. Если знаете лучший способ сделать то же самое или расширить скрипт для другого варианта использования — дайте знать в комментариях!

Комментарии (26)


  1. bvn13
    26.12.2018 18:11

    а где настраивается авторизация к Dropbox?


    1. xedas
      26.12.2018 18:18

      Видимо, в настройках rclone.


    1. denaspireone
      26.12.2018 18:28

      rclone.org/dropbox

      из cmd

      PS: я так делаю бекапы на google drive


  1. MzMz
    26.12.2018 18:45

    я призадумался зачем DropBox вводить такие ограничения и мне кажется дело в дедупликации которую они активно эксплуатируют и которая позволяет им экономить на хранении — зашифрованные личным ключом файлы всегда уникальны и дедупликации не поддаются, так что возможно это чистая коммерция.


    1. powerman
      26.12.2018 19:24
      +5

      Вообще-то клиент dropbox на подключенном шифрованном разделе видит файлы расшифрованными, так же, как любые другие приложения. Так что дедупликации это мешать не должно. Другое дело, что синхронизация файлов с зашифрованного раздела в не зашифрованный dropbox по факту снимает с них шифрование, что может быть неожиданно и неприемлемо для обычных юзеров.


      1. GamePad64
        26.12.2018 21:12

        Для чего тогда прокатили юзеров с btrfs, и прочими не-ext4 fs?


        1. avost
          26.12.2018 23:20
          -1

          Скорее всего, просто криворукие. Как криворукие мозилловцы прокатили тех, у кого нет пшшшаудио, отрезав поддержку alsa…
          В случае же дропбокса есть минимум два способа остаться на нём малыми силами. Первый — запихать раздел дропбокса в файл — контейнер с екст4 и подмонтировать его. Второй способ — есть патч дропбокса, легко гуглится.


          1. powerman
            27.12.2018 00:15

            Файрфокс вроде через https://github.com/i-rinat/apulse работает нормально и без pulseaudio.


          1. JerleShannara
            27.12.2018 10:14
            -1

            /etc/portage/make.conf
            USE="-systemd -pulseaudio"

            При этом в огнелисе звук есть, ЧЯДНТ?


            1. powerman
              28.12.2018 04:28

              Когда я последний раз (несколько месяцев назад) проверял, то в www-client/firefox — да, звук есть, а вот в www-client/firefox-bin — увы, без apulse его нет. К сожалению, там был довольно слабый комп, 2GB RAM, и собрать firefox из исходников там уже нереально.


          1. alex1t
            27.12.2018 10:40

            А про первый способ можно подробнее?


  1. powerman
    26.12.2018 19:20

    Не совсем уловил конструкцию с find — он же вернёт существующие в этот момент файлы/каталоги, что будет если Вы создадите новый подкаталог с файлами, их entr отследит? Если да, т.е. он умеет рекурсивно добавлять новые цели в мониторинг на лету, то тогда почему нет возможности передать ему один корневой каталог параметром и чтобы он сам добавил на мониторинг всё его содержимое? Если нет, т.е. нужно вручную не забыть перезапустить сервис после создания новых файлов и/или подкаталогов, то это решение так себе получилось.


    1. saboteur_kiev
      26.12.2018 19:33

      Судя по сайту eradman.com/entrproject, entr не умеет рекурсивно.
      Поэтому ему нужно поименно добавлять все файлы/каталоги для мониторинга. Если там такой уже есть, то ничего не произойдет. Таким образом find просто обновляет список файлов и каталогов в entr.


    1. MzMz
      26.12.2018 19:55

      Для этой ситуации `man entr` предлагает следующий пример с модификатором `-d`:

      while sleep 1; do ls src/*.rb | entr -d rake; done

      то есть при добавлении нового файла или поддиректории `entr` выходит с сообщением и вся цепочка запускается заново


      1. powerman
        26.12.2018 20:03

        Волшебно. Т.е. нужен поллинг для того, чтобы работало приложение, которое отслеживает изменения файлов без поллинга.


        1. MzMz
          26.12.2018 20:12

          Похоже выбора нет, поскольку `entr` ничего не знает об исходных правилах, а получает простой список файлов и директорий. Например, добавили файл `main.cpp` в директорию — нужно его мониторить или нет? Наверное можно сделать более сложную утилиту, которая принимает на вход файловые маски, но это уже вроде как не совсем Unix-way.


          1. alexxxst
            26.12.2018 22:10

            incrontab, incrond


    1. iig
      27.12.2018 08:35
      +1

      Да, решение не универсальное. Если создать subdirectory — entr это, скорее всего, заметит. А subdirectory/newfile — уже нет. Понадобится не однострочник на bash, а полноценный демон на python. Строк на 30:)
      Как оно будет работать с набором файлов типа ядра linux, сложно представить :)


  1. selenite
    26.12.2018 22:05
    +1

    rclone умеет работать с другими S3-совместимыми хранилищами из коробки? (с minio тем же)

    > с популярными сервисами облачного хранения, включая Amazon S3, Google Drive и Dropbox.

    Учитывая, что dropbox сам по себе использует S3, как хранилище — не стоит задаться вопросом об исключении ненужного посредника из цепочки?

    А вообще, надо бы накатать LD_PRELOAD библиотеку, вряд ли настолько сложно предотвратить попытки считать нечто несущественное из mtab (и потом, любой интерес облачного сервиса к тому, что, где и как примонтировано — нельзя считать чем-то этичным в принципе).


  1. ihormanchik
    26.12.2018 22:44
    +13

    Только я один ожидал увидеть здесь какую-то лютую магию на С, где прям действительно будет клиент, с авторизацией, файл-хендлингом и остальным реализован? Здесь же по факту клиентом dropbox является rclone, а не скрипт на баше, который его вызывает. Таким же образом можно написать статью о однострочном видеоплерее (где будет в баше вызываться VLC) или куда дальше — однострочном 3D шутере…


    1. bergamot
      27.12.2018 09:19
      -1

      В rclone нет отслеживания изменения файлов, однострочник из статьи его добавляет.


      1. ihormanchik
        27.12.2018 09:26
        +3

        Вы, пожалуйста, еще раз внимательно прочитайте заголовок статьи и скажите как это связано с тем, что клиентом к дропбоксу тот скрипт не является? Плюс ко всему этот скрипт одноразовый, это не скрипт демона (демоны на баше пишутся по-другому) и find там вызывается только 1 раз, до следующего перезапуска скрипта…


    1. xenon
      27.12.2018 21:03

      Ну не совсем так. Здесь, скорее получился «комбайн», ведь rclone не умеет мониторить файлы на изменение. То есть, если продолжать аналогии, то здесь взяли готовую утилиту для оцифровки голоса и готовую утилиту передачи данных (netcat, telnet) и из них сделали «скайп», который может то, что не может каждая отдельная программа.


  1. celebrate
    27.12.2018 07:04
    +1

    Из-за наличия find на входе этот демон нужно рестартовать по крону, иначе он не увидит новые файлы. В целом, решение ничем не отличается от «aws s3 sync» по крону.


  1. vviz
    27.12.2018 10:34
    +1

    В чем смысл использования entr если rclone вызывается с параметром sync? Съэкономить пару сотен килобайт на определении того, что появились изменения между локалью и облаком? На мой взгляд, облачные клиенты как раз и заточены на отсылку изменившихся файлов, а не постоянной пересылки всего каталога.


  1. Arris
    27.12.2018 12:22
    +2

    Нет никакого смысла в использовании Entr. Rclone sync прекрасно все умеет делать сам.

    В комментариях к статье этого Software Engineering student at the University of Waterloo предложили решения лучше.