2 puan yazan GN⁺ 2024-03-27 | 1 yorum | WhatsApp'ta paylaş
  • Rust ekosisteminde bakımı bırakılmış bir bağımlılık RUSTSEC'e girer girmez, doğrudan sorun yaşamayan bir kütüphane bile kullanıcıları ve CI üzerinden teknik borca dönüşebiliyor
  • insta'nın bağımlı olduğu yaml-rust, ilk yazarının ilgisini kaybetmesinin ardından özellik istekleri ve hataların biriktiği bir durumdaydı
  • RUSTSEC kaydından sonra doğrudan ve dolaylı kullanıcıların CI'ları başarısız olmaya başladı; finans benzetmesiyle bu, bir not düşüşü ve marjin çağrısı anlamına geliyordu
  • Alternatif kütüphaneler ya da fork'lar da net bir çözüm değildi; bağımlılığı değiştirseniz bile bakım yükü ve yeni bağımlılık riskleri sürüyordu
  • Nihai yanıt, yaml-rust kodunu insta içine vendor etmek oldu ve bu da sorunlu teknik borcun AAA notuyla paketlenmiş bir CDO'ya dönüştürüldüğü eleştirisine yol açtı

yaml-rust bağımlılığının teknik borç olarak ortaya çıkma süreci

  • insta, yaml-rust'a bağımlıydı ve yaml-rust, ilk yazarı ilgisini kaybettikten sonra issue'ların durmadan biriktiği bir durumdaydı
    • Bunların bir kısmı özellik isteğiydi, bir kısmı ise gerçek hatalardı
    • insta bakımcısı bu sorunları doğrudan yaşamamıştı ama bakım dışı kalmış bir bağımlılık olması nedeniyle bu bir teknik borçtu
  • yaml-rust'ın RUSTSEC veritabanına eklenmesine dair tartışma gündeme gelince durum değişti
    • RUSTSEC, finans benzetmesinde bir kredi derecelendirme kuruluşu rolü görüyor
    • Kayıttan sonra yaml-rust'ı doğrudan ya da dolaylı kullanan birçok projenin CI'ı birkaç dakika içinde başarısız olmaya başladı
    • Kullanıcılar insta bakımcısına yaml-rust kullanımını sorun etmeye başlayınca, finans benzetmesinde adeta bir marjin çağrısı yaşanmış oldu

Seçenekler ve fiili yanıt

  • Bir alternatife geçmek cazip değildi
    • Alternatiflerden biri yaml-rust'ın bir fork'uydu, yalnızca 1 bakımcısı vardı ve 3 bağımlılık daha ekliyordu
    • Bunlardan biri zaten “B-” notu almış durumdaydı
    • Ekosistemdeki bir diğer seçenek ise eleştirilmeden önce varsayılanı değiştirme kararı almıştı
  • Doğrudan fork'lamak da temel bir çözüm değildi
    • Fork'lanan kütüphane aynı bakım gereksinimlerini beraberinde getiriyor
    • Hata raporlarına yanıt verilmezse sonunda eski yaml-rust gibi eleştiri konusu oluyordu
    • Bu yüzden fork, zaman kazandırabilir ama sorunu ortadan kaldırmaz
  • Fiili yanıt, yaml-rust kodunu insta içine almak yani vendor etmek oldu
    • insta artık insta kodu ile yaml-rust'ın birleştiği bir yapıya dönüştü
    • Bu, sorunlu teknik borcun AAA seviyesine yükseltilmesine benzer bir yapı oluşturuyor
    • Başlıktaki CDO, 2007 finans krizinde kötü ün kazanan teminatlandırılmış borç yükümlülüğünü ifade ediyor
  • Nihai değerlendirme, “kimse kazanmadı” demeye daha yakın
    • Sorunlu kod ortadan kalkmadı, sadece insta'nın içine taşındı
    • Dış bağımlılık gibi görünmesinden doğan baskı azaldı ama bakım yükünün kendisi ortada kaldı

1 yorum

 
GN⁺ 2024-03-27
Hacker News yorumları
  • Açık konuşmak gerekirse, en popüler YAML ayrıştırıcısı olan serde_yaml'ın(https://lib.rs/crates/serde_yaml) yazarı, önceden haber vermeden ya da yerine bir bakımcı atamadan bir anda elini çekmiş ve paketi deprecated ve unmaintained olarak işaretlemiş durumda.
    left-pad ile tamamen aynı değil. Paket hâlâ çalışıyor ve crates.io silmeye de izin vermiyor, ancak bu paket 4.000 başka crate tarafından kullanılıyor.
    Denetim ve otomatik güncelleme araçları, bakımı yapılmayan crate kullanımını sorun olarak işaretlemeye başlayacak.

    • Doğru değil. Orijinal yazı yaml-rust'a(https://github.com/chyh1990/yaml-rust) bağımlı olduğunu söylüyor; artık bakımı yapılmayan proje bu.
      Aynı zamanda insanların kitlesel olarak oraya taşınmasını önlemek için serde_yaml da unmaintained olarak işaretlenmiş.
    • Burada geçerli değil ama bağımlılığı olmayan kütüphaneler bazen gerçekten işlevsel olarak tamamlanmış durumda olabilir ve güvenlik düzeltmeleri dışında neredeyse hiç değiştirilmeleri gerekmeyebilir.
      Denetim araçlarının ve şirket politikalarının, sırf yakın zamanda commit yok diye sürekli “bakımı yapılmıyor” uyarısı vermek yerine bu tür durumları ayırt edecek kadar akıllı olmasını isterdim.
    • O yazar Rust kütüphane ekosisteminde epey üretken biri değil mi? Diğer kütüphanelerinde böyle bir adım atmadı.
      Daha ayrıntılı bilgi olup olmadığını merak ediyorum.
  • Açıklamasız geçen CDO kısaltmasını hemen anlayamadım; yazıda collateralized ifadesi birkaç kez geçtiğine göre teminatlandırılmış borç yükümlülüğü (collateralized debt obligation) olmalı.
    https://en.wikipedia.org/wiki/Collateralized_debt_obligation
    İlk başta chief data officer'ı düşündüm.

    • Buradaki benzetme, CDO'nun başka borçlardan oluşturulan bir finansal ürün olmasıyla ilgili.
      Somut olarak 2008'de, çeşitli konut kredilerinde kısmi sahiplik gibi bir şeydi; sorunlu konut kredileri temerrüde düşünce CDO'lar da beraberinde bozuldu [1].
      Her hâlükârda yazarın düşündüğü şey, borç temelli bir benzetmeden ziyade leftpad ya da zincirleme DNS arızaları gibi sistemik riske daha yakın. 2008'in bu kadar büyük bir kargaşaya dönüşmesinin önemli nedeni de, borçtan ürün yapılmış olması gerçeğinden çok sistemik sorunlardı [2].
      1. İlginç bir bilgi olarak, 2008'den önce konut kredisine dayalı finansal ürünlere talep durmadan büyüdüğü için CDO'lardan yapılmış CDO'lar bile üretmeye başladılar. İşi olmayan birine bile konut kredisi verip bunu AAA kredi notlu bir ürüne paketlerseniz, satması kolay ve kârlı bir ürün olur.
      2. Lehman ve Bear Stearns'ün kaldıraç oranlarının 30-40 kat olması da var. Bu çılgınca bir seviye.
    • Evet. İma edilen şey, kötü teknik borçları itibarlı paketlere, yani AAA paketlere bağlamak için teşvikler yaratırsanız Rust ekosisteminin bir balona doğru gidebileceği ve sonunda çökebileceği.
      Ayrıca düzenleyici rolü üstlenmesi gereken derecelendirme kuruluşlarının zaten ele geçirilmiş olduğu anlamına da geliyor.
    • The Big Short'u izlemek lazım. CDO'nun ne olduğunu oradan öğrendim.
    • CDO'ların dünya ekonomisini çökerttiği dönemin manşetlerini okumak için fazla genç olan bir neslin artık var olduğunu fark ettim. Yaşlı hissettim.
    • Aklıma https://en.wikipedia.org/wiki/Collaboration_Data_Objects geldi ;)
  • Bunun bir “zafer” olup olmadığı, “zafer” tanımına fazlasıyla bağlı olduğu için tartışmak istemem ama avantajları kesinlikle var. Çalıştırılmayan ve dış kütüphaneden erişilemeyen savunmasız kod yolları artık güvenli kod yolları hâline gelir.
    Elbette rahatsız edici bir durum, ama güvenli.
    Bu tür vendoringin başka bir avantajı daha var. Kendi kütüphanenizde sağlam bir test kapsamı varsa, yeni içeri aldığınız kütüphane için kod kapsamı araçları çalıştırabilirsiniz.
    Kütüphaneyi değiştirmek zor olabilir, ancak kendi kodunuzun dokunmadığı kısımları nispeten kolayca silip azaltabilirsiniz. Yapıya bağlıdır ama savunmasız kodun tamamı silinirse bu açık bir kazançtır; aslında bir kısmını kullanıyor olduğunuzu keşfetmek bile daha belirgin bir kazanç olabilir.
    Yani kamuya açık bakım için bir kütüphaneyi fork etmek büyük bir sorumlulukken, yalnızca ihtiyaç duyulan kısmı vendor edip elden geçirmek çok daha küçük bir yüktür. Gerçekten budama yapmasanız bile bunu kolaylaştırması başlı başına bir ilerlemedir.
    Dezavantajları da kesinlikle var, ama tamamen kötü değil.

    • Aslında çok iyi bir sonuç. Her bağımlılık bir güvenlik riskidir ve tüm bağımlılıkları vendor etmeme yönündeki argüman, bilinen güvenlik sorunlarından kaçınmak için dış bağımlılıkları güncel tutmanız gerektiğine dayanır.
      Ama dış bağımlılığı artık izleyen kimse yoksa bu argüman ortadan kalkar ve o bağımlılık bir yük olur.
      Bağımlılığın abandoned olarak işaretlenip güvenlik raporlarında görünmeye başlaması istenen davranıştır. Bu sayede vendor edip etmeyeceğinize, yani “kötü niyetli bir aktörün gizlice bir şey eklemesi” riskini ortadan kaldırıp kaldırmayacağınıza ya da başka bir seçenek seçip seçmeyeceğinize bilgiye dayalı karar verebilirsiniz.
      Rust derleme sisteminin buna kolayca izin vermesi de güzel.
    • Google'da tüm üçüncü taraf bağımlılıkların politika gereği vendor edilmek zorunda olduğunu belirtmekte fayda var.
      Genellikle devasa monorepo'nun tamamında o bağımlılığın yalnızca tek bir sürümüne izin verilir. Ben ayrıldıktan sonra değişmiş olabilir.
      Ayrıca her third_party bağımlılığı için atanmış bir sorumlu ya da OWNERS bulunur.
      Bu sayede nispeten düzen korunur.
      Ancak bu tür zorunlu disiplin, yeterince zamanı ve parası olan ve “hızlı hareket et, bir şeyleri kır” felsefesine bağlı olmayan Google gibi kuruluşlarda iyi işleyebilir. Startup'larda ne kadar iyi işler bilmiyorum.
    • Kütüphane bakımcılarının kendi kütüphanelerinin geçişli kod kapsamını, örneğin başka hangi kütüphanelerin test süitlerinin kendilerini kullandığını hesaplayabilecekleri bir araç var mı merak ediyorum.
      Bir anlamda başka kütüphaneler rastgeleye yakın çağrılar sağladığı için, yönlendirilmiş bir fuzz testi gibi; bu da ilginç bir test stratejisi olabilir.
  • JS npm ekosisteminde de aynı kalıbı gördüm
    npm audit güvenlik sorunları konusunda çoğunlukla yalancı çoban gibi davranıyor; lisans izin veriyorsa kodu içeri almak, kullanıcıların sahte sorunları altında ezilmemenin en istikrarlı yollarından biri
    Kullanıcılar çoğu zaman bağlamı anlamıyor ya da işverenlerinin politikaları gerçeklikten kopuk yerlerde belirlendiği için bunu umursamıyor
    Build pipeline’ındaki geçişli bağımlılık kod tabanının bir kısmında kullanılan bir regex’in gerçekten hizmet reddi saldırısında kullanılabilecek olması söz konusu değil
    Derin geçişli bağımlılıklardaki “sorunlar” özellikle etrafından dolaşması zahmetli olabiliyor. Yapı gereği “biz o kod yoluna asla girmiyoruz, bu yüzden kusurdan etkilenmiyoruz” ya da “o yola girilen tek durum, çevrimdışı bir ortamda güvenilir girdidir” gibi gerçekleri teknik olarak kanıtlamak çoğu zaman zor oluyor

    • JS dünyasında geliştirme bağımlılıklarındaki sorunlar gerçekten baş ağrısı
      Bu tür sorunların önemli olduğu senaryolar elbette var. Örneğin ele geçirilmiş bir build aracının, derlenmekte olan kütüphaneye kötü amaçlı kod enjekte etmesi gibi
      Ama bu durumlar son derece nadir ve build sırasında yalnızca çağrıldığı için pratikte önemli olmayan hizmet reddine açık regex dalgalarının arasında kayboluyor
      Buna bir de tipik build araçlarının yaklaşık 50 milyar geçişli bağımlılıktan oluşan ağaçlara sahip olması eklenince iş gerçekten yorucu hale geliyor
      Bu tür sorunları raporlayan araçların “yeniden dağıtılırsa istismar edilebilir” ile “build pipeline’ında kullanılırsa istismar edilebilir” ayrımını yapması gerektiğini düşünüyorum
    • Şu anda o sorunlu yola girmiyor olsanız bile, ileride bağımlılık güncellendiğinde sorunlu yola girmeye başlayabilir
  • “Artık kötü teknik borç bir anda AAA derecesine çıktı” ifadesindeki “bir anda”, aynı kodun vendoring yapılmış olması nedeniyle eskisinden daha iyi bir borç notu almasının mantıksız olduğu anlamına geliyor gibi
    Ama bu, yalnızca kodun kendi değerine bakmak demek ve toplam değer önerisinin en önemli kısmını kaçırıyor
    Bir bakımcı kodu içeri aldığında, artık o kod o bakımcının mülkiyetinde olur. Ölü bir projenin kodunu aktif bir bakımcı vendor ederse, sorunlara yanıt verebilecek, pull request’leri inceleyebilecek ve hataları düzeltebilecek aktif bir kişi ortaya çıktığı için kodun değeri artar
    Başka bir benzetmeyle, ihmal edilen bir evcil hayvanı yeni bir sahibine verdiğinizde daha iyi bakılacağı, sağlıklı olacağı ve daha uzun yaşayacağı için değerinin artmasına benzer

    • Bu yalnızca o bağımlılığı dolaylı olarak kullananlar için geçerli. Bu durumda hata bulmak için bakan göz sayısı çok az olabilir
      Bakımcının da büyük ve yabancı bir kod tabanına alışması gerekeceğinden, düzeltme uygulamak veya inceleme yapmak için giriş engeli oluşacaktır
  • Biraz yan konu ve tartışmalı bir düşünce ama, kaynak tabanlı paket yöneticileri yayımlanmış paketlerin bakımını registry’nin zorla devralmasına yönelik hukuki hakkı güvence altına almadıkça korkunç sorunlardan kaçınmanın zor olduğunu düşünüyorum
    Bunlar ihmal, kötü niyetli değişiklikler, kötü niyetli kaldırmalar ve taklit gibi sorunlar
    Bir paketin daha geniş topluluk için yeterince önemli olduğuna karar verilirse, paket registry kaydını asıl sahibinin elinden alıp bir fork’u gösterecek şekilde değiştirmenin bir yoluna ihtiyaç var
    Elbette böyle bir adım çok drama yaratır, ama alt kullanıcıları aktif biçimde koruyabilir

    • Bu pek sorun gibi gelmiyor. Açık kaynağın güzelliği fork edilebilmesinde
      Asıl sorun, açık kaynak projelerini sürdürmenin zaman ve emek gerektirmesi ve boş zamanı olan başka birini bulmanın kolay olmaması
    • Registry gerekli gördüğünde paket sahipliğini elinden alan kaynak tabanlı bir paket yöneticisinin katkı çekmekte zorlanması gerekir
      Tüm katkıların otomatik olarak belirli bir grubun mülkiyetine geçtiği telif hakkı modelinden bile daha az çekici
      GitHub’ın özgür yazılım barındırırken o yazılımın telif hakkı ihlaline özel bir yer olduğu ileri sürülebilir belki, ama en azından şu anda paketlerin nominal sahipliğini elinden almaya çalışmıyor
    • Topluluk açısından önemli olması gerekçesiyle yapılacaksa, en iyi ihtimalle paket düzeyinde yapılacak bir iştir; registry düzeyinde değil
      Topluluktan söz edildiğine göre bu bir müşteri-tedarikçi ilişkisi değil ve çoğu paket ücretsiz sunulacak kadar önemli
      “Ayda 10 dolar verelim, bizim için 100 bin paketi yönetin” gibi aşağılayıcı bir tutara dönüşebilir
    • Bu sorunların hepsi aynı türden değil. Dondurulmuş bir paket, alt bağımlılıkların karar vermesi gerektiği anlamına gelir; ama vendoring dahil yeterince çok seçenek var
      İnternette bakımı yapılmayan çok sayıda kaynak kodu var; sadece olduğu haliyle bir kez yayımlanmış durumdalar. Ücretsiz kod için kimse güncelleme garantisi almaz
    • Alternatif Kik NPM sorunu. Her iki taraf da kötü
  • Birinin yaml-rust’ı zaten fork’layıp yaml-rust2(https://github.com/Ethiraric/yaml-rust2/blob/master/document...) oluşturmuş olması oldukça şanslıydı
    Bu fork’un YAML test suite’ini tamamen geçmesi ve benchmark’larda da daha hızlı olması güzel. Migrasyon da basit görünüyor
    Sonuçta sorun devam ediyor. Şu anda gönüllü olarak ücretsiz emek veren başkalarının çalışmalarına bağımlıyız, ama bu sonsuza kadar sürmeyebilir
    Onların zamanını ve emeğini ödüllendirip iyi işlerini sürdürmelerini ummaktan başka bir çıkar yol var mı bilmiyorum

    • yaml-rust baştan beri saf Rust uygulamasıydı ve tagline’da kelimesi kelimesine böyle yazıyor
      “A pure rust YAML implementation.”
      Aksine serde_yaml, libyaml’ın c2rust ile dönüştürülmüş hali olan unsafe-libyaml’a bağımlı olduğu için saf Rust sayılması daha zordu
    • Otobüs faktörü 1 olan projeler doğası gereği riskli
      Yeterince uzun bir zaman aralığında bir açık kaynak bakımcısının projeyi bırakma olasılığı 1’dir
      Bundan kaçınmanın tek yolu, tek kişilik bakım projelerini tabu haline getirmektir
    • Bu sorun için varsayılan çözümüm, mümkün olduğunca üçüncü taraf bağımlılıklardan kaçınmak
      Rust standart kütüphanesini yapanlar standart kütüphaneyi zayıf tutmak istediği için Rust projelerinde muhtemelen bir seçenek olmayabilir
      Ama yeterli özelliklere sahip standart kütüphanesi olan başka diller kullanıldığında kesinlikle mümkün bir seçenek
      İhtiyaç duyduğum şeyler yerleşik gelen dilleri bilinçli olarak kullandığım için, veritabanı sürücüleri dışında neredeyse hiç harici kütüphane kullanmıyorum
  • Tüm bu durum biraz gülünç görünüyor. Kod çalışıyorsa ve yıllardır da böyle çalıştıysa, bakımının yapılmıyor olmasının neden sorun olduğunu anlamıyorum
    Düzeltmeye gerek yoksa ve sınırları ile özelliklerini biliyorsanız sorun yok
    Kod kendi kendine bozulmaz. Onlarca yıl önce yazılmış kodu ödünç alıp ya da entegre edip sorunsuz kullandığım pek çok kez oldu
    Şahsen o kütüphaneyle ilgili tüm şikâyetleri görmezden gelip geçerdim

    • Bariz cevap, onun birçok açıdan “çalışmadığı”dır
      Zaten bir sürü hata birikmiş durumda ve düzeltmeler mevcut olsa bile asla yamanmayacak. https://github.com/chyh1990/yaml-rust/issues ve /pulls’a bakmak yeterli
    • Onlarca yıl önce yazılmış kodu ödünç almak ya da entegre etmek dediğiniz şey, yazarın kütüphaneyi kendi projesinin içine vendor etmesiyle yaptığı şey değil mi?
      Kullandığınız kod parçasının bakımını üstlenmekle aynı şey
      Bazen kötü olabilir. Çünkü kopyala-yapıştır kodlama ya da mükerrer emek anlamına gelebilir
      Ama üçüncü taraf bileşen tamamen bakımsız durumdaysa oldukça anlaşılır
  • Doğru, bağımlılıklar vendor edilebilir. “Neredeyse tamamlanmış” seviyeye yakın olan ve geliştirme ile bakımı yavaşlamış bağımlılıklar için 20 yıldır genelde böyle yaptım
    Ancak “batteries are not included” olan dillerde hiç çalışmadım

  • cargo vendor --aggressive gibi bir şey yapıp, kendi crate’im açısından bağımlılıkların içindeki tüm ölü kodu budamanın bir yolu var mı?
    “Bağımlılıkları inceleyin” sorununu daha yönetilebilir hâle getirip getiremeyeceğini merak ediyorum
    Yazının ana konusundan sapıyor ama sonuçta bağımlılık seçimi ve bunun getirdiği tüm sorumluluklar bize ait olduğu için bağlantılı
    Gerçekte crate’e derlenip giren şeyler konusunda daha fazla sorumluluk almamıza yardımcı olacak araçlara yer var gibi görünüyor

    • O zaman kütüphanedeki tüm hata raporlarını da kendi hata takip sisteminize mi kopyalıyorsunuz?
      Kopyalamıyorsanız neyin iyileştiğini anlamıyorum