PyVFS

Материал из ALT Linux Wiki

Пакет python-module-pyvfs позволяет иметь представление объектов питона в виде директорий и файлов на виртуальной ФС в целях мониторинга, отладки и т.п.

Быстрый старт

Допустим, вы имеете скрипт my_script.py и хотите понять, что происходит внутри него с объектами класса MyClass. Для этого нужно следующее:


from pyvfs.objectfs import export

@export
class MyClass(object):
    pass

После этого достаточно запустить скрипт. Пока он будет работать, объекты класса MyClass будут доступны на виртуальной файловой системе.

Как выбрать ФС и как её подключить

Для простоты интеграции с существующими сервисами (разрабатывается она для отладки большого сурового демона на питоне) библиотека ориентируется на переменные окружения.

  • PYVFS_PROTO — может быть 9p (по умолчанию) или fuse.
  • PYVFS_PORT — TCP-порт (только для 9p, по умолчанию 10001)
  • PYVFS_ADDRESS — IPv4-адрес, на котором слушать запросы (только для 9p, по умолчанию 127.0.0.1)
  • PYVFS_MOUNTPOINT — директория, куда монтировать ФС (только для fuse, по умолчанию ./mnt)
  • PYVFS_DEBUG — включать ли отладочный вывод сервера ФС на stderr (по умолчанию False)
  • PYVFS_LOG — добавлять ли файл /log и корневой обработчик журналирования (по умолчанию False)

Если протокол выбран 9p, в системе необходимо иметь python-module-py9p. ФС будет экспортирована по умолчанию по адресу 127.0.0.1:10001, подключить её можно с помощью команды

# mount -t 9p -o ro,port=10001 127.0.0.1 /mnt

Если протокол выбран fuse, файловая система автоматически будет уже смонтирована в директорию, указанную в переменной окружения PYVFS_MOUNTPOINT. Для работы протокола fuse нужно иметь в системе python-module-fuse. По окончанию работы не забудьте отмонтировать ФС (пока что библиотека этого автоматически не делает).

Подробности

Файловая система стартует автоматически при импорте библиотеки pyvfs.objectfs. Для того, чтобы изменить это поведение, нужно использовать переменную окружения OBJECTFS_AUTOSTART=False. Например, так собирается документация проекта: sphinx автоматически импортирует все модули, и чтобы не запускать при этом каждый раз сервер ФС, его автостарт выключен в Makefile.

Также, можно управлять поведением объектов при экспорте на файловую систему. Для этого нужно использовать параметры декоратора:

  • blacklist — список имён, запрещённых к экспорту (по умолчанию пуст)
  • weakref — использовать ли слабые ссылки (по умолчанию True)
  • basedir — директория, куда экспортировать объект (по умолчанию корень); если такой директории нет, она будет создана
  • functions — экспортировать ли функции (при экспорте объекта, по умолчанию False; при экспорте отдельной функции True)
  • cycle_detect — форсировать режим работы распознавания циклических ссылок:
 * none — не распознавать циклические ссылки; если объект или один из его атрибутов содержит ссылку на него же, то будет создана новая поддиректория и так до бесконечности
 * symlink — создавать символические ссылки ну уже созданные inode для этого объекта (так по умолчанию)
 * drop — пропускать атрибуты, ссылающиеся на объекты, файлы которых уже созданы; если необходимо использовать ФС для поиска через рекурсивный grep, то нужно использовать эту опцию

Например:

@export(
    blacklist=["/log", "/thread/class"],  # корнем **здесь** считается директория объекта
    weakref=False,                        # использовать обычную ссылку вместо weakref, объект не будет собран GC никогда
    basedir="/my/cool/objects/")          # создать директорию /my/cool/objects и помещать объекты туда
class MyClass(object):
    

Плюсы

  • Может использоваться для мониторинга структур без использования отладчиков, без установки брейкпойнтов и так далее. Библиотека не служит и не может служить заменой отладчикам, однако часто нужно всего лишь получить содержимое внутренних структур в рантайме.
  • Простота интеграции: всё, что надо, это добавить в любой код две строчки, одну на импорт, вторую для декорирования нужного класса. Если необходимо интегрировать с сервисом, то переменные окружения можно экспортировать в init-скрипте или где там теперь это модно делать, либо использовать значения по умолчанию.
  • В отличие от разных RPC API, позволяет работать простыми старыми средствами шелла.

Минусы

  • Некоторые заморочные случаи питонических структур, криво отображённые на файловую структуру, могут обрушить модуль VFS. А если ФС примонтирована, скажем, через системный mount, то дело может дойти до оопса. На рабочие сервера имеет смысл ставить только если до конца понимаете, что может случиться.
  • Пока что работает только на read-only. Но read-write режим запланирован на ближайшее будущее. В первом приближении он позволит менять значения имеющихся атрибутов (да хоть из shell-скриптов), во втором — создавать объекты.
  • Библиотека на довольно ранней стадии развития, это тоже вряд ли можно занести в плюсы.

Сделай сам

Модуль pyvfs.objectfs построен на базе pyvfs.vfs / pyvfs.utils. Вы можете создавать свои собственные VFS точно так же. Например, вот создание простейшей пустой read-write файловой системы:

from pyvfs.vfs import Storage
from pyvfs.utils import Server

srv = Server(Storage())
# запустить сервер в синхронном режиме;
# для запуска в фоне используйте start()
srv.run()

Функционал

Поддерживаемый функционал:

  • экспорт объектов питона как файловых деревьев
  • экспорт функций, как методов объекта, так и обычных
  • возможность вызова функций через запись в файл
  • доступ на чтение/запись к файлам, представляющим атрибуты объекта
  • распознавание циклических ссылок (self.attr ⇒ self) с возможностью либо обрубания их, либо создания симлинка на ФС
  • монтирование получаемой ФС либо как fuse, либо через протокол 9p, через TCP/IP или UNIX-сокет
  • смешанная ФС, где часть файлов может быть обычными файлами, а часть — представлять собой живые объекты питона

Про вызовы функций

Для каждой экспортированной функции создаётся директория, в которой несколько файлов. Запись параметров в файл call вызывает функцию с такими параметрами. Ответ будет записан в этот же файл. Чтение файла context создаёт ещё один файл call-{uuid}, чтобы была возможность параллельного доступа к вызову. Изначально файл call содержит сигнатуру функции в виде ini-файла.

Про чтение/запись

Пока что поддерживается чтение/запись только литералов. Возможно, потом будет поддерживаться и pickle'ing, как метод импорта/экспорта. Пока не думал.

Смотри также

Более подробно с переменными окружения и примерами использования можно ознакомиться здесь: http://peet.spb.ru/pyvfs/

Ещё более подробно можно посмотреть в коде на гитхабе https://github.com/svinota/pyvfs или на git.alt.