Быстрое добавление 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.

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

Компиляция и сборка ядра linux 4.17

Теперь для автоматический сборки новых версий ядра Linux потребуются следующие установленные пакеты:

apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison

Скрипт автоматический сборки немного поменялся:

#!/bin/sh

# unpack and prepare
cd /usr/src

# check for new file
kernelfile=`wget -O - 2>&1 https://www.kernel.org | grep "latest_link" -A 2 | grep -o 'https://[^"]*'`
newkernel="`echo $kernelfile | grep -o 'linux-.*\.tar\.xz' | cut -b 7- - | cut -b -5 -`"
currentkernel="`cat /proc/version | grep -o 'Linux version [^ ]*' | cut -b 15- -`"

# check new kernel version
if [ "$newkernel" != "$currentkernel" ];
then
    echo "New kernel found!"
    /usr/bin/wget -c $kernelfile
    archname=`find *.xz`
    tar xxf $archname
    dirsrc=`find -P linux-* -maxdepth 0 -type d | head -n 1`
    rm linux
    ln -s $dirsrc linux

    # compile
    cd /usr/src/linux
    make clean && make mrproper
    cp /boot/config-`uname -r` ./.config
    make menuconfig
    make-kpkg clean
    startdate=`date`
    make deb-pkg
    finishdate=`date`

    rm -rf $dirsrc

    echo "Начало: $startdate"
    echo "Завершение: $finishdate"
else
    echo "No new kernel found"
fi

Блог скорее мёртв, чем жив, но автор пока живее всех живых. 🙂