Dette er hjemmesiden/dokumentationen til crosh, Chromium OS shell. Hvis du er på en CrOS-enhed lige nu, skal du være i stand til at starte crosh ved at trykke på Ctrl+Alt+T. hvis du ikke er på CrOS, vil det sandsynligvis ikke gøre noget nyttigt :).
Kør barehelp
for at få information om tilgængelige kommandoer og opdage mere.
Du kan også bruge fanen færdiggørelse til hurtigt at finde eksisterende kommandoer.
det er et eventyr!
- for Chromium OS udviklere
- Sikkerhedsadvarsel
- hvor filer lever
- Source Repos
- tilføjelse af nye kommandoer
- Kommandodesign
- eksempler
- modulopsætning
- Kommandoimplementering
- Kommandohjælp
- Deprecating kommandoer
- test
- iterativ udvikling
- Unittests
- fremtidigt arbejde
- Legacy Crosh dokumentation
- Command API
- Kommandohjælp
- Skjul kommandoer
for Chromium OS udviklere
dette afsnit er beregnet til folk hacking på Chromium OS, især når de har brug for at ændre/udvide crosh.
Sikkerhedsadvarsel
Installer ikke nye moduler uden fuld sikkerhedsanmeldelse. Enhver usikker kode, som crosh indlæser, vil være direkte tilgængelig for folk i verificeret tilstand. Det er en let angrebsvektor til at køre vilkårlig kode og rod med brugerens tilstand. Vi ønsker ikke at underminere sikkerheden for CrOS!
Hvis du er på udkig efter korrekturlæsere, se på ./ Ejere fil.
hvor filer lever
Crosh migreres fra shell til Rust. Crosh begynder at udføre fra src/main.rs, men de fleste kommandoer implementeres som deres egen undermodul for et af modulerne på højt niveau (f.eks. base
eller dev
).
det vigtigstecrosh
script indeholder den ældre implementering af core crosh logic, mens andre ældre funktioner lever i modulmapper. Den ældre version af crosh er installeret på enheden som crosh.sh
.
Source Repos
moduler, der er specifikke for et kort, eller stærkt specifikke for en pakke, skal generelt leve med det pågældende bord og / eller pakke. For funktioner, der altid er tilgængelige på alle CrOS-enheder, skal denne kode opbevares i denne repo.
Hvis du er usikker, bare spørg på [email protected].
tilføjelse af nye kommandoer
bestem først, hvilken implementeringsstrategi den nye kommando vil bruge. Når du vælger en strategi, hjælper det med at vide, hvilke tilladelser og privilegier der er behov for. Med strategien i tankerne, tjek de forskellige eksempler nedenfor.
Kommandodesign
crosh-skallen kører i det samme miljø som bro.ser (samme bruger / gruppe, samme navnerum osv…). Så alle værktøjer, du kører i crosh, eller oplysninger, du forsøger at erhverve, skal være tilgængelige for chronos
bruger.
Vi ønsker dog sjældent, at crosh rent faktisk udfører værktøjer direkte. I stedet skal du tilføje D-Bus-tilbagekald til debugd-dæmonen og sende alle anmodninger til den. Vi kan bedre kontrollere adgangen i debugd og låse værktøjer ned. Så er den eneste logik, der findes i crosh, et D-Bus IPC-opkald og viser derefter output fra disse programmer. Diskussion af debugd er uden for rækkevidde her, så tjek debugd-biblioteket i stedet.
eksempler
eksempel implementeringer:
- D-Bus metode indpakning (debugd): base::verify_ro
Brug dette, når en D-Bus API allerede er planlagt eller crosh mangler de nødvendige tilladelser eller kapaciteter. - ekstern binær indpakning: base:: ccd_pass
Brug dette, når der allerede er et kommandolinjeværktøj, der implementerer den kommando, der fungerer, når den køres som chronos med funktionerne i crosh. - kommando skrevet i Rust: base::arc
Dette er bedst egnet til tilfælde, hvor ekstra funktioner ikke er nødvendige, og at have et separat kommandolinjeværktøj er ikke berettiget.
en eksempelarbejdsproces er inkluderet nedenfor for at skrive en ny kommando.
modulopsætning
Vælg et passende modul, som kommandoen skal tilhøre. For Dev-tilstandskommandoer vil dette være dev
, de fleste andre kommandoer hører hjemme i base
. Dette eksempel bruger base
som modul, men de samme trin skal stadig gælde i andre tilfælde.
vælg derefter et kommandonavn, Opret et undermodul med det navn, og Registrer det med det overordnede modul. I dette eksempel er kommandoen verify_ro
, så den nye kildefil er src/base/verify_ro.rs
og to linjer skal tilføjes til src/base/mod.rs
:
først skal undermodulet importeres:
mod verify_ro;
for det andet skal registerfunktionen (oprettes nedenfor) kaldes af registerfunktionen i modermodulet src/base/mod.rs
:
pub fn register(dispatcher: &mut Dispatcher) { ... verify_ro::register(dispatcher); ...}
nusrc/base/verify_ro.rs
kildefilen er klar til at blive skrevet. Start med denne minimale kildefil, og kontroller, at crosh kompilerer med 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!();}
Kommandoimplementering
dette forudsætter, at ovenstående instruktioner allerede er komplette.
da privilegerede operationer ikke kan udføres af Crosh (men skal implementeres i debugd eller hvor som helst andet), fokuserer eksemplet nedenfor især på D-Bus og antager, at der er en eksisterende D-Bus-metode, der skal kaldes fra en ny Crosh-kommando.
Bemærk, at debugds D-Bus-interface allerede har Rustbindinger genereret gennem dev-rust/system_api, så bindingerne og D-busforbindelsen kan importeres med:
use dbus::blocking::Connection;use system_api::client::OrgChromiumDebugd;
Hvis du vil gennemse kildekoden for de genererede bindinger, skal du kigge på følgende sti efter at have kørt build_packages:
/build/${BOARD}/usr/lib/cros_rust_registry/registry/system_api-*/src/bindings/client/
inde i kommandoimplementeringen skal en D-busforbindelse initialiseres. En blokeringsforbindelse bruges i dette eksempel.
let connection = Connection::new_system().map_err(|err| { error!("ERROR: Failed to get D-Bus connection: {}", err); dispatcher::Error::CommandReturnedError})?;
busforbindelsen kan derefter bruges til at få en grænseflade til den ønskede tjeneste, som er debugd i dette tilfælde:
let conn_path = connection.with_proxy( "org.chromium.debugd", "/org/chromium/debugd", DEFAULT_DBUS_TIMEOUT,);
resten af metodeopkaldet bruger det faktum, at den importerede egenskab system_api::client::OrgChromiumDebugd
implementeres for conn_path
så medlemsfunktionerne, der kortlægges til D-Bus-metoder, kan kaldes fra conn_path
. For eksempel:
conn_path .update_and_verify_fwon_usb_stop(handle) .map_err(|err| { println!("ERROR: Got unexpected result: {}", err); dispatcher::Error::CommandReturnedError })?;
dette dækker det grundlæggende. Hvis du ser på den faktiske kildekode til base::verify_ro, det giver et mere kompliceret eksempel med et startmetodeopkald, en overvåger og et stopmetodeopkald.
Kommandohjælp
standard hjælpestrengene udfyldes ved hjælp af kommandonavnet, brugsstrengen, beskrivelsesstrengen og eventuelle indstillinger eller flag, der er registreret via dispatcher API.
Alternativt kan en hjælp-tilbagekald indstilles, når du registrerer kommandoen for at udføre brugerdefineret logik som at påberåbe sig hjælpemuligheden for en binær. Eksempel:
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!(); }}
Deprecating kommandoer
Hvis du vil erstatte en crosh-kommando med et andet brugergrænseflade (som en chrome:// page), og du vil afskrive kommandoen yndefuldt ved at efterlade en venlig note, hvis folk forsøger at bruge den, her er formularen.
# 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")
sørg for at tilføje TODO-kommentaren, så folk ved i fremtiden, hvornår det er OK at rydde op.
test
iterativ udvikling
Du kan køre./crosh
på dit skrivebordssystem for at få en prøveskal. Du kan hurtigt teste grundlæggende interaktioner (som argument parsing) her, eller tjek hjælp output. Du har ikke adgang til CrOS-Tjenesterne, som mange crosh-kommandoer forventer at tale med (via D-Bus), så disse kommandoer mislykkes.
Hvis du vil indlæse Dev mode-moduler, kan du bruge ./crosh --dev
. Det indlæser kun lokale moduler (./dev.d/
), så hvis dit modul bor et andet sted, kan du kopiere det her midlertidigt.
tilsvarende, hvis du vil indlæse flytbare enhedsmoduler, kan du bruge ./crosh --removable
.
Unittests
for at køre enhedstestene skal du enten ringe cargo test --workspace
i crosh-mappen eller køre emege-${BOARD} crosh && FEATURES=test emerge-${BOARD}
./run_tests.sh
legacy unittest runner udfører en masse grundlæggende stil-og sundhedskontrol. Kør det mod eventuelle ændringer i shell-koden!
fremtidigt arbejde
enhver bør føle sig fri til at hente disse ideer og forsøge at gennemføre dem :).
- Flyt eventuelle resterende kommandoer, der er implementeret på plads for at debugd opkald, så de kan gøres over D-Bus.
- Kør crosh selv i en begrænset sandkasse (navnerum/seccomp/etc…). Når alle kommandoer er udført via IPC, er der ingen grund til at holde privs. Kan gøre det afhængigt af dev-tilstand, selvom vi ikke bryder
shell
. - Overfør yderligere ældre shell-kommandoer til Rust. Dette kan også gøres på samme tid som migrering af en kommando til debugd.
Legacy Crosh dokumentation
Crosh blev oprindeligt skrevet i shell. I skrivende stund er mange af kommandoerne stadig i skal og er endnu ikke overført til Rust crosh. Denne dokumentation opbevares her til vedligeholdelse af disse kommandoer.
Command API
for hver kommando definerer du to variabler og en funktion. Der er ingen grund til at registrere de nye kommandoer overalt, da crosh vil inspicere sit eget runtime-miljø for at opdage dem.
Sådan registrerer du en nyfoo
kommando.
# 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!...)
se designafsnittet nedenfor for flere detaljer om, hvad og hvordan du strukturerer den nye kommando.
Kommandohjælp
Hvis din crosh-kommando blot ringer til et eksternt program for at udføre behandlingen, og dette program allerede tilbyder brugsoplysninger, vil du sandsynligvis ikke have at duplikere ting. Du kan håndtere dette scenario ved at definere en help_foo
funktion, der foretager det respektive opkald.
# Set the help string so crosh can discover us automatically.HELP_foo=''cmd_foo() ( ...)help_foo() ( /some/command --help)
vær opmærksom på, at vi stadig indstillerHELP_foo
. Dette er nødvendigt, så crosh kan opdage OS automatisk og vise os i de relevante brugervendte lister (som kommandoen help_advanced
). Vi behøver ikke at indstille USAGE_foo
selvom siden help_foo
funktionen gør det for os.
Skjul kommandoer
hvis en kommando endnu ikke er klar til “prime time”, vil du måske have den i crosh til tidlig test, men ikke få den vist ihelp
output, hvor brugerne nemt kan opdage det (selvfølgelig er koden al offentlig, så alle, der læser den faktiske kilde, kan finde den). Sådan gør du det.
# 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() ( ...)