İçeriğe geç
academia.sh

Ders 05 / 12

Konteyner İmaj Tarama

348 bileşenlik bir imajın 144 bulgusu kaynağına göre ayrılıyor: 75'i temel katmandan, 69'u uygulama katmanından gelir ve temel imajı yeni sürüme almak tek işlemde 64 bulguyu, temel kaynaklı olanların yüzde 85,3'ünü kapatırken uygulama katmanına hiç dokunmaz; 18 açık ise paket kaydında olmayan 31 bileşende durduğu için hiçbir koşumda görünmez. Üç imajın bulgu satırı toplamı 269, tekil açık 144. Her ağır bulguyu bloklayan politika 60 yapının 49'unu durdurur ve 12'sinde duran bulgunun tamamı ekibin düzeltemeyeceği temel katmandadır; blokajı daraltmak ağır temel maruziyetini 940 yapı-bulguda bırakır, yirmi yapıda bir temel tazelemesi 382'ye indirir.

İçindekiler

Depodaki dosyalar dört denetimden geçti. Üretime giden şey ise bir imajdır ve içinde ekibin hiç yazmadığı, hiç seçmediği bir katman yığını taşır. Konteyner imaj tarama, bu yığındaki bileşenleri çıkarıp bilinen açık kataloğuyla karşılaştıran denetimdir; eşleştirme mekaniği bağımlılık bileşen analiziyle aynıdır, farklı olan girdinin yapısıdır.

Bir imajda bulunan açığın tek bir ciddiyet değeri vardır ama iki ayrı düzeltme yolu. Bir bölümü uygulamanın eklediği katmanlardadır ve o katmanı üreten ekip düzeltebilir. Bir bölümü hiç dokunulmamış temel katmandan miras alınır; onun için yazılacak kod yoktur, kapatan şey temel imajın sürümünü değiştirmektir. Bu ders bulgu kümesini bu eksende ayırır ve ayrımın hatta ne anlama geldiğini sayar.

  • OD24. Bir imaj katman listesidir; alttaki katmanlar temel imajdan gelir, üsttekiler uygulamanın ekledikleridir. Katman mekaniği bu kursta girdidir, tekrar kurulmaz. Aşağıdaki katman adları, bileşen sayıları ve açıklar kurgudur.
  • OD25. Bir bulgunun kaynağı, açığı taşıyan bileşenin bulunduğu katmandır. Bu alan tarama çıktısında ayrı bir sütundur ve düzeltme yolunu belirler.
  • OD26. Tarama envanterden okur. Paket kaydında görünmeyen bir bileşen — elle yerleştirilmiş bir ikili — envantere hiç girmez ve taşıdığı açık hiçbir koşumda görünmez.
  • OD27. Temel katmandaki bir açığın yeni temel sürümde kapalı olup olmadığı ayrı bir alandır. Uygulama katmanındaki açık temel yükseltmesinden hiç etkilenmez.
  • OD28. Katalog kayıtları zamanla yayımlanır: imaj hiç değişmese bile bilinen bulgu sayısı artar.
  • OD29. Yapı başına 1,5, bloke yapı başına 35 model dakikası. Maruziyet yapı-bulgu birimindedir: her yapıda imajda duran ağır temel açık sayısının yapılar boyunca toplamı. Süreler veridir, ölçüm değildir.

Açığın Kaynağı ve Yükseltmenin Kapattığı

// imaj.mjs — bir imajin katman listesi taraniyor; olculen sey acigin temel katmandan mi
// uygulama katmanindan mi geldigi ve temel yukseltmesinin kacini kapattigidir. MODELDIR.
export const TOHUM = 20260404, TARAMA_DK = 1.5;
const uretec = (t) => { let s = t >>> 0;
  return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; };
const r = uretec(TOHUM);
export const CIDDIYET = ["dusuk", "orta", "yuksek", "kritik"];
const AGIR = new Set(["yuksek", "kritik"]);

// Katmanlar alttan uste: ilk ikisi temel imajdan gelir, ustteki ucu uygulamanin
// ekledikleridir. Katman adlari ve bilesen sayilari kurgudur.
export const KATMAN = [
  ["isletim taban", "temel", 96],
  ["calisma zamani", "temel", 64],
  ["bagimliliklar", "uygulama", 148],
  ["derlenmis cikti", "uygulama", 22],
  ["yardimci araclar", "uygulama", 18],
].map(([ad, kaynak, sayi]) => ({ ad, kaynak, sayi }));

// envanterde: bilesenin paket yoneticisi kaydinda gorunup gorunmedigi. Kayitta
// olmayan bilesen (elle kopyalanmis ikili) tarayicinin envanterine hic girmez.
// yeniTemelde: acigin, temel imajin yeni surumunde kapali olup olmadigi.
export const BILESEN = [];
for (const k of KATMAN) for (let i = 0; i < k.sayi; i++) {
  const envanterde = r() < (k.kaynak === "temel" ? 0.98 : 0.86), acik = [];
  const n = r() < 0.26 ? 1 + Math.floor(r() * 2.4) : 0;
  for (let j = 0; j < n; j++) acik.push({
    ciddiyet: CIDDIYET[Math.floor(r() * 4)],
    yeniTemelde: k.kaynak === "temel" && r() < 0.84, duzeltmeVar: r() < 0.72 });
  BILESEN.push({ katman: k, kaynak: k.kaynak, envanterde, acik });
}

// Tarama envanterden okur: kayitta olmayan bilesenin acigi hicbir kosumda gorunmez.
export function tara(yeniTemel = false) {
  const bulgu = [], gorulmeyen = [], kapanan = [];
  for (const b of BILESEN) for (const a of b.acik) {
    const kayit = { ...a, kaynak: b.kaynak, katman: b.katman.ad };
    if (!b.envanterde) gorulmeyen.push(kayit);
    else if (yeniTemel && a.yeniTemelde) kapanan.push(kayit);
    else bulgu.push(kayit);
  }
  return { bulgu, gorulmeyen, kapanan };
}

const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  const { bulgu, gorulmeyen } = tara();
  console.log(`model (tohum ${TOHUM}): ${BILESEN.length} bilesen, ` +
    `${BILESEN.reduce((a, b) => a + b.acik.length, 0)} acik; ` +
    `${BILESEN.filter((b) => !b.envanterde).length} bilesen paket kaydinda yok`);
  const y1 = gen([18, 11, 10, 14, 8, 9, 18]);
  console.log("\n" + y1(["katman", "kaynak", "bilesen", "kayitta yok", "acik", "bulgu",
    "gorulmeyen acik"]));
  for (const k of KATMAN) {
    const l = BILESEN.filter((b) => b.katman === k);
    const ac = l.reduce((a, b) => a + b.acik.length, 0);
    const gor = l.filter((b) => !b.envanterde).reduce((a, b) => a + b.acik.length, 0);
    console.log(y1([k.ad, k.kaynak, k.sayi, l.filter((b) => !b.envanterde).length,
      ac, ac - gor, gor]));
  }

  const once = tara(), sonra = tara(true);
  const y2 = gen([12, 9, 8, 13, 12, 11, 12]);
  console.log("\ntemel imaj yeni surume alindiginda");
  console.log(y2(["kaynak", "bulgu", "agir", "yeni bulgu", "yeni agir", "kapanan",
    "kapanan %"]));
  for (const kay of ["temel", "uygulama"]) {
    const o = once.bulgu.filter((a) => a.kaynak === kay);
    const s = sonra.bulgu.filter((a) => a.kaynak === kay);
    console.log(y2([kay, o.length, o.filter((a) => AGIR.has(a.ciddiyet)).length, s.length,
      s.filter((a) => AGIR.has(a.ciddiyet)).length, o.length - s.length,
      (100 * (o.length - s.length) / o.length).toFixed(1)]));
  }
  const kalanAgir = sonra.bulgu.filter((a) => AGIR.has(a.ciddiyet));
  console.log(`\nyukseltme ${once.bulgu.length - sonra.bulgu.length} bulguyu tek islemde ` +
    `kapatiyor, ${sonra.bulgu.length} bulgu kaliyor; kalan ${kalanAgir.length} agir bulgunun ` +
    `${kalanAgir.filter((a) => a.kaynak === "uygulama").length} tanesi uygulama katmanindadir`);
  console.log(`kalan agir bulgunun ${kalanAgir.filter((a) => !a.duzeltmeVar).length} tanesinin ` +
    `yayimlanmis bir duzeltmesi yok; ${gorulmeyen.length} acik ise hicbir kosumda gorunmuyor, ` +
    `cunku tasidigi bilesen paket kaydinda hic yer almiyor`);
}
model (tohum 20260404): 348 bilesen, 162 acik; 31 bilesen paket kaydinda yok

katman                 kaynak   bilesen   kayitta yok    acik    bulgu   gorulmeyen acik
isletim taban           temel        96             2      43       41                 2
calisma zamani          temel        64             3      36       34                 2
bagimliliklar        uygulama       148            21      64       50                14
derlenmis cikti      uygulama        22             2       8        8                 0
yardimci araclar     uygulama        18             3      11       11                 0

temel imaj yeni surume alindiginda
kaynak          bulgu    agir   yeni bulgu   yeni agir    kapanan   kapanan %
temel              75      33           11           6         64        85.3
uygulama           69      39           69          39          0         0.0

yukseltme 64 bulguyu tek islemde kapatiyor, 80 bulgu kaliyor; kalan 45 agir bulgunun 39 tanesi uygulama katmanindadir
kalan agir bulgunun 10 tanesinin yayimlanmis bir duzeltmesi yok; 18 acik ise hicbir kosumda gorunmuyor, cunku tasidigi bilesen paket kaydinda hic yer almiyor

İlk tablo bulgu kümesini katmana göre bölüyor. 348 bileşenin 160’ı temel katmanlardadır ve 79 açık taşır; 188’i uygulamanın eklediği katmanlardadır ve 83 açık taşır. Sayılar birbirine yakındır, ama bu iki yarının hattaki karşılığı aynı değildir. Temel katmandaki 75 bulgunun düzeltmesi imajı kuran ekibin elinde değildir; o katmanı başkası üretmiştir ve içindeki paketleri tek tek değiştirmek imajın kimliğini bozar.

Aynı tablonun son iki sütunu tarayıcının kendi sınırını yazıyor. 31 bileşen paket kaydında hiç görünmüyor ve bunların 21’i bağımlılıklar katmanındadır: derleme sırasında elle yerleştirilmiş, bir paket yöneticisinden geçmemiş ikililer. Taşıdıkları 18 açık hiçbir koşumda raporlanmıyor. Bu sayı bir eşik ayarıyla değişmez; kaynağı envanterin nasıl kurulduğudur. Bir imaj taramasının kapsama listesi, kaç bileşeni envanterin tanıdığıdır, ve bu sayı raporlanmadıkça temiz görünen bir katmanın gerçekten temiz mi yoksa okunmamış mı olduğu bilinmez.

İkinci tablo ayrımın karşılığını veriyor. Temel imajı yeni sürüme almak tek bir işlemde 64 bulguyu kapatıyor: temel kaynaklı bulguların yüzde 85,3’ü. Aynı işlem uygulama katmanına hiç dokunmuyor — 69 bulgu olduğu gibi kalıyor, kapanan sıfır. Bu, ciddiyet alanının hiç taşımadığı bir bilgidir: aynı ağırlıktaki iki kalemden biri bir satırlık sürüm değişikliğiyle, diğeri ayrı ayrı ele alınacak onlarca değişiklikle kapanır.

Yükseltmeden sonra kalan 45 ağır bulgunun 39’u uygulama katmanındadır ve 10’unun yayımlanmış bir düzeltmesi yoktur. Yani temel imaj yükseltmesi ağır kalemlerin çoğunu taşımaz; ağır bulgunun büyük bölümü zaten ekibin kendi eklediği katmanlardaydı. İki cümlenin birlikte okunması gerekir: yükseltme bulgu sayısını hızla düşürür, ama düşürdüğü bulguların ciddiyet dağılımı kalanlardan farklıdır.

Aynı Bulgu Kaç Kez Sayılıyor

// hat.mjs — ayni temel imajdan uretilen uc imaj 60 yapi boyunca taraniyor; olculen sey
// ayni bulgunun kac imajda tekrar sayildigi ve blokajin kime dustugudur. MODELDIR.
import { tara, TARAMA_DK } from "./imaj.mjs";

const YAPI = 60, TAZELEME = 20, BLOKE_DK = 35;
const AGIR = new Set(["yuksek", "kritik"]);
// yayim: kaydin yayimlandigi yapi. Imaj hic degismese bile bulgu sayisi artar,
// cunku yeni kayitlar zamanla yayimlanir.
const damga = tara().bulgu.map((a, i) => ({ ...a, yayim: (i * 37) % YAPI }));
const TEMEL = damga.filter((a) => a.kaynak === "temel");
const UYGULAMA = damga.filter((a) => a.kaynak === "uygulama");

// Iki temel imaj: t-a tam bilesen kumesini, t-b daha dar bir tabani tasir.
const TABAN = { "t-a": TEMEL, "t-b": TEMEL.filter((_, i) => i % 3 !== 0) };
const IMAJ = [
  { ad: "abone portali", taban: "t-a", uyg: UYGULAMA.filter((_, i) => i % 3 === 0) },
  { ad: "sayac alim", taban: "t-a", uyg: UYGULAMA.filter((_, i) => i % 3 === 1) },
  { ad: "yonetim araci", taban: "t-b", uyg: UYGULAMA.filter((_, i) => i % 3 === 2) },
];

const POLITIKA = [
  { ad: "her agir bulgu", blok: (a) => AGIR.has(a.ciddiyet), tazele: false },
  { ad: "yalniz uygulama katmani", blok: (a) => AGIR.has(a.ciddiyet) &&
    a.kaynak === "uygulama", tazele: false },
  { ad: "uygulama + temel tazeleme", blok: (a) => AGIR.has(a.ciddiyet) &&
    a.kaynak === "uygulama", tazele: true },
];

function olc(p) {
  const gorulen = new Set(), kapali = new Set();
  let bloke = 0, cozemez = 0, maruziyet = 0, bloklayan = 0;
  for (let y = 0; y < YAPI; y++) {
    const im = IMAJ[y % IMAJ.length];
    if (p.tazele && y > 0 && y % TAZELEME === 0)
      for (const a of TEMEL) if (a.yeniTemelde && a.yayim <= y) kapali.add(a);
    const kume = [...TABAN[im.taban], ...im.uyg]
      .filter((a) => a.yayim <= y && !kapali.has(a));
    const yeni = kume.filter((a) => p.blok(a) && !gorulen.has(a));
    for (const a of yeni) gorulen.add(a);
    if (yeni.length) {
      bloke++; bloklayan += yeni.length;
      if (yeni.every((a) => a.kaynak === "temel")) cozemez++;
    }
    maruziyet += kume.filter((a) => a.kaynak === "temel" && AGIR.has(a.ciddiyet)).length;
  }
  return { ad: p.ad, bloklayan, bloke, cozemez, maruziyet,
    dk: Math.round(YAPI * TARAMA_DK + bloke * BLOKE_DK) };
}

const gen = (B) => (h) => h.map((v, j) => (j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0]))).join("");

const ham = IMAJ.reduce((a, im) => a + TABAN[im.taban].length + im.uyg.length, 0);
const tekil = new Set(IMAJ.flatMap((im) => [...TABAN[im.taban], ...im.uyg])).size;
console.log(`${IMAJ.length} imaj, ${YAPI} yapi; uc imajin bulgu satiri toplami ${ham}, ` +
  `tekil acik ${tekil}. Fark temel katmanin her imajda yeniden sayilmasidir`);
const y = gen([28, 12, 9, 14, 16, 11]);
console.log("\n" + y(["politika", "bloklayan", "bloke", "ekip cozemez", "agir maruziyet",
  "toplam dk"]));
for (const p of POLITIKA) {
  const o = olc(p);
  console.log(y([o.ad, o.bloklayan, o.bloke, o.cozemez, o.maruziyet, o.dk]));
}

const [hepsi, uyg, taze] = POLITIKA.map(olc);
console.log(`\nher agir bulguyu bloklayan politika ${hepsi.bloke} yapiyi durduruyor ve ` +
  `${hepsi.cozemez} tanesinde duran bulgunun tamami temel katmandadir: imaji kuran ekibin ` +
  `yazabilecegi tek satir kod yoktur`);
console.log(`blokaji uygulama katmanina daraltmak duran yapiyi ${uyg.bloke}'ye indiriyor ama ` +
  `agir temel maruziyetini ${uyg.maruziyet} yapi-bulgu olarak yerinde birakiyor`);
console.log(`${TAZELEME} yapida bir temel tazelemesi ayni blokajla maruziyeti ` +
  `${taze.maruziyet} yapi-bulguya, yuzde ` +
  `${(100 * (1 - taze.maruziyet / uyg.maruziyet)).toFixed(1)} daha aza indiriyor`);
3 imaj, 60 yapi; uc imajin bulgu satiri toplami 269, tekil acik 144. Fark temel katmanin her imajda yeniden sayilmasidir

politika                       bloklayan    bloke  ekip cozemez  agir maruziyet  toplam dk
her agir bulgu                        72       49            12             940       1805
yalniz uygulama katmani               39       37             0             940       1385
uygulama + temel tazeleme             39       37             0             382       1385

her agir bulguyu bloklayan politika 49 yapiyi durduruyor ve 12 tanesinde duran bulgunun tamami temel katmandadir: imaji kuran ekibin yazabilecegi tek satir kod yoktur
blokaji uygulama katmanina daraltmak duran yapiyi 37'ye indiriyor ama agir temel maruziyetini 940 yapi-bulgu olarak yerinde birakiyor
20 yapida bir temel tazelemesi ayni blokajla maruziyeti 382 yapi-bulguya, yuzde 59.4 daha aza indiriyor

İlk satır bir sayma hatasının kaynağını gösteriyor. Üç imajın raporları alt alta konduğunda 269 bulgu satırı çıkıyor, ama tekil açık sayısı 144. Aradaki 125 satır aynı temel katmanın iki imajda yeniden sayılmasıdır. Bir kuruluşun toplam bulgu sayısı, imaj sayısıyla çarpılmış bir büyüklüktür; iki katı imaj üretmek aynı açıkları iki katı kez raporlar ve rakam kötüleşirken altındaki durum değişmez. Aynı çarpan tersine de çalışır: tek bir temel imaj yükseltmesi bütün imajlarda aynı anda kapanır.

Politika tablosunun ilk satırı hattın en yaygın kurulumudur: ağır her bulgu yapıyı durdurur. 60 yapının 49’u duruyor ve bunların 12’sinde durduran bulguların tamamı temel katmandadır. O on iki yapıda geliştiriciye düşen bir iş yoktur; bulgu doğrudur, ciddiyeti doğrudur, ama kapatacak değişiklik başka bir deponun sorumluluğundadır. Bu, blokajın en pahalı biçimidir: duran yapı, düzeltmesi kendisinde olmayan bir ekibin önünde durur.

İkinci satır blokajı uygulama katmanına daraltıyor. Duran yapı 49’dan 37’ye, toplam bedel 1 805 dakikadan 1 385 dakikaya iniyor ve ekibin çözemeyeceği blokaj sıfırlanıyor. Ama maruziyet sütunu hiç değişmiyor: her iki politikada da 940 yapı-bulgu. Bu sütun asıl soruyu yazıyor — temel katmandaki ağır açıklar altmış yapı boyunca üretime gitmeye devam ediyor. Yapıyı durdurmak onları kapatmıyordu; yalnız birinin dikkatini çekiyordu.

Üçüncü satır kapatanı gösteriyor. Yirmi yapıda bir temel imajı tazelemek, aynı blokaj ve aynı 1 385 dakika ile maruziyeti 382 yapı-bulguya, yüzde 59,4 daha aza indiriyor. Temel katman açığını kapatan şey bir kapı değil, bir tazeleme ritmidir. Kapı yalnız bulguyu görünür kılar; imajın hangi sıklıkla yeniden kurulduğu ise onu gerçekten kaldırır. İmaj hiç değişmese bile bilinen bulgu sayısının artması bunu zorunlu kılar: yeni kayıtlar yayımlanmaya devam eder ve kurulduğu gün temiz raporlanan bir imaj, hiç dokunulmadan aylar sonra ağır bulgular taşır.

Özet

  • Aynı bulgu kümesi kaynağına göre bölünür: 144 bulgunun 75’i temel katmandan, 69’u uygulamanın eklediği katmanlardan gelir ve iki yarının düzeltme yolu birbirine benzemez.
  • Temel imajı yeni sürüme almak tek işlemde 64 bulguyu — temel kaynaklıların yüzde 85,3’ünü — kapatır ve uygulama katmanına hiç dokunmaz; kapanan oran uygulama tarafında sıfırdır.
  • Yükseltmeden sonra kalan 45 ağır bulgunun 39’u uygulama katmanındadır: yükseltme bulgu sayısını hızla düşürür ama ağır kalemlerin çoğunu yerinde bırakır.
  • 31 bileşen paket kaydında görünmez ve taşıdığı 18 açık hiçbir koşumda raporlanmaz; bu sayı eşikle değişmez, kaynağı envanterin nasıl kurulduğudur.
  • Üç imajın 269 bulgu satırı 144 tekil açığa karşılık gelir; bulgu sayısı imaj sayısıyla çarpılan bir büyüklüktür ve tek bir temel yükseltmesi bütün imajlarda aynı anda kapanır.
  • Blokaj maruziyeti düşürmez: her ağır bulguyu bloklamak 49 yapı durdurur ve 12’sinde ekibin yapabileceği bir iş yoktur, ama ağır temel maruziyeti 940 yapı-bulguda kalır; yirmi yapıda bir tazeleme aynı blokajla onu 382’ye indirir.

Sonraki Adım

İmaj bir yerden gelir: onu üreten ve çalıştıran ortamın kendisi de yazılmış bir metindir. Kaç kopya koşacağı, hangi ağ kuralının açık kalacağı, hangi deponun dışarıdan okunabilir olacağı bir şablonda tanımlıdır ve bu şablon da depoda durur. Buradaki denetimlerin hiçbiri ona bakmadı; oysa şablondaki tek bir alan, imajın içindeki bütün bulgulardan daha geniş bir yol açabilir. Şablon denetiminin ayırt edici yanı zamanlamasıdır: dağıtımdan önce koşabilen bir kural, kaynağı oluşmadan yanlış yapılandırmayı durdurur. Sonraki ders bir şablon kümesini kural setinden geçirir, dağıtımdan önce yakalanan kalemi sayar ve kaç yapının bu yüzden bloke olduğunu ölçer.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat