Наушники Pioneer SE-MS7BT-S и aptX, AAC кодеки в Debian

Заставляем работать наушники Pioneer SE-MS7BT-S в Debian на все 100%.

Из коробки эти наушники работать с кодеком aptX не будут, хотя они его знают и с ним работают просто великолепно.

Итак, чтобы добавить в вашу систему поддержку aptX потребуется модуль pulseaudio-modules-bt, который расположен по адресу https://github.com/EHfive/pulseaudio-modules-bt. Инструкция там есть, по ней можно собрать этот модуль, но я всё же приведу последовательность действий, которые сделал я, чтобы модуль собрался и заработал.

Предполагается, что у вас в системе установлен и настроен bluetooth, pulseaudio, а также gcc, cmake и git. Если нет — нужно поставить:

apt install pulseaudio pulseaudio-module-bluetooth pavucontrol bluez-firmware gcc cmake git

Поставим необходимые зависимости:

apt-get install libfdk-aac-dev libavcodec-dev libsbc-dev libdbus-1-dev libpulse-dev libbluetooth-dev

Дальше идём по инструкции модуля:

MODDIR=`pkg-config --variable=modlibexecdir libpulse`
sudo find $MODDIR -regex ".*\(bluez5\|bluetooth\).*\.so" -exec cp {} {}.bak \;
git clone https://github.com/EHfive/pulseaudio-modules-bt.git
cd pulseaudio-modules-bt
git submodule update --init
git -C pa/ checkout master
mkdir build && cd build
cmake -DFORCE_LARGEST_PA_VERSION=ON ..
make

Результат работы команды make в итоге будет примерно такой:

[  5%] Building C object CMakeFiles/bluez5-util.dir/src/modules/bluetooth/backend-native.c.o
[ 11%] Building C object CMakeFiles/bluez5-util.dir/src/modules/bluetooth/a2dp/a2dp_aptx.c.o
[ 17%] Building C object CMakeFiles/bluez5-util.dir/src/modules/bluetooth/a2dp/ffmpeg_libs.c.o
[ 23%] Building C object CMakeFiles/bluez5-util.dir/src/modules/bluetooth/a2dp/a2dp_aac.c.o
[ 29%] Linking C shared library libbluez5-util.so
[ 52%] Built target bluez5-util
Scanning dependencies of target module-bluez5-discover
[ 58%] Building C object CMakeFiles/module-bluez5-discover.dir/src/modules/bluetooth/module-bluez5-discover.c.o
[ 64%] Linking C shared module module-bluez5-discover.so
[ 64%] Built target module-bluez5-discover
Scanning dependencies of target module-bluetooth-policy
[ 70%] Building C object CMakeFiles/module-bluetooth-policy.dir/src/modules/bluetooth/module-bluetooth-policy.c.o
[ 76%] Linking C shared module module-bluetooth-policy.so
[ 76%] Built target module-bluetooth-policy
Scanning dependencies of target module-bluez5-device
[ 82%] Building C object CMakeFiles/module-bluez5-device.dir/src/modules/bluetooth/module-bluez5-device.c.o
[ 88%] Linking C shared module module-bluez5-device.so
[ 88%] Built target module-bluez5-device
Scanning dependencies of target module-bluetooth-discover
[ 94%] Building C object CMakeFiles/module-bluetooth-discover.dir/src/modules/bluetooth/module-bluetooth-discover.c.o
[100%] Linking C shared module module-bluetooth-discover.so
[100%] Built target module-bluetooth-discover

Остаётся установить собранные модули:

make install

Следуя инструкции, нужно отредактировать файл /etc/pulse/default.pa. Найти строку:

load-module module-bluetooth-discover 
И дополнить её вот так:
load-module module-bluetooth-discover a2dp_config="ldac_eqmid=hq ldac_fmt=f32"

Перезапустим pulseaudio:

killall pulseaudio

Конфигурируем bluetooth, находим наушники и коннектимся к ним:

Pioneer SE-MS7BT-S

Когда наушники успешно найдены и подключены, в аудионастройках выбираем профиль aptX:

Pioneer SE-MS7BT-S

И наслаждаемся качественным звучанием. 🙂

Быстрое добавление deploy ключа в Gitlab в несколько проектов

Иногда при работе с репозиториями в Gitlab бывает необходимость добавить один deploy ключ в более, чем один репозиторий. Можно заходить в каждый проект и руками активировать нужный ключ. Для 2-3 проектов это ещё приемлимо, но когда количество проектов больше указанного количества, это действие можно и нужно автоматизировать. 😉

Для этого будем использовать API Gitlab’а.

Сначала нужно зайти в профиль в получение персонального токена по урлу:

https://gitlab.yourdomain.com/profile/personal_access_tokens

и сгенерировать ваш токен. Сгенерированный токен нужно сохранить куда-то в безопасное место, так как больше в Gitlab вы его не увидите.

Далее добавляем deploy ключ в первый проект в разделе Settings -> Repository, блок Deploy keys. После добавления ключа нужно узнать его идентификатор (ID).

Если у вас есть админские права, можно сделать запрос к APi

curl --request POST --header "PRIVATE-TOKEN: <your token>" https://gitlab.yourdomain.com/api/v4/deploy_keys

Результатом запроса будет список ключей с идентификаторами, нужно только найти в выдаче нужный вам ключ.

Если админских прав нет, посмотреть идентификатор ключа можно на всё той же странице Settings -> Repository, в блоке Deploy keys. При наведении на иконку редактирования ключа, в урле будет его идентификатор. В моём случае вот так:

https://gitlab.yourdomain.com/group/project/-/deploy_keys/19/edit

Таким образом мы знаем ID ключа — 19.

Далее отправляем запрос:

curl --request POST --header "PRIVATE-TOKEN: <your token>" https://gitlab.yourdomain.com/api/v4/projects/3/deploy_keys/19/enable

который разрешает использование ключа 19 для деплоя проекта с ID=3.

Вместо идентификатора проекта можно использовать его URL:

curl --request POST --header "PRIVATE-TOKEN: <your token>" https://gitlab.yourdomain.com/api/v4/projects/group_name%2Fproject_name/deploy_keys/19/enable

А дальше вариантов как минимум два. Я для своих целей написал bash скрипт, в котором лежит массив урлов проектов и для каждого элемента массива вызывается curl. Если для вас проще сделать copy-paste команды curl с разными урлами репозиториев — можно и так. Главное, что этот способ намного быстрее, чем включать ключ вручную через веб-интерфейс. 🙂

Установка и настройка Vault в docker

Vault — хранилище для паролей и любых других секретных данных, которые нежелательно хранить где-то в файлах, репозиториях или иных легкодоступных вариантах. Данные хранятся в формате ключ-значение (Key-Value). Доступ к этим данным осуществляются с помощью API.

Приведу вырезку из docker-compose.yml файла, который вы можете использовать, чтобы попробовать это хранилище в действии. Это не dev-режим, где данные хранятся в памяти, а вполне себе production, где данные хранятся постоянно.

vault:
  build: ./docker/vault
  container_name: my_vault
  command: server
    -config=/vault/config/vault-config.json
  cap_add:
    - IPC_LOCK
  env_file:
    - ./.env
  depends_on:
    - prometheus
  ports:
    - ${VAULT_PORT}:8200
  volumes:
    - ./data/vault:/vault/file
    - ./logs/vault:/vault/logs
  networks:
    - ${NETWORK_NAME}

В данном варианте у меня vault работает в связке с Prometheus’ом, куда пишутся метрики.

Файлы логов и хранилище лежат не во внутреннем volume, а в каталоге на хосте.

Переменные ${VAULT_PORT} и ${NETWORK_NAME} задаются в .env файле и выглядят так:

VAULT_PORT=8200
VAULT_ADDR=http://127.0.0.1:8200
NETWORK_NAME=project_web

Dockerfile, который лежит в каталоге ./docker/vault выглядит так:

ROM vault:1.3.1
LABEL Component="vault-server"

COPY vault-config.json /vault/config/vault-config.json
ENTRYPOINT ["vault"]

EXPOSE ${VAULT_PORT}

Содержимое конфига vault-config.json:

{
  "storage": {
    "file": {
      "path": "/vault/file"
    }
  },
  "listener": {
    "tcp":{
      "address": "0.0.0.0:8200",
      "tls_disable": 1
    }
  },
  "telemetry": {
    "prometheus": {
      "prometheus_retention_time": "30s",
      "disable_hostname": true
    }
  },
  "ui": true
}

После запуска docker-compose up -d, хранилище должно заработать. Но пользоваться им ещё нельзя. 🙂

Инициализируем оператора:

docker exec -it my_vault /bin/sh -c "vault operator init"

Команда отработает и выдаст результат:

Unseal Key 1: ключ 1
Unseal Key 2: ключ 2
Unseal Key 3: ключ 3
Unseal Key 4: ключ 4
Unseal Key 5: ключ 5

Initial Root Token: рутовый токен

Значения ключей я вырезал, у вас они будут свои.

Далее выполняем следующие команды, подставляя значения ключей, выданных предыдущей командой:

docker exec -it my_vault /bin/sh -c "vault operator unseal <unseal key 1>"
docker exec -it my_vault /bin/sh -c "vault operator unseal <unseal key 2>"
docker exec -it my_vault /bin/sh -c "vault operator unseal <unseal key 3>"

Логинимся под root’ом, указав вместо <root token> значение рутового токена, выданого командой operator init:

docker exec -it my_vault /bin/sh -c "vault login <root token>"

Активируем KV движок:

docker exec -it my_vault /bin/sh -c "vault secrets enable -version=1 -path=secret kv"

Теперь мы можем писать:

vault kv put secret/foo bar=baz

и читать данные из secret:

vault kv get --format=json secret/foo

Хранилище готово к работе, теперь можно обращаться к нему по http и получать или сохранять секретные данные.

Более подробная документация по API Vault’а находится на сайте проекта — https://www.vaultproject.io/api/overview.

Error: symbol grub_file_filters not found

При очередной перезагрузке десктопа вдруг выскочила такая ошибка:

Error: symbol grub_file_filters not found

Попытка загрузиться вручную с помощью команд insmod, linux и т.д. не привела к успеху — загрузиться не получалось, ошибка оставалась. Я был уже на новом Debian Bullseye, версия grub — grub2/2.04-1. Никакие пляски с бубном не помогали, пока я не решил загрузиться с live cd образа Debian, записанного на флэшку. При загрузке выбрал не установку, а восстановление (Rescue), дошёл до шага, где можно восстановить grub и, собственно, проделал это. После этого десктоп вполне успешно загрузился. Если бы сделал это сразу, не потратил бы пару часов на попытку решить эту проблему, а давно уже работал. 😉

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

Ошибка обновления Google Chrome

Если вы пользуетесь браузером Google Chrome, то после недавних обновлений вы могли увидеть следующую ошибку при работе команды apt-get update:

root@xxx:~# apt-get update
Hit:1 http://linux.teamviewer.com/deb stable InRelease
Ign:2 http://dl.google.com/linux/chrome/deb stable InRelease
Hit:3 http://security.debian.org buster/updates InRelease
Hit:4 http://linux.teamviewer.com/deb preview InRelease
Get:5 http://dl.google.com/linux/chrome/deb stable Release [943 B]
Get:6 http://dl.google.com/linux/chrome/deb stable Release.gpg [819 B]
Hit:7 https://repo.skype.com/deb stable InRelease
Hit:8 https://download.docker.com/linux/debian stretch InRelease
Hit:9 https://download.virtualbox.org/virtualbox/debian stretch InRelease
Hit:10 http://http.us.debian.org/debian buster InRelease
Hit:11 http://http.us.debian.org/debian buster-updates InRelease
Hit:12 https://download.sublimetext.com apt/stable/ InRelease
Reading package lists... Done
E: Repository 'http://dl.google.com/linux/chrome/deb stable Release' changed its 'Origin' value from 'Google, Inc.' to 'Google LLC'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.

Решается данная проблема очень просто:

root@xxx:~# apt update
Ign:1 http://dl.google.com/linux/chrome/deb stable InRelease
Hit:2 http://linux.teamviewer.com/deb stable InRelease
Hit:3 http://security.debian.org buster/updates InRelease
Get:4 http://dl.google.com/linux/chrome/deb stable Release [943 B]
Hit:5 http://linux.teamviewer.com/deb preview InRelease
Hit:6 http://http.us.debian.org/debian buster InRelease
Get:7 http://dl.google.com/linux/chrome/deb stable Release.gpg [819 B]
Hit:8 https://download.docker.com/linux/debian stretch InRelease
Hit:9 https://repo.skype.com/deb stable InRelease
Hit:10 https://download.virtualbox.org/virtualbox/debian stretch InRelease
Hit:11 http://http.us.debian.org/debian buster-updates InRelease
Hit:12 https://download.sublimetext.com apt/stable/ InRelease
E: Repository 'http://dl.google.com/linux/chrome/deb stable Release' changed its 'Origin' value from 'Google, Inc.' to 'Google LLC'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.
Do you want to accept these changes and continue updating from this repository? [y/N] y
Get:13 http://dl.google.com/linux/chrome/deb stable/main amd64 Packages [1,131 B]
Fetched 1,950 B in 9s (221 B/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.

И обновляйтесь дальше без ошибок. 😉