fellow.xsendfile, BLOB-объекты ZODB и разрешения для файлов UNIX

В настоящее время я пытаюсь настроить colle.xsendfile, Apache mod_xsendfile и Plone 4.

Очевидно, процесс Apache не видит файлы blobstrage в файловой системе, потому что они содержат разрешения:

ls -lh var / blobstorage / 0x00 / 0x00 / 0x00 / 0x00 / 0x00 / 0x18 / 0xd5 / 0x19 / 0x038ea09d0eddc611.blob -r -------- 1 plone plone 1006K 28 мая 15:30 var/blobstorage/0x00/0x00/0x00/0x00/0x00/0x18/0xd5/0x19/0x038ea09d0eddc611.blob

Как настроить blobstorage для предоставления дополнительных разрешений, чтобы Apache мог получить доступ к этим файлам?

2 ответа

Решение

Режимы, с помощью которых blobstorage записывает свои каталоги и файлы, жестко запрограммированы в ZODB.blob, В частности, стандарт ZODB.blob.FileSystemHelper Класс по умолчанию создает безопасные каталоги (только для чтения и записи для текущего пользователя).

Вы можете предоставить свою собственную реализацию FileSystemHelper это либо сделало бы это настраиваемым, либо просто установило бы режимы каталогов на 0750, а затем патч ZODB.blob.BlobStorageMixin использовать ваш класс вместо значения по умолчанию:

import os
from ZODB import utils
from ZODB.blob import FilesystemHelper, BlobStorageMixin
from ZODB.blob import log, LAYOUT_MARKER

class GroupReadableFilesystemHelper(FilesystemHelper):
    def create(self):
        if not os.path.exists(self.base_dir):
            os.makedirs(self.base_dir, 0750)
            log("Blob directory '%s' does not exist. "
                "Created new directory." % self.base_dir)
        if not os.path.exists(self.temp_dir):
            os.makedirs(self.temp_dir, 0750)
            log("Blob temporary directory '%s' does not exist. "
                "Created new directory." % self.temp_dir)

        if not os.path.exists(os.path.join(self.base_dir, LAYOUT_MARKER)):
            layout_marker = open(
                os.path.join(self.base_dir, LAYOUT_MARKER), 'wb')
            layout_marker.write(self.layout_name)
        else:
            layout = open(os.path.join(self.base_dir, LAYOUT_MARKER), 'rb'
                          ).read().strip()
            if layout != self.layout_name:
                raise ValueError(
                    "Directory layout `%s` selected for blob directory %s, but "
                    "marker found for layout `%s`" %
                    (self.layout_name, self.base_dir, layout))

    def isSecure(self, path):
        """Ensure that (POSIX) path mode bits are 0750."""
        return (os.stat(path).st_mode & 027) == 0

    def getPathForOID(self, oid, create=False):
        """Given an OID, return the path on the filesystem where
        the blob data relating to that OID is stored.

        If the create flag is given, the path is also created if it didn't
        exist already.

        """
        # OIDs are numbers and sometimes passed around as integers. For our
        # computations we rely on the 64-bit packed string representation.
        if isinstance(oid, int):
            oid = utils.p64(oid)

        path = self.layout.oid_to_path(oid)
        path = os.path.join(self.base_dir, path)

        if create and not os.path.exists(path):
            try:
                os.makedirs(path, 0750)
            except OSError:
                # We might have lost a race.  If so, the directory
                # must exist now
                assert os.path.exists(path)
        return path


def _blob_init_groupread(self, blob_dir, layout='automatic'):
    self.fshelper = GroupReadableFilesystemHelper(blob_dir, layout)
    self.fshelper.create()
    self.fshelper.checkSecure()
    self.dirty_oids = []

BlobStorageMixin._blob_init = _blob_init_groupread

Вполне возможно, вы захотите сделать это запросом функции для ZODB3:-)

При настройке процедуры резервного копирования для установки ZOPE/ZEO я столкнулся с той же проблемой с разрешениями BLOB-объектов.

После попытки применить патч обезьяны, который написал Микко (что не так просто), я придумал "настоящий" патч для решения проблемы.

Патч, предложенный Martijn, не является полным, он все еще не устанавливает правильный режим для файлов BLOB-объектов.

Итак, вот мое решение:

1.) Создать патч, содержащий:

Index: ZODB/blob.py
===================================================================
--- ZODB/blob.py    (Revision 121959)
+++ ZODB/blob.py    (Arbeitskopie)
@@ -337,11 +337,11 @@

     def create(self):
         if not os.path.exists(self.base_dir):
-            os.makedirs(self.base_dir, 0700)
+            os.makedirs(self.base_dir, 0750)
             log("Blob directory '%s' does not exist. "
                 "Created new directory." % self.base_dir)
         if not os.path.exists(self.temp_dir):
-            os.makedirs(self.temp_dir, 0700)
+            os.makedirs(self.temp_dir, 0750)
             log("Blob temporary directory '%s' does not exist. "
                 "Created new directory." % self.temp_dir)

@@ -359,8 +359,8 @@
                     (self.layout_name, self.base_dir, layout))

     def isSecure(self, path):
-        """Ensure that (POSIX) path mode bits are 0700."""
-        return (os.stat(path).st_mode & 077) == 0
+        """Ensure that (POSIX) path mode bits are 0750."""
+        return (os.stat(path).st_mode & 027) == 0

     def checkSecure(self):
         if not self.isSecure(self.base_dir):
@@ -385,7 +385,7 @@

         if create and not os.path.exists(path):
             try:
-                os.makedirs(path, 0700)
+                os.makedirs(path, 0750)
             except OSError:
                 # We might have lost a race.  If so, the directory
                 # must exist now
@@ -891,7 +891,7 @@
             file2.close()
         remove_committed(f1)
     if chmod:
-        os.chmod(f2, stat.S_IREAD)
+        os.chmod(f2, stat.S_IRUSR | stat.S_IRGRP)

 if sys.platform == 'win32':
     # On Windows, you can't remove read-only files, so make the

Вы также можете посмотреть патч здесь -> http://pastebin.com/wNLYyXvw

2.) Сохраните патч под именем blob.patch в корневой директории вашего компоновщика.

3.) Расширьте свою конфигурацию сборки:

parts += 
    patchblob
    postinstall

[patchblob]
recipe = collective.recipe.patch
egg = ZODB3
patches = blob.patch

[postinstall]
recipe = plone.recipe.command
command = 
    chmod -R g+r ${buildout:directory}/var
    find ${buildout:directory}/var -type d | xargs chmod g+x
update-command = ${:command}

Разделы postinstall устанавливают нужные права на чтение групп для уже существующих больших двоичных объектов. Обратите внимание, также разрешение на выполнение должно быть дано папкам BLOB-объектов, чтобы эта группа могла входить в каталоги.

Я тестировал этот патч с ZODB 3.10.2 и 3.10.3.

Как предположил Мартейн, это должно быть настраиваемо и быть частью ZODB напрямую.

Другие вопросы по тегам