Toto je úvodní stránka/dokumentace pro crosh, Chromium OS shell. Pokud jste právě na zařízení CrOS, měli byste být schopni spustit crosh stisknutím kláves Ctrl + Alt+T. Pokud nejste na CrOS, pak s největší pravděpodobností to nebude dělat nic užitečného :).
stačí spustit help
Chcete-li získat informace o dostupných příkazech a zjistit více.
můžete také použít dokončení karty k rychlému nalezení existujících příkazů.
je to dobrodružství!
- pro vývojáře Chromium OS
- bezpečnostní varování
- kde soubory žijí
- repo zdroje
- přidání nových příkazů
- návrh příkazu
- Příklady
- Nastavení modulu
- Příkaz Provádění
- Příkaz Nápověda
- Kritizovat Příkazů
- Testování
- Iterativní Vývoj
- Unittests
- budoucí práce
- starší Krosh dokumentace
- příkaz API
- Příkaz Nápověda
- Skrytí Příkazů
pro vývojáře Chromium OS
tato část je určena pro lidi hacking na Chromium OS, zvláště když potřebují upravit / rozšířit crosh.
bezpečnostní varování
neinstalujte nové moduly bez úplné bezpečnostní kontroly. Jakýkoli nezabezpečený kód, který načte crosh, bude přímo k dispozici lidem v ověřeném režimu. To je snadný útok vektor spustit libovolný kód a nepořádek se stavem uživatele. Nechceme podkopat bezpečnost CrOS!
Pokud hledáte recenzenty, podívejte se na ./ Soubor vlastníků.
kde soubory žijí
Crosh je migrován z shellu na Rust. Crosh začne vykonávat od src/main.rs, ale většina příkazů jsou implementovány jako jejich vlastní submodul jednoho na vysoké úrovni modulů (např. base
nebo dev
).
hlavnícrosh
skript obsahuje starší implementaci core crosh logiky, zatímco ostatní starší funkce žijí v adresářích modulů. Starší verze crosh je nainstalována do zařízení jako crosh.sh
.
repo zdroje
moduly, které jsou specifické pro desku nebo silně specifické pro balíček, by měly obecně žít s touto deskou a / nebo balíčkem. U funkcí, které jsou vždy k dispozici na všech zařízeních CrOS, by měl být tento kód uchováván v tomto repo.
Pokud si nejste jisti, zeptejte se [email protected].
přidání nových příkazů
nejprve určete, jakou implementační strategii bude nový příkaz používat. Při výběru strategie pomáhá vědět, jaká oprávnění a oprávnění jsou potřebná. S ohledem na strategii, podívejte se na různé příklady níže.
shell crosh běží ve stejném prostředí jako prohlížeč (stejný uživatel / skupina, stejné jmenné prostory Linuxu atd…). Takže všechny nástroje, které spustíte v crosh, nebo informace, které se pokusíte získat, musí být přístupné uživateli chronos
.
zřídka však chceme, aby crosh skutečně prováděl nástroje přímo. Místo toho byste měli do debugd démona přidat zpětná volání D-Bus a odeslat na něj všechny požadavky. Můžeme lépe řídit přístup v debugd a uzamknout nástroje. Pak jediná logika, která existuje v crosh je D-Bus IPC volání a pak zobrazí výstup z těchto programů. Diskuse o debugd je mimo rozsah zde, takže Podívejte se na adresář debugd místo.
Příklady
Příklad implementace:
- D-Bus metoda obal (debugd): base::verify_ro
Použijte, když D-Bus API je již plánované nebo crosh nemá potřebné oprávnění, nebo schopnosti. - Externí binární obal: base::ccd_pass
když už tam je nástroj příkazového řádku, který provádí příkaz, který funguje při běhu jako chronos s možností crosh. - příkaz napsaný v Rust: base::arc
To se nejlépe hodí pro případy, kdy nejsou potřeba další funkce a není opodstatněné mít samostatný nástroj příkazového řádku.
ukázkový pracovní postup je uveden níže pro psaní nového příkazu.
Nastavení modulu
vyberte vhodný modul, do kterého má příkaz patřit. Pro příkazy režimu dev to bude dev
, většina ostatních příkazů bude patřit do base
. Tento příklad použije jako modul base
, ale stejné kroky by měly platit i v jiných případech.
poté vyberte název příkazu, vytvořte dílčí modul s tímto názvem a zaregistrujte jej u nadřazeného modulu. Na tomto příkladu je příkaz verify_ro
, tak nový zdrojový soubor je src/base/verify_ro.rs
a dva řádky musí být přidány do src/base/mod.rs
:
za Prvé, submodul musí být dovezen:
mod verify_ro;
Druhý rejstříku funkci (musí být vytvořen níže) musí být povolán zaregistrovat funkce v mateřské modul src/base/mod.rs
:
pub fn register(dispatcher: &mut Dispatcher) { ... verify_ro::register(dispatcher); ...}
nyní je zdrojový soubor src/base/verify_ro.rs
připraven k zápisu. Začít s touto minimální zdrojový soubor a ověřte, že crosh sestavuje s cargo build
:
use crate::dispatcher::Dispatcher;pub fn register(dispatcher: &mut Dispatcher) { dispatcher.register_command( Command::new( "verify_ro".to_string(), "TODO put usage here".to_string(), "TODO put description here".to_string(), ) .set_command_callback(Some(execute_verify_ro)), );}fn execute_verify_ro(_cmd: &Command, args: &Arguments) -> Result<(), dispatcher::Error> { unimplemented!();}
Příkaz Provádění
Toto předpokládá, že výše uvedené pokyny jsou již kompletní.
Od té doby privilegované operace nemohou být provedeny podle Crosh (ale měla by být provedena v debugd nebo kdekoli jinde), níže uvedený příklad se zaměřuje na D-Bus zejména a předpokládá, že existuje D-Bus metoda, která musí být volána z nové Crosh příkaz.
Všimněte si, že debugd je D-Bus rozhraní již má Rez vazby generované prostřednictvím dev-rez/system_api, takže vázání a D-Bus připojení mohou být importovány:
use dbus::blocking::Connection;use system_api::client::OrgChromiumDebugd;
Pokud chcete procházet zdrojový kód vytvořené vazby, po spuštění build_packages, podívejte se na následující cestu:
/build/${BOARD}/usr/lib/cros_rust_registry/registry/system_api-*/src/bindings/client/
Uvnitř příkazu implementaci D-Bus připojení musí být inicializován. V tomto příkladu se používá blokovací připojení.
let connection = Connection::new_system().map_err(|err| { error!("ERROR: Failed to get D-Bus connection: {}", err); dispatcher::Error::CommandReturnedError})?;
připojení sběrnice pak může být použita, aby se rozhraní pro požadovanou službu, která je debugd v tomto případě:
let conn_path = connection.with_proxy( "org.chromium.debugd", "/org/chromium/debugd", DEFAULT_DBUS_TIMEOUT,);
zbytek volání metody využívá faktu, že dovážené rys system_api::client::OrgChromiumDebugd
je realizován za conn_path
takže členské funkce, které mapují do D-Bus metody mohou být volány z conn_path
. Například:
conn_path .update_and_verify_fwon_usb_stop(handle) .map_err(|err| { println!("ERROR: Got unexpected result: {}", err); dispatcher::Error::CommandReturnedError })?;
to zahrnuje základy. Pokud se podíváte na skutečný zdrojový kód pro základnu::verify_ro, poskytuje složitější příklad s voláním metody start, pozorovatelem a voláním metody stop.
Příkaz Nápověda
výchozí pomoci struny jsou naplněna pomocí příkazu název, použití řetězec, řetězec popisu a nějaké volby nebo vlajky, které jsou registrovány prostřednictvím dispečera API.
alternativně lze při registraci příkazu nastavit zpětné volání nápovědy k provedení vlastní logiky, jako je vyvolání možnosti nápovědy binárního souboru. Příklad:
const EXECUTABLE: &str = "/usr/bin/vmc";pub fn register(dispatcher: &mut Dispatcher) { dispatcher.register_command( Command::new("vmc".to_string(), "".to_string(), "".to_string()) .set_command_callback(Some(execute_vmc)) .set_help_callback(vmc_help), );}fn vmc_help(_cmd: &Command, w: &mut dyn Write, _level: usize) { let mut sub = process::Command::new(EXECUTABLE) .arg("--help") .stdout(Stdio::piped()) .spawn() .unwrap(); if copy(&mut sub.stdout.take().unwrap(), w).is_err() { panic!(); } if sub.wait().is_err() { panic!(); }}
Kritizovat Příkazů
Pokud chcete nahradit crosh příkaz s jiným UI (jako chrome:// page), a ty chceš, abych odsuzoval příkaz elegantně tím, že opustí za přátelské poznámka: pokud se lidé snaží, aby ji používat, zde je formulář.
# Set the vars to pass the unittests ...USAGE_storage_status=''HELP_storage_status=''# ... then unset them to hide the command from "help" output.unset USAGE_storage_status HELP_storage_statuscmd_storage_status() ( # TODO: Delete this after the R## release branch. echo "Removed. See storage_info section in chrome://system")
ujistěte se, že přidáte komentář TODO, aby lidé věděli v budoucnu, kdy je v pořádku vyčistit.
Testování
Iterativní Vývoj
můžete spustit ./crosh
na ploše systému získat vzorek pláště. Zde můžete rychle otestovat základní interakce (například analýzu argumentů) nebo zkontrolovat výstup nápovědy. Nebudete mít přístup k CrOS služby, které mnoho crosh příkazy očekávat, že mluvit (přes D-Bus), takže tyto příkazy se nezdaří.
Chcete-li načíst moduly režimu dev, můžete použít ./crosh --dev
. Načte pouze lokální moduly (./dev.d/
), takže pokud váš modul žije jinde, můžete jej dočasně zkopírovat zde.
podobně, pokud chcete načíst moduly vyměnitelných zařízení, můžete použít ./crosh --removable
.
Unittests
spustit jednotkové testy a to buď volání cargo test --workspace
v crosh složku nebo spustit emege-${BOARD} crosh && FEATURES=test emerge-${BOARD}
./run_tests.sh
legacy unittest běžec provádí spoustu základní styl a spolehlivost kontroly. Spusťte jej proti jakýmkoli změnám kódu shellu!
budoucí práce
každý by měl bez obav vyzvednout tyto nápady a pokusit se je realizovat :).
- přesunout všechny zbývající příkazy, které jsou implementovány na místě debugd volání, takže je lze provést přes D-Bus.
- spusťte crosh sám v omezeném sandboxu (namespaces / seccomp / etc…). Jakmile jsou všechny příkazy prováděny prostřednictvím IPC, není třeba udržovat Priv. Může to být závislé na režimu dev, takže neporušujeme
shell
. - migrovat další starší příkazy shellu na Rust. To lze také provést současně s migrací příkazu na debugd.
starší Krosh dokumentace
Crosh byl původně napsán v shellu. V době psaní mnoho příkazů stále zůstává ve skořápce a ještě musí být přeneseno na Rust crosh. Tato dokumentace je zde uložena pro údržbu těchto příkazů.
příkaz API
pro každý příkaz definujete dvě proměnné a jednu funkci. Není třeba registrovat nové příkazy kdekoli, protože crosh zkontroluje své vlastní runtime prostředí, aby je objevil.
zde je návod, jak zaregistrovat nový příkaz foo
.
# A short description of arguments that this command accepts.USAGE_foo='<some args>'HELP_foo=' Extended description of this command.'# Not required, but lets crosh detect if the foo program is available in the# current system (e.g. the package is not installed on all devices). If it# isn't available, crosh will automatically display an error message and never# call cmd_foo.EXEC_foo='/full/path/to/program'cmd_foo() ( # Implementation for the foo command. # You should validate $# and "$@" and process them first. # For invalid args, call the help function with an error message # before returning non-zero. ...foo code goes here!...)
Další podrobnosti o tom, co a jak strukturovat nový příkaz, naleznete v sekci návrh níže.
Příkaz Nápověda
Pokud vaše crosh příkaz jednoduše zavolá externí program, dělat zpracování, a že program už nabízí podrobnosti o využití, budete pravděpodobně nechcete mít duplicitní věci. Tento scénář můžete zvládnout definováním funkce help_foo
, která provede příslušné volání.
# Set the help string so crosh can discover us automatically.HELP_foo=''cmd_foo() ( ...)help_foo() ( /some/command --help)
Vezměte na vědomí, že jsme stále HELP_foo
. To je nutné, aby nás crosh mohl automaticky objevit a zobrazit nás v příslušných seznamech orientovaných na uživatele (jako příkaz help_advanced
). Nemusíme nastavovat USAGE_foo
i když funkce help_foo
to dělá za nás.
Skrytí Příkazů
Pokud příkaz není ještě připraven pro „prime time“, možná budete chtít, aby to v crosh na začátku testování, ale není to objeví v help
výstup, kde uživatelé mohou snadno zjistit (samozřejmě, kód je vše veřejné, takže každý, kdo čte skutečný zdroj může najít). Tady je návod, jak to udělat.
# Set the vars to pass the unittests ...USAGE_vmc=''HELP_vmc=''# ... then unset them to hide the command from "help" output.unset USAGE_vmc HELP_vmccmd_vmc() ( ...)