Как перенести директорию, в которой живёт docker, если у вас systemd?

У меня на домашнем сервере Debian живёт на относительно небольшом корневом разделе, а большой раздел предназначен для данных разных сервисов и смонтирован в /data. Таким образом, я хочу, чтобы докер жил не в /var/lib/docker (где ему будет тесно), а в /data/docker/, где хватит места и киту, и всем его контейнерам 🙂

  1. Первым делом – останавливаю докер
$ sudo systemctl stop docker.service
$ sudo systemctl stop docker.socket
  1. далее корректирую параметры его запуска
$ sudo systemctl edit docker.service

В открывшемся текстовом редакторе вбиваю между комментариями следующее:

### Anything between here and the comment below will become the new contents of the file

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --data-root=/data/docker -H fd:// --containerd=/run/containerd/containerd.sock

### Lines below this comment will be discarded
  1. перевожу пожитки (перемещаю /var/lib/docker в /data/docker/)
  2. и, наконец, запускаю…
$ sudo systemctl daemon-reload
$ sudo systemctl start docker

Готовенько! 🙂

Proxmox и здоровый сон

Обещанного три года ждут. Изрядно заебавшись ждать сделал вот что:

[Unit]
Description=PVE save guests
ConditionPathExists=/usr/bin/save-mvs.sh
Wants=pve-guests.service
Wants=pvestatd.service
Wants=pveproxy.service
Wants=spiceproxy.service
Wants=pve-firewall.service
Wants=lxc.service
After=pveproxy.service
After=pvestatd.service
After=spiceproxy.service
After=pve-firewall.service
After=lxc.service
After=pve-ha-crm.service pve-ha-lrm.service
After=pve-guests.service

[Service]
ExecStop=/bin/bash /usr/bin/save-mvs.sh
Type=oneshot
RemainAfterExit=yes
TimeoutSec=infinity

[Install]
WantedBy=multi-user.target pve-guests.service
#/bin/bash

echo "START!" 2>&1 >> /save.log
qm list | grep running | awk '{print $1}' | while read vmid; do qm suspend ${vmid} --todisk; done 2>&1 >> /save.log

Ну и разумеется активация и запуск сервиса:

# systemctl daemon-reload
# systemctl enable save-guests
# systemctl start save-guests

Всё. Теперь все запущенные виртуалки благополучно засыпают при штатном выключении и перезагрузке. А если у них выставлен флаг запуска при загрузке – то ещё и просыпаются!

Как я делаю windows пригодным к использованию

Не смотря на, в целом, весьма прискорбную тенденцию Microsoft делать Windows всё менее и менее удобной, есть ПО, призванное улучшить её юзабилити. Мне известны два программных продукта, одним из которых я пользуюсь ещё со времён XP, другой же стал мне известен недавно.

  1. Sysinternals от Марка Русиновича
  2. Опенсурсный PowerToys

Sysinternals – это весьма обширный пакет самых разных программ, позволяюших, как организовать несколько рабочих столов (Microsoft только в десятку догадалась добавить функциональность, которую в KDE я видел и активно использовал уже лет 15-20) так и просматривать всяческую внутрянку (использование памяти, всё, что запускается вместе с системой, кэши, инструменты для мониторинга сетевых подключений, работы с файловой системой и реестром и многое другое). Инструмент полезен мне по большей части, как разработчику/администратору.

PowerToys – это программа улучшает качество использования Windows, скорее со стороны (продвинутого) пользователя. В нём я использую следующие инструменты: “Always On Top” – позволяющие держать выбранное окно поверх остальных; “File Locksmith” – расширение проводника, позволяющего посмотреть процессы, которые держат открытые файлы в выбранной директории и “Text Extractor” – OCR-плагин для выбранной области экрана. Однако в нём есть и удобный редактор файла hosts и устройство для биндинга “клавиатурных аккордов” на нажатие одной клавиши (например, отсутствующей на некоторых клавиатурах “Sleep”…)

docker jwilder/nginx-proxy и загрузка больших файлов

Связка из jwilder/nginx-proxy и docker.bintray.io/jfrog/artifactory-cpp-ce не хочет заливать в репозиторий conan большие пакеты с ошибкой

413 client error request entity too large for url

Содежимое docker-compose.yml для обратного прокси:

version: "3"

services:
  revproxy:
    container_name: revproxy
    image: jwilder/nginx-proxy:latest
    ports:
      - "80:80/tcp"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /data/docker/revproxy/etc/nginx/certs:/etc/nginx/certs
      - /data/docker/revproxy/etc/nginx/conf.d:/etc/nginx/conf.d
    restart: unless-stopped
    dns:
      - '127.0.0.1'
    network_mode: "host"

Содежимое docker-compose.yml для JFrog:

version: "3"

services:
  jfrog:
    container_name: conan
    image: docker.bintray.io/jfrog/artifactory-cpp-ce:latest
    ports:
      - "8081:8081/tcp"
      - "8082:8082/tcp"
    environment:
      VIRTUAL_HOST: 'conan.my_domain'
      VIRTUAL_PORT: '8082'
    restart: unless-stopped
    dns:
      - '127.0.0.1'
      - '8.8.8.8'
      - '1.1.1.1'

Создаю файл дополнительной конфигурации для nginx /data/docker/revproxy/etc/nginx/conf.d/custom.conf с таким содержимым

client_max_body_size 0;

После пересоздания контейнера с обратным прокси ошибка пропала.

WSL2 и проблемы сетью

Изначальный сетап:
Компьютер с Windows10 pro, связь с интернетом через VPN, включен WSL2, внутри WSL свежеустановленный Debian.

Пробуем обновиться…

root@win10pro:/home/user# apt update
Get:1 http://deb.debian.org/debian bullseye InRelease [116 kB]
Get:2 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Err:1 http://deb.debian.org/debian bullseye InRelease
Connection timed out [IP: 151.101.246.132 80]
Err:2 http://security.debian.org/debian-security bullseye-security InRelease
Connection timed out [IP: 151.101.246.132 80]
Get:3 http://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Get:4 http://ftp.debian.org/debian bullseye-backports InRelease [49.0 kB]
Err:3 http://deb.debian.org/debian bullseye-updates InRelease
Connection timed out [IP: 151.101.246.132 80]
Err:4 http://ftp.debian.org/debian bullseye-backports InRelease
Connection timed out [IP: 151.101.246.132 80]
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
All packages are up to date.
W: Failed to fetch http://deb.debian.org/debian/dists/bullseye/InRelease Connection timed out [IP: 151.101.246.132 80]
W: Failed to fetch http://deb.debian.org/debian/dists/bullseye-updates/InRelease Connection timed out [IP: 151.101.246.132 80]
W: Failed to fetch http://security.debian.org/debian-security/dists/bullseye-security/InRelease Connection timed out [IP: 151.101.246.132 80]
W: Failed to fetch http://ftp.debian.org/debian/dists/bullseye-backports/InRelease Connection timed out [IP: 151.101.246.132 80]
W: Some index files failed to download. They have been ignored, or old ones used instead.
root@win10pro:/home/user#

Пичалька.

Проблема кроется в размерах MTU.

root@win10pro:/home/user# ip link show eth0
4: eth0: mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:15:5d:50:34:71 brd ff:ff:ff:ff:ff:ff
root@win10pro:/home/user#
C:>netsh interface ipv4 show subinterfaces | findstr /e VPN
1400 1 239048269 40639330 VPN
C:>

Ставим в WSL2 MTU такой же, как MTU в VPN

root@win10pro:/home/user# ip link set dev eth0 mtu 1400

Вуаля!

root@win10pro:/home/user# apt update
Hit:1 http://deb.debian.org/debian bullseye InRelease
Get:2 http://security.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Hit:3 http://ftp.debian.org/debian bullseye-backports InRelease
Hit:4 http://deb.debian.org/debian bullseye-updates InRelease
Fetched 48.4 kB in 1s (50.7 kB/s)
Reading package lists… Done
Building dependency tree… Done
Reading state information… Done
All packages are up to date.
root@win10pro:/home/user#

GitLab Admin | One project failed its last repository check

Пришло на почту письмо с таким заголовком от GitLab. Что делать?

  1. Переходим по ссылке “See the affected projects in the GitLab admin panel” из письма (для примера допустим, что она приведёт, сюда: http://git.local/admin/projects?last_repository_check_failed=1)
  2. Переходим в проблемный проект (Пусть это будет project1 в группе group1 http://git.local/admin/projects/group1/project1)
  3. Ищем значение поля “Gitaly relative path”. Пусть оно будет таким @hashed/aa/bb/aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899.git
  4. Идём в консоль сервера (например, по ssh) и проверяем состояние репозитория
    /opt/gitlab/embedded/bin/git -C /var/opt/gitlab/git-data/repositories/@hashed/aa/bb/aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899.git fsck

    Checking object directories: 100% (256/256), done.
    Checking objects: 100% (1239/1239), done.
    Verifying commits in commit graph: 100% (30/30), done.
    error: Could not read 0123456789abcdef01234567890abcdef0123456
    failed to parse commit 0123456789abcdef01234567890abcdef0123456
    from object database for commit-graph
  5. В той же консоли выполняем сборку мусора в репозитории:
    /opt/gitlab/embedded/bin/git -C /var/opt/gitlab/git-data/repositories/@hashed/aa/bb/aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899.git gc

    Enumerating objects: 1242, done.
    Counting objects: 100% (1242/1242), done.
    Compressing objects: 100% (302/302), done.
    Writing objects: 100% (1242/1242), done.
    Selecting bitmap commits: 163, done.
    Building bitmaps: 100% (106/106), done.
    Total 1242 (delta 938), reused 1239 (delta 936), pack-reused 0
  6. Повторно проверяем состояние репозитория
    /opt/gitlab/embedded/bin/git -C /var/opt/gitlab/git-data/repositories/@hashed/aa/bb/aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899.git fsck

    Checking object directories: 100% (256/256), done.
    Checking objects: 100% (1242/1242), done.
    Verifying commits in commit graph: 100% (218/218), done.


    Всё починилось.
  7. На страничке репозитория в GitLab (http://git.local/admin/projects/group1/project1) заставим его перепроверить репозиторий (Кнопка “Trigger repository check”).
  8. Наслаждаемся ушедшей проблемой 🙂

Обновление моего окружения разработчика

Пришло время обновления.

Компилятор TGM-GCC 10.3.0 (x64)

MinGW-w64 заменил на TDM-GCC 10.3.0. Скачал установщик, и установил в песочнице (Windows Sandbox) по пути c:\dev\10.3.0\x64\tdm-gcc. По окончанию установки скопировал папку из песочницы в хостовую систему.

OpenSSL 3.0.3

Так как мне нужен Qt с поддержкой OpenSSL, буду его собирать. Сборкубуду производить в MSys2, поскольку у меня он всё равно есть (если он не нужен, его вместе с компилятором можно установить в песочнице).

Качаю исходники openssl-3.0.3.tar.gz, распаковываю и перехожу в директорию с исходниками (у меня это /d/tmp/build/openssl-3.0.3). Поскольку я хочу использовать TDM-GCC, то ставлю его в пути раньше всего остального.

$ cd /d/tmp/build/openssl-3.0.3
$ export PATH=/c/dev/10.3.0/x64/tdm-gcc/bin/:$PATH

Конфигурирую, собираю и устанавливаю статическую сборку

$ ./Configure no-shared --prefix=/c/dev/10.3.0/x64/openssl-3.0.3/static mingw64
$ mingw32-make -j 16
$ mingw32-make install_sw

Конфигурирую, собираю и устанавливаю динамическую сборку

$ ./Configure shared --prefix=/c/dev/10.3.0/x64/openssl-3.0.3/shared mingw64
$ mingw32-make -j 16
$ mingw32-make install_sw

Qt 5.15.4

Для сборки потребуется python (я использовал 3.9.7, у меня он расположен в C:\dev\tools\python-3.9.7\), если его нет, то придётся поставить.

Качаю исходники qt-everywhere-opensource-src-5.15.4.zip, распаковываю в d:\tmp\build\qt-everywhere-src-5.15.4. Сборку буду производить out-of-source, поэтому создаю рядом пустую директорию для сборки d:\tmp\build\qt-everywhere-src-5.15.4-build.

Начну со статической сборки. Запускаю командную строку, перехожу в директорию сборки, конфигурирую, компилирую и устанавливаю статическую сборку (release-only). Из-за проблем со сборкой отключаю рендеринг через DirectX12 и поддержку WMF, поскольку мне они всё равно не нужны.

d:\> cd d:\tmp\build\qt-everywhere-src-5.15.4-build
d:\tmp\build\qt-everywhere-src-5.15.4-build> ..\qt-everywhere-src-5.15.4\configure -prefix C:\dev\10.3.0\x64\Qt\5.15.4\static OPENSSL_LIBS="-llibssl -llibcrypto -lcrypt32 -lgdi32 -lws2_32" -openssl-linked -I C:\dev\10.3.0\x64\openssl-3.0.3\static\include -L C:\dev\10.3.0\x64\openssl-3.0.3\static\lib64 -opensource -nomake tests -no-compile-examples -confirm-license -release -optimize-size -static -c++std c++17 -static-runtime -silent -feature-relocatable -opengl desktop -no-wmf -no-feature-d3d12
d:\tmp\build\qt-everywhere-src-5.15.4-build> mingw32-make -j16
d:\tmp\build\qt-everywhere-src-5.15.4-build> mingw32-make install

Теперь динамическая сборка. Удаляю всё из директории сборки, конфигурирую, компилирую и устанавливаю динамическую сборку (debug+release). Из-за проблем со сборкой отключаю рендеринг через DirectX12, а вот поддержку WMF не отключаю, потому что и с ней собирается нормально.

d:\tmp\build\qt-everywhere-src-5.15.4-build> set OPENSSL_HOME=C:\dev\10.3.0\x64\openssl-3.0.3
d:\tmp\build\qt-everywhere-src-5.15.4-build> ..\qt-everywhere-src-5.15.4\configure -prefix C:\dev\10.3.0\x64\Qt\5.15.4\shared OPENSSL_LIBS="-llibssl -llibcrypto -lcrypt32 -lgdi32 -lws2_32" -openssl-linked -I C:\dev\10.3.0\x64\openssl-3.0.3\static\include -L C:\dev\10.3.0\x64\openssl-3.0.3\static\lib64 -opensource -nomake tests -no-compile-examples -confirm-license -debug-and-release -optimize-size -c++std c++17 -silent -feature-relocatable -opengl desktop -no-feature-d3d12
d:\tmp\build\qt-everywhere-src-5.15.4-build> mingw32-make -j16
d:\tmp\build\qt-everywhere-src-5.15.4-build> mingw32-make install

QtCreator 7.0.2

Качаю архив с исходниками, распаковываю в d:\tmp\build\qt-creator-opensource-src-7.0.2 и обнаруживаю, что теперь его нельзя собрать через qmake – только CMake или QBS. Выбираю CMake – он мне знаком и его можно скачать уже собранным в виде архива. Качаю CMake-3.23.2 и распаковываю в c:\dev\tools\cmake-3.23.2-windows-x86_64. Python буду использовать тот же, что и при сборке Qt.

Сборку буду производить out-of-source, поэтому создаю директорию для сборки d:\tmp\build\qt-creator-opensource-src-7.0.2-build.

Запускаю командную строку, перехожу в директорию сборки, устанавливаю необходимые пути, конфигурирую (с поддержкой новомодной и расхваливаемой QBS – надо же посмотреть, что это) и пытаюсь собрать.

d:\> cd d:\tmp\build\qt-creator-opensource-src-7.0.2-build
d:\tmp\build\qt-creator-opensource-src-7.0.2-build> set PATH=C:\dev\tools\python-3.9.7;C:\dev\tools\cmake-3.23.2-windows-x86_64\bin;C:\dev\10.3.0\x64\Qt\5.15.4\shared\bin;C:\dev\10.3.0\x64\tdm-gcc\bin;%PATH%
d:\tmp\build\qt-creator-opensource-src-7.0.2-build> cmake -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_QBS=ON ..\qt-creator-opensource-src-7.0.2
d:\tmp\build\qt-creator-opensource-src-7.0.2-build> cmake --build . -j 16

Поскольку у меня сборка ломается с вот таким сообщением об ошибке

In file included from D:\tmp\build\qt-creator-opensource-src-7.0.2\src\shared\qbs\src\shared\qtscript\src\script\bridge\qscriptfunction.cpp:43:
D:/tmp/build/qt-creator-opensource-src-7.0.2-build/src/shared/qbs/src/lib/scriptengine/include/QtScript/5.15.4/QtScript/private/qscriptengine_p.h:1:10: fatal error: ../../../../../../../../../../../../qt-creator-opensource-src-7.0.2/src/shared/qbs/src/shared/qtscript/src/script/api/qscriptengine_p.h: No such file or directory
    1 | #include "../../../../../../../../../../../../qt-creator-opensource-src-7.0.2/src/shared/qbs/src/shared/qtscript/src/script/api/qscriptengine_p.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

начинаю рукосуйствовать. Разбираться с источником проблемы я не хочу, поэтому лечение будет симптоматическим – в директории d:\tmp\build\qt-creator-opensource-src-7.0.2-build\src\shared\qbs\src\lib\scriptengine\include\QtScript\5.15.4\QtScript\private лежат заголовочные файлы, содержимое которых и не позволяет проекту собраться. Во всех этих файлах нужно убрать одно “../”
Например:

БылоСтало
include “../../../../../../../../../../../../qt-creator-opensource-src-7.0.2/src/shared/qbs/src/shared/qtscript/src/script/parser/qscriptastfwd_p.h”include “../../../../../../../../../../../qt-creator-opensource-src-7.0.2/src/shared/qbs/src/shared/qtscript/src/script/parser/qscriptastfwd_p.h”

Теперь можно приступить к сборке и установке

d:\tmp\build\qt-creator-opensource-src-7.0.2-build> cmake --build . -j 16
d:\tmp\build\qt-creator-opensource-src-7.0.2-build> cmake --install . --prefix C:\dev\tools\QtCreator-7.0.2\
d:\tmp\build\qt-creator-opensource-src-7.0.2-build> cmake --install . --prefix C:\dev\tools\QtCreator-7.0.2\ --component Dependencies

Если всё прошло успешно – поздравляю, но у меня на последнем этапе возникла вот такая проблема:

'C:/dev/tools/python-3.9.7/python.exe' 'D:/tmp/build/qt-creator-opensource-src-7.0.2/scripts/deployqt.py' 'C:\dev\tools\QtCreator-7.0.2\/bin/qtcreator' 'C:/dev/10.3.0/x64/Qt/5.15.4/shared/bin/qmake.exe'
Traceback (most recent call last):
  File "D:\tmp\build\qt-creator-opensource-src-7.0.2\scripts\deployqt.py", line 41, in <module>
    import common
ModuleNotFoundError: No module named 'common'

Патчу скрипт qt-creator-opensource-src-7.0.2\scripts\deployqt.py
Было

import argparse
import collections
import os
import locale
import sys
import subprocess
import re
import shutil
from glob import glob

import common

Стало

import argparse
import collections
import os
import locale
import sys
import subprocess
import re
import shutil
from glob import glob

sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import common

Запускаю повторно.

d:\tmp\build\qt-creator-opensource-src-7.0.2-build> cmake --install . --prefix C:\dev\tools\QtCreator-7.0.2\ --component Dependencies
Всё 🙂

Алгоритм выполнения любой задачи в оргструктуре предприятия

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

  1. Если задачу можно делегировать – делегируем.
  2. Иначе: Если задачу можно выполнить самому – выполняем.
  3. Иначе: Эскалируем задачу выше.
Блок-схема алгоритма выполнения задачи

Поскольку управление возможно только в замкнутых циклах, делегирование дополняется контролем, а эскалация мониторингом.

Цикл управления при делегировании
Цикл управления при эскалации

Такие циклы могут растягиваться на несколько уровней вниз через делегирование и вверх через эскалацию. Комбинация эскалации и делегирования может передать выполнение задачи в соседнюю ветку корпоративной иерархии до тех пор, пока задача не окажется там, где она может и должна быть выполнена.

PS: жаль, что некоторые осознают это только после увольнения.

Внезапно сходил на King’s Man: Начало

undefined

Третий фильм оказался не хуже двух предыдущих. После начала титров не надо торопиться покидать зал – в конце есть небольшой, но вполне забавный эпизод.