Pull to refresh

Сколько Надо Строк Кода Для Того Чтобы Подписать Артефакты?

Level of difficultyMedium
Reading time3 min
Views2.2K

Иногда бывает такая ситуация, что надо чтобы прошивка или любой другой артефакт сам сказал в каком состоянии был GIT репозиторий с кодовой базой, когда эту прошивку собирали. Надо как-то добавить в Flash память такие метаданные как "из какой ветки собрали прошивку", "какой была контрольная сумма последнего коммита".

Эта инфа окажется очень полезна, если в prod(акшене) найдут ошибку в коде и надо будет понять, когда прошивка была собрана и из чего.

Можно конечно вручную прописывать эти контрольные суммы в FlashFs, но это очень плохая идея.

Лучше написать *.bat скрипт sign_code.bat, который будет перед компиляцией подписывать прошивку. И добавить скрипт sign_code в скрипт основной сборки артефактов до вызова препроцессора. Вот так как показано на строчке 14.

cls
@echo off
set project_dir=%~dp0
echo project_dir=%project_dir%
cd %project_dir%
set workspace_dir=%project_dir%\..\..\..\
echo workspace_dir=%workspace_dir%

If exist "*.exe" (
    Echo *.exe exist
    del *.exe
)

call %workspace_dir%\tool\sign_code.bat %project_dir%

cd %project_dir%
make all

В папке с проектом надо создать файл auto_version.h. Это шаблон для метаданных про версию репозитория.

#ifndef AUTO_VERSION_H
#define AUTO_VERSION_H

#define GIT_BRANCH  "GIT_BRANCH_AUTO_REPLACE"
#define GIT_LAST_COMMIT_HASH  "GIT_LAST_COMMIT_HASH_AUTO_REPLACE"

#endif /*AUTO_VERSION_H*/

Надо чтобы скрипт sign_code на место строк GIT_BRANCH_AUTO_REPLACE и GIT_LAST_COMMIT_HASH_AUTO_REPLACE вставлял реальные значения, которые скажет утилита git (git branch, git rev-parse --short HEAD ).

После отработки скрипта sign_code получится валидный файл.

#ifndef AUTO_VERSION_H
#define AUTO_VERSION_H

#define GIT_BRANCH  "main"
#define GIT_LAST_COMMIT_HASH  "e53349f7"

#endif /*AUTO_VERSION_H*/

Вот полный код скрипта sign_code.bat

echo off
echo %0
set project_dir=%1
set workspace_dir=%project_dir%\..\..\..\
echo sing_firmware
echo ....

echo workspace_dir=%workspace_dir%
echo project_dir=%project_dir%

COPY /Y  %workspace_dir%auto_version_pattern.h %project_dir%\auto_version.h
set tool_path=%workspace_dir%tool\
echo tool_path=%tool_path% 
FOR /F "tokens=* delims=" %%a IN ('git branch') DO (
 set branch_var=%%a
)

FOR /F "tokens=*delims=" %%a IN ('git rev-parse --short HEAD') DO (
 set last_hash_var=%%a
)

rem echo branch_var=%branch_var% 
set branch_var=%branch_var:~2%
echo branch_var=%branch_var%
echo last_hash_var=%last_hash_var%

python %tool_path%replace_word_in_file.py %project_dir%\auto_version.h GIT_BRANCH_AUTO_REPLACE %branch_var%
python %tool_path%replace_word_in_file.py %project_dir%\auto_version.h GIT_LAST_COMMIT_HASH_AUTO_REPLACE %last_hash_var%

Скрипт sign_code сначала вычисляет абсолютные адреса к утилитам, затирает предыдущие настройки версии репозитория в файле auto_version.h, берет нынешние настройки репозитория из консольных git команд и прописывает эти текущие настройки репозитория в файл auto_version.h

Лог отработки скрипта подписи прошивки sign_code.bat
Лог отработки скрипта подписи прошивки sign_code.bat

Как видно, внутри sign_code.bat фигурирует Python(ский) скрипт replace_word_in_file.py. Дело в том, что авто замена в файле реализуется на Python проще чем на Batch. У скрипта replace_word_in_file три аргумента: файл, нежелательный token, желательный token

#!/usr/bin/python

import sys

print ('Number of arguments:', len(sys.argv), 'arguments.')
print ('Argument List:', str(sys.argv))
arguments = len(sys.argv) - 1
position = 1
while (arguments >= position):
    print ("Parameter %i: %s" % (position, sys.argv[position]))
    position = position + 1

with open(sys.argv[1], 'r') as file :
    filedata = file.read()

# Replace the target string
filedata = filedata.replace(sys.argv[2], sys.argv[3])

# Write the file out again
with open(sys.argv[1], 'w') as file:
    file.write(filedata)    

Когда прошивка подписалась, собралась и загрузилась, то в логе загрузки можно увидеть метаданные про репозиторий: branch, lastCommit. Успех!

Лог загрузки показывает версию репозитория
Лог загрузки показывает версию репозитория

Можно было бы и на С(ях) написать одну монолитную утилиту sign_code.exe, которая бы авто заменяла ключевые слова в соответствии с состоянием репозитория, однако тогда пришлось бы еще писать такую утилиту для каждой операционной системы, плюс писать makefile, набор исходников и поддерживать эту утилиту на плаву, или подвергать версионному контроль артефакт *.exe который может еще и не запуститься на другом PC. Потом появились бы временные файлы сборки (*.o) , которые бы засоряли жесткий диск.

Скрипты удобнее для простых задач.

Вывод

Как видите чтобы подписать прошивку потребовалось 55 строк кода. Подпись прошивок это простой и эффективный DevOps приём. Подпись потом поможет Вам в случае выявленного осечки откатиться назад, собрать прошивку с той кодовой базой, что была и понять причину в условиях максимально приближенных к реальности.

Подписывайте свои прошивки. В этом нет ничего сложного.

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

Контрольные вопросы:

— Зачем собирать артефакты из скриптов, если всегда можно мышкой щелкнуть на треугольник в GUI‑IDE?

Only registered users can participate in poll. Log in, please.
Вы подписываете артефакты состоянием репозитория?
40% да8
60% нет12
20 users voted. 6 users abstained.
Only registered users can participate in poll. Log in, please.
Вы пишете скрипты на Batch?
28.57% да8
71.43% нет20
28 users voted. 1 user abstained.
Only registered users can participate in poll. Log in, please.
Вы используете Python для DevOps(а)?
48% да12
52% нет13
25 users voted. 3 users abstained.
Only registered users can participate in poll. Log in, please.
Вы пользуетесь GIT?
96.67% да29
3.33% нет1
30 users voted. 1 user abstained.
Tags:
Hubs:
Total votes 7: ↑3 and ↓40
Comments9

Articles