Перейти к содержимому

Облачное хранилище

Доступ к S3-совместимому объектному хранилищу. Загрузка, скачивание, перечисление и управление файлами с поддержкой presigned URL.

Настройку хранилища см. в Cloud Storage.

local cloudstorage = require("cloudstorage")

Получить ресурс облачного хранилища по ID реестра:

local storage, err = cloudstorage.get("app.infra:files")
if err then
return nil, err
end
storage:upload_object("data/file.txt", "content")
storage:release()
ПараметрТипОписание
idstringID ресурса хранилища

Возвращает: Storage, error

Загрузка содержимого из строки или файла:

local storage = cloudstorage.get("app.infra:files")
-- Загрузка строкового содержимого
local ok, err = storage:upload_object("reports/daily.json", json.encode({
date = "2024-01-15",
total = 1234
}))
-- Загрузка из файла
local fs = require("fs")
local vol = fs.get("app:data")
local file = vol:open("/large-file.bin", "r")
storage:upload_object("backups/large-file.bin", file)
file:close()
storage:release()
ПараметрТипОписание
keystringКлюч/путь объекта
contentstring или ReaderСодержимое как строка или файловый reader
optionstableОпциональные метаданные и опции условной записи

Возвращает: boolean, error

Прикрепите метаданные или защитите запись с помощью таблицы опций:

storage:upload_object("reports/daily.json", body, {
content_type = "application/json",
cache_control = "max-age=3600",
metadata = { owner = "team-a", run_id = "1234" }, -- stored as x-amz-meta-*
only_if_absent = true -- fail if the key already exists
})
ОпцияТипОписание
content_typestringMIME-тип
cache_controlstringЗаголовок Cache-Control
content_dispositionstringЗаголовок Content-Disposition
content_encodingstringЗаголовок Content-Encoding
metadatatableПользовательские метаданные (строковые ключи/значения), хранятся как x-amz-meta-*
headerstableДополнительные заголовки запроса (строковые ключи/значения)
if_matchstringЗаписать, только если текущий ETag объекта совпадает
if_none_matchstringЗаписать, только если ни один объект не совпадает с ETag ("*" означает любой)
only_if_absentbooleanЗаписать, только если ключ не существует (алиас для if_none_match = "*")

Условная запись, не прошедшая своё предусловие, возвращает ошибку precondition_failed.

Скачать объект в файловый writer:

local storage = cloudstorage.get("app.infra:files")
local fs = require("fs")
local vol = fs.get("app:temp")
local file = vol:open("/downloaded.json", "w")
local ok, err = storage:download_object("reports/daily.json", file)
file:close()
-- Скачивание части (первый 1KB)
local partial = vol:open("/partial.bin", "w")
storage:download_object("backups/large-file.bin", partial, {
range = "bytes=0-1023"
})
partial:close()
storage:release()
ПараметрТипОписание
keystringКлюч объекта для скачивания
writerWriterФайловый writer назначения
options.rangestringДиапазон байт (например, “bytes=0-1023”)
options.if_matchstringСкачать, только если ETag объекта совпадает
options.if_none_matchstringСкачать, только если ETag не совпадает

Возвращает: boolean, error

Непройденное предусловие (if_match/if_none_match) возвращает ошибку precondition_failed.

Список объектов с опциональной фильтрацией по префиксу:

local storage = cloudstorage.get("app.infra:files")
local result, err = storage:list_objects({
prefix = "reports/2024/",
max_keys = 100
})
for _, obj in ipairs(result.objects) do
print(obj.key, obj.size, obj.etag)
end
-- Пагинация для больших результатов
local token = nil
repeat
local result = storage:list_objects({
prefix = "logs/",
max_keys = 1000,
continuation_token = token
})
for _, obj in ipairs(result.objects) do
process(obj)
end
token = result.next_continuation_token
until not result.is_truncated
storage:release()
ПараметрТипОписание
options.prefixstringФильтр по префиксу ключа
options.max_keysintegerМаксимум объектов для возврата
options.continuation_tokenstringТокен пагинации
options.include_ownerbooleanВключить owner каждого объекта (id, display_name)
options.include_versionsbooleanПеречислить версии объектов; каждый элемент включает version_id

Возвращает: table, error

Результат содержит objects, is_truncated, next_continuation_token. Каждый объект имеет key, size, etag, storage_class, а также опциональные last_modified, version_id и owner.

В результатах списка content_type всегда пуст — операции списка S3 его не возвращают. Используйте head_object, чтобы прочитать content type и метаданные объекта.

Получить метаданные одного объекта без скачивания его тела:

local storage = cloudstorage.get("app.infra:files")
local meta, err = storage:head_object("reports/daily.json")
if err then
return nil, err
end
print(meta.size, meta.etag, meta.content_type)
for k, v in pairs(meta.metadata) do
print("meta", k, v)
end
storage:release()
ПараметрТипОписание
keystringКлюч объекта

Возвращает: table, error

Поля результата:

ПолеТипОписание
sizeintegerРазмер объекта в байтах
etagstringEntity tag
content_typestringMIME-тип
cache_controlstringЗаголовок Cache-Control
content_dispositionstringЗаголовок Content-Disposition
content_encodingstringЗаголовок Content-Encoding
storage_classstringКласс хранения
version_idstringID версии (присутствует при включённом версионировании)
last_modifiedintegerВремя последнего изменения (Unix-секунды)
metadatatableПользовательские метаданные (x-amz-meta-*)
headerstableСырые заголовки ответа (ключи в нижнем регистре)

Отсутствующий объект возвращает ошибку not_found.

Удалить несколько объектов:

local storage = cloudstorage.get("app.infra:files")
storage:delete_objects({
"temp/file1.txt",
"temp/file2.txt",
"temp/file3.txt"
})
storage:release()
ПараметрТипОписание
keysstring[]Массив ключей объектов для удаления

Возвращает: boolean, error

Создать временный URL для скачивания объекта без учётных данных. Полезно для передачи файлов внешним пользователям или отдачи контента через приложение.

local storage, err = cloudstorage.get("app.infra:files")
if err then
return nil, err
end
local url, err = storage:presigned_get_url("reports/quarterly.pdf", {
expiration = 3600
})
storage:release()
if err then
return nil, err
end
-- Вернуть URL клиенту для прямого скачивания
return {download_url = url}
ПараметрТипОписание
keystringКлюч объекта
options.expirationintegerСекунд до истечения URL (по умолчанию: 3600)

Возвращает: string, error

Создать временный URL для загрузки объекта без учётных данных. Позволяет клиентам загружать файлы напрямую в хранилище без проксирования через сервер.

local storage, err = cloudstorage.get("app.infra:files")
if err then
return nil, err
end
local url, err = storage:presigned_put_url("uploads/user-123/avatar.jpg", {
expiration = 600,
content_type = "image/jpeg",
content_length = 1024 * 1024
})
storage:release()
if err then
return nil, err
end
-- Вернуть URL клиенту для прямой загрузки
return {upload_url = url}
ПараметрТипОписание
keystringКлюч объекта
options.expirationintegerСекунд до истечения URL (по умолчанию: 3600)
options.content_typestringОбязательный content type для загрузки
options.content_lengthintegerМаксимальный размер загрузки в байтах

Возвращает: string, error

МетодВозвращаетОписание
upload_object(key, content, opts?)boolean, errorЗагрузить строку или файл
download_object(key, writer, opts?)boolean, errorСкачать в файловый writer
head_object(key)table, errorПолучить метаданные объекта
list_objects(opts?)table, errorСписок объектов с фильтром по префиксу
delete_objects(keys)boolean, errorУдалить несколько объектов
presigned_get_url(key, opts?)string, errorСгенерировать временный URL для скачивания
presigned_put_url(key, opts?)string, errorСгенерировать временный URL для загрузки
release()booleanОсвободить ресурс хранилища

Операции облачного хранилища подчиняются вычислению политики безопасности.

ДействиеРесурсОписание
cloudstorage.getID хранилищаПолучить ресурс хранилища
УсловиеKindПовторяемо
Пустой ID ресурсаerrors.INVALIDнет
Ресурс не найденerrors.NOT_FOUNDнет
Не ресурс облачного хранилищаerrors.INVALIDнет
Хранилище освобожденоerrors.INVALIDнет
Пустой ключerrors.INVALIDнет
Содержимое nilerrors.INVALIDнет
Writer некорректенerrors.INVALIDнет
Объект не найденerrors.NOT_FOUNDнет
Условное предусловие не выполненоerrors.CONFLICTнет
Доступ запрещёнerrors.PERMISSION_DENIEDнет
Операция не удаласьerrors.INTERNALнет

См. Обработка ошибок для работы с ошибками.