Saya punya proyek menengah sekarang yang hampir mendekati akhir "prototipe bertenaga kafein ceroboh untuk demo klien" dan beralih ke fase "pikirkan tentang masa depan". Proyek ini terdiri dari perangkat berbasis Linux dengan perangkat lunak dan firmware, dan server web administrasi pusat. 10 prototipe saat ini ada, produksi diharapkan berada di urutan 1000-an rendah.
Tidak pandai dalam bidang pembaruan otomatis, dan kekurangan waktu, saya dengan cepat meluncurkan strategi penyebaran / pembaruan perangkat lunak saya sendiri dan, sejujurnya, itu menyebalkan. Saat ini terdiri dari yang berikut:
- Host git repo (GitLab) dengan cabang rilis produksi (perhatikan sumber server web juga dalam repo yang sama, serta beberapa hal lainnya).
- Tombol "deploy update" pada antarmuka web yang:
- Menarik versi terbaru dari cabang rilis produksi ke area repo lokal dan juga menyalinnya ke area pementasan persiapan paket sementara.
- Menjalankan skrip sanitasi (disimpan dalam repo) di area pementasan untuk menghapus file sumber yang tidak terkait (mis. Sumber server, sumber firmware, dll.) Dan file .git.
- Menulis hash git saat ini ke file dalam paket pembaruan (tujuannya akan menjadi jelas di bawah).
- Jika semuanya berjalan dengan baik, maka akan dizip dan membuatnya siap untuk melayani dengan menimpa paket gzip sebelumnya dengan file dengan nama yang sama, kemudian menghapus area pementasan.
- Perhatikan bahwa sekarang ada dua salinan dari perangkat lunak perangkat saat ini di server, yang diharapkan akan disinkronkan: Repo git lokal penuh pada cabang produksi terbaru dan paket gzip siap-untuk-pergi yang sekarang diasumsikan mewakili bahwa versi yang sama.
- Perangkat lunak pada perangkat mandiri dalam sebuah direktori bernama
/opt/example/current
, yang merupakan symlink ke versi perangkat lunak saat ini. - Fungsi pembaruan otomatis pada perangkat yang, saat boot:
- Memeriksa keberadaan
do_not_update
file dan tidak mengambil tindakan lebih lanjut jika ada (untuk perangkat dev, lihat di bawah). - Membaca hash komit saat ini dari file teks yang disebutkan di atas.
- Membuat permintaan HTTP ke server dengan hash itu sebagai parameter kueri. Server akan merespons dengan 304 (hash adalah versi saat ini) atau akan melayani paket pembaruan yang di-gzip.
- Instal paket pembaruan, jika diterima,
/opt/example
oleh:- Mengekstrak info perangkat lunak yang diperbarui, sebuah folder bernama
stage
. - Menjalankan skrip pasca pemasangan dari paket pembaruan yang melakukan hal-hal seperti membuat perubahan lokal yang diperlukan untuk pembaruan itu, dll.
- Menyalin folder root perangkat lunak saat ini ke
previous
(menghapus yang sudah adaprevious
, jika ada). - Menyalin
stage
folder kelatest
(menghapus yang sudah adalatest
, jika ada). - Memastikan
current
symlink mengarah kelatest
. - Mem-boot ulang perangkat (pembaruan firmware, jika ada, diterapkan saat reboot).
- Mengekstrak info perangkat lunak yang diperbarui, sebuah folder bernama
- Memeriksa keberadaan
Ada juga masalah penyebaran awal pada perangkat yang baru dibangun. Perangkat saat ini berbasis kartu SD (memiliki masalah sendiri, di luar cakupan di sini) sehingga proses ini terdiri dari:
- Ada gambar SD yang memiliki beberapa versi perangkat lunak sebelumnya yang stabil.
- Kartu SD dibuat dari gambar ini.
- Pada boot pertama, berbagai inisialisasi spesifik-perangkat (nomor seri) pertama kali terjadi dan kemudian pembaruan otomatis mengambil dan menginstal versi produksi terbaru dari perangkat lunak seperti biasa.
Selain itu, saya membutuhkan dukungan untuk perangkat pengembangan. Untuk perangkat pengembangan:
- Repo git lokal lengkap dipertahankan pada perangkat.
- The
current
symlink menunjuk ke direktori pembangunan. - Ada
do_not_update
file lokal yang mencegah pembaruan otomatis meniup kode pengembangan dengan pembaruan produksi.
Sekarang, proses penyebaran secara teoritis dimaksudkan untuk menjadi:
- Setelah kode siap untuk ditempatkan, dorong ke cabang rilis.
- Tekan tombol "deploy update" di server.
- Pembaruan sekarang hidup dan perangkat akan memperbarui secara otomatis saat berikutnya mereka memeriksa.
Namun, ada banyak masalah dalam praktiknya:
- Kode server web dalam repo yang sama dengan kode perangkat, dan server memiliki repo git lokal yang saya jalankan. Kode server web terbaru tidak pada cabang yang sama dengan kode perangkat terbaru. Struktur direktori bermasalah. Ketika tombol "deploy update" menarik versi terbaru dari cabang produksi, itu menariknya ke subdirektori dari kode server. Ini berarti bahwa ketika saya menyebarkan ke server dari awal, saya harus secara manual "seed" subdirektori ini dengan mengambil cabang produksi perangkat ke dalamnya, karena, mungkin dari kesalahan pengguna git pada bagian saya, jika saya tidak melakukan upaya penyebaran untuk tarik kode perangkat dari cabang server web direktori induk . Saya pikir ini dapat dipecahkan dengan membuat area pementasan tidak menjadi subdirektori dari git repo lokal server.
- Server web saat ini tidak mempertahankan hash git perangkat lunak perangkat secara terus-menerus. Pada startup server, ia melakukan
git rev-parse HEAD
repo dalam perangkat lunak perangkat lokal untuk mengambil hash saat ini. Untuk alasan saya tidak dapat membungkus kepala saya di sekitar ini juga menyebabkan satu ton kesalahan logika yang tidak akan saya jelaskan di sini, cukup untuk mengatakan bahwa kadang-kadang memulai kembali server mengacaukan segalanya, terutama jika server baru dan tidak ada produksi repo cabang telah ditarik. Saya dengan senang hati berbagi sumber untuk logika itu jika diminta, tetapi posting ini semakin panjang. - Jika skrip sanitasi (sisi server) gagal karena beberapa alasan, maka server dibiarkan dengan repo yang up-to-date tetapi paket pembaruan tidak sinkron / hilang, sehingga
git rev-parse HEAD
akan mengembalikan hash yang tidak cocok dengan apa yang sebenarnya sedang disajikan ke perangkat, dan masalah di sini harus diperbaiki secara manual pada baris perintah server. Yaitu server tidak tahu paket pembaruan tidak benar, itu hanya selalu menganggap begitu pada keyakinan murni. Ini dikombinasikan dengan poin-poin sebelumnya membuat server sangat rapuh dalam praktiknya. - Salah satu masalah terbesar adalah : Saat ini tidak ada daemon updater terpisah yang berjalan pada perangkat. Karena komplikasi menunggu akses internet wifi muncul dan beberapa peretasan menit terakhir, itu adalah perangkat lunak kontrol perangkat utama itu sendiri yang memeriksa dan memperbarui perangkat. Ini berarti bahwa jika entah bagaimana versi yang diuji dengan buruk membuatnya menjadi produksi, dan perangkat lunak kontrol tidak dapat memulai, semua perangkat yang ada pada dasarnya rusak, karena tidak dapat lagi memperbarui sendiri. Ini akan menjadi mimpi buruk mutlak dalam produksi. Kesepakatan yang sama untuk satu perangkat jika kehilangan daya pada saat yang sial.
- Masalah utama lainnya adalah : Tidak ada dukungan untuk pembaruan tambahan. Jika suatu perangkat, katakanlah, tidak dinyalakan untuk sementara waktu, maka pada saat pembaruannya melompati banyak versi rilis, ia harus dapat melakukan pembaruan melompat-lompat versi langsung. Konsekuensi dari ini adalah penyebaran yang diperbarui adalah mimpi buruk untuk memastikan bahwa setiap pembaruan yang diberikan dapat diterapkan di atas semua versi masa lalu yang diberikan. Lebih jauh lagi, karena hash git digunakan untuk mengidentifikasi versi daripada nomor versi, perbandingan leksikografis dari versi untuk memfasilitasi pembaruan tambahan saat ini tidak dimungkinkan.
- Persyaratan baru yang saat ini tidak saya dukung adalah bahwa akan ada beberapa opsi konfigurasi per perangkat (pasangan kunci / nilai) yang harus dikonfigurasi pada sisi server administratif. Entah bagaimana saya menyajikan opsi per-perangkat ini kembali ke perangkat dengan permintaan HTTP yang sama dengan pembaruan perangkat lunak (mungkin saya bisa merangkumnya dalam header / cookie HTTP) meskipun saya tidak terlalu khawatir tentang ini, karena saya bisa selalu menjadikannya permintaan HTTP yang terpisah.
- Ada sedikit kerumitan karena kenyataan bahwa ada dua (dan lebih banyak di masa depan) versi perangkat keras. Versi perangkat keras saat ini sebenarnya disimpan sebagai variabel lingkungan pada gambar SD awal (mereka tidak dapat mengidentifikasi diri) dan semua perangkat lunak dirancang agar kompatibel dengan semua versi perangkat. Pembaruan firmware dipilih berdasarkan variabel lingkungan ini dan paket pembaruan berisi firmware untuk semua versi perangkat keras. Saya bisa hidup dengan ini meskipun agak kikuk.
- Saat ini tidak ada cara untuk secara manual mengunggah pembaruan ke perangkat (singkatnya, perangkat ini memiliki dua adapter wifi di dalamnya, satu untuk terhubung ke internet, dan satu dalam mode AP yang digunakan pengguna untuk mengkonfigurasi perangkat; di masa mendatang Saya bermaksud menambahkan fungsi "perbarui perangkat lunak" ke antarmuka web lokal perangkat). Ini bukan masalah besar tetapi memiliki dampak pada metode instalasi pembaruan.
- Sekelompok frustrasi lain dan ketidakamanan umum.
Jadi ... itu panjang. Tapi pertanyaan saya sampai pada ini:
Bagaimana saya melakukan ini dengan benar dan aman? Apakah ada penyesuaian kecil yang dapat saya lakukan untuk proses yang ada? Apakah ada strategi teruji / sistem yang sudah ada yang dapat saya manfaatkan sehingga saya tidak perlu menggulirkan sistem pembaruan jelek saya sendiri ? Atau jika saya harus memutar sendiri, hal-hal apa yang harus benar agar proses penyebaran / pembaruan menjadi aman dan sukses? Saya juga harus bisa menyertakan perangkat pengembangan dalam campuran.
Saya harap pertanyaannya jelas. Saya menyadari ini agak kabur, tetapi saya 100% yakin bahwa ini adalah masalah yang telah ditangani sebelumnya dan berhasil diselesaikan, saya hanya tidak tahu apa strategi yang saat ini diterima.
Jawaban:
Bisakah Anda memberikan informasi lebih lanjut tentang distribusi, bootloader, dan arsitektur Linux (x86, ARM, MIPS?) Yang sedang digunakan?
Saya akan mencoba menebak dengan cara apa pun dan mudah-mudahan mengarahkan Anda ke arah yang benar.
Jika itu adalah distro berbasis Yocto dengan U-Boot, saya akan merekomendasikan melihat di mender.io atau swupdate . Proyek-proyek ini tampaknya sesuai dengan kriteria dengan baik. Tujuan utama mereka adalah memastikan pembaruan atom.
Mender menyediakan banyak alat termasuk daemon (dan banyak skrip systemd) yang ditulis dalam Go yang akan mengangkat beban ini dari bahu Anda. Proyek ini cukup mudah digunakan dengan Yocto (mereka menyediakan meta-layer untuk banyak perangkat yang seharusnya mudah diadaptasi untuk kasus spesifik dan tata letak partisi Anda. Mereka juga memiliki banyak solusi siap pakai untuk SOC populer) . Jika Anda tidak menggunakan Yocto, Anda dapat melihat ke dalam posting ini yang menjelaskan langkah-langkah apa yang perlu Anda lakukan untuk menggunakannya dengan distro non-Yocto.
swupdate juga cukup mengagumkan tetapi sepertinya usaha satu orang dari seorang pria dari DENX (organisasi di belakang U-Boot). Sepertinya cukup dewasa juga.
Ada juga Ubuntu Snappy yang saya tidak punya pengalaman dengan dan saya tidak bisa kompeten mengomentari ini (mungkin seseorang akan melempar masuk). Idenya adalah untuk mengirim Anda aplikasi di "terkunci" mandiri. Dari apa yang saya pahami ini hampir tidak merupakan solusi untuk masalah Anda, meskipun karena itu bukan sistem.
Faktanya sepertinya tren saat ini adalah menggunakan Docker (bahkan di embedded system) dan teman-teman di APT / YUM. Belakangan mungkin membuatnya sangat sulit untuk memastikan konsistensi.
sumber