iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
Cloud Native

關於 WebAssembly 也能變成 Container 的這檔事系列 第 11

Wasm+containerd-shim-wasm+sandbox - part 2

  • 分享至 

  • xImage
  •  

Wasm+containerd-shim-wasm+sandbox - part 2

sandbox 資料夾結構

sandbox
├── cli.rs (*)
├── error.rs (part 1)
├── instance.rs
├── instance_utils.rs
├── manager.rs
├── mod.rs (part 1)
├── oci.rs
├── shim.rs
└── stdio.rs

sandbox/cli.rs

本章節要來看的是 cli,此處為當我們執行 containerd-shim-... 時,會呼叫的實際函式。
需要注意的是,不管是哪一種版本的執行檔,包含:containerd-shim-[runtime]-v1containerd-shim-[runtime]d-v1containerd-[runtime]d,實際上都會進入同樣的進入點,再根據執行程式的名稱決定建立與觸發對應的執行模式。有了這個關係,在追蹤程式碼的時候可以更加有結構性的深入。

use std::path::PathBuf;
use std::sync::mpsc::channel;
use std::sync::Arc;

use containerd_shim::{parse, run, Config};
use ttrpc::Server;

use crate::sandbox::manager::Shim;
use crate::sandbox::{Instance, Local, ManagerService, ShimCli};
use crate::services::sandbox_ttrpc::{create_manager, Manager};

// 使用 `git_version` 函式庫中的 `git_describe` 來取得版本資訊
pub mod r#impl {
    pub use git_version::git_describe;
}

// 從本 crates 中取得版本與修訂版本的資訊
pub use crate::{revision, version};

// 定義版本與修訂版本的 macro
#[macro_export]
macro_rules! version {
    () => {
        env!("CARGO_PKG_VERSION")
    };
}

// 定義修訂版本的 macro
#[macro_export]
macro_rules! revision {
    () => {
        Some($crate::sandbox::cli::r#impl::git_describe!(
            "--match=:",
            "--always",
            "--abbrev=15",
            "--dirty=.m"
        ))
    };
}

// 主函式,用於啟動 shim
pub fn shim_main<I>(name: &str, version: &str, revision: Option<&str>, config: Option<Config>)
where
    I: 'static + Instance + Sync + Send,
    I::Engine: Default,
{
    // 解析命令行參數
    let os_args: Vec<_> = std::env::args_os().collect();
    // argv0 代表呼叫 shim 的命令行的第一個參數,為 shim 的名稱,下面會藉由這個名稱來判斷 shim 的執行模式
    // flags 代表除了 argv0 以外的命令行參數,為對應執行模式的參數
    let flags = parse(&os_args[1..]).unwrap();
    let argv0 = PathBuf::from(&os_args[0]);
    let argv0 = argv0.file_stem().unwrap_or_default().to_string_lossy();

    // 處理 --version 參數
    if flags.version {
        println!("{argv0}:");
        println!("  Runtime: {name}");
        println!("  Version: {version}");
        println!("  Revision: {}", revision.unwrap_or("<none>"));
        println!();

        std::process::exit(0);
    }

    // name 指的是該 runtime 的名稱,例如:wasmtime
    // 為了能統一化,因此將其轉換為小寫
    let lower_name = name.to_lowercase();
    // 根據名稱產生對應的 shim 名稱
    let shim_cli = format!("containerd-shim-{lower_name}-v1");
    let shim_client = format!("containerd-shim-{lower_name}d-v1");
    let shim_daemon = format!("containerd-{lower_name}d");
    let shim_id = format!("io.containerd.{lower_name}.v1");

    // 根據 argv0 與 shim 名稱判斷並選擇對應的執行模式
    match argv0.to_lowercase() {
        s if s == shim_cli => {
            run::<ShimCli<I>>(&shim_id, config);
        }
        s if s == shim_client => {
            run::<Shim>(&shim_client, config);
        }
        s if s == shim_daemon => {
            // 如果是 shim_daemon,則啟動 ttrpc 服務
            log::info!("starting up!");
            let s: ManagerService<Local<I>> = Default::default();
            let s = Arc::new(Box::new(s) as Box<dyn Manager + Send + Sync>);
            let service = create_manager(s);

            let mut server = Server::new()
                .bind("unix:///run/io.containerd.wasmwasi.v1/manager.sock")
                .expect("failed to bind to socket")
                .register_service(service);

            server.start().expect("failed to start daemon");
            log::info!("server started!");
            let (_tx, rx) = channel::<()>();
            rx.recv().unwrap();
        }
        _ => {
            // 如果不是 shim_cli、shim_client、shim_daemon,則印出錯誤訊息並結束程式
            eprintln!("error: unrecognized binary name, expected one of {shim_cli}, {shim_client}, or {shim_daemon}.");
            std::process::exit(1);
        }
    }
}


上一篇
Wasm+containerd-shim-wasm+sandbox - part 1
下一篇
Wasm+containerd-shim-wasm+sandbox - part 3
系列文
關於 WebAssembly 也能變成 Container 的這檔事15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言