Şimdi "müşteri demoları için özensiz kafeinle çalışan prototipler" aşamasının sonuna yaklaşan ve "geleceği düşün" aşamasına geçiş yapan orta ölçekli bir projem var. Proje, yazılım ve bellenim içeren Linux tabanlı cihazlardan ve merkezi bir yönetim web sunucusundan oluşur. Şu anda 10 prototip var, üretimin düşük 1000'ler seviyesinde olması bekleniyor.
Otomatik güncellemeler konusunda bilgili olmamak ve zamanında kısa olmamakla birlikte, kendi yazılım dağıtım / otomatik güncelleme stratejimi hızlı bir şekilde yuvarlamıştım ve açıkçası berbat. Şu anda aşağıdakilerden oluşmaktadır:
- Bir üretim sürümü şubesine sahip barındırılan bir git repo (GitLab) (web sunucusu kaynağının da aynı repoda ve diğer birkaç şeyde olduğunu unutmayın).
- Web arayüzünde şu güncellemeyi dağıt "düğmesi:
- Üretim sürümü dalından en son sürümü yerel bir repo alanına çeker ve ayrıca geçici bir paket hazırlama hazırlama alanına kopyalar.
- İlişkisiz kaynak dosyalarını (örn. Sunucu kaynağı, bellenim kaynağı, vb.) Ve .git dosyalarını kaldırmak için hazırlama alanında bir dezenfeksiyon komut dosyası (depoda depolanan) çalıştırır.
- Geçerli git karmasını güncelleme paketindeki bir dosyaya yazar (amaç aşağıda açıklığa kavuşturulacaktır).
- Her şey yolunda giderse, onu sıkıştırır ve bir önceki gzip paketinin üzerine aynı adda bir dosya yazarak hizmet vermeye hazır hale getirir, ardından hazırlama alanını siler.
- Sunucuda şu an senkronize olması beklenen mevcut cihaz yazılımının iki kopyası olduğunu unutmayın: En son üretim dalında tam bir yerel git repo ve şimdi bunu temsil ettiği kabul edilen hazır bir sıkıştırılmış paket aynı sürüm.
- Cihazdaki
/opt/example/current
yazılım, yazılımın geçerli sürümünün bir sembolik bağlantısı olan bir dizinde bağımsızdır . - Cihazda, önyükleme sırasında otomatik güncelleme işlevi:
- Bir
do_not_update
dosyanın varlığını kontrol eder ve varsa başka bir işlem yapmaz (geliştirici cihazlar için aşağıya bakın). - Yukarıda belirtilen metin dosyasından mevcut sağlama karmasını okur.
- Sorgu parametresi olarak bu karma ile sunucuya bir HTTP isteği yapar. Sunucu ya 304 (karma geçerli sürüm) ile yanıt verecek ya da gzip güncelleme paketini sunacaktır.
- Güncelleme paketini (eğer alınmışsa) şuraya yükler
/opt/example
:- Güncellenmiş yazılım bilgilerini adlı bir klasöre ayıklama
stage
. - Güncelleme paketinden, bu güncelleştirme için gerekli yerel değişiklikleri yapmak gibi şeyleri yapan bir yükleme sonrası komut dosyası çalıştırma.
- Geçerli yazılım kök klasörünün kopyalanması
previous
(previous
varsa önce mevcut olanı siler ). stage
Klasörü şuraya kopyalamaklatest
(latest
varsa önce mevcut olanı siler ).- İşaretçinin
current
işaret etmesini sağlamaklatest
. - Cihazı yeniden başlatma (varsa, yeniden başlatma sırasında ürün yazılımı güncellemeleri uygulanır).
- Güncellenmiş yazılım bilgilerini adlı bir klasöre ayıklama
- Bir
Yeni inşa edilen cihazlara ilk dağıtım sorunu da var. Cihazlar şu anda SD kart tabanlıdır (burada kapsam dışında kendi sorunlarına sahiptir), bu nedenle bu süreç aşağıdakilerden oluşur:
- Üzerinde yazılımın kararlı bir önceki sürümüne sahip bir SD görüntüsü var.
- Bu görüntüden bir SD kart oluşturulur.
- İlk önyüklemede, çeşitli ilk kez cihaza özgü (seri numarasına dayalı) başlatma yapılır ve daha sonra otomatik güncelleme her zamanki gibi yazılımın en son üretim sürümünü alır ve yükler.
Ayrıca, geliştirme cihazları için desteğe ihtiyacım vardı. Geliştirme cihazları için:
- Cihazda tam bir yerel git repo korunur.
current
Sembolik bağ geliştirme dizinine işaret ediyor.do_not_update
Otomatik güncelleyicinin geliştirme kodunu bir üretim güncellemesiyle patlatmasını önleyen yerel bir dosya vardır.
Şimdi, dağıtım süreci teorik olarak:
- Kod dağıtım için hazır olduğunda serbest bırakma dalına itin.
- Sunucudaki "güncellemeyi dağıt" düğmesine basın.
- Güncelleme şu anda yayında ve cihazlar bir sonraki kontrolünde otomatik olarak güncellenecek.
Ancak, orada tonluk pratikte sorunlar:
- Web sunucusu kodu aygıt koduyla aynı repoda ve sunucunun yürüttüğüm bir yerel git repo'su var. En son web sunucusu kodu, en son cihaz koduyla aynı dalda değildir. Dizin yapısı sorunludur. "Güncelleştirmeyi dağıt" düğmesi en son sürümü üretim dalından aldığında, sunucu kodunun bir alt dizinine çeker. Bu, bir sunucuya sıfırdan konuşlandırdığımda, aygıt üretim dalını içine alarak bu alt dizini el ile "tohumlamak" zorunda olduğum anlamına gelir, çünkü dağıtım yapmaya çalışmazsam muhtemelen benim tarafımda git kullanıcı hatasından aygıt kodunu üst yöneticinin web sunucusu şubesinden çekin . Bu hazırlama alanı sunucunun yerel git repo bir alt dizini yapmak yaparak çözülebilir olduğunu düşünüyorum.
- Web sunucusu şu anda aygıt yazılımının git karmasını sürekli olarak korumamaktadır. Sunucu başlangıcında,
git rev-parse HEAD
geçerli karmayı almak için yerel aygıt yazılımı deposunda bir a yapar . Nedenlerimi kafamın etrafına saramıyorum, burada açıklamayacağım bir ton mantık hatasına da neden oluyor, bazen sunucu vidalarını yeniden başlatmanın, özellikle sunucu yepyeni ve üretim yoksa, şubesi repo henüz çekilmedi. İstenirse bu mantığın kaynağını mutlulukla paylaşırdım, ancak bu yazı uzuyor. - Sanitizasyon komut dosyası (sunucu tarafı) herhangi bir nedenle başarısız olursa, sunucu güncel bir repo ile senkronize değil / eksik bir güncelleme paketiyle bırakılır, böylece
git rev-parse HEAD
gerçekte olanla eşleşmeyen bir karma döndürür ve sorunların sunucu komut satırından elle düzeltilmesi gerekir. Yani sunucu güncelleme paketinin doğru olmadığını bilmiyor, sadece her zaman saf bir inanç olduğunu varsayıyor. Bu, önceki noktalarla birleştiğinde sunucuyu pratikte son derece kırılgan hale getirir. - En büyük sorunlardan biri : Cihazda çalışan ayrı bir güncelleyici arka plan programı yoktur. Wifi internet erişiminin gelmesini bekleyen komplikasyonlar ve bazı son dakika hackery nedeniyle, cihazı kontrol eden ve güncelleyen ana cihaz kontrol yazılımıdır. Bu, bir şekilde kötü test edilmiş bir sürümün üretime geçmesini sağlarsa ve kontrol yazılımı başlatılamazsa, var olan tüm cihazların artık kendini güncelleyemediği için esasen tuğlayır. Bu üretimde mutlak bir kabus olurdu. Şanssız bir zamanda güç kaybederse tek bir cihaz için de aynı şey geçerli.
- Diğer önemli sorun : Artımlı güncellemeler için destek yoktur. Bir cihaz, diyelim ki, bir süre açılmazsa, bir sonraki güncellemesinde bir sürü yayın sürümü atladığında, doğrudan sürüm atlama güncellemesi yapabilmesi gerekir. Bunun güncellenmiş dağıtımının sonucu, verilen herhangi bir güncellemenin, herhangi bir geçmiş sürümün üzerine uygulanabileceğinden emin olmanın bir kabusudur. Ayrıca, git karmaları sürüm numaraları yerine sürümleri tanımlamak için kullanıldığından, artımlı güncellemeleri kolaylaştırmak için sürümlerin sözlüksel karşılaştırması şu anda mümkün değildir.
- Şu anda desteklemediğim yeni bir gereksinim, yönetim sunucusu tarafında yapılandırılması gereken bazı aygıt başına yapılandırma seçeneklerinin (anahtar / değer çiftleri) mevcut olmasıdır. Bir şekilde bu cihaz başına seçenekleri, yazılım güncellemesi ile aynı HTTP isteğinde (belki de HTTP üstbilgileri / çerezlerde kapsülleyebilir) cihaza geri sunmayı umursamıyorum, ancak bu konuda çok endişelenmiyorum. her zaman ayrı bir HTTP isteği yapın.
- Donanımın iki (ve gelecekte daha fazla) versiyonunun mevcut olması nedeniyle hafif bir komplikasyon var. Donanımın mevcut sürümü aslında ilk SD görüntüsünde bir ortam değişkeni olarak saklanır (kendi kendini tanımlayamazlar) ve tüm yazılımlar cihazların tüm sürümleriyle uyumlu olacak şekilde tasarlanmıştır. Bellenim güncellemeleri bu ortam değişkenine göre seçilir ve güncelleme paketi donanımın tüm sürümleri için bellenim içerir. Her ne kadar biraz tıknaz olsa bununla yaşayabilir.
- Şu anda cihaza manuel olarak bir güncelleme yüklemenin bir yolu yoktur (uzun hikaye kısa bu cihazların içinde iki adet internet bağdaştırıcısı vardır, biri internete bağlanmak için ve diğeri kullanıcının cihazı yapılandırmak için kullandığı AP modunda; gelecekte Cihazın yerel web arayüzüne bir "güncelleme yazılımı" fonksiyonu eklemeyi planlıyorum). Bu büyük bir anlaşma değil, ancak güncelleme yükleme yöntemi üzerinde bazı etkileri var.
- Bir sürü diğer hayal kırıklığı ve genel güvensizlik.
Yani ... bu çok uzundu. Ama sorum şu şekilde kayboluyor:
Bunu nasıl düzgün ve güvenli bir şekilde yapabilirim? Mevcut süreçlerimde yapabileceğim küçük ayarlamalar var mı? Kendi boktan güncelleme sistemimi yuvarlamak zorunda kalmamak için kaldırabileceğim zamanla test edilmiş bir strateji / mevcut sistem var mı? Ya da kendiminkini döndürmem gerekirse, bir dağıtım / güncelleme işleminin güvenli ve başarılı olması için doğru olması gereken şeyler nelerdir? Ayrıca karışıma geliştirme cihazlarını da dahil edebilmeliyim.
Umarım soru açıktır. Biraz bulanık olduğunu anlıyorum, ancak bunun daha önce ele alınan ve başarıyla çözülen bir sorun olduğundan% 100 eminim, şu anda kabul edilen stratejilerin ne olduğunu bilmiyorum.