У мене зараз середній розмір проекту, який лише наближається до завершення фази "неохайного кофеїну з прототипами для демонстрацій клієнтів" і переходить до фази "думати про майбутнє". Проект складається з пристроїв на базі Linux із програмним та програмним забезпеченням та центрального адміністративного веб-сервера. В даний час існує 10 прототипів, очікується, що виробництво буде близько 1000-х.
Не будучи добре знайомим у мистецтві автоматичних оновлень і не маючи часу, я швидко розгорнув власну стратегію розгортання / автоматичного оновлення програмного забезпечення, і, чесно кажучи, це відстійно. В даний час він складається з наступного:
- Розміщене git repo (GitLab) з відділенням випуску виробництва (зауважте, джерело веб-сервера також є в цьому ж репо, як і деякі інші речі).
- Кнопка "розгортати оновлення" у веб-інтерфейсі, яка:
- Перетягує останню версію з відділення випуску продукції в місцеву репо-зону, а також копіює її у тимчасову зону попередньої постановки пакету.
- Запускає сценарій санітарії (зберігається в репо) в області постановки для видалення непов'язаних вихідних файлів (наприклад, серверного джерела, джерела прошивки тощо) та файлів .git.
- Записує поточний хеш-код git у файл у пакеті оновлень (мета стане зрозумілою нижче).
- Якщо все пішло добре, він gzips і робить його готовим до обслуговування, перезаписавши попередній gzipped пакет із однойменним файлом, а потім видаляє область постановки.
- Зауважте, що зараз на сервері є дві копії поточного програмного забезпечення пристрою, які, як очікується, синхронізуються: Повна локальна репортажна програма git в останній галузі виробництва та готовий пакет gzipped, який тепер повинен вважати, що це та ж версія.
- Програмне забезпечення на пристрої міститься в каталозі з назвою
/opt/example/current
, що є символьним посиланням на поточну версію програмного забезпечення. - Функція автоматичного оновлення на пристрої, яка під час завантаження:
- Перевіряє наявність
do_not_update
файлу і не здійснює подальших дій, якщо він існує (для пристроїв розробника див. Нижче). - Читає поточний хеш комісій з вищевказаного текстового файлу.
- Здійснює HTTP-запит до сервера з таким хешем як параметр запиту. Сервер відповість або 304 (хеш - поточна версія), або буде обслуговувати пакет оновлень gzipped.
- Встановлює пакет оновлень, якщо такий був отриманий
/opt/example
:- Витяг оновленої інформації про програмне забезпечення в папку з назвою
stage
. - Запуск сценарію після встановлення з пакета оновлення, який робить такі дії, як внести необхідні локальні зміни для цього оновлення тощо.
- Скопіюйте поточну кореневу папку програмного забезпечення у
previous
(видаляєтьсяprevious
перша, якщо вона є). - Скопіюйте
stage
папкуlatest
(latest
спочатку видаляється існуюча , якщо така є). - Забезпечення
current
символьного посилання, на яке слід вказуватиlatest
. - Перезавантаження пристрою (оновлення мікропрограмного забезпечення, якщо вони є, застосовуються при перезавантаженні).
- Витяг оновленої інформації про програмне забезпечення в папку з назвою
- Перевіряє наявність
Існує також питання про початкове розгортання на щойно побудованих пристроях. Пристрої в даний час SD карта на основі (має свій власний набір проблем, з сфери тут) , так що цей процес складається з:
- Існує зображення SD, на якому є якась стабільна більш рання версія програмного забезпечення.
- З цього зображення створюється карта SD.
- Під час першої завантаження відбувається ініціалізація різноманітних пристроїв (на основі серійного номера), після чого автоматичний оновлення захоплює та встановлює останню виробничу версію програмного забезпечення, як зазвичай.
Крім того, мені була потрібна підтримка пристроїв розвитку. Для пристроїв розробки:
- На пристрої підтримується повний локальний git repo.
current
Символічна вказує на каталог розвитку.- Існує локальний
do_not_update
файл, який запобігає автоматичному оновленню здути код розробки з оновленням виробництва.
Тепер теоретично процес розгортання повинен був:
- Після того, як код буде готовий до розгортання, пересуньте його до гілки випуску.
- Натисніть кнопку "розгорнути оновлення" на сервері.
- Зараз оновлення наживо, і пристрої автоматично оновлюються під час наступного перевірки.
Однак на практиці є низка проблем:
- Код веб-сервера знаходиться в тому ж репо, що і код пристрою, а на сервері є локальне gpo repo, яке я виконую. Останній код веб-сервера не в тій же гілці, що і останній код пристрою. Структура каталогів є проблематичною. Коли кнопка «розгортати оновлення» витягує останню версію з виробничої галузі, вона перетягує її у підкаталог коду сервера. Це означає, що коли я розгортаюсь на сервері з нуля, мені доведеться вручну "засіяти" цей підкаталог, захопивши в нього гілку виробництва пристрою, тому що, ймовірно, з помилки користувача git з мого боку, якщо я не намагаюся розгортати витягніть код пристрою з відділення веб-сервера батьківського каталогу . Я думаю, що це вирішимо, зробивши область постановки не підкаталогом локального git repo сервера.
- Наразі веб-сервер не підтримує постійний вміст git-хешу програмного забезпечення пристрою. При запуску сервера він робить
git rev-parse HEAD
репо-репост на своєму локальному пристрої для отримання поточного хешу. З причин, що я не можу обернути голову, це також спричиняє багато логічних помилок, які я тут не опишу, достатньо сказати, що іноді перезапуск сервера накручує речі, особливо якщо сервер абсолютно новий і немає виробництва галузеве репо вже витягнули. Я б із задоволенням поділився джерелом такої логіки, якщо це вимагається, але ця публікація стає довго. - Якщо сценарій дезінфекції (серверна сторона) з якоїсь причини виходить з ладу, сервер залишається з оновленим репо, але не з синхронізованим / відсутнім пакетом оновлення, таким чином
git rev-parse HEAD
поверне хеш, який не відповідає тому, що є насправді подається на пристрої, і проблеми тут потрібно виправити вручну в командному рядку сервера. Тобто сервер не знає, що пакет оновлень є невірним, він просто завжди передбачає чисту віру. Це в поєднанні з попередніми пунктами робить сервер надзвичайно крихким на практиці. - Одна з найбільших проблем : На даний момент на пристрої не працює окремий демон оновлення. Через ускладнення, які чекають появи доступу до Інтернету через Інтернет, а також певну хакерську роботу в останні хвилини, саме головне програмне забезпечення для управління пристроєм перевіряє та оновлює пристрій. Це означає, що якщо якимось чином погано тестована версія робить її виробництвом, а програмне забезпечення управління не може запуститися, всі наявні пристрої по суті є цегляними, оскільки він більше не може оновлюватись. Це був би абсолютний кошмар у виробництві. Те ж саме угоди для одного пристрою, якщо він втрачає живлення в невдалий час.
- Інша серйозна проблема є : Там немає підтримки для додаткових оновлень. Якщо пристрій, скажімо, деякий час не вмикається, то наступного разу, коли його оновлення пропускає купу версій версій, воно повинно мати можливість робити оновлення, що пропускається безпосередньо. Наслідком цього є оновлене розгортання - це кошмар, що гарантує, що будь-яке дане оновлення може бути застосовано поверх будь-якої даної попередньої версії. Крім того, оскільки git хеші використовуються для ідентифікації версій, а не номерів версій, лексикографічне порівняння версій для полегшення поступових оновлень наразі неможливе.
- Новою вимогою, яку я зараз не підтримую, є те, що існуватимуть деякі параметри конфігурації на кожному пристрої (пари ключів / значень), які необхідно налаштувати на стороні адміністративного сервера. Я б не заперечував якось обробляти ці параметри на пристрої назад у тому самому HTTP-запиті, що і оновлення програмного забезпечення (можливо, я міг би інкапсулювати його в заголовки / куки HTTP), хоча я не надто переймаюся цим, як можу завжди робити це окремим запитом HTTP.
- Існує незначне ускладнення через те, що існують дві (і більше в майбутньому) версії обладнання. Поточна версія обладнання фактично зберігається як змінна середовище на своєму початковому зображенні SD (вони не можуть самостійно ідентифікувати), і все програмне забезпечення призначене для сумісного з усіма версіями пристроїв. Оновлення прошивки вибираються на основі цієї змінної середовища, і пакет оновлень містить вбудовану програму для всіх версій апаратного забезпечення. Я можу з цим жити, хоча це трохи незграбно.
- Наразі не існує способу завантаження оновлення на пристрій вручну (короткий огляд, ці пристрої мають у собі два адаптери Wi-Fi: один для підключення до Інтернету та один у режимі AP, який користувач використовує для налаштування пристрою; надалі Я маю намір додати функцію "оновлення програмного забезпечення" до локального веб-інтерфейсу пристрою). Це не велика справа, але має певний вплив на метод встановлення оновлення.
- Купа інших розчарувань і загальної небезпеки.
Отже ... це було довго. Але моє запитання зводиться до цього:
Як це зробити правильно та безпечно? Чи є невеликі коригування, які я можу внести до свого існуючого процесу? Чи є перевірена часом стратегія / існуюча система, яку я можу використовувати, щоб мені не довелося прокручувати свою власну банальну систему оновлення ? Або якщо мені доведеться розгорнути своє, які речі повинні бути правдивими, щоб процес розгортання / оновлення був безпечним і успішним? Я також повинен мати можливість включати в суміш пристрої розробки.
Сподіваюся, питання зрозуміле. Я усвідомлюю, що це трохи нечітко, але я на 100% впевнений, що це проблема, яку було вирішено раніше і успішно вирішено, я просто не знаю, що таке прийняті в даний час стратегії.