Yazılım / bellenim otomatik güncelleme stratejisi


9

Ş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:
    1. Ü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.
    2. İ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.
    3. Geçerli git karmasını güncelleme paketindeki bir dosyaya yazar (amaç aşağıda açıklığa kavuşturulacaktır).
    4. 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.
    5. 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/currentyazı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:
    1. Bir do_not_updatedosyanın varlığını kontrol eder ve varsa başka bir işlem yapmaz (geliştirici cihazlar için aşağıya bakın).
    2. Yukarıda belirtilen metin dosyasından mevcut sağlama karmasını okur.
    3. 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.
    4. Güncelleme paketini (eğer alınmışsa) şuraya yükler /opt/example:
      1. Güncellenmiş yazılım bilgilerini adlı bir klasöre ayıklama stage.
      2. 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.
      3. Geçerli yazılım kök klasörünün kopyalanması previous( previousvarsa önce mevcut olanı siler ).
      4. stageKlasörü şuraya kopyalamak latest( latestvarsa önce mevcut olanı siler ).
      5. İşaretçinin currentişaret etmesini sağlamak latest.
      6. Cihazı yeniden başlatma (varsa, yeniden başlatma sırasında ürün yazılımı güncellemeleri uygulanır).

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:

  1. Üzerinde yazılımın kararlı bir önceki sürümüne sahip bir SD görüntüsü var.
  2. Bu görüntüden bir SD kart oluşturulur.
  3. İ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.
  • currentSembolik bağ geliştirme dizinine işaret ediyor.
  • do_not_updateOtomatik 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:

  1. Kod dağıtım için hazır olduğunda serbest bırakma dalına itin.
  2. Sunucudaki "güncellemeyi dağıt" düğmesine basın.
  3. 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 HEADgeç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 HEADgerç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.


2
Cihazlarınız Linux tabanlı olduğundan, orada bulunan Linux paket yöneticilerinden birini (apt, yum, rpm, vb.) Kullanmanızı öneririz. İlk adım olarak, Linux taban kurulumunuzun zaten bir tane ile gelip gelmediğini kontrol edin.
Bart van Ingen Schenau

Sistemin boyutları hakkında fikir verebilir misiniz? MB veya GB hakkında mı konuşuyoruz?
lbenini

MB; gziplendiğinde güncelleme paketleri genellikle 1-2 MB'dir.
Jason C

Yanıtlar:


1

Kullanımda olan Linux dağıtımı, önyükleyici ve mimari (x86, ARM, MIPS) hakkında daha fazla bilgi verebilir misiniz?

Her iki şekilde de tahmin etmeye çalışacağım ve umarım doğru yöne yönlendireceğim.

Bu, U-Boot ile Yocto tabanlı bir dağıtımsa, mender.io veya swupdate'a göz atmanızı öneririm . Bu projeler kriterlere tam olarak uyuyor gibi görünüyor. Birincil hedefleri atomik güncellemeler sağlamaktır.

En büyük sorunlardan biri: Cihazda çalışan ayrı bir güncelleyici arka plan programı yoktur. Wifi internet erişimi ve bazı son dakika hackery gelmesini bekleyen komplikasyonlar nedeniyle, onu kontrol ve güncellemek ana cihaz kontrol yazılımı kendisi. 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.

Mender, Go'da yazılmış ve bu yükü omuzlarınızdan kaldıracak bir daemon (ve bir grup sistemd komut dosyası) gibi bir dizi araç sağlar. Bu projenin Yocto ile kullanımı oldukça kolaydır (özel durumunuza ve bölüm düzeninize uyarlanması kolay olması gereken birçok cihaz için bir meta katman sağlarlar. Popüler SOC'ler için de hazır çözümlere sahiptirler) . Eğer Yocto kullanmayan durumda bunun içine bakabilirsiniz yazı olmayan Yocto tabanlı dağıtımlar ile kullanmak için yapmaları gereken adımları tam olarak ne açıklar.

swupdate de harika ama DENX'ten (U-Boot'un arkasındaki bir organizasyon) bir adamdan tek kişilik bir çaba gibi görünüyor. Aynı zamanda oldukça olgun görünüyor.

Ayrıca Ubuntu Snappy ile herhangi bir deneyimim yok ve bu konuda yetkin bir şekilde yorum yapamam (belki birisi içeri girecek). Fikir, uygulamaları bağımsız "enstantane" olarak göndermek. Anladığım kadarıyla bu, sistem çapında olmasa da, sorununuza neredeyse bir çözüm değil.

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, sadece kabul edilen mevcut stratejilerin ne olduğunu bilmiyorum.

Aslında bugünkü eğilim, Docker'ı (gömülü sistemlerde bile) ve arkadaşlarını APT / YUM üzerinden kullanmak gibi görünüyor. İkincisi tutarlılığı sağlamayı zorlaştırabilir.


Bu cevabı nasıl fark etmediğimden emin değilim. Yakında istenen bilgileri vereceğim, bu proje geçici olarak ertelendi ve dün yeniden başladı, bu yüzden atlara geri dönüyorum ve bu özel konu şimdi 1 numaralı öncelik.
Jason C
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.