dette er hjemmesiden / dokumentasjonen for crosh, Chromium OS shell. Hvis Du er På En CrOS-enhet akkurat nå, bør du kunne starte crosh ved Å trykke Ctrl + Alt + T. hvis Du ikke er På CrOS, så sannsynligvis vil det ikke gjøre noe nyttig:).
bare kjør help
for å få informasjon om tilgjengelige kommandoer og oppdage mer.
du kan også bruke tabulatorfullføring for raskt å finne eksisterende kommandoer.
det er et eventyr!
- For Chromium OS Utviklere
- Sikkerhetsadvarsel
- Hvor Filer Lever
- Source Repos
- Legge Til Nye Kommandoer
- Kommandodesign
- Eksempler
- Moduloppsett
- Kommandoimplementering
- Kommando Hjelp
- Deprecating Commands
- Testing
- Iterativ Utvikling
- Unittests
- Fremtidig Arbeid
- Eldre Crosh Dokumentasjon
- Kommando API
- Kommando Hjelp
- Skjul Kommandoer
For Chromium OS Utviklere
denne delen er ment for folk hacking På Chromium OS, spesielt når de trenger å endre / utvide crosh.
Sikkerhetsadvarsel
vennligst ikke installer nye moduler uten full sikkerhetsvurdering. Enhver usikker kode som crosh laster, vil være direkte tilgjengelig for personer i verifisert modus. Det er en enkel angrepsvektor for å kjøre vilkårlig kode og rote med brukerens tilstand. Vi ønsker ikke å undergrave Sikkerheten Til CrOS!
hvis du er ute etter anmeldere, se på ./ EIERE fil.
Hvor Filer Lever
Crosh blir migrert fra skall Til Rust. Crosh begynner å kjøre fra src/main.rs, men de fleste kommandoer er implementert som egen submodul av en av modulene på høyt nivå (f.eks. base
eller dev
).
hovedcrosh
script inneholder eldre implementering av kjerne crosh logikk mens andre eldre funksjoner lever i modul kataloger. Den eldre versjonen av crosh er installert på enheten som crosh.sh
.
Source Repos
Moduler som er spesifikke for et brett, eller tungt spesifikke for en pakke, bør generelt leve med det brettet og / eller pakken. For funksjoner som alltid er tilgjengelige på Alle CrOS-enheter, bør denne koden holdes i denne repo.
hvis du er usikker, bare spør på [email protected].
Legge Til Nye Kommandoer
bestem først hvilken implementeringsstrategi den nye kommandoen skal bruke. Når du velger en strategi, hjelper det å vite hvilke tillatelser og privilegier som trengs. Med strategien i tankene, sjekk ut de ulike eksemplene nedenfor.
Kommandodesign
crosh-skallet kjører i samme miljø som nettleseren (samme bruker / gruppe, Samme Linux-navnerom, etc…). Så alle verktøy du kjører i crosh, eller informasjon du prøver å skaffe, må være tilgjengelig forchronos
bruker.
vi vil imidlertid sjelden at crosh faktisk utfører verktøy direkte. I stedet bør du legge Til d-Bus tilbakeringinger til debugd-demonen og sende alle forespørsler til den. Vi kan bedre kontrollere tilgang i debugd og låse verktøy ned. Da er den eneste logikken som eksisterer i crosh en D-Bus IPC-samtale og viser deretter utdata fra disse programmene. Diskusjon av debugd er ute av omfang her, så sjekk ut debugd-katalogen i stedet.
Eksempler
eksempel implementeringer:
- D-Bus method wrapper (debugd): base::verify_ro
Bruk dette når En D-Bus API allerede er planlagt eller crosh mangler nødvendige tillatelser eller evner. - Ekstern binær wrapper: base:: ccd_pass
Bruk dette når det allerede er et kommandolinjeverktøy som implementerer kommandoen som fungerer når du kjører som chronos med evnen til crosh. - Kommando skrevet I Rust: base::arc
Dette passer best for tilfeller der ekstra evner ikke er nødvendig, og det er ikke berettiget å ha et eget kommandolinjeverktøy.
en eksempelarbeidsflyt er inkludert nedenfor for å skrive en ny kommando.
Moduloppsett
Velg en passende modul for kommandoen å tilhøre. For dev mode kommandoer vil dette være dev
, de fleste andre kommandoer vil tilhøre base
. Dette eksemplet vil bruke base
som modul, men de samme trinnene skal fortsatt gjelde i andre tilfeller.
velg deretter et kommandonavn, opprett en undermodul med det navnet, og registrer det med overordnet modul. For dette eksemplet er kommandoen verify_ro
, så den nye kildefilen er src/base/verify_ro.rs
og to linjer må legges til src/base/mod.rs
:
først må submodulen importeres:
mod verify_ro;
for det andre må registerfunksjonen (som skal opprettes nedenfor) kalles av registerfunksjonen i foreldremodulen src/base/mod.rs
:
pub fn register(dispatcher: &mut Dispatcher) { ... verify_ro::register(dispatcher); ...}
nå ersrc/base/verify_ro.rs
kildefilen klar til å bli skrevet. Start med denne minimale kildefilen 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 forutsetter at instruksjonene ovenfor allerede er fullført.siden privilegerte operasjoner ikke kan utføres Av Crosh (men bør implementeres i debugd eller hvor som helst annet), fokuserer eksemplet nedenfor spesielt På D-Bus og antar at det er en eksisterende d-Bus-metode som må kalles fra en ny Crosh-kommando.
merk at debugds d-Bus-grensesnitt allerede har Rustbindinger generert gjennom dev-rust/system_api, slik at bindingene og d-Bus-tilkoblingen kan importeres med:
use dbus::blocking::Connection;use system_api::client::OrgChromiumDebugd;
hvis du vil bla gjennom kildekoden til de genererte bindingene, etter å ha kjørt build_packages, ta en titt på følgende sti:
/build/${BOARD}/usr/lib/cros_rust_registry/registry/system_api-*/src/bindings/client/
inne i kommandoimplementeringen må en d-bus-tilkobling initialiseres. En blokkerende tilkobling brukes i dette eksemplet.
let connection = Connection::new_system().map_err(|err| { error!("ERROR: Failed to get D-Bus connection: {}", err); dispatcher::Error::CommandReturnedError})?;
bussforbindelsen kan da brukes til å få et grensesnitt til ønsket tjeneste, som er debugd i dette tilfellet:
let conn_path = connection.with_proxy( "org.chromium.debugd", "/org/chromium/debugd", DEFAULT_DBUS_TIMEOUT,);
resten av metodekallet bruker det faktum at den importerte egenskapen system_api::client::OrgChromiumDebugd
er implementert for conn_path
så medlemsfunksjonene som kartlegger til d-bus-metoder Kan kalles 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 dekker grunnleggende. Hvis du ser på den faktiske kildekoden for base::verify_ro, det gir et mer komplisert eksempel med en startmetodeanrop, en watcher og et stoppmetodeanrop.
Kommando Hjelp
standard hjelpestrenger fylles ut ved hjelp av kommandonavnet, bruksstrengen, beskrivelsesstrengen og eventuelle alternativer eller flagg som er registrert GJENNOM dispatcher API.
Alternativt kan en hjelp tilbakeringing settes når du registrerer kommandoen for å utføre tilpasset logikk som å påkalle hjelp alternativet av en binær. Eksempelvis:
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 Commands
Hvis du vil erstatte en crosh-kommando med et annet BRUKERGRENSESNITT (som en chrome:// page), og du vil deprecate kommandoen grasiøst ved å etterlate et vennlig notat hvis folk prøver å bruke det, er det skjemaet.
# 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")
Pass på at DU legger TIL TODO-kommentaren slik at folk vet i fremtiden NÅR DET ER OK å rydde opp.
Testing
Iterativ Utvikling
du kan kjøre ./crosh
på skrivebordet ditt for å få et prøveskall. Du kan raskt teste grunnleggende interaksjoner (som argumentparsing) her, eller sjekk hjelpeutgangen. Du har ikke tilgang Til CrOS-tjenestene som mange crosh-kommandoer forventer å snakke med (via D-Bus), så disse kommandoene vil mislykkes.
hvis du vil laste dev mode moduler, kan du bruke ./crosh --dev
. Det vil bare laste lokale moduler (./dev.d/
), så hvis modulen din bor andre steder, kan du kopiere den her midlertidig.
På Samme måte, hvis du vil laste flyttbare enhetsmoduler, kan du bruke ./crosh --removable
.
Unittests
for å kjøre enheten tester enten ringe cargo test --workspace
i crosh mappen eller kjøre emege-${BOARD} crosh && FEATURES=test emerge-${BOARD}
./run_tests.sh
legacy unittest runner utfører en haug med grunnleggende stil og soliditet sjekker. Kjør det mot eventuelle endringer i shell-koden!
Fremtidig Arbeid
Alle bør gjerne hente disse ideene og prøve å implementere dem:).Flytt eventuelle gjenværende kommandoer som er implementert på plass for å feilsøke samtaler slik at De kan gjøres over D-Bus.
shell
.Eldre Crosh Dokumentasjon
Crosh ble opprinnelig skrevet i shell. I skrivende stund er mange av kommandoene fortsatt i shell og har ennå ikke blitt overført til Rust crosh. Denne dokumentasjonen holdes her for vedlikehold av disse kommandoene.
Kommando API
for hver kommando definerer du to variabler og en funksjon. Det er ikke nødvendig å registrere de nye kommandoene hvor som helst som crosh vil inspisere sin egen runtime miljø for å oppdage dem.
slik registrerer du en ny foo
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 design-delen nedenfor for mer informasjon om hva og hvordan du strukturerer den nye kommandoen.
Kommando Hjelp
hvis crosh-kommandoen bare ringer ut til et eksternt program for å gjøre behandlingen, og det programmet allerede tilbyr bruksdetaljer, vil du sannsynligvis ikke måtte duplisere ting. Du kan håndtere dette scenariet ved å definere en help_foo
funksjon som gjør det respektive anropet.
# Set the help string so crosh can discover us automatically.HELP_foo=''cmd_foo() ( ...)help_foo() ( /some/command --help)
Legg merke til at vi fortsatt angir HELP_foo
. Dette er nødvendig slik at crosh kan oppdage oss automatisk og vise oss i de relevante bruker overfor lister (somhelp_advanced
kommando). Vi trenger ikke å sette USAGE_foo
men sidenhelp_foo
funksjonen gjør det for oss.
Skjul Kommandoer
hvis en kommando ikke er klar for «prime time», vil du kanskje ha den i crosh for tidlig testing, men ikke ha den opp ihelp
utgang der brukerne enkelt kan oppdage det (selvfølgelig er koden all offentlig, så alle som leser den faktiske kilden kan finne den). Slik gjø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() ( ...)