ActiveScaleинженерная практика

CLI sherpa: базовые команды DSS/S3/IAM

Эксплуатация clisherpadssiams3howto

Коротко. /opt/ampli/bin/sherpa — вендорская инженерная консоль: это IPython (Python 2.7) с уже импортированными библиотеками продукта. Через неё смотрят барометр DSS, политики и неймспейсы, проверяют S3 вендорским путём и работают с IAM. Консоль помечена «для инженеров»: чтение — обычная эксплуатация, запись — только осознанно и по штатному сценарию.


1. Что это такое

sherpa — bash-обёртка, запускающая интерактивную среду Python 2.7 с объектом cli (обёртка над библиотеками продукта). Это штатная альтернатива ручной работе с mongodb, pymongo и внутренними демонами: продукт сам знает, куда и как обращаться.

Запуск:

sudo -i
sherpa

При старте печатается Connecting to marvin... и Successfully connected to marvin. (в stderr). Подключение занимает заметное время — десятки секунд, это нормально.

Два режима:

  1. Интерактивный — обычная сессия IPython, удобна для серии вызовов и чтения структур.
  2. Однострочный — sherpa -c "<код>"; удобен для скриптов и агентов. Важно: в режиме -c имена не попадают в глобальную область, поэтому писать нужно полностью: cli.marvin, cli.dss, cli.ha, cli._connection_factory, cli.s3_connect. И код должен быть одной строкой — многострочный ввод в PTY уходит в продолжение строки и зависает; разделяйте операторы ;.

Консоль требует TTY: удалённый запуск «в один вызов» без псевдотерминала не работает.


2. Пространства имён: что доступно

cli — не один объект, а набор подключений к подсистемам:

Объект Назначение
cli.marvin подключение к модели: окружения, сущности
cli.ha HTTP-клиент Model API: get/post/put по /model/...; возвращает строку JSON
cli.dss подсистема DSS: capacity, namespace, policy, blockstore, storage_daemon, client_daemon, repair_daemon, object, container, superblock, syncstore, permissions, delete_queue, system_info, monitoring
cli._connection_factory фабрика подключений: .create_iamd_connection() — gRPC-клиент IAM
cli.s3_connect(<ключ>) boto2-подключение к S3 с корректным endpoint и секретом из IAM
cli.get_configrule / cli.update_configrule чтение/запись ConfigRule — тех же правил, из которых продукт рендерит конфиги
cli.configure_all_instances(<тип>) переприменение конфигурации приложений
cli.mongo, cli.scalerdb, cli.releng доступ к БД/релизным данным (осторожно: это уже «под капотом»)

Проверить окружение проще всего так:

cli.marvin.environment.list()

Ожидается список имён окружений (например, одно окружение кластера).


3. DSS: ёмкость, политики, неймспейсы

3.1 Здоровье и ёмкость

cli.dss.capacity.read_barometer()                  # ожидается 'ok'
cli.dss.capacity.read_capacity()                   # свободно/занято
cli.dss.capacity.get_namespaces_with_fill_status() # по неймспейсам: status, cap_raw, cap_usable
cli.dss.capacity.max_customer_usable_capacity()
cli.dss.capacity.convert_raw_to_usable(<n>)

Читать это надо вместе: barometer = full при большом free и пустых cap_raw/cap_usable означает не «диски полны», а «учёт ёмкости не заполнен» — тогда S3 отвечает 507 Storage is full при свободном месте. Отдельный разбор — Формула политики DSS и S3 507 при свободных дисках.

3.2 Политики

cli.dss.policy.list_all()   # id -> spread_width, safety, hierarchy_rules, codec_info, full_copy
cli.dss.policy.show('0')    # id строкой!

policy.show требует строковый id: целое число даёт TypeError: coercing to Unicode: need string or buffer, int found.

Политика живёт по формуле продукта: usable = (w − s) / w, и обязано выполняться w + s ≤ N, где N — число блоксторов. Иначе генератор экстентов не может разложить данные, и запись упирается в 507. Готовые ветки под малое число дисков задаются при установке (policy_type в config-ng.ini или флаг -P), а не правкой каталога политик «на глаз».

3.3 Неймспейсы

cli.dss.namespace.list_all()

Возвращает словарь «имя неймспейса → поля» (id, policy_id, small_files, owner_id, permission_settings и др.). Смена политики:

cli.dss.namespace.change_policy('<NS_NAME>', '<POLICY_ID>', port=11060)
cli.dss.namespace.change_small_files_policy_and_threshold('<NS_NAME>', '<POLICY_ID>', 524288, port=11060)

Две ловушки, проверенные живьём:

  • Оба аргумента — строки. Числовой id неймспейса вместо имени даёт ответ демона bucket is not valid: Name shorter than 3 — он ждёт имя.
  • Порт. DSS thrift слушает 11060; дефолт 23510 даёт connection-refused. Порты 11000–11003 — данные клиентского демона, 10000–10003 — AXM, 12100/12101 — storage daemon, 13100/13101 — repair daemon; это не точка входа для cli.dss.*.

Успех вызова — возврат None, а не текстовое «OK».

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


4. S3: проверка без установки клиента

Вендорский способ — cli.s3_connect(<ACCESS_KEY>): консоль сама берёт endpoint и секрет из IAM, поэтому не нужно угадывать адрес и порт.

conn = cli.s3_connect('<ACCESS_KEY>')
b = conn.get_bucket('<BUCKET>', validate=False)      # validate=False обязателен
b.new_key('probe.txt').set_contents_from_string('hello')
print b.get_key('probe.txt').get_contents_as_string()

Ожидается успешный PUT и GET с тем же телом. validate=False нужен потому, что проверка имени бакета у boto2 ходит в DNS и на внутреннем endpoint даёт ложный отказ.

Если PUT/GET проходит, а внешний клиент получает 403, ищите не в DSS, а в подписи и времени: типовая причина — расхождение часов (SigV4 допускает ±15 минут), см. S3 403 из-за часов. Если клиент получает AccessDenied на листинге при валидных ключах — нет resource policy, см. IAM и resource policy.


5. IAM: аккаунты, пользователи, политики

Аккаунты и пользователи живут не в модели, а в службе IAM (gRPC). Поэтому /model/account/ не существует, а GET к IAM без параметров отвечает 400 — служба жива и ждёт корректный запрос.

from google.protobuf.json_format import MessageToDict
iam = cli._connection_factory.create_iamd_connection()
MessageToDict(iam.ListAccounts(marker='', onlyIfQuotaExceeded=False,
                               nameOrEmailRegex='', maxItems=100, allowDisabled=True))

Для ListUsers в proto используется oneof: нужно передать ровно одно из accountId / accountCanonicalId / accountEmail, остальные — пустыми:

MessageToDict(iam.ListUsers(accountEmail='<USER>', maxItems=100, marker='',
                            pathPrefix='', allowDisabled=True, nameOrEmailRegex='',
                            accountCanonicalId=''))

Ошибка вида missing required argument(s): ... oneof arguments: ... — не поломка, а подсказка: в ответе перечислены поля, которые надо заполнить.

Выдача доступа к бакету:

iam.PutResourcePolicy(resourceArn='arn:aws:s3:::<BUCKET>',
                      resourcePolicyDocument=<json>, expectedResourceId='')

Имя поля — именно resourcePolicyDocument; пустой ответ {} означает успех. Обходить это системным ключом нельзя: такой «ремонт» ломает модель прав и не переживает следующую проверку.

Лимит ключей у системного аккаунта — 2. Для пользователя заводится отдельный аккаунт: CreateAccount → CreateUser → CreateAccessKey → PutResourcePolicy. Это штатная последовательность, а не обход.


6. sherpa или ascli

Это разные инструменты, и путать их не надо:

Инструмент Для чего
sherpa инженерная консоль: DSS, модель, IAM, внутренняя диагностика
ascli вендорский CLI для прикладных задач: аккаунты, ключи, NFS/UDA, квоты

Примеры ascli (из проверенной практики): ascli login (сессия живёт только внутри одного вызова оболочки — логин и команду надо склеивать в одну строку), ascli uda volume list, ascli uda nfs-export list, ascli uda nfs-export create ..., ascli s3 account access-key generate, ascli account quota show.


7. Правила безопасной работы

  1. Сначала чтение. list_all, read_barometer, show, MessageToDict(...) — безопасны.
  2. Запись — только по штатному сценарию. policy.add, change_policy, PutResourcePolicy, abandon меняют состояние; перед ними нужен бэкап и понимание, что именно меняется.
  3. Не «лечить» БД напрямую. cli.mongo/cli.scalerdb — крайний случай, не первый.
  4. Не оставлять «мусор». Пробные неймспейсы и политики потом штатно удалить нельзя — они остаются в DSS и мешают читать каталог.
  5. Помнить про Python 2. Нет f-строк; print — оператор; строки и байты — разные типы.
  6. cli.ha.get() бросает исключение на любой не-2xx (например, 404), а не возвращает код.
  7. cli.dss.repair_daemon перекрыт объектом Namespace — start_crawl_all() там даёт AttributeError; использовать cli.dss.storage_daemon.start_crawl_all().

8. Источники

  • Quantum Software Documentation Center (7.3) (2026-11-07)
  • ActiveScale Z200 datasheet — CLI в перечне интерфейсов управления
  • Release Notes 7.3 — ascli account quota show, IAM conditions (7.1)
  • Наша практика (обезличенно): вызовы cli.dss.*, cli.s3_connect, IAM gRPC и порт 11060 проверены на кластере из трёх нод, ActiveScale 7.3.1.2; round-trip PUT/GET подтверждён.
  • Обновлено: 2026-11-07.

Нужен инженер? Разберу вашу ситуацию и скажу, что делать — по шагам, с проверками.

Обсудить задачу